Fixed history database
This commit is contained in:
parent
b75aafe638
commit
fd7f2620ba
@ -49,5 +49,7 @@ Toxygen is powerful cross-platform [Tox](https://tox.chat/) client written in pu
|
|||||||
This hard-forked from https://github.com/toxygen-project/toxygen
|
This hard-forked from https://github.com/toxygen-project/toxygen
|
||||||
```next_gen``` branch.
|
```next_gen``` branch.
|
||||||
|
|
||||||
|
See ToDo.md to the current ToDo list.
|
||||||
|
|
||||||
Work on this project is suspended until the
|
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!
|
[MultiDevice](https://git.plastiras.org/emdee/tox_profile/wiki/MultiDevice-Announcements-POC) problem is solved. Fork me!
|
18
ToDo.md
18
ToDo.md
@ -6,15 +6,16 @@ The code is in there but it's not working.
|
|||||||
|
|
||||||
## Fix Audio
|
## Fix Audio
|
||||||
|
|
||||||
The code is in there but it's not working.
|
The code is in there but it's not working. It looks like audio input
|
||||||
I may have broken it trying to wire up the ability to
|
is working but not output. The code is all in there; I may have broken
|
||||||
set the audio device from the command line.
|
it trying to wire up the ability to set the audio device from the
|
||||||
|
command line.
|
||||||
|
|
||||||
## Fix Video
|
## Fix Video
|
||||||
|
|
||||||
The code is in there but it's not working.
|
The code is in there but it's not working. I may have broken it
|
||||||
I may have broken it trying to wire up the ability to
|
trying to wire up the ability to set the audio device from the command
|
||||||
set the audio device from the command line.
|
line.
|
||||||
|
|
||||||
## Groups
|
## Groups
|
||||||
|
|
||||||
@ -22,9 +23,6 @@ set the audio device from the command line.
|
|||||||
```group.peer_id``` The code is broken in places because I have not
|
```group.peer_id``` The code is broken in places because I have not
|
||||||
seen the path to change from the old API ro the new one.
|
seen the path to change from the old API ro the new one.
|
||||||
|
|
||||||
2. There is no way to delete a group in the UI
|
|
||||||
|
|
||||||
3. Distinguish between Frieds, Groups and Whispers in the UI.
|
|
||||||
|
|
||||||
## Plugin system
|
## Plugin system
|
||||||
|
|
||||||
@ -34,6 +32,8 @@ set the audio device from the command line.
|
|||||||
|
|
||||||
3. Should the plugins be in toxygen or a separate repo?
|
3. Should the plugins be in toxygen or a separate repo?
|
||||||
|
|
||||||
|
4. There needs to be a uniform way for plugins to wire into callbacks.
|
||||||
|
|
||||||
## check toxygen_wrapper
|
## check toxygen_wrapper
|
||||||
|
|
||||||
1. I've broken out toxygen_wrapper to be standalone,
|
1. I've broken out toxygen_wrapper to be standalone,
|
||||||
|
131
toxygen/app.py
131
toxygen/app.py
@ -86,29 +86,29 @@ iNODES=8
|
|||||||
|
|
||||||
def setup_logging(oArgs):
|
def setup_logging(oArgs):
|
||||||
global LOG
|
global LOG
|
||||||
|
logging._defaultFormatter = logging.Formatter(datefmt='%m-%d %H:%M:%S',
|
||||||
|
fmt='%(levelname)s:%(name)s %(message)s')
|
||||||
|
logging._defaultFormatter.default_time_format = '%m-%d %H:%M:%S'
|
||||||
|
logging._defaultFormatter.default_msec_format = ''
|
||||||
|
|
||||||
if coloredlogs:
|
if coloredlogs:
|
||||||
aKw = dict(level=oArgs.loglevel,
|
aKw = dict(level=oArgs.loglevel,
|
||||||
logger=LOG,
|
logger=LOG,
|
||||||
fmt='%(name)s %(levelname)s %(message)s')
|
fmt='%(name)s %(levelname)s %(message)s')
|
||||||
if oArgs.logfile:
|
aKw['stream'] = sys.stdout
|
||||||
oFd = open(oArgs.logfile, 'wt')
|
|
||||||
setattr(oArgs, 'log_oFd', oFd)
|
|
||||||
aKw['stream'] = oFd
|
|
||||||
coloredlogs.install(**aKw)
|
coloredlogs.install(**aKw)
|
||||||
|
|
||||||
else:
|
else:
|
||||||
aKw = dict(level=oArgs.loglevel,
|
aKw = dict(level=oArgs.loglevel,
|
||||||
format='%(name)s %(levelname)-4s %(message)s')
|
format='%(name)s %(levelname)-4s %(message)s')
|
||||||
if oArgs.logfile:
|
aKw['stream'] = sys.stdout
|
||||||
aKw['filename'] = oArgs.logfile
|
|
||||||
logging.basicConfig(**aKw)
|
logging.basicConfig(**aKw)
|
||||||
if not oArgs.logfile:
|
|
||||||
oHandler = logging.StreamHandler(stream=sys.stdout)
|
|
||||||
LOG.addHandler(oHandler)
|
|
||||||
|
|
||||||
logging._defaultFormatter = logging.Formatter(datefmt='%m-%d %H:%M:%S')
|
if oArgs.logfile:
|
||||||
logging._defaultFormatter.default_time_format = '%m-%d %H:%M:%S'
|
oFd = open(oArgs.logfile, 'wt')
|
||||||
logging._defaultFormatter.default_msec_format = ''
|
setattr(oArgs, 'log_oFd', oFd)
|
||||||
|
oHandler = logging.StreamHandler(stream=oFd)
|
||||||
|
LOG.addHandler(oHandler)
|
||||||
|
|
||||||
LOG.setLevel(oArgs.loglevel)
|
LOG.setLevel(oArgs.loglevel)
|
||||||
LOG.trace = lambda l: LOG.log(0, repr(l))
|
LOG.trace = lambda l: LOG.log(0, repr(l))
|
||||||
@ -124,7 +124,6 @@ logging.getLogger('PyQt5.uic').setLevel(logging.ERROR)
|
|||||||
logging.getLogger('PyQt5.uic.uiparser').setLevel(logging.ERROR)
|
logging.getLogger('PyQt5.uic.uiparser').setLevel(logging.ERROR)
|
||||||
logging.getLogger('PyQt5.uic.properties').setLevel(logging.ERROR)
|
logging.getLogger('PyQt5.uic.properties').setLevel(logging.ERROR)
|
||||||
|
|
||||||
|
|
||||||
global iI
|
global iI
|
||||||
iI = 0
|
iI = 0
|
||||||
|
|
||||||
@ -155,7 +154,7 @@ class App:
|
|||||||
def __init__(self, version, oArgs):
|
def __init__(self, version, oArgs):
|
||||||
global LOG
|
global LOG
|
||||||
self._args = oArgs
|
self._args = oArgs
|
||||||
self.oArgs = oArgs
|
self._oArgs = oArgs
|
||||||
self._path = path_to_profile = oArgs.profile
|
self._path = path_to_profile = oArgs.profile
|
||||||
uri = oArgs.uri
|
uri = oArgs.uri
|
||||||
logfile = oArgs.logfile
|
logfile = oArgs.logfile
|
||||||
@ -179,18 +178,21 @@ class App:
|
|||||||
self._group_factory = self._groups_service = self._profile = None
|
self._group_factory = self._groups_service = self._profile = None
|
||||||
if uri is not None and uri.startswith('tox:'):
|
if uri is not None and uri.startswith('tox:'):
|
||||||
self._uri = uri[4:]
|
self._uri = uri[4:]
|
||||||
|
self._history = None
|
||||||
|
|
||||||
# -----------------------------------------------------------------------------------------------------------------
|
# -----------------------------------------------------------------------------------------------------------------
|
||||||
# Public methods
|
# Public methods
|
||||||
# -----------------------------------------------------------------------------------------------------------------
|
# -----------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
def set_trace(self):
|
def set_trace(self):
|
||||||
|
"""unused"""
|
||||||
LOG.debug('pdb.set_trace ')
|
LOG.debug('pdb.set_trace ')
|
||||||
sys.stdin = sys.__stdin__
|
sys.stdin = sys.__stdin__
|
||||||
sys.stdout = sys.__stdout__
|
sys.stdout = sys.__stdout__
|
||||||
import pdb; pdb.set_trace()
|
import pdb; pdb.set_trace()
|
||||||
|
|
||||||
def ten(self, i=0):
|
def ten(self, i=0):
|
||||||
|
"""unused"""
|
||||||
global iI
|
global iI
|
||||||
iI += 1
|
iI += 1
|
||||||
if logging.getLogger('app').getEffectiveLevel() != 10:
|
if logging.getLogger('app').getEffectiveLevel() != 10:
|
||||||
@ -219,11 +221,11 @@ class App:
|
|||||||
# this throws everything as errors
|
# this throws everything as errors
|
||||||
if not self._select_and_load_profile():
|
if not self._select_and_load_profile():
|
||||||
return 2
|
return 2
|
||||||
if hasattr(self._args, 'update') and self._args.update:
|
if hasattr(self._oArgs, 'update') and self._oArgs.update:
|
||||||
if self._try_to_update(): return 3
|
if self._try_to_update(): return 3
|
||||||
|
|
||||||
self._load_app_styles()
|
self._load_app_styles()
|
||||||
if self._args.language != 'English':
|
if self._oArgs.language != 'English':
|
||||||
# > /var/local/src/toxygen/toxygen/app.py(303)_load_app_translations()->None
|
# > /var/local/src/toxygen/toxygen/app.py(303)_load_app_translations()->None
|
||||||
# -> self._app.translator = translator
|
# -> self._app.translator = translator
|
||||||
# (Pdb) Fatal Python error: Segmentation fault
|
# (Pdb) Fatal Python error: Segmentation fault
|
||||||
@ -271,26 +273,34 @@ class App:
|
|||||||
|
|
||||||
def quit(self, retval=0):
|
def quit(self, retval=0):
|
||||||
LOG.debug("quit")
|
LOG.debug("quit")
|
||||||
oArgs = self._args
|
self._stop_app()
|
||||||
if hasattr(oArgs, 'log_oFd'):
|
|
||||||
oArgs.log_oFd.close()
|
|
||||||
delattr(oArgs, 'log_oFd')
|
|
||||||
|
|
||||||
# failsafe: segfaults on exit
|
# failsafe: segfaults on exit
|
||||||
if hasattr(self, '_tox'):
|
if hasattr(self, '_tox'):
|
||||||
if self._tox and hasattr(self._tox, 'kill'):
|
if self._tox and hasattr(self._tox, 'kill'):
|
||||||
|
LOG.debug(f"quit: Killing {self._tox}")
|
||||||
self._tox.kill()
|
self._tox.kill()
|
||||||
del self._tox
|
del self._tox
|
||||||
|
|
||||||
self._stop_app()
|
|
||||||
if hasattr(self, '_app'):
|
if hasattr(self, '_app'):
|
||||||
self._app.quit()
|
self._app.quit()
|
||||||
del self._app.quit
|
del self._app.quit
|
||||||
del self._app
|
del self._app
|
||||||
|
|
||||||
|
sys.stderr.write('quit raising SystemExit' +'\n')
|
||||||
|
# hanging on gevents
|
||||||
|
# Thread 1 "python3.9" received signal SIGSEGV, Segmentation fault.
|
||||||
|
#44 0x00007ffff7fb2f93 in () at /usr/lib/python3.9/site-packages/greenlet/_greenlet.cpython-39-x86_64-linux-gnu.so
|
||||||
|
#45 0x00007ffff7fb31ef in () at /usr/lib/python3.9/site-packages/greenlet/_greenlet.cpython-39-x86_64-linux-gnu.so
|
||||||
|
#46 0x00007ffff452165c in hb_shape_plan_create_cached2 () at /usr/lib64/libharfbuzz.so.0
|
||||||
|
|
||||||
raise SystemExit(retval)
|
raise SystemExit(retval)
|
||||||
|
|
||||||
def _stop_app(self):
|
def _stop_app(self):
|
||||||
LOG.debug("_stop_app")
|
LOG.debug("_stop_app")
|
||||||
|
self._save_profile()
|
||||||
|
#? self._history.save_history()
|
||||||
|
|
||||||
self._plugin_loader.stop()
|
self._plugin_loader.stop()
|
||||||
try:
|
try:
|
||||||
self._stop_threads(is_app_closing=True)
|
self._stop_threads(is_app_closing=True)
|
||||||
@ -299,31 +309,38 @@ class App:
|
|||||||
pass
|
pass
|
||||||
if hasattr(self, '_tray') and self._tray:
|
if hasattr(self, '_tray') and self._tray:
|
||||||
self._tray.hide()
|
self._tray.hide()
|
||||||
self._save_profile()
|
|
||||||
self._settings.close()
|
self._settings.close()
|
||||||
|
|
||||||
|
LOG.debug(f"stop_app: Killing {self._tox}")
|
||||||
self._kill_toxav()
|
self._kill_toxav()
|
||||||
self._kill_tox()
|
self._kill_tox()
|
||||||
sys.stderr.write('_stop_app end' +'\n')
|
del self._tox
|
||||||
|
|
||||||
|
oArgs = self._oArgs
|
||||||
|
if hasattr(oArgs, 'log_oFd'):
|
||||||
|
LOG.debug(f"Closing {oArgs.log_oFd}")
|
||||||
|
oArgs.log_oFd.close()
|
||||||
|
delattr(oArgs, 'log_oFd')
|
||||||
|
|
||||||
# -----------------------------------------------------------------------------------------------------------------
|
# -----------------------------------------------------------------------------------------------------------------
|
||||||
# App loading
|
# App loading
|
||||||
# -----------------------------------------------------------------------------------------------------------------
|
# -----------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
def _load_base_style(self):
|
def _load_base_style(self):
|
||||||
if self._args.theme in ['', 'default']: return
|
if self._oArgs.theme in ['', 'default']: return
|
||||||
|
|
||||||
if qdarkstyle:
|
if qdarkstyle:
|
||||||
LOG.debug("_load_base_style qdarkstyle " +self._args.theme)
|
LOG.debug("_load_base_style qdarkstyle " +self._oArgs.theme)
|
||||||
# QDarkStyleSheet
|
# QDarkStyleSheet
|
||||||
if self._args.theme == 'light':
|
if self._oArgs.theme == 'light':
|
||||||
from qdarkstyle.light.palette import LightPalette
|
from qdarkstyle.light.palette import LightPalette
|
||||||
style = qdarkstyle.load_stylesheet(palette=LightPalette)
|
style = qdarkstyle.load_stylesheet(palette=LightPalette)
|
||||||
else:
|
else:
|
||||||
from qdarkstyle.dark.palette import DarkPalette
|
from qdarkstyle.dark.palette import DarkPalette
|
||||||
style = qdarkstyle.load_stylesheet(palette=DarkPalette)
|
style = qdarkstyle.load_stylesheet(palette=DarkPalette)
|
||||||
else:
|
else:
|
||||||
LOG.debug("_load_base_style qss " +self._args.theme)
|
LOG.debug("_load_base_style qss " +self._oArgs.theme)
|
||||||
name = self._args.theme + '.qss'
|
name = self._oArgs.theme + '.qss'
|
||||||
with open(util.join_path(util.get_styles_directory(), name)) as fl:
|
with open(util.join_path(util.get_styles_directory(), name)) as fl:
|
||||||
style = fl.read()
|
style = fl.read()
|
||||||
style += '\n' +sSTYLE
|
style += '\n' +sSTYLE
|
||||||
@ -337,9 +354,9 @@ class App:
|
|||||||
if self._settings['theme'] != theme:
|
if self._settings['theme'] != theme:
|
||||||
continue
|
continue
|
||||||
if qdarkstyle:
|
if qdarkstyle:
|
||||||
LOG.debug("_load_base_style qdarkstyle " +self._args.theme)
|
LOG.debug("_load_base_style qdarkstyle " +self._oArgs.theme)
|
||||||
# QDarkStyleSheet
|
# QDarkStyleSheet
|
||||||
if self._args.theme == 'light':
|
if self._oArgs.theme == 'light':
|
||||||
from qdarkstyle.light.palette import LightPalette
|
from qdarkstyle.light.palette import LightPalette
|
||||||
style = qdarkstyle.load_stylesheet(palette=LightPalette)
|
style = qdarkstyle.load_stylesheet(palette=LightPalette)
|
||||||
else:
|
else:
|
||||||
@ -356,7 +373,7 @@ class App:
|
|||||||
LOG.debug('_load_app_styles: loading theme file ' + file_path)
|
LOG.debug('_load_app_styles: loading theme file ' + file_path)
|
||||||
style += '\n' +sSTYLE
|
style += '\n' +sSTYLE
|
||||||
self._app.setStyleSheet(style)
|
self._app.setStyleSheet(style)
|
||||||
LOG.info('_load_app_styles: loaded theme ' +self._args.theme)
|
LOG.info('_load_app_styles: loaded theme ' +self._oArgs.theme)
|
||||||
break
|
break
|
||||||
|
|
||||||
def _load_login_screen_translations(self):
|
def _load_login_screen_translations(self):
|
||||||
@ -503,7 +520,7 @@ class App:
|
|||||||
|
|
||||||
def _select_profile(self):
|
def _select_profile(self):
|
||||||
LOG.debug("_select_profile")
|
LOG.debug("_select_profile")
|
||||||
if self._args.language != 'English':
|
if self._oArgs.language != 'English':
|
||||||
self._load_login_screen_translations()
|
self._load_login_screen_translations()
|
||||||
ls = LoginScreen()
|
ls = LoginScreen()
|
||||||
profiles = ProfileManager.find_profiles()
|
profiles = ProfileManager.find_profiles()
|
||||||
@ -542,7 +559,7 @@ class App:
|
|||||||
util_ui.tr('Error'))
|
util_ui.tr('Error'))
|
||||||
return False
|
return False
|
||||||
name = profile_name or 'toxygen_user'
|
name = profile_name or 'toxygen_user'
|
||||||
assert self._args
|
assert self._oArgs
|
||||||
self._path = profile_path
|
self._path = profile_path
|
||||||
if result.password:
|
if result.password:
|
||||||
self._toxes.set_password(result.password)
|
self._toxes.set_password(result.password)
|
||||||
@ -644,7 +661,7 @@ class App:
|
|||||||
|
|
||||||
def _create_dependencies(self):
|
def _create_dependencies(self):
|
||||||
LOG.info(f"_create_dependencies toxygen version {self._version}")
|
LOG.info(f"_create_dependencies toxygen version {self._version}")
|
||||||
if hasattr(self._args, 'update') and self._args.update:
|
if hasattr(self._oArgs, 'update') and self._oArgs.update:
|
||||||
self._backup_service = BackupService(self._settings,
|
self._backup_service = BackupService(self._settings,
|
||||||
self._profile_manager)
|
self._profile_manager)
|
||||||
self._smiley_loader = SmileyLoader(self._settings)
|
self._smiley_loader = SmileyLoader(self._settings)
|
||||||
@ -697,9 +714,11 @@ class App:
|
|||||||
self._ms,
|
self._ms,
|
||||||
self._profile_manager,
|
self._profile_manager,
|
||||||
self._contacts_provider,
|
self._contacts_provider,
|
||||||
history, self._tox_dns,
|
history,
|
||||||
|
self._tox_dns,
|
||||||
messages_items_factory)
|
messages_items_factory)
|
||||||
history.set_contacts_manager(self._contacts_manager)
|
history.set_contacts_manager(self._contacts_manager)
|
||||||
|
self._history = history
|
||||||
self._calls_manager = CallsManager(self._tox.AV,
|
self._calls_manager = CallsManager(self._tox.AV,
|
||||||
self._settings,
|
self._settings,
|
||||||
self._ms,
|
self._ms,
|
||||||
@ -754,14 +773,14 @@ class App:
|
|||||||
self._ms.show()
|
self._ms.show()
|
||||||
|
|
||||||
# FixMe:
|
# FixMe:
|
||||||
self._log = lambda line: LOG.log(self._args.loglevel,
|
self._log = lambda line: LOG.log(self._oArgs.loglevel,
|
||||||
self._ms.status(line))
|
self._ms.status(line))
|
||||||
self._ms._log = self._log # used in callbacks.py
|
self._ms._log = self._log # used in callbacks.py
|
||||||
self.LOG = self._log # backwards
|
self.LOG = self._log # backwards
|
||||||
|
|
||||||
if False:
|
if False:
|
||||||
self.status_handler = logging.Handler()
|
self.status_handler = logging.Handler()
|
||||||
self.status_handler.setLevel(logging.INFO) # self._args.loglevel
|
self.status_handler.setLevel(logging.INFO) # self._oArgs.loglevel
|
||||||
self.status_handler.handle = self._ms.status
|
self.status_handler.handle = self._ms.status
|
||||||
|
|
||||||
self._init_callbacks()
|
self._init_callbacks()
|
||||||
@ -780,9 +799,9 @@ class App:
|
|||||||
|
|
||||||
def _create_tox(self, data, settings_):
|
def _create_tox(self, data, settings_):
|
||||||
LOG.info("_create_tox calling tox_factory")
|
LOG.info("_create_tox calling tox_factory")
|
||||||
assert self._args
|
assert self._oArgs
|
||||||
retval = tox_factory(data=data, settings=settings_,
|
retval = tox_factory(data=data, settings=settings_,
|
||||||
args=self._args, app=self)
|
args=self._oArgs, app=self)
|
||||||
LOG.debug("_create_tox succeeded")
|
LOG.debug("_create_tox succeeded")
|
||||||
self._tox = retval
|
self._tox = retval
|
||||||
return retval
|
return retval
|
||||||
@ -807,12 +826,12 @@ class App:
|
|||||||
self._profile.reset_avatar(self._settings['identicons'])
|
self._profile.reset_avatar(self._settings['identicons'])
|
||||||
|
|
||||||
def _kill_toxav(self):
|
def _kill_toxav(self):
|
||||||
LOG.debug("_kill_toxav")
|
# LOG_debug("_kill_toxav")
|
||||||
self._calls_manager.set_toxav(None)
|
self._calls_manager.set_toxav(None)
|
||||||
self._tox.AV.kill()
|
self._tox.AV.kill()
|
||||||
|
|
||||||
def _kill_tox(self):
|
def _kill_tox(self):
|
||||||
LOG.debug("_kill_tox")
|
# LOG.debug("_kill_tox")
|
||||||
self._tox.kill()
|
self._tox.kill()
|
||||||
|
|
||||||
def loop(self, n):
|
def loop(self, n):
|
||||||
@ -832,17 +851,17 @@ class App:
|
|||||||
|
|
||||||
def test_net(self, lElts=None, oThread=None, iMax=4):
|
def test_net(self, lElts=None, oThread=None, iMax=4):
|
||||||
|
|
||||||
LOG.debug("test_net " +self._args.network)
|
LOG.debug("test_net " +self._oArgs.network)
|
||||||
# bootstrap
|
# bootstrap
|
||||||
LOG.debug('Calling generate_nodes: udp')
|
LOG.debug('Calling generate_nodes: udp')
|
||||||
lNodes = ts.generate_nodes(oArgs=self._args,
|
lNodes = ts.generate_nodes(oArgs=self._oArgs,
|
||||||
ipv='ipv4',
|
ipv='ipv4',
|
||||||
udp_not_tcp=True)
|
udp_not_tcp=True)
|
||||||
self._settings['current_nodes_udp'] = lNodes
|
self._settings['current_nodes_udp'] = lNodes
|
||||||
if not lNodes:
|
if not lNodes:
|
||||||
LOG.warn('empty generate_nodes udp')
|
LOG.warn('empty generate_nodes udp')
|
||||||
LOG.debug('Calling generate_nodes: tcp')
|
LOG.debug('Calling generate_nodes: tcp')
|
||||||
lNodes = ts.generate_nodes(oArgs=self._args,
|
lNodes = ts.generate_nodes(oArgs=self._oArgs,
|
||||||
ipv='ipv4',
|
ipv='ipv4',
|
||||||
udp_not_tcp=False)
|
udp_not_tcp=False)
|
||||||
self._settings['current_nodes_tcp'] = lNodes
|
self._settings['current_nodes_tcp'] = lNodes
|
||||||
@ -850,8 +869,8 @@ class App:
|
|||||||
LOG.warn('empty generate_nodes tcp')
|
LOG.warn('empty generate_nodes tcp')
|
||||||
|
|
||||||
# if oThread and oThread._stop_thread: return
|
# if oThread and oThread._stop_thread: return
|
||||||
LOG.debug("test_net network=" +self._args.network +' iMax=' +str(iMax))
|
LOG.debug("test_net network=" +self._oArgs.network +' iMax=' +str(iMax))
|
||||||
if self._args.network not in ['local', 'localnew', 'newlocal']:
|
if self._oArgs.network not in ['local', 'localnew', 'newlocal']:
|
||||||
b = ts.bAreWeConnected()
|
b = ts.bAreWeConnected()
|
||||||
if b is None:
|
if b is None:
|
||||||
i = os.system('ip route|grep ^def')
|
i = os.system('ip route|grep ^def')
|
||||||
@ -860,22 +879,22 @@ class App:
|
|||||||
else:
|
else:
|
||||||
b = True
|
b = True
|
||||||
if not b:
|
if not b:
|
||||||
LOG.warn("No default route for network " +self._args.network)
|
LOG.warn("No default route for network " +self._oArgs.network)
|
||||||
text = 'You have no default route - are you connected?'
|
text = 'You have no default route - are you connected?'
|
||||||
reply = util_ui.question(text, "Are you connected?")
|
reply = util_ui.question(text, "Are you connected?")
|
||||||
if not reply: return
|
if not reply: return
|
||||||
iMax = 1
|
iMax = 1
|
||||||
else:
|
else:
|
||||||
LOG.debug("Have default route for network " +self._args.network)
|
LOG.debug("Have default route for network " +self._oArgs.network)
|
||||||
|
|
||||||
LOG.debug(f"test_net {self._args.network} iMax= {iMax}")
|
LOG.debug(f"test_net {self._oArgs.network} iMax= {iMax}")
|
||||||
i = 0
|
i = 0
|
||||||
while i < iMax:
|
while i < iMax:
|
||||||
# if oThread and oThread._stop_thread: return
|
# if oThread and oThread._stop_thread: return
|
||||||
i = i + 1
|
i = i + 1
|
||||||
LOG.debug(f"bootstrapping status # {i}")
|
LOG.debug(f"bootstrapping status # {i}")
|
||||||
self._test_bootstrap(self._settings['current_nodes_udp'])
|
self._test_bootstrap(self._settings['current_nodes_udp'])
|
||||||
if hasattr(self._args, 'proxy_type') and self._args.proxy_type > 0:
|
if hasattr(self._oArgs, 'proxy_type') and self._oArgs.proxy_type > 0:
|
||||||
LOG.debug(f"relaying status # {i}")
|
LOG.debug(f"relaying status # {i}")
|
||||||
self._test_relays(self._settings['current_nodes_tcp'])
|
self._test_relays(self._settings['current_nodes_tcp'])
|
||||||
status = self._tox.self_get_connection_status()
|
status = self._tox.self_get_connection_status()
|
||||||
@ -906,16 +925,14 @@ class App:
|
|||||||
+_settings['proxy_host'] +':' \
|
+_settings['proxy_host'] +':' \
|
||||||
+str(_settings['proxy_port']))
|
+str(_settings['proxy_port']))
|
||||||
lElts = _settings['current_nodes_tcp']
|
lElts = _settings['current_nodes_tcp']
|
||||||
LOG.debug(f"test_env {len(lElts)}")
|
# LOG.debug(f"test_env {len(lElts)}")
|
||||||
return env
|
return env
|
||||||
|
|
||||||
def _test_bootstrap(self, lElts=None):
|
def _test_bootstrap(self, lElts=None):
|
||||||
env = self._test_env()
|
|
||||||
if lElts is None:
|
if lElts is None:
|
||||||
lElts = self._settings['current_nodes_udp']
|
lElts = self._settings['current_nodes_udp']
|
||||||
shuffle(lElts)
|
shuffle(lElts)
|
||||||
LOG.debug(f"_test_bootstrap #Elts={len(lElts)}")
|
LOG.debug(f"_test_bootstrap #Elts={len(lElts)}")
|
||||||
shuffle(lElts)
|
|
||||||
ts.bootstrap_good(lElts[:iNODES], [self._tox])
|
ts.bootstrap_good(lElts[:iNODES], [self._tox])
|
||||||
LOG.info("Connected status: " +repr(self._tox.self_get_connection_status()))
|
LOG.info("Connected status: " +repr(self._tox.self_get_connection_status()))
|
||||||
|
|
||||||
@ -962,10 +979,10 @@ class App:
|
|||||||
text = 'Run the Extended Test Suite?\nThe program may freeze for 20-60 minutes.'
|
text = 'Run the Extended Test Suite?\nThe program may freeze for 20-60 minutes.'
|
||||||
reply = util_ui.question(text, title)
|
reply = util_ui.question(text, title)
|
||||||
if reply:
|
if reply:
|
||||||
if hasattr(self._args, 'proxy_type') and self._args.proxy_type:
|
if hasattr(self._oArgs, 'proxy_type') and self._oArgs.proxy_type:
|
||||||
lArgs = ['--proxy_host', self._args.proxy_host,
|
lArgs = ['--proxy_host', self._oArgs.proxy_host,
|
||||||
'--proxy_port', str(self._args.proxy_port),
|
'--proxy_port', str(self._oArgs.proxy_port),
|
||||||
'--proxy_type', str(self._args.proxy_type), ]
|
'--proxy_type', str(self._oArgs.proxy_type), ]
|
||||||
else:
|
else:
|
||||||
lArgs = list()
|
lArgs = list()
|
||||||
try:
|
try:
|
||||||
|
@ -18,6 +18,18 @@ from middleware.threads import BaseThread
|
|||||||
global LOG
|
global LOG
|
||||||
import logging
|
import logging
|
||||||
LOG = logging.getLogger('app.'+__name__)
|
LOG = logging.getLogger('app.'+__name__)
|
||||||
|
# callbacks can be called in any thread so were being careful
|
||||||
|
def LOG_ERROR(l): print('EROR< '+l)
|
||||||
|
def LOG_WARN(l): print('WARN< '+l)
|
||||||
|
def LOG_INFO(l):
|
||||||
|
bIsVerbose = hasattr(__builtins__, 'app') and app.oArgs.loglevel <= 20-1
|
||||||
|
if bIsVerbose: print('INFO< '+l)
|
||||||
|
def LOG_DEBUG(l):
|
||||||
|
bIsVerbose = hasattr(__builtins__, 'app') and app.oArgs.loglevel <= 10-1
|
||||||
|
if bIsVerbose: print('DBUG< '+l)
|
||||||
|
def LOG_TRACE(l):
|
||||||
|
bIsVerbose = hasattr(__builtins__, 'app') and app.oArgs.loglevel < 10-1
|
||||||
|
pass # print('TRACE+ '+l)
|
||||||
|
|
||||||
TIMER_TIMEOUT = 30.0
|
TIMER_TIMEOUT = 30.0
|
||||||
bSTREAM_CALLBACK = False
|
bSTREAM_CALLBACK = False
|
||||||
@ -27,6 +39,7 @@ class AV(common.tox_save.ToxAvSave):
|
|||||||
|
|
||||||
def __init__(self, toxav, settings):
|
def __init__(self, toxav, settings):
|
||||||
super().__init__(toxav)
|
super().__init__(toxav)
|
||||||
|
self._toxav = toxav
|
||||||
self._settings = settings
|
self._settings = settings
|
||||||
self._running = True
|
self._running = True
|
||||||
s = settings
|
s = settings
|
||||||
@ -62,7 +75,10 @@ class AV(common.tox_save.ToxAvSave):
|
|||||||
self._video_width = 320
|
self._video_width = 320
|
||||||
self._video_height = 240
|
self._video_height = 240
|
||||||
|
|
||||||
iOutput = self._settings._args.audio['output']
|
# was iOutput = self._settings._args.audio['output']
|
||||||
|
iInput = self._settings['audio']['input']
|
||||||
|
self.lPaSampleratesI = ts.lSdSamplerates(iInput)
|
||||||
|
iOutput = self._settings['audio']['output']
|
||||||
self.lPaSampleratesO = ts.lSdSamplerates(iOutput)
|
self.lPaSampleratesO = ts.lSdSamplerates(iOutput)
|
||||||
global oPYA
|
global oPYA
|
||||||
oPYA = self._audio = pyaudio.PyAudio()
|
oPYA = self._audio = pyaudio.PyAudio()
|
||||||
@ -180,33 +196,35 @@ class AV(common.tox_save.ToxAvSave):
|
|||||||
def start_audio_thread(self):
|
def start_audio_thread(self):
|
||||||
"""
|
"""
|
||||||
Start audio sending
|
Start audio sending
|
||||||
|
from a callback
|
||||||
"""
|
"""
|
||||||
global oPYA
|
global oPYA
|
||||||
iInput = self._settings._args.audio['input']
|
# was iInput = self._settings._args.audio['input']
|
||||||
|
iInput = self._settings['audio']['input']
|
||||||
if self._audio_thread is not None:
|
if self._audio_thread is not None:
|
||||||
LOG.warn(f"start_audio_thread device={iInput}")
|
LOG_WARN(f"start_audio_thread device={iInput}")
|
||||||
return
|
return
|
||||||
iInput = self._settings._args.audio['input']
|
LOG_DEBUG(f"start_audio_thread device={iInput}")
|
||||||
LOG.debug(f"start_audio_thread device={iInput}")
|
|
||||||
lPaSamplerates = ts.lSdSamplerates(iInput)
|
lPaSamplerates = ts.lSdSamplerates(iInput)
|
||||||
if not(len(lPaSamplerates)):
|
if not(len(lPaSamplerates)):
|
||||||
e = f"No supported sample rates for device: audio[input]={iInput!r}"
|
e = f"No supported sample rates for device: audio[input]={iInput!r}"
|
||||||
LOG.error(f"No supported sample rates {e}")
|
LOG_ERROR(f"start_audio_thread {e}")
|
||||||
raise RuntimeError(e)
|
#?? dunno - cancel call?
|
||||||
|
return
|
||||||
if not self._audio_rate_pa in lPaSamplerates:
|
if not self._audio_rate_pa in lPaSamplerates:
|
||||||
LOG.warn(f"{self._audio_rate_pa} not in {lPaSamplerates!r}")
|
LOG_WARN(f"{self._audio_rate_pa} not in {lPaSamplerates!r}")
|
||||||
if False:
|
if False:
|
||||||
self._audio_rate_pa = oPYA.get_device_info_by_index(iInput)['defaultSampleRate']
|
self._audio_rate_pa = oPYA.get_device_info_by_index(iInput)['defaultSampleRate']
|
||||||
else:
|
else:
|
||||||
LOG.warn(f"Setting audio_rate to: {lPaSamplerates[0]}")
|
LOG_WARN(f"Setting audio_rate to: {lPaSamplerates[0]}")
|
||||||
self._audio_rate_pa = lPaSamplerates[0]
|
self._audio_rate_pa = lPaSamplerates[0]
|
||||||
|
|
||||||
try:
|
try:
|
||||||
LOG.debug( f"start_audio_thread framerate: {self._audio_rate_pa}" \
|
LOG_DEBUG( f"start_audio_thread framerate: {self._audio_rate_pa}" \
|
||||||
+f" device: {iInput}"
|
+f" device: {iInput}"
|
||||||
+f" supported: {lPaSamplerates!r}")
|
+f" supported: {lPaSamplerates!r}")
|
||||||
if self._audio_rate_pa not in lPaSamplerates:
|
if self._audio_rate_pa not in lPaSamplerates:
|
||||||
LOG.warn(f"PAudio sampling rate was {self._audio_rate_pa} changed to {lPaSamplerates[0]}")
|
LOG_WARN(f"PAudio sampling rate was {self._audio_rate_pa} changed to {lPaSamplerates[0]}")
|
||||||
self._audio_rate_pa = lPaSamplerates[0]
|
self._audio_rate_pa = lPaSamplerates[0]
|
||||||
|
|
||||||
if bSTREAM_CALLBACK:
|
if bSTREAM_CALLBACK:
|
||||||
@ -244,10 +262,12 @@ class AV(common.tox_save.ToxAvSave):
|
|||||||
input=True,
|
input=True,
|
||||||
input_device_index=iInput,
|
input_device_index=iInput,
|
||||||
frames_per_buffer=self._audio_sample_count_pa * 10)))
|
frames_per_buffer=self._audio_sample_count_pa * 10)))
|
||||||
# catcher in place in calls_manager
|
# catcher in place in calls_manager? not if from a callback
|
||||||
raise RuntimeError(e)
|
# calls_manager._call.toxav_call_state_cb(friend_number, mask)
|
||||||
|
# raise RuntimeError(e)
|
||||||
|
return
|
||||||
else:
|
else:
|
||||||
LOG.debug(f"start_audio_thread {self._audio_stream!r}")
|
LOG_DEBUG(f"start_audio_thread {self._audio_stream!r}")
|
||||||
|
|
||||||
def stop_audio_thread(self):
|
def stop_audio_thread(self):
|
||||||
|
|
||||||
@ -339,7 +359,8 @@ class AV(common.tox_save.ToxAvSave):
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
if self._out_stream is None:
|
if self._out_stream is None:
|
||||||
iOutput = self._settings._args.audio['output']
|
# was iOutput = self._settings._args.audio['output']
|
||||||
|
iOutput = self._settings['audio']['output']
|
||||||
if not rate in self.lPaSampleratesO:
|
if not rate in self.lPaSampleratesO:
|
||||||
LOG.warn(f"{rate} not in {self.lPaSampleratesO!r}")
|
LOG.warn(f"{rate} not in {self.lPaSampleratesO!r}")
|
||||||
if False:
|
if False:
|
||||||
@ -362,7 +383,8 @@ class AV(common.tox_save.ToxAvSave):
|
|||||||
self.stop()
|
self.stop()
|
||||||
return
|
return
|
||||||
|
|
||||||
LOG.debug(f"audio_chunk output_device_index={self._settings._args.audio['input']} rate={rate} channels={channels_count}")
|
iOutput = self._settings['audio']['output']
|
||||||
|
LOG.debug(f"audio_chunk output_device_index={iOutput} rate={rate} channels={channels_count}")
|
||||||
self._out_stream.write(samples)
|
self._out_stream.write(samples)
|
||||||
|
|
||||||
# -----------------------------------------------------------------------------------------------------------------
|
# -----------------------------------------------------------------------------------------------------------------
|
||||||
|
@ -16,7 +16,8 @@ LOG = logging.getLogger('app.'+__name__)
|
|||||||
class CallsManager:
|
class CallsManager:
|
||||||
|
|
||||||
def __init__(self, toxav, settings, main_screen, contacts_manager, app=None):
|
def __init__(self, toxav, settings, main_screen, contacts_manager, app=None):
|
||||||
self._call = av.calls.AV(toxav, settings) # object with data about calls
|
self._callav = av.calls.AV(toxav, settings) # object with data about calls
|
||||||
|
self._call = self._callav
|
||||||
self._call_widgets = {} # dict of incoming call widgets
|
self._call_widgets = {} # dict of incoming call widgets
|
||||||
self._incoming_calls = set()
|
self._incoming_calls = set()
|
||||||
self._settings = settings
|
self._settings = settings
|
||||||
@ -27,7 +28,7 @@ class CallsManager:
|
|||||||
self._app = app
|
self._app = app
|
||||||
|
|
||||||
def set_toxav(self, toxav):
|
def set_toxav(self, toxav):
|
||||||
self._call.set_toxav(toxav)
|
self._callav.set_toxav(toxav)
|
||||||
|
|
||||||
# -----------------------------------------------------------------------------------------------------------------
|
# -----------------------------------------------------------------------------------------------------------------
|
||||||
# Events
|
# Events
|
||||||
@ -52,13 +53,13 @@ class CallsManager:
|
|||||||
num = self._contacts_manager.get_active_number()
|
num = self._contacts_manager.get_active_number()
|
||||||
if not self._contacts_manager.is_active_a_friend():
|
if not self._contacts_manager.is_active_a_friend():
|
||||||
return
|
return
|
||||||
if num not in self._call and self._contacts_manager.is_active_online(): # start call
|
if num not in self._callav and self._contacts_manager.is_active_online(): # start call
|
||||||
if not self._settings['audio']['enabled']:
|
if not self._settings['audio']['enabled']:
|
||||||
return
|
return
|
||||||
self._call(num, audio, video)
|
self._callav(num, audio, video)
|
||||||
self._main_screen.active_call()
|
self._main_screen.active_call()
|
||||||
self._call_started_event(num, audio, video, True)
|
self._call_started_event(num, audio, video, True)
|
||||||
elif num in self._call: # finish or cancel call if you call with active friend
|
elif num in self._callav: # finish or cancel call if you call with active friend
|
||||||
self.stop_call(num, False)
|
self.stop_call(num, False)
|
||||||
|
|
||||||
def incoming_call(self, audio, video, friend_number):
|
def incoming_call(self, audio, video, friend_number):
|
||||||
@ -89,7 +90,7 @@ class CallsManager:
|
|||||||
sys.stdout.flush()
|
sys.stdout.flush()
|
||||||
|
|
||||||
try:
|
try:
|
||||||
self._call.call_accept_call(friend_number, audio, video)
|
self._callav.call_accept_call(friend_number, audio, video)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
LOG.error(f"accept_call _call.accept_call ERROR for {friend_number} {e}")
|
LOG.error(f"accept_call _call.accept_call ERROR for {friend_number} {e}")
|
||||||
self._main_screen.call_finished()
|
self._main_screen.call_finished()
|
||||||
@ -139,14 +140,14 @@ class CallsManager:
|
|||||||
else:
|
else:
|
||||||
is_declined = False
|
is_declined = False
|
||||||
self._main_screen.call_finished()
|
self._main_screen.call_finished()
|
||||||
self._call.finish_call(friend_number, by_friend) # finish or decline call
|
self._callav.finish_call(friend_number, by_friend) # finish or decline call
|
||||||
if friend_number in self._call_widgets:
|
if friend_number in self._call_widgets:
|
||||||
self._call_widgets[friend_number].close()
|
self._call_widgets[friend_number].close()
|
||||||
del self._call_widgets[friend_number]
|
del self._call_widgets[friend_number]
|
||||||
|
|
||||||
def destroy_window():
|
def destroy_window():
|
||||||
#??? FixMed
|
#??? FixMed
|
||||||
is_video = self._call.is_video_call(friend_number)
|
is_video = self._callav.is_video_call(friend_number)
|
||||||
if is_video:
|
if is_video:
|
||||||
import cv2
|
import cv2
|
||||||
cv2.destroyWindow(str(friend_number))
|
cv2.destroyWindow(str(friend_number))
|
||||||
@ -155,8 +156,8 @@ class CallsManager:
|
|||||||
self._call_finished_event(friend_number, is_declined)
|
self._call_finished_event(friend_number, is_declined)
|
||||||
|
|
||||||
def friend_exit(self, friend_number):
|
def friend_exit(self, friend_number):
|
||||||
if friend_number in self._call:
|
if friend_number in self._callav:
|
||||||
self._call.finish_call(friend_number, True)
|
self._callav.finish_call(friend_number, True)
|
||||||
|
|
||||||
# -----------------------------------------------------------------------------------------------------------------
|
# -----------------------------------------------------------------------------------------------------------------
|
||||||
# Private methods
|
# Private methods
|
||||||
|
@ -28,7 +28,7 @@ class BaseContact:
|
|||||||
self._kind = kind
|
self._kind = kind
|
||||||
self._status, self._widget = None, widget
|
self._status, self._widget = None, widget
|
||||||
self._tox_id = tox_id
|
self._tox_id = tox_id
|
||||||
|
|
||||||
self._name_changed_event = event.Event()
|
self._name_changed_event = event.Event()
|
||||||
self._status_message_changed_event = event.Event()
|
self._status_message_changed_event = event.Event()
|
||||||
self._status_changed_event = event.Event()
|
self._status_changed_event = event.Event()
|
||||||
|
@ -93,7 +93,7 @@ class ContactsManager(ToxSave):
|
|||||||
return False
|
return False
|
||||||
if not self._contacts[self._active_contact]:
|
if not self._contacts[self._active_contact]:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
return self._contacts[self._active_contact].tox_id == contact.tox_id
|
return self._contacts[self._active_contact].tox_id == contact.tox_id
|
||||||
|
|
||||||
# -----------------------------------------------------------------------------------------------------------------
|
# -----------------------------------------------------------------------------------------------------------------
|
||||||
@ -198,7 +198,7 @@ class ContactsManager(ToxSave):
|
|||||||
# -----------------------------------------------------------------------------------------------------------------
|
# -----------------------------------------------------------------------------------------------------------------
|
||||||
# Filtration
|
# Filtration
|
||||||
# -----------------------------------------------------------------------------------------------------------------
|
# -----------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
def filtration_and_sorting(self, sorting=0, filter_str=''):
|
def filtration_and_sorting(self, sorting=0, filter_str=''):
|
||||||
"""
|
"""
|
||||||
Filtration of friends list
|
Filtration of friends list
|
||||||
@ -245,7 +245,7 @@ class ContactsManager(ToxSave):
|
|||||||
else:
|
else:
|
||||||
self._contacts = sorted(self._contacts, key=lambda x: x.name.lower())
|
self._contacts = sorted(self._contacts, key=lambda x: x.name.lower())
|
||||||
|
|
||||||
|
|
||||||
# change item widgets
|
# change item widgets
|
||||||
for index, contact in enumerate(self._contacts):
|
for index, contact in enumerate(self._contacts):
|
||||||
list_item = self._screen.friends_list.item(index)
|
list_item = self._screen.friends_list.item(index)
|
||||||
|
@ -53,7 +53,7 @@ class GroupsService(tox_save.ToxSave):
|
|||||||
try:
|
try:
|
||||||
group_number = self._tox.group_join(chat_id, password, nick, status)
|
group_number = self._tox.group_join(chat_id, password, nick, status)
|
||||||
assert type(group_number) == int, group_number
|
assert type(group_number) == int, group_number
|
||||||
assert group_number < UINT32_MAX, group_number
|
assert group_number < UINT32_MAX, group_number
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
# gui
|
# gui
|
||||||
title = f"join_gc_by_id {chat_id}"
|
title = f"join_gc_by_id {chat_id}"
|
||||||
@ -73,7 +73,7 @@ class GroupsService(tox_save.ToxSave):
|
|||||||
return
|
return
|
||||||
group.status = constants.TOX_USER_STATUS['NONE']
|
group.status = constants.TOX_USER_STATUS['NONE']
|
||||||
self._contacts_manager.update_filtration()
|
self._contacts_manager.update_filtration()
|
||||||
|
|
||||||
# -----------------------------------------------------------------------------------------------------------------
|
# -----------------------------------------------------------------------------------------------------------------
|
||||||
# Groups reconnect and leaving
|
# Groups reconnect and leaving
|
||||||
# -----------------------------------------------------------------------------------------------------------------
|
# -----------------------------------------------------------------------------------------------------------------
|
||||||
|
@ -6,20 +6,16 @@ import utils.util as util
|
|||||||
# LOG=util.log
|
# LOG=util.log
|
||||||
global LOG
|
global LOG
|
||||||
import logging
|
import logging
|
||||||
LOG = logging.getLogger('app.'+__name__)
|
LOG = logging.getLogger('app.db')
|
||||||
log = lambda x: LOG.info(x)
|
|
||||||
|
|
||||||
TIMEOUT = 11
|
TIMEOUT = 11
|
||||||
|
|
||||||
SAVE_MESSAGES = 500
|
SAVE_MESSAGES = 500
|
||||||
|
|
||||||
MESSAGE_AUTHOR = {
|
MESSAGE_AUTHOR = {
|
||||||
'ME': 0,
|
'ME': 0,
|
||||||
'FRIEND': 1,
|
'FRIEND': 1,
|
||||||
'NOT_SENT': 2,
|
'NOT_SENT': 2,
|
||||||
'GC_PEER': 3
|
'GC_PEER': 3
|
||||||
}
|
}
|
||||||
|
|
||||||
CONTACT_TYPE = {
|
CONTACT_TYPE = {
|
||||||
'FRIEND': 0,
|
'FRIEND': 0,
|
||||||
'GC_PEER': 1,
|
'GC_PEER': 1,
|
||||||
@ -54,6 +50,7 @@ class Database:
|
|||||||
except Exception as ex:
|
except Exception as ex:
|
||||||
LOG.error('Db writing error: ' +path +' ' + str(ex))
|
LOG.error('Db writing error: ' +path +' ' + str(ex))
|
||||||
os.remove(path)
|
os.remove(path)
|
||||||
|
LOG.info('Db opened: ' +path)
|
||||||
|
|
||||||
# -----------------------------------------------------------------------------------------------------------------
|
# -----------------------------------------------------------------------------------------------------------------
|
||||||
# Public methods
|
# Public methods
|
||||||
@ -75,6 +72,7 @@ class Database:
|
|||||||
data = self._toxes.pass_encrypt(data)
|
data = self._toxes.pass_encrypt(data)
|
||||||
with open(new_path, 'wb') as fout:
|
with open(new_path, 'wb') as fout:
|
||||||
fout.write(data)
|
fout.write(data)
|
||||||
|
LOG.info('Db exported: ' +new_path)
|
||||||
|
|
||||||
def add_friend_to_db(self, tox_id):
|
def add_friend_to_db(self, tox_id):
|
||||||
db = self._connect()
|
db = self._connect()
|
||||||
@ -91,11 +89,12 @@ class Database:
|
|||||||
db.commit()
|
db.commit()
|
||||||
return True
|
return True
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
LOG("ERROR: " +self._name +' Database exception! ' +str(e))
|
LOG.error("dd_friend_to_db " +self._name +' Database exception! ' +str(e))
|
||||||
db.rollback()
|
db.rollback()
|
||||||
return False
|
return False
|
||||||
finally:
|
finally:
|
||||||
db.close()
|
db.close()
|
||||||
|
LOG.debug(f"add_friend_to_db {tox_id}")
|
||||||
|
|
||||||
def delete_friend_from_db(self, tox_id):
|
def delete_friend_from_db(self, tox_id):
|
||||||
db = self._connect()
|
db = self._connect()
|
||||||
@ -105,11 +104,12 @@ class Database:
|
|||||||
db.commit()
|
db.commit()
|
||||||
return True
|
return True
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
LOG("ERROR: " +self._name +' Database exception! ' +str(e))
|
LOG.error("delete_friend_from_db " +self._name +' Database exception! ' +str(e))
|
||||||
db.rollback()
|
db.rollback()
|
||||||
return False
|
return False
|
||||||
finally:
|
finally:
|
||||||
db.close()
|
db.close()
|
||||||
|
LOG.debug(f"delete_friend_from_db {tox_id}")
|
||||||
|
|
||||||
def save_messages_to_db(self, tox_id, messages_iter):
|
def save_messages_to_db(self, tox_id, messages_iter):
|
||||||
db = self._connect()
|
db = self._connect()
|
||||||
@ -117,15 +117,16 @@ class Database:
|
|||||||
cursor = db.cursor()
|
cursor = db.cursor()
|
||||||
cursor.executemany('INSERT INTO id' + tox_id +
|
cursor.executemany('INSERT INTO id' + tox_id +
|
||||||
'(message, author_name, author_type, unix_time, message_type) ' +
|
'(message, author_name, author_type, unix_time, message_type) ' +
|
||||||
'VALUES (?, ?, ?, ?, ?, ?);', messages_iter)
|
'VALUES (?, ?, ?, ?, ?);', messages_iter)
|
||||||
db.commit()
|
db.commit()
|
||||||
return True
|
return True
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
LOG("ERROR: " +self._name +' Database exception! ' +str(e))
|
LOG.error("" +self._name +' Database exception! ' +str(e))
|
||||||
db.rollback()
|
db.rollback()
|
||||||
return False
|
return False
|
||||||
finally:
|
finally:
|
||||||
db.close()
|
db.close()
|
||||||
|
LOG.debug(f"save_messages_to_db {tox_id}")
|
||||||
|
|
||||||
def update_messages(self, tox_id, message_id):
|
def update_messages(self, tox_id, message_id):
|
||||||
db = self._connect()
|
db = self._connect()
|
||||||
@ -136,11 +137,12 @@ class Database:
|
|||||||
db.commit()
|
db.commit()
|
||||||
return True
|
return True
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
LOG("ERROR: " +self._name +' Database exception! ' +str(e))
|
LOG.error("" +self._name +' Database exception! ' +str(e))
|
||||||
db.rollback()
|
db.rollback()
|
||||||
return False
|
return False
|
||||||
finally:
|
finally:
|
||||||
db.close()
|
db.close()
|
||||||
|
LOG.debug(f"update_messages {tox_id}")
|
||||||
|
|
||||||
def delete_message(self, tox_id, unique_id):
|
def delete_message(self, tox_id, unique_id):
|
||||||
db = self._connect()
|
db = self._connect()
|
||||||
@ -150,11 +152,12 @@ class Database:
|
|||||||
db.commit()
|
db.commit()
|
||||||
return True
|
return True
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
LOG("ERROR: " +self._name +' Database exception! ' +str(e))
|
LOG.error("" +self._name +' Database exception! ' +str(e))
|
||||||
db.rollback()
|
db.rollback()
|
||||||
return False
|
return False
|
||||||
finally:
|
finally:
|
||||||
db.close()
|
db.close()
|
||||||
|
LOG.debug(f"delete_message {tox_id}")
|
||||||
|
|
||||||
def delete_messages(self, tox_id):
|
def delete_messages(self, tox_id):
|
||||||
db = self._connect()
|
db = self._connect()
|
||||||
@ -164,11 +167,12 @@ class Database:
|
|||||||
db.commit()
|
db.commit()
|
||||||
return True
|
return True
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
LOG("ERROR: " +self._name +' Database exception! ' +str(e))
|
LOG.error("" +self._name +' Database exception! ' +str(e))
|
||||||
db.rollback()
|
db.rollback()
|
||||||
return False
|
return False
|
||||||
finally:
|
finally:
|
||||||
db.close()
|
db.close()
|
||||||
|
LOG.debug(f"delete_messages {tox_id}")
|
||||||
|
|
||||||
def messages_getter(self, tox_id):
|
def messages_getter(self, tox_id):
|
||||||
self.add_friend_to_db(tox_id)
|
self.add_friend_to_db(tox_id)
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
# -*- mode: python; indent-tabs-mode: nil; py-indent-offset: 4; coding: utf-8 -*-
|
# -*- mode: python; indent-tabs-mode: nil; py-indent-offset: 4; coding: utf-8 -*-
|
||||||
from history.history_logs_generators import *
|
from history.history_logs_generators import *
|
||||||
|
|
||||||
|
|
||||||
class History:
|
class History:
|
||||||
|
|
||||||
def __init__(self, contact_provider, db, settings, main_screen, messages_items_factory):
|
def __init__(self, contact_provider, db, settings, main_screen, messages_items_factory):
|
||||||
@ -28,7 +27,7 @@ class History:
|
|||||||
Save history to db
|
Save history to db
|
||||||
"""
|
"""
|
||||||
# me a mistake? was _db not _history
|
# me a mistake? was _db not _history
|
||||||
if self._settings['save_history'] or self._settings['save_db']:
|
if self._settings['save_history']:
|
||||||
for friend in self._contact_provider.get_all_friends():
|
for friend in self._contact_provider.get_all_friends():
|
||||||
self._db.add_friend_to_db(friend.tox_id)
|
self._db.add_friend_to_db(friend.tox_id)
|
||||||
if not self._settings['save_unsent_only']:
|
if not self._settings['save_unsent_only']:
|
||||||
|
@ -21,7 +21,7 @@ iMAX = 70
|
|||||||
try:
|
try:
|
||||||
# https://github.com/pyqtconsole/pyqtconsole
|
# https://github.com/pyqtconsole/pyqtconsole
|
||||||
from pyqtconsole.console import PythonConsole
|
from pyqtconsole.console import PythonConsole
|
||||||
import pyqtconsole.highlighter as hl
|
import pyqtconsole.highlighter as hl
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
LOG.warn(e)
|
LOG.warn(e)
|
||||||
PythonConsole = None
|
PythonConsole = None
|
||||||
@ -39,12 +39,12 @@ else:
|
|||||||
_format.setFontWeight(QFont.Bold)
|
_format.setFontWeight(QFont.Bold)
|
||||||
if 'italic' in style:
|
if 'italic' in style:
|
||||||
_format.setFontItalic(True)
|
_format.setFontItalic(True)
|
||||||
|
|
||||||
_fgcolor = QColor()
|
_fgcolor = QColor()
|
||||||
_fgcolor.setNamedColor('white')
|
_fgcolor.setNamedColor('white')
|
||||||
_format.setForeground(_fgcolor)
|
_format.setForeground(_fgcolor)
|
||||||
return _format
|
return _format
|
||||||
|
|
||||||
aFORMATS = {
|
aFORMATS = {
|
||||||
'keyword': hl.format('blue', 'bold'),
|
'keyword': hl.format('blue', 'bold'),
|
||||||
'operator': hl.format('red'),
|
'operator': hl.format('red'),
|
||||||
@ -59,7 +59,7 @@ else:
|
|||||||
'outprompt': hl.format('darkRed', 'bold'),
|
'outprompt': hl.format('darkRed', 'bold'),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
class QTextEditLogger(logging.Handler):
|
class QTextEditLogger(logging.Handler):
|
||||||
def __init__(self, parent, app):
|
def __init__(self, parent, app):
|
||||||
super().__init__()
|
super().__init__()
|
||||||
@ -194,7 +194,7 @@ class MainWindow(QtWidgets.QMainWindow):
|
|||||||
|
|
||||||
self.actionAdd_friend = QtWidgets.QAction(window)
|
self.actionAdd_friend = QtWidgets.QAction(window)
|
||||||
self.actionAdd_friend.setObjectName("actionAdd_friend")
|
self.actionAdd_friend.setObjectName("actionAdd_friend")
|
||||||
|
|
||||||
self.actionProfile_settings = QtWidgets.QAction(window)
|
self.actionProfile_settings = QtWidgets.QAction(window)
|
||||||
self.actionProfile_settings.setObjectName("actionProfile_settings")
|
self.actionProfile_settings.setObjectName("actionProfile_settings")
|
||||||
self.actionPrivacy_settings = QtWidgets.QAction(window)
|
self.actionPrivacy_settings = QtWidgets.QAction(window)
|
||||||
@ -621,10 +621,10 @@ class MainWindow(QtWidgets.QMainWindow):
|
|||||||
else:
|
else:
|
||||||
size = 12
|
size = 12
|
||||||
font_name = "Courier New"
|
font_name = "Courier New"
|
||||||
|
|
||||||
size = font_width = 10
|
size = font_width = 10
|
||||||
font_name = "DejaVu Sans Mono"
|
font_name = "DejaVu Sans Mono"
|
||||||
|
|
||||||
try:
|
try:
|
||||||
if not self._pe:
|
if not self._pe:
|
||||||
self._pe = PythonConsole(sFont=font_name,
|
self._pe = PythonConsole(sFont=font_name,
|
||||||
|
@ -360,7 +360,6 @@ class Settings(dict):
|
|||||||
'y': 400,
|
'y': 400,
|
||||||
'message_font_size': 14,
|
'message_font_size': 14,
|
||||||
'unread_color': 'red',
|
'unread_color': 'red',
|
||||||
'save_unsent_only': False,
|
|
||||||
'compact_mode': False,
|
'compact_mode': False,
|
||||||
'identicons': True,
|
'identicons': True,
|
||||||
'show_welcome_screen': True,
|
'show_welcome_screen': True,
|
||||||
|
Loading…
Reference in New Issue
Block a user