From 3ce822fc275a9b613f370b2dbdb4fd17cd6a8a8d Mon Sep 17 00:00:00 2001 From: "emdee@spm.plastiras.org" Date: Sat, 3 Feb 2024 04:34:10 +0000 Subject: [PATCH] update --- README.md | 4 +++ pyproject.tom | 51 ++++++++++++++++++++++++++++ requirements.txt | 5 +++ setup.py | 10 ++++-- toxygen/av/calls.py | 3 +- toxygen/contacts/basecontact.py | 6 ++++ toxygen/contacts/contact_provider.py | 20 +++++++---- toxygen/contacts/contacts_manager.py | 37 +++++++++++++------- toxygen/contacts/group_chat.py | 4 +-- toxygen/main.py | 23 +++++++++---- toxygen/messenger/messenger.py | 24 +++++++++---- toxygen/middleware/callbacks.py | 6 +++- toxygen/middleware/tox_factory.py | 9 ++--- toxygen/notifications/sound.py | 7 ++-- toxygen/tests/tests_wrapper.py | 2 +- toxygen/ui/av_widgets.py | 3 +- toxygen/ui/menu.py | 4 ++- toxygen/user_data/settings.py | 48 +++++++++++++++----------- 18 files changed, 198 insertions(+), 68 deletions(-) create mode 100644 pyproject.tom diff --git a/README.md b/README.md index eebbfe4..22fc9d4 100644 --- a/README.md +++ b/README.md @@ -85,3 +85,7 @@ Work on Tox on this project is suspended until the This will probably be ported to Qt6 using qtpy https://github.com/spyder-ide/qtpy . +Up-to-date code is on https://git.plastiras.org/emdee/toxygen + +Work on this project is suspended until the +[MultiDevice](https://git.plastiras.org/emdee/tox_profile/wiki/MultiDevice-Announcements-POC) problem is solved. Fork me! diff --git a/pyproject.tom b/pyproject.tom new file mode 100644 index 0000000..3a178d7 --- /dev/null +++ b/pyproject.tom @@ -0,0 +1,51 @@ +[project] +name = "stem_examples" +description = "examples of using stem" +authors = [{ name = "emdee", email = "emdee@spm.plastiras.org" } ] +requires-python = ">=3.6" +dependencies = [ + 'stem', +] +keywords = ["stem", "python3", "tor"] +classifiers = [ + "License :: OSI Approved", + "Operating System :: POSIX :: BSD :: FreeBSD", + "Operating System :: POSIX :: Linux", + "Programming Language :: Python :: 3 :: Only", + "Programming Language :: Python :: 3.6", + "Programming Language :: Python :: 3.7", + "Programming Language :: Python :: 3.8", + "Programming Language :: Python :: 3.9", + "Programming Language :: Python :: 3.10", + "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: Implementation :: CPython", + ] +# +dynamic = ["version", "readme", ] # cannot be dynamic ['license'] + +[project.scripts] +toxygen = "toxygen.toxygen.main:main" + +#[project.license] +#file = "LICENSE.md" + +[project.urls] +repository = "https://git.plastiras.org/emdee/toxygen" + +[build-system] +requires = ["setuptools >= 61.0"] +build-backend = "setuptools.build_meta" + +[tool.setuptools.dynamic] +version = {attr = "stem_examples.__version__"} +readme = {file = ["README.md", "ToDo.txt"]} + +[tool.setuptools] +packages = ["toxygen"] + +[tool.setuptools.packages.find] +where = "toxygen" + +[tool.setuptools.packages.package-data] +"*" = ["*.ui"] + diff --git a/requirements.txt b/requirements.txt index b38e8ac..20bb04b 100644 --- a/requirements.txt +++ b/requirements.txt @@ -4,3 +4,8 @@ numpy opencv-python pydenticon cv2 +gevent +greenlet +pydenticon +pyqtconsole +toxygen_wrapper diff --git a/setup.py b/setup.py index 25f8bde..a3f543d 100644 --- a/setup.py +++ b/setup.py @@ -5,8 +5,7 @@ from setuptools.command.install import install version = '1.0.0' -MODULES = ['argparse', 'PyQt5', 'PyAudio', 'numpy', 'opencv-python', 'cv2', - 'pydenticon', 'pyqtconsole', 'toxygen_wrapper'] # qweechat +MODULES = open('requirements.txt', 'rt').readlines() def get_packages(): directory = os.path.join(os.path.dirname(__file__), 'tox_wrapper') @@ -35,11 +34,18 @@ setup(name='Toxygen', include_package_data=True, classifiers=[ 'Programming Language :: Python :: 3 :: Only', + "Programming Language :: Python :: 3.6", + "Programming Language :: Python :: 3.7", + "Programming Language :: Python :: 3.8", + "Programming Language :: Python :: 3.9", + "Programming Language :: Python :: 3.10", + "Programming Language :: Python :: 3.11", 'Programming Language :: Python :: 3.11', ], entry_points={ 'console_scripts': ['toxygen=toxygen.main:main'] }, + package_data={"": ["*.ui"],}, cmdclass={ 'install': InstallScript, }, diff --git a/toxygen/av/calls.py b/toxygen/av/calls.py index 8fdfa10..81aa440 100644 --- a/toxygen/av/calls.py +++ b/toxygen/av/calls.py @@ -1,5 +1,4 @@ # -*- mode: python; indent-tabs-mode: nil; py-indent-offset: 4; coding: utf-8 -*- -import pyaudio import time import threading import itertools @@ -8,6 +7,8 @@ from tox_wrapper.toxav_enums import * from tox_wrapper.tests import support_testing as ts from tox_wrapper.tests.support_testing import LOG_ERROR, LOG_WARN, LOG_INFO, LOG_DEBUG, LOG_TRACE +with ts.ignoreStderr(): + import pyaudio from av import screen_sharing from av.call import Call import common.tox_save diff --git a/toxygen/contacts/basecontact.py b/toxygen/contacts/basecontact.py index c80a75d..21fdcbb 100644 --- a/toxygen/contacts/basecontact.py +++ b/toxygen/contacts/basecontact.py @@ -161,6 +161,12 @@ class BaseContact: # Widgets def init_widget(self): + # File "/mnt/o/var/local/src/toxygen/toxygen/contacts/contacts_manager.py", line 252, in filtration_and_sorting + # contact.set_widget(item_widget) + # File "/mnt/o/var/local/src/toxygen/toxygen/contacts/contact.py", line 320, in set_widget + if not self._widget: + LOG_WARN("BC.init_widget self._widget is NULL") + return self._widget.name.setText(self._name) self._widget.status_message.setText(self._status_message) if hasattr(self._widget, 'kind'): diff --git a/toxygen/contacts/contact_provider.py b/toxygen/contacts/contact_provider.py index a9d16a6..09fbde2 100644 --- a/toxygen/contacts/contact_provider.py +++ b/toxygen/contacts/contact_provider.py @@ -33,9 +33,11 @@ class ContactProvider(tox_save.ToxSave): if friend is not None: return friend friend = self._friend_factory.create_friend_by_public_key(public_key) - self._add_to_cache(public_key, friend) - LOG_INFO(f"CP.get_friend_by_public_key ADDED {friend} ") - + if friend is None: + LOG_WARN(f"CP.get_friend_by_public_key NULL {friend} ") + else: + self._add_to_cache(public_key, friend) + LOG_DEBUG(f"CP.get_friend_by_public_key ADDED {friend} ") return friend def get_all_friends(self): @@ -72,7 +74,7 @@ class ContactProvider(tox_save.ToxSave): def get_group_by_number(self, group_number): group = None try: - LOG_INFO(f"CP.CP.group_get_number {group_number} ") +# LOG_DEBUG(f"CP.CP.group_get_number {group_number} ") # original code chat_id = self._tox.group_get_chat_id(group_number) if chat_id is None: @@ -110,7 +112,7 @@ class ContactProvider(tox_save.ToxSave): return group group = self._group_factory.create_group_by_public_key(public_key) if group is None: - LOG_ERROR(f"get_group_by_public_key NULL group public_key={public_key}") + LOG_WARN(f"get_group_by_public_key NULL group public_key={public_key}") else: self._add_to_cache(public_key, group) @@ -123,13 +125,17 @@ class ContactProvider(tox_save.ToxSave): def get_group_peer_by_id(self, group, peer_id): peer = group.get_peer_by_id(peer_id) - if peer: + if peer is not None: return self._get_group_peer(group, peer) + LOG_WARN(f"get_group_peer_by_id peer_id={peer_id}") + return None def get_group_peer_by_public_key(self, group, public_key): peer = group.get_peer_by_public_key(public_key) - if peer: + if peer is not None: return self._get_group_peer(group, peer) + LOG_WARN(f"get_group_peer_by_public_key public_key={public_key}") + return None # All contacts diff --git a/toxygen/contacts/contacts_manager.py b/toxygen/contacts/contacts_manager.py index 951388f..f830930 100644 --- a/toxygen/contacts/contacts_manager.py +++ b/toxygen/contacts/contacts_manager.py @@ -99,6 +99,10 @@ class ContactsManager(ToxSave): LOG.warn(f"ERROR NULL {self._contacts[self._active_contact]} {contact.tox_id}") return False + if not hasattr(contact, 'tox_id'): + LOG.warn(f"ERROR is_contact_active no contact.tox_id {type(contact)} contact={contact}") + return False + return self._contacts[self._active_contact].tox_id == contact.tox_id # Reconnection support @@ -142,7 +146,11 @@ class ContactsManager(ToxSave): current_contact.curr_text = self._screen.messageEdit.toPlainText() except: pass + # IndexError: list index out of range + if value >= len(self._contacts): + LOG.warn("CM.set_active value too big: {{self._contacts}}") + return contact = self._contacts[value] self._subscribe_to_events(contact) contact.remove_invalid_unsent_files() @@ -171,9 +179,8 @@ class ContactsManager(ToxSave): # self._screen.call_finished() self._set_current_contact_data(contact) self._active_contact_changed(contact) - except Exception as ex: # no friend found. ignore - LOG.warn(f"no friend found. Friend value: {value!s}") - LOG.error('in set active: ' + str(ex)) + except Exception as e: # no friend found. ignore + LOG.warn(f"CM.set_active EXCEPTION value:{value} len={len(self._contacts)} {e}") # gulp raise active_contact = property(get_active, set_active) @@ -249,6 +256,9 @@ class ContactsManager(ToxSave): for index, contact in enumerate(self._contacts): list_item = self._screen.friends_list.item(index) item_widget = self._screen.friends_list.itemWidget(list_item) + if not item_widget: + LOG_WARN("CM.filtration_and_sorting( item_widget is NULL") + continue contact.set_widget(item_widget) for index, friend in enumerate(self._contacts): @@ -287,16 +297,16 @@ class ContactsManager(ToxSave): def get_or_create_group_peer_contact(self, group_number, peer_id): group = self.get_group_by_number(group_number) peer = group.get_peer_by_id(peer_id) - if peer is None: # broken? is 0 allowed? - if not hasattr(peer, 'public_key') or not peer.public_key: - LOG.error(f'no peer public_key ' + repr(dir(peer))) - else: - if not self.check_if_contact_exists(peer.public_key): - self.add_group_peer(group, peer) - return self.get_contact_by_tox_id(peer.public_key) - else: - LOG.warn(f'no peer group_number={group_number} peer_id={peer_id}') - return peer + if peer is None: + LOG.warn(f'get_or_create_group_peer_contact group_number={group_number} peer_id={peer_id} peer={peer}') + return None + LOG.debug(f'get_or_create_group_peer_contact group_number={group_number} peer_id={peer_id} peer={peer}') + if not self.check_if_contact_exists(peer.public_key): + contact = self.add_group_peer(group, peer) + # dunno + return contact + # me - later wrong kind of object? + return self.get_contact_by_tox_id(peer.public_key) def check_if_contact_exists(self, tox_id): return any(filter(lambda c: c.tox_id == tox_id, self._contacts)) @@ -436,6 +446,7 @@ class ContactsManager(ToxSave): self._contacts.append(contact) contact.reset_avatar(self._settings['identicons']) self._save_profile() + return contact def remove_group_peer_by_id(self, group, peer_id): peer = group.get_peer_by_id(peer_id) diff --git a/toxygen/contacts/group_chat.py b/toxygen/contacts/group_chat.py index dbe1019..c6f11e0 100644 --- a/toxygen/contacts/group_chat.py +++ b/toxygen/contacts/group_chat.py @@ -107,7 +107,7 @@ class GroupChat(contact.Contact, ToxSave): return peers[0] else: LOG_WARN(f"get_peer_by_id empty peers for {peer_id}") - return [] + return None def get_peer_by_public_key(self, public_key): peers = list(filter(lambda p: p.public_key == public_key, self._peers)) @@ -117,7 +117,7 @@ class GroupChat(contact.Contact, ToxSave): return peers[0] else: LOG_WARN(f"get_peer_by_public_key empty peers for {public_key}") - return [] + return None def remove_all_peers_except_self(self): self._peers = self._peers[:1] diff --git a/toxygen/main.py b/toxygen/main.py index e4d5849..a73cd3d 100644 --- a/toxygen/main.py +++ b/toxygen/main.py @@ -72,7 +72,11 @@ def setup_default_audio(): def setup_video(oArgs): video = setup_default_video() - if oArgs.video_input == '-1': + # this is messed up - no video_input in oArgs + # parser.add_argument('--video_input', type=str,) + if not hasattr(oArgs, 'video_input'): + video['device'] = video['output_devices'][0] + elif oArgs.video_input == '-1': video['device'] = video['output_devices'][1] else: video['device'] = oArgs.video_input @@ -165,7 +169,7 @@ def setup_audio(oArgs): def setup_default_video(): default_video = ["-1"] default_video.extend(ts.get_video_indexes()) - LOG.info(f"Video input choices: {default_video!r}") + LOG.info(f"Video input choices: {default_video}") video = {'device': -1, 'width': 320, 'height': 240, 'x': 0, 'y': 0} video['output_devices'] = default_video return video @@ -179,7 +183,7 @@ def main_parser(_=None, iMode=2): lIpV6Choices=[bIpV6, 'False'] audio = setup_default_audio() - default_video = setup_default_video() + default_video = setup_default_video()['output_devices'] parser = ts.oMainArgparser() parser.add_argument('--version', action='store_true', help='Prints Toxygen version') @@ -225,7 +229,7 @@ def main_parser(_=None, iMode=2): help='Update program (broken)') parser.add_argument('--video_input', type=str, default=-1, - choices=default_video['output_devices'], + choices=default_video, help="Video input device number - /dev/video?") parser.add_argument('--audio_input', type=str, default=oPYA.get_default_input_device_info()['name'], @@ -266,6 +270,8 @@ lKEEP_SETTINGS = ['uri', 'ipv6_enabled', 'udp_enabled', 'local_discovery_enabled', + 'trace_enabled', + 'theme', 'network', 'message_font_size', @@ -283,9 +289,11 @@ lKEEP_SETTINGS = ['uri', class A(): pass -def main(lArgs): +def main(lArgs=None): global oPYA from argparse import Namespace + if lArgs is None: + lArgs = sys.argv[1:] parser = main_parser() default_ns = parser.parse_args([]) oArgs = parser.parse_args(lArgs) @@ -328,7 +336,10 @@ def main(lArgs): oApp = app.App(__version__, oArgs) # for pyqtconsole - __builtins__.app = oApp + try: + setattr(__builtins__, 'app', oApp) + except Exception as e: + pass i = oApp.iMain() return i diff --git a/toxygen/messenger/messenger.py b/toxygen/messenger/messenger.py index 534ebc0..50795bf 100644 --- a/toxygen/messenger/messenger.py +++ b/toxygen/messenger/messenger.py @@ -192,21 +192,33 @@ class Messenger(tox_save.ToxSave): return if group.number < 0: return - if peer_id and peer_id < 0: + if peer_id is not None and peer_id < 0: return assert_main_thread() - # FixMe: peer_id is None? - group_peer_contact = self._contacts_manager.get_or_create_group_peer_contact(group_number, peer_id) - # group_peer_contact now may be None group = self._get_group_by_number(group_number) messages = self._split_message(text.encode('utf-8')) + + # FixMe: peer_id is None? + group_peer_contact = self._contacts_manager.get_or_create_group_peer_contact(group_number, peer_id) + if group_peer_contact is None: + LOG.warn("M.group_send_private_message group_peer_contact is None") + return + # group_peer_contact now may be None + t = util.get_unix_time() for message in messages: - self._tox.group_send_private_message(group_number, peer_id, message_type, message) + bRet = self._tox.group_send_private_message(group_number, peer_id, message_type, message) + if not bRet: + LOG.warn("M.group_send_private_messag failed") + continue message_author = MessageAuthor(group.get_self_name(), MESSAGE_AUTHOR['GC_PEER']) message = OutgoingTextMessage(text, message_author, t, message_type) - group_peer_contact.append_message(message) + # AttributeError: 'GroupChatPeer' object has no attribute 'append_message' + if not hasattr(group_peer_contact, 'append_message'): + LOG.warn("M. group_peer_contact has no append_message group_peer_contact={group_peer_contact}") + else: + group_peer_contact.append_message(message) if not self._contacts_manager.is_contact_active(group_peer_contact): return self._create_message_item(message) diff --git a/toxygen/middleware/callbacks.py b/toxygen/middleware/callbacks.py index cd6f807..3421fdc 100644 --- a/toxygen/middleware/callbacks.py +++ b/toxygen/middleware/callbacks.py @@ -473,7 +473,11 @@ def group_private_message(window, tray, tox, messenger, settings, profile): if window.isActiveWindow(): return bl = settings['notify_all_gc'] or profile.name in message - name = tox.group_peer_get_name(group_number, peer_id) + try: + name = tox.group_peer_get_name(group_number, peer_id) + except Exception as e: + LOG_WARN("tox.group_peer_get_name {group_number} {peer_id}") + name = '' if settings['notifications'] and settings['tray_icon'] \ and profile.status != TOX_USER_STATUS['BUSY'] \ and (not settings.locked) and bl: diff --git a/toxygen/middleware/tox_factory.py b/toxygen/middleware/tox_factory.py index 4562714..dfb3a1a 100644 --- a/toxygen/middleware/tox_factory.py +++ b/toxygen/middleware/tox_factory.py @@ -69,12 +69,9 @@ def tox_factory(data=None, settings=None, args=None, app=None): if 'trace_enabled' in settings and not settings['trace_enabled']: LOG_DEBUG("settings['trace_enabled' disabled" ) - elif tox_options._options_pointer: - c_callback = CFUNCTYPE(None, c_void_p, c_int, c_char_p, c_int, c_char_p, c_char_p, c_void_p) - tox_options.self_logger_cb = c_callback(ts.tox_log_cb) - tox_wrapper.tox.Tox.libtoxcore.tox_options_set_log_callback( - tox_options._options_pointer, - tox_options.self_logger_cb) + elif tox_options._options_pointer and \ + 'trace_enabled' in settings and settings['trace_enabled']: + ts.vAddLoggerCallback(tox_options) LOG_INFO("c-toxcore trace_enabled enabled" ) else: LOG_WARN("No tox_options._options_pointer to add self_logger_cb" ) diff --git a/toxygen/notifications/sound.py b/toxygen/notifications/sound.py index a106e80..5a65548 100644 --- a/toxygen/notifications/sound.py +++ b/toxygen/notifications/sound.py @@ -1,7 +1,10 @@ +import os.path import utils.util import wave -import pyaudio -import os.path + +import tox_wrapper.tests.support_testing as ts +with ts.ignoreStderr(): + import pyaudio global LOG import logging diff --git a/toxygen/tests/tests_wrapper.py b/toxygen/tests/tests_wrapper.py index 19cffce..a4eebf4 100644 --- a/toxygen/tests/tests_wrapper.py +++ b/toxygen/tests/tests_wrapper.py @@ -1756,7 +1756,7 @@ class ToxSuite(unittest.TestCase): else: LOG.info("passed test_tox_savedata") -def vOargsToxPreamble(oArgs, Tox, ToxTest): +def vOargsToxPreamble(oArgs, Tox, ToxTest) -> None: ts.vSetupLogging(oArgs) diff --git a/toxygen/ui/av_widgets.py b/toxygen/ui/av_widgets.py index 8ea7180..deacd37 100644 --- a/toxygen/ui/av_widgets.py +++ b/toxygen/ui/av_widgets.py @@ -1,12 +1,13 @@ import threading from PyQt5 import QtCore, QtGui, QtWidgets -import pyaudio import wave from ui import widgets import utils.util as util import tox_wrapper.tests.support_testing as ts +with ts.ignoreStderr(): + import pyaudio global LOG import logging diff --git a/toxygen/ui/menu.py b/toxygen/ui/menu.py index 1111679..269bf18 100644 --- a/toxygen/ui/menu.py +++ b/toxygen/ui/menu.py @@ -1,6 +1,6 @@ # -*- mode: python; indent-tabs-mode: nil; py-indent-offset: 4; coding: utf-8 -*- from PyQt5 import QtCore, QtGui, QtWidgets, uic -import pyaudio + from user_data.settings import * from utils.util import * @@ -8,6 +8,8 @@ from ui.widgets import CenteredWidget, DataLabel, LineEdit, RubberBandWindow import updater.updater as updater import utils.ui as util_ui import tox_wrapper.tests.support_testing as ts +with ts.ignoreStderr(): + import pyaudio from user_data import settings global LOG diff --git a/toxygen/user_data/settings.py b/toxygen/user_data/settings.py index d5002e8..644d0f2 100644 --- a/toxygen/user_data/settings.py +++ b/toxygen/user_data/settings.py @@ -17,7 +17,6 @@ LOG = logging.getLogger('settings') def merge_args_into_settings(args, settings): if args: - print(repr(args.__dict__.keys())) if not hasattr(args, 'audio'): LOG.warn('No audio ' +repr(args)) settings['audio'] = getattr(args, 'audio') @@ -131,17 +130,17 @@ class Settings(dict): Settings of current profile + global app settings """ - def __init__(self, toxes, path, app): - self._path = path - self._profile_path = path.replace('.json', '.tox') + def __init__(self, toxes, json_path, app): self._toxes = toxes self._app = app self._path = app._path self._args = app._args self._oArgs = app._args self._log = lambda l: LOG.log(self._oArgs.loglevel, l) + self._profile_path = app._path # json_path.replace('.json', '.tox') self._settings_saved_event = Event() + path = json_path.replace('.tox', '.json') if path and os.path.isfile(path): try: with open(path, 'rb') as fl: @@ -151,9 +150,9 @@ class Settings(dict): info = json.loads(str(data, 'utf-8')) LOG.debug('Parsed settings from: ' + str(path)) except Exception as ex: - title = 'Error opening/parsing settings file: ' - text = title + path - LOG.error(title +str(ex)) + title = f"Error opening/parsing settings file:" + text = title +f"\n{path}\n" + LOG.error(text +str(ex)) util_ui.message_box(text, title) info = Settings.get_default_settings(app._args) user_data.settings.clean_settings(info) @@ -161,7 +160,7 @@ class Settings(dict): LOG.debug('get_default_settings for: ' + repr(path)) info = Settings.get_default_settings(app._args) - if not os.path.exists(path): + if not path or not os.path.exists(path): merge_args_into_settings(app._args, info) else: aC = self._changed(app._args, info) @@ -178,12 +177,16 @@ class Settings(dict): merge_args_into_settings(app._args, info) info['audio'] = getattr(app._args, 'audio') info['video'] = getattr(app._args, 'video') - info['trace_enabled'] = getattr(app._args, 'trace_enabled') + if getattr(app._args, 'trace_enabled'): + info['trace_enabled'] = getattr(app._args, 'trace_enabled') + else: + LOG.warn("app._args, 'trace_enabled") + info['trace_enabled'] = False super().__init__(info) self._upgrade() LOG.info('Parsed settings from: ' + str(path)) - ex = f"self=id(self) {self!r}" + ex = f"self=id(self) {self}" LOG.debug(ex) self.save() @@ -206,10 +209,16 @@ class Settings(dict): text = bytes(self._toxes.pass_encrypt(bytes(text, 'utf-8'))) else: text = bytes(text, 'utf-8') + if not self._path: + #? + self._path = os.path.join(get_user_config_path(), 'toxygen.json') tmp = self._path + str(os.getpid()) try: with open(tmp, 'wb') as fl: fl.write(text) + if os.path.exists(self._path+'.bak'): + os.remove(self._path+'.bak') + os.rename(self._path, self._path+'.bak') os.rename(tmp, self._path) except Exception as e: LOG.warn(f'Error saving to {self._path} ' +str(e)) @@ -221,17 +230,17 @@ class Settings(dict): if os.path.isfile(path): os.remove(path) - def set_active_profile(self): + def set_active_profile(self, profile_path): """ Mark current profile as active """ - path = self._profile_path + '.lock' + path = profile_path + '.lock' try: import shutil except: pass else: - shutil.copy2(self._profile_path, path) + shutil.copy2(profile_path, path) # need to open this with the same perms as _profile_path # copy profile_path and then write? with open(path, 'wb') as fl: @@ -250,9 +259,9 @@ class Settings(dict): # Static methods @staticmethod - def get_auto_profile(): + def get_auto_profile(appdir): # self._path = - p = os.path.join(os.path.dirname(self._app._path), 'toxygen.json') + p = os.path.join(appdir, 'toxygen.json') if not os.path.isfile(p): return None with open(p) as fl: @@ -260,14 +269,15 @@ class Settings(dict): try: auto = json.loads(data) except Exception as ex: - LOG.warn(f"json.loads {data}: {ex!s}") + LOG.warn(f"json.loads {data}: {ex}") auto = {} if 'profile_path' in auto: path = str(auto['profile_path']) if not os.path.isabs(path): - path = join_path(path, curr_directory(__file__)) + path = join_path(path, os.path.dirname(os.path.realpath(__file__))) if os.path.isfile(path): return path + return None @staticmethod def supported_languages(): @@ -276,7 +286,7 @@ class Settings(dict): @staticmethod def set_auto_profile(path): - p = os.path.join(os.path.dirname(self._app._path), 'toxygen.json') + p = os.path.join(os.path.dirname(path), 'toxygen.json') if os.path.isfile(p): with open(p) as fl: data = fl.read() @@ -289,7 +299,7 @@ class Settings(dict): @staticmethod def reset_auto_profile(): - p = os.path.join(os.path.dirname(self._app._path), 'toxygen.json') + p = os.path.join(os.path.dirname(app._path), 'toxygen.json') if os.path.isfile(p): with open(p) as fl: data = fl.read()