mirror of
https://github.com/arsenetar/dupeguru.git
synced 2025-03-10 05:34:36 +00:00
Updated hscommon
This commit is contained in:
parent
4e3cad5702
commit
162378bb0a
0
hscommon/__init__.py
Normal file → Executable file
0
hscommon/__init__.py
Normal file → Executable file
@ -1,9 +1,9 @@
|
|||||||
# Created By: Virgil Dupras
|
# Created By: Virgil Dupras
|
||||||
# Created On: 2013-10-12
|
# Created On: 2013-10-12
|
||||||
# Copyright 2014 Hardcoded Software (http://www.hardcoded.net)
|
# Copyright 2014 Hardcoded Software (http://www.hardcoded.net)
|
||||||
#
|
#
|
||||||
# This software is licensed under the "BSD" License as described in the "LICENSE" file,
|
# This software is licensed under the "BSD" License as described in the "LICENSE" file,
|
||||||
# which should be included with this package. The terms are also available at
|
# which should be included with this package. The terms are also available at
|
||||||
# http://www.hardcoded.net/licenses/bsd_license
|
# http://www.hardcoded.net/licenses/bsd_license
|
||||||
|
|
||||||
import os.path as op
|
import os.path as op
|
||||||
@ -30,10 +30,10 @@ def reveal_path(path):
|
|||||||
|
|
||||||
def special_folder_path(special_folder, appname=None):
|
def special_folder_path(special_folder, appname=None):
|
||||||
"""Returns the path of ``special_folder``.
|
"""Returns the path of ``special_folder``.
|
||||||
|
|
||||||
``special_folder`` is a SpecialFolder.* const. The result is the special folder for the current
|
``special_folder`` is a SpecialFolder.* const. The result is the special folder for the current
|
||||||
application. The running process' application info is used to determine relevant information.
|
application. The running process' application info is used to determine relevant information.
|
||||||
|
|
||||||
You can override the application name with ``appname``. This argument is ingored under Qt.
|
You can override the application name with ``appname``. This argument is ingored under Qt.
|
||||||
"""
|
"""
|
||||||
return _special_folder_path(special_folder, appname)
|
return _special_folder_path(special_folder, appname)
|
||||||
@ -49,7 +49,7 @@ try:
|
|||||||
_open_url = proxy.openURL_
|
_open_url = proxy.openURL_
|
||||||
_open_path = proxy.openPath_
|
_open_path = proxy.openPath_
|
||||||
_reveal_path = proxy.revealPath_
|
_reveal_path = proxy.revealPath_
|
||||||
|
|
||||||
def _special_folder_path(special_folder, appname=None):
|
def _special_folder_path(special_folder, appname=None):
|
||||||
if special_folder == SpecialFolder.Cache:
|
if special_folder == SpecialFolder.Cache:
|
||||||
base = proxy.getCachePath()
|
base = proxy.getCachePath()
|
||||||
@ -58,7 +58,7 @@ try:
|
|||||||
if not appname:
|
if not appname:
|
||||||
appname = proxy.bundleInfo_('CFBundleName')
|
appname = proxy.bundleInfo_('CFBundleName')
|
||||||
return op.join(base, appname)
|
return op.join(base, appname)
|
||||||
|
|
||||||
except ImportError:
|
except ImportError:
|
||||||
try:
|
try:
|
||||||
from PyQt5.QtCore import QUrl, QStandardPaths
|
from PyQt5.QtCore import QUrl, QStandardPaths
|
||||||
@ -69,26 +69,25 @@ except ImportError:
|
|||||||
def _open_path(path):
|
def _open_path(path):
|
||||||
url = QUrl.fromLocalFile(str(path))
|
url = QUrl.fromLocalFile(str(path))
|
||||||
QDesktopServices.openUrl(url)
|
QDesktopServices.openUrl(url)
|
||||||
|
|
||||||
def _reveal_path(path):
|
def _reveal_path(path):
|
||||||
_open_path(op.dirname(str(path)))
|
_open_path(op.dirname(str(path)))
|
||||||
|
|
||||||
def _special_folder_path(special_folder, appname=None):
|
def _special_folder_path(special_folder, appname=None):
|
||||||
if special_folder == SpecialFolder.Cache:
|
if special_folder == SpecialFolder.Cache:
|
||||||
qtfolder = QStandardPaths.CacheLocation
|
qtfolder = QStandardPaths.CacheLocation
|
||||||
else:
|
else:
|
||||||
qtfolder = QStandardPaths.DataLocation
|
qtfolder = QStandardPaths.DataLocation
|
||||||
return QStandardPaths.standardLocations(qtfolder)[0]
|
return QStandardPaths.standardLocations(qtfolder)[0]
|
||||||
|
|
||||||
except ImportError:
|
except ImportError:
|
||||||
# We're either running tests, and these functions don't matter much or we're in a really
|
# We're either running tests, and these functions don't matter much or we're in a really
|
||||||
# weird situation. Let's just have dummy fallbacks.
|
# weird situation. Let's just have dummy fallbacks.
|
||||||
logging.warning("Can't setup desktop functions!")
|
logging.warning("Can't setup desktop functions!")
|
||||||
def _open_path(path):
|
def _open_path(path):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def _reveal_path(path):
|
def _reveal_path(path):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def _special_folder_path(special_folder, appname=None):
|
def _special_folder_path(special_folder, appname=None):
|
||||||
return '/tmp'
|
return '/tmp'
|
||||||
|
179
hscommon/reg.py
179
hscommon/reg.py
@ -1,179 +0,0 @@
|
|||||||
# Created By: Virgil Dupras
|
|
||||||
# Created On: 2009-05-16
|
|
||||||
# Copyright 2014 Hardcoded Software (http://www.hardcoded.net)
|
|
||||||
|
|
||||||
# This software is licensed under the "BSD" License as described in the "LICENSE" file,
|
|
||||||
# which should be included with this package. The terms are also available at
|
|
||||||
# http://www.hardcoded.net/licenses/bsd_license
|
|
||||||
|
|
||||||
import re
|
|
||||||
from hashlib import md5
|
|
||||||
|
|
||||||
from . import desktop
|
|
||||||
from .trans import trget
|
|
||||||
|
|
||||||
tr = trget('hscommon')
|
|
||||||
|
|
||||||
ALL_APPS = [
|
|
||||||
(1, 'dupeGuru'),
|
|
||||||
(2, 'moneyGuru'),
|
|
||||||
(3, 'musicGuru'),
|
|
||||||
(6, 'PdfMasher'),
|
|
||||||
]
|
|
||||||
|
|
||||||
OLDAPPIDS = {
|
|
||||||
1: {1, 4, 5},
|
|
||||||
2: {6, },
|
|
||||||
3: {2, },
|
|
||||||
}
|
|
||||||
|
|
||||||
class InvalidCodeError(Exception):
|
|
||||||
"""The supplied code is invalid."""
|
|
||||||
|
|
||||||
DEMO_PROMPT = tr("{name} is fairware, which means \"open source software developed with expectation "
|
|
||||||
"of fair contributions from users\". It's a very interesting concept, but one year of fairware has "
|
|
||||||
"shown that most people just want to know how much it costs and not be bothered with theories "
|
|
||||||
"about intellectual property."
|
|
||||||
"\n\n"
|
|
||||||
"So I won't bother you and will be very straightforward: You can try {name} for free but you have "
|
|
||||||
"to buy it in order to use it without limitations. In demo mode, {name} {limitation}."
|
|
||||||
"\n\n"
|
|
||||||
"So it's as simple as this. If you're curious about fairware, however, I encourage you to read "
|
|
||||||
"more about it by clicking on the \"Fairware?\" button.")
|
|
||||||
|
|
||||||
class RegistrableApplication:
|
|
||||||
#--- View interface
|
|
||||||
# get_default(key_name)
|
|
||||||
# set_default(key_name, value)
|
|
||||||
# setup_as_registered()
|
|
||||||
# show_message(msg)
|
|
||||||
# show_demo_nag(prompt)
|
|
||||||
|
|
||||||
PROMPT_NAME = "<undefined>"
|
|
||||||
DEMO_LIMITATION = "<undefined>"
|
|
||||||
|
|
||||||
def __init__(self, view, appid):
|
|
||||||
self.view = view
|
|
||||||
self.appid = appid
|
|
||||||
self.registered = False
|
|
||||||
self.fairware_mode = False
|
|
||||||
self.registration_code = ''
|
|
||||||
self.registration_email = ''
|
|
||||||
self._unpaid_hours = None
|
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def _is_code_valid(appid, code, email):
|
|
||||||
if len(code) != 32:
|
|
||||||
return False
|
|
||||||
appid = str(appid)
|
|
||||||
for i in range(100):
|
|
||||||
blob = appid + email + str(i) + 'aybabtu'
|
|
||||||
digest = md5(blob.encode('utf-8')).hexdigest()
|
|
||||||
if digest == code:
|
|
||||||
return True
|
|
||||||
return False
|
|
||||||
|
|
||||||
def _set_registration(self, code, email):
|
|
||||||
self.validate_code(code, email)
|
|
||||||
self.registration_code = code
|
|
||||||
self.registration_email = email
|
|
||||||
self.registered = True
|
|
||||||
self.view.setup_as_registered()
|
|
||||||
|
|
||||||
def initial_registration_setup(self):
|
|
||||||
# Should be called only after the app is finished launching
|
|
||||||
if self.registered:
|
|
||||||
# We've already set registration in a hardcoded way (for example, for the Ubuntu Store)
|
|
||||||
# Just ignore registration, but not before having set as registered.
|
|
||||||
self.view.setup_as_registered()
|
|
||||||
return
|
|
||||||
code = self.view.get_default('RegistrationCode')
|
|
||||||
email = self.view.get_default('RegistrationEmail')
|
|
||||||
if code and email:
|
|
||||||
try:
|
|
||||||
self._set_registration(code, email)
|
|
||||||
except InvalidCodeError:
|
|
||||||
pass
|
|
||||||
if not self.registered:
|
|
||||||
if self.view.get_default('FairwareMode'):
|
|
||||||
self.fairware_mode = True
|
|
||||||
if not self.fairware_mode:
|
|
||||||
prompt = DEMO_PROMPT.format(name=self.PROMPT_NAME, limitation=self.DEMO_LIMITATION)
|
|
||||||
self.view.show_demo_nag(prompt)
|
|
||||||
|
|
||||||
def validate_code(self, code, email):
|
|
||||||
code = code.strip().lower()
|
|
||||||
email = email.strip().lower()
|
|
||||||
if self._is_code_valid(self.appid, code, email):
|
|
||||||
return
|
|
||||||
# Check if it's not an old reg code
|
|
||||||
for oldappid in OLDAPPIDS.get(self.appid, []):
|
|
||||||
if self._is_code_valid(oldappid, code, email):
|
|
||||||
return
|
|
||||||
# let's see if the user didn't mix the fields up
|
|
||||||
if self._is_code_valid(self.appid, email, code):
|
|
||||||
msg = "Invalid Code. It seems like you inverted the 'Registration Code' and"\
|
|
||||||
"'Registration E-mail' field."
|
|
||||||
raise InvalidCodeError(msg)
|
|
||||||
# Is the code a paypal transaction id?
|
|
||||||
if re.match(r'^[a-z\d]{17}$', code) is not None:
|
|
||||||
msg = "The code you submitted looks like a Paypal transaction ID. Registration codes are "\
|
|
||||||
"32 digits codes which you should have received in a separate e-mail. If you haven't "\
|
|
||||||
"received it yet, please visit http://www.hardcoded.net/support/"
|
|
||||||
raise InvalidCodeError(msg)
|
|
||||||
# Invalid, let's see if it's a code for another app.
|
|
||||||
for appid, appname in ALL_APPS:
|
|
||||||
if self._is_code_valid(appid, code, email):
|
|
||||||
msg = "This code is a {0} code. You're running the wrong application. You can "\
|
|
||||||
"download the correct application at http://www.hardcoded.net".format(appname)
|
|
||||||
raise InvalidCodeError(msg)
|
|
||||||
DEFAULT_MSG = "Your code is invalid. Make sure that you wrote the good code. Also make sure "\
|
|
||||||
"that the e-mail you gave is the same as the e-mail you used for your purchase."
|
|
||||||
raise InvalidCodeError(DEFAULT_MSG)
|
|
||||||
|
|
||||||
def set_registration(self, code, email, register_os):
|
|
||||||
if not self.fairware_mode and 'fairware' in {code.strip().lower(), email.strip().lower()}:
|
|
||||||
self.fairware_mode = True
|
|
||||||
self.view.set_default('FairwareMode', True)
|
|
||||||
self.view.show_message("Fairware mode enabled.")
|
|
||||||
return True
|
|
||||||
try:
|
|
||||||
self._set_registration(code, email)
|
|
||||||
self.view.show_message("Your code is valid. Thanks!")
|
|
||||||
if register_os:
|
|
||||||
self.register_os()
|
|
||||||
self.view.set_default('RegistrationCode', self.registration_code)
|
|
||||||
self.view.set_default('RegistrationEmail', self.registration_email)
|
|
||||||
return True
|
|
||||||
except InvalidCodeError as e:
|
|
||||||
self.view.show_message(str(e))
|
|
||||||
return False
|
|
||||||
|
|
||||||
def register_os(self):
|
|
||||||
# We don't do that anymore.
|
|
||||||
pass
|
|
||||||
|
|
||||||
def contribute(self):
|
|
||||||
desktop.open_url("http://open.hardcoded.net/contribute/")
|
|
||||||
|
|
||||||
def buy(self):
|
|
||||||
desktop.open_url("http://www.hardcoded.net/purchase.htm")
|
|
||||||
|
|
||||||
def about_fairware(self):
|
|
||||||
desktop.open_url("http://open.hardcoded.net/about/")
|
|
||||||
|
|
||||||
@property
|
|
||||||
def should_show_fairware_reminder(self):
|
|
||||||
return (not self.registered) and (self.fairware_mode) and (self.unpaid_hours >= 1)
|
|
||||||
|
|
||||||
@property
|
|
||||||
def should_apply_demo_limitation(self):
|
|
||||||
return (not self.registered) and (not self.fairware_mode)
|
|
||||||
|
|
||||||
@property
|
|
||||||
def unpaid_hours(self):
|
|
||||||
# We don't bother verifying unpaid hours anymore, the only app that still has fairware
|
|
||||||
# dialogs is dupeGuru and it has a huge surplus. Now, "fairware mode" really means
|
|
||||||
# "free mode".
|
|
||||||
return 0
|
|
||||||
|
|
Loading…
x
Reference in New Issue
Block a user