updates
Some checks are pending
CI / Python ${{ matrix.python-version }} (3.10) (push) Waiting to run
CI / Python ${{ matrix.python-version }} (3.7) (push) Waiting to run
CI / Python ${{ matrix.python-version }} (3.8) (push) Waiting to run
CI / Python ${{ matrix.python-version }} (3.9) (push) Waiting to run

This commit is contained in:
emdee@spm.plastiras.org 2024-02-13 21:00:45 +00:00
parent f7e260a355
commit 2717f4f6e5
88 changed files with 440 additions and 2806 deletions

8
.gitignore vendored
View File

@ -3,9 +3,15 @@
*.pyc
*.pyo
*.zip
*.bak
*.lis
*.dst
*.so
toxygen/toxcore
tests/tests
tests/libs
toxygen/libs
tests/.cache
tests/__pycache__
tests/avatars

23
.pre-commit-config.yaml Normal file
View File

@ -0,0 +1,23 @@
# -*- mode: yaml; indent-tabs-mode: nil; tab-width: 2; coding: utf-8-unix -*-
---
default_language_version:
python: python3.11
default_stages: [pre-commit]
fail_fast: true
repos:
- repo: local
hooks:
- id: pylint
name: pylint
entry: env PYTHONPATH=/mnt/o/var/local/src/toxygen.git/toxygen toxcore_pylint.bash
language: system
types: [python]
args:
[
"--source-roots=/mnt/o/var/local/src/toxygen.git/toxygen",
"-rn", # Only display messages
"-sn", # Don't display the score
"--rcfile=/usr/local/etc/testforge/pylint.rc", # Link to your config file
"-E"
]

4
.pylintrc Normal file
View File

@ -0,0 +1,4 @@
[pre-commit-hook]
command=env PYTHONPATH=/mnt/o/var/local/src/toxygen.git/toxygen /usr/local/bin/toxcore_pylint.bash
params= -E --exit-zero
limit=8

View File

@ -1,7 +1,7 @@
#!/bin/sh
find * -name \*.py | xargs grep -l '[ ]*$' | xargs sed -i -e 's/[ ]*$//'
rsync "$@" -vax --include \*.py \
#find * -name \*.py | xargs grep -l '[ ]*$' | xargs sed -i -e 's/[ ]*$//'
rsync "$@" -vaxL --include \*.py \
--exclude Toxygen.egg-info --exclude build \
--exclude \*.pyc --exclude .pyl\* --exclude \*~ \
--exclude __pycache__ --exclude \*.egg-info --exclude \*.new \

View File

@ -1,51 +0,0 @@
[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"]

View File

@ -1,53 +0,0 @@
import sys
import os
from setuptools import setup
from setuptools.command.install import install
version = '1.0.0'
MODULES = open('requirements.txt', 'rt').readlines()
def get_packages():
directory = os.path.join(os.path.dirname(__file__), 'tox_wrapper')
for root, dirs, files in os.walk(directory):
packages = map(lambda d: 'toxygen.' + d, dirs)
packages = ['toxygen'] + list(packages)
return packages
class InstallScript(install):
"""This class configures Toxygen after installation"""
def run(self):
install.run(self)
setup(name='Toxygen',
version=version,
description='Toxygen - Tox client',
long_description='Toxygen is powerful Tox client written in Python3',
url='https://git.plastiras.org/emdee/toxygen/',
keywords='toxygen Tox messenger',
author='Ingvar',
maintainer='',
license='GPL3',
packages=get_packages(),
install_requires=MODULES,
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,
},
zip_safe=False
)

View File

@ -1,4 +1,4 @@
class TestToxygen:
def test_main(self):
import toxygen.main # check for syntax errors
import toxygen.__main__ # check for syntax errors

View File

@ -208,7 +208,7 @@ class App:
"""
Main function of app. loads login screen if needed and starts main screen
"""
self._app = QtWidgets.QApplication([])
self._app = QApplication([])
self._load_icon()
# is this still needed?

View File

@ -1,4 +1,4 @@
# -*- mode: python; indent-tabs-mode: nil; py-indent-offset: 4; coding: utf-8 -*-
class Call:

View File

@ -13,6 +13,7 @@ with ts.ignoreStderr():
from av import screen_sharing
from av.call import Call
import common.tox_save
from middleware.threads import BaseQThread
from utils import ui as util_ui
from middleware.threads import invoke_in_main_thread
@ -36,7 +37,7 @@ class AudioThread(BaseQThread):
LOG_DEBUG(f"AudioThread join {self}")
# dunno
def run(self):
def run(self) -> None:
LOG_DEBUG('AudioThread run: ')
# maybe not needed
while not self._stop_thread:
@ -53,7 +54,7 @@ class VideoThread(BaseQThread):
LOG_DEBUG(f"VideoThread join {self}")
# dunno
def run(self):
def run(self) -> None:
LOG_DEBUG('VideoThread run: ')
# maybe not needed
while not self._stop_thread:
@ -109,13 +110,13 @@ class AV(common.tox_save.ToxAvSave):
global oPYA
oPYA = self._audio = pyaudio.PyAudio()
def stop(self):
def stop(self) -> None:
LOG_DEBUG(f"AV.CA stop {self._video_thread}")
self._running = False
self.stop_audio_thread()
self.stop_video_thread()
def __contains__(self, friend_number):
def __contains__(self, friend_number:int) -> bool:
return friend_number in self._calls
# Calls
@ -141,9 +142,9 @@ class AV(common.tox_save.ToxAvSave):
def accept_call(self, friend_number, audio_enabled, video_enabled):
# obsolete
return self.call_accept_call(friend_number, audio_enabled, video_enabled)
self.call_accept_call(friend_number, audio_enabled, video_enabled)
def call_accept_call(self, friend_number, audio_enabled, video_enabled):
def call_accept_call(self, friend_number, audio_enabled, video_enabled) -> None:
# called from CM.accept_call in a try:
LOG.debug(f"call_accept_call from F={friend_number} R={self._running}" +
f" A={audio_enabled} V={video_enabled}")
@ -171,7 +172,7 @@ class AV(common.tox_save.ToxAvSave):
# may raise
self.start_audio_thread()
def finish_call(self, friend_number, by_friend=False):
def finish_call(self, friend_number, by_friend=False) -> None:
LOG.debug(f"finish_call {friend_number}")
if friend_number in self._calls:
del self._calls[friend_number]
@ -191,13 +192,13 @@ class AV(common.tox_save.ToxAvSave):
self._toxav.call_control(friend_number, TOXAV_CALL_CONTROL['CANCEL'])
LOG.debug(f"finish_call after call_control {friend_number}")
def finish_not_started_call(self, friend_number):
def finish_not_started_call(self, friend_number:int) -> None:
if friend_number in self:
call = self._calls[friend_number]
if not call.is_active:
self.finish_call(friend_number)
def toxav_call_state_cb(self, friend_number, state):
def toxav_call_state_cb(self, friend_number, state) -> None:
"""
New call state
"""
@ -214,12 +215,12 @@ class AV(common.tox_save.ToxAvSave):
if state | TOXAV_FRIEND_CALL_STATE['ACCEPTING_V'] and call.out_video:
self.start_video_thread()
def is_video_call(self, number):
def is_video_call(self, number) -> bool:
return number in self and self._calls[number].in_video
# Threads
def start_audio_thread(self, bSTREAM_CALLBACK=False):
def start_audio_thread(self, bSTREAM_CALLBACK=False) -> None:
"""
Start audio sending
from a callback
@ -309,7 +310,7 @@ class AV(common.tox_save.ToxAvSave):
else:
LOG_DEBUG(f"start_audio_thread {self._audio_stream}")
def stop_audio_thread(self):
def stop_audio_thread(self) -> None:
LOG_DEBUG(f"stop_audio_thread {self._audio_stream}")
if self._audio_thread is None:
@ -326,7 +327,7 @@ class AV(common.tox_save.ToxAvSave):
self._out_stream.close()
self._out_stream = None
def start_video_thread(self):
def start_video_thread(self) -> None:
if self._video_thread is not None:
return
s = self._settings
@ -334,7 +335,7 @@ class AV(common.tox_save.ToxAvSave):
LOG.warn("AV.__init__ 'video' not in s" )
LOG.debug(f"start_video_thread {s}" )
raise RuntimeError("start_video_thread not 'video' in s)" )
elif 'device' not in s['video']:
if 'device' not in s['video']:
LOG.error("start_video_thread not 'device' in s['video']" )
LOG.debug(f"start_video_thread {s['video']}" )
raise RuntimeError("start_video_thread not 'device' ins s['video']" )
@ -342,7 +343,7 @@ class AV(common.tox_save.ToxAvSave):
self._video_height = s['video']['height']
# dunno
if True or s['video']['device'] == -1:
if s['video']['device'] == -1:
self._video = screen_sharing.DesktopGrabber(s['video']['x'],
s['video']['y'],
s['video']['width'],
@ -509,24 +510,24 @@ class AV(common.tox_save.ToxAvSave):
if frame is None:
LOG_WARN(f"send_video video_send_frame _video.read result={result} frame={frame}")
continue
LOG_TRACE(f"send_video video_send_frame _video.read result={result}")
height, width, channels = frame.shape
friends = []
for friend_num in self._calls:
if self._calls[friend_num].out_video:
friends.append(friend_num)
if len(friends) == 0:
LOG_WARN(f"send_video video_send_frame no friends")
else:
LOG_TRACE(f"send_video video_send_frame _video.read result={result}")
height, width, channels = frame.shape
friends = []
for friend_num in self._calls:
if self._calls[friend_num].out_video:
friends.append(friend_num)
if len(friends) == 0:
LOG_WARN(f"send_video video_send_frame no friends")
else:
LOG_TRACE(f"send_video video_send_frame {friends}")
friend_num = friends[0]
try:
y, u, v = self.convert_bgr_to_yuv(frame)
self._toxav.video_send_frame(friend_num, width, height, y, u, v)
except Exception as e:
LOG_WARN(f"send_video video_send_frame ERROR {e}")
pass
LOG_TRACE(f"send_video video_send_frame {friends}")
friend_num = friends[0]
try:
y, u, v = self.convert_bgr_to_yuv(frame)
self._toxav.video_send_frame(friend_num, width, height, y, u, v)
except Exception as e:
LOG_WARN(f"send_video video_send_frame ERROR {e}")
pass
except Exception as e:
LOG_ERROR(f"send_video video_send_frame {e}")

View File

@ -31,7 +31,7 @@ class CallsManager:
self._call_finished_event = event.Event() # friend_number, is_declined
self._app = app
def set_toxav(self, toxav):
def set_toxav(self, toxav) -> None:
self._callav.set_toxav(toxav)
# Events
@ -48,7 +48,7 @@ class CallsManager:
# AV support
def call_click(self, audio=True, video=False):
def call_click(self, audio=True, video=False) -> None:
"""User clicked audio button in main window"""
num = self._contacts_manager.get_active_number()
if not self._contacts_manager.is_active_a_friend():
@ -62,7 +62,7 @@ class CallsManager:
elif num in self._callav: # finish or cancel call if you call with active friend
self.stop_call(num, False)
def incoming_call(self, audio, video, friend_number):
def incoming_call(self, audio, video, friend_number) -> None:
"""
Incoming call from friend.
"""
@ -80,7 +80,7 @@ class CallsManager:
self._call_widgets[friend_number].set_pixmap(friend.get_pixmap())
self._call_widgets[friend_number].show()
def accept_call(self, friend_number, audio, video):
def accept_call(self, friend_number, audio, video) -> None:
"""
Accept incoming call with audio or video
Called from a thread
@ -127,7 +127,7 @@ class CallsManager:
self.close_call(friend_number)
LOG.debug(f" closed self._call_widgets[{friend_number}]")
def close_call(self, friend_number):
def close_call(self, friend_number:int) -> None:
# refactored out from above because the accept window not getting
# taken down in some accept audio calls
LOG.debug(f"close_call {friend_number}")
@ -145,7 +145,7 @@ class CallsManager:
QtCore.QCoreApplication.processEvents()
def stop_call(self, friend_number, by_friend):
def stop_call(self, friend_number, by_friend) -> None:
"""
Stop call with friend
"""
@ -174,7 +174,7 @@ class CallsManager:
LOG.debug(f"CM.stop_call _call_finished_event")
self._call_finished_event(friend_number, is_declined)
def friend_exit(self, friend_number):
def friend_exit(self, friend_number:int) -> None:
if friend_number in self._callav:
self._callav.finish_call(friend_number, True)

View File

@ -1,5 +1,6 @@
from qtpy import QtWidgets
# -*- mode: python; indent-tabs-mode: nil; py-indent-offset: 4; coding: utf-8 -*-
from qtpy import QtWidgets
class DesktopGrabber:
@ -12,7 +13,7 @@ class DesktopGrabber:
self._height -= height % 4
self._screen = QtWidgets.QApplication.primaryScreen()
def read(self):
def read(self) -> tuple:
pixmap = self._screen.grabWindow(0, self._x, self._y, self._width, self._height)
image = pixmap.toImage()
s = image.bits().asstring(self._width * self._height * 4)

View File

@ -19,7 +19,7 @@ import toxygen_wrapper.tests.support_testing as ts
global LOG
LOG = logging.getLogger('app.'+'bootstrap')
def download_nodes_list(settings, oArgs):
def download_nodes_list(settings, oArgs) -> str:
if not settings['download_nodes_list']:
return ''
if not ts.bAreWeConnected():
@ -40,7 +40,7 @@ def download_nodes_list(settings, oArgs):
_save_nodes(result, settings._app)
return result
def _save_nodes(nodes, app):
def _save_nodes(nodes, app) -> None:
if not nodes:
return
with open(_get_nodes_path(app._args), 'wb') as fl:

View File

@ -1,4 +1,4 @@
# -*- mode: python; indent-tabs-mode: nil; py-indent-offset: 4; coding: utf-8 -*-
class Event:

View File

@ -1,4 +1,4 @@
# -*- mode: python; indent-tabs-mode: nil; py-indent-offset: 4; coding: utf-8 -*-
class Provider:

View File

@ -1,4 +1,4 @@
# -*- mode: python; indent-tabs-mode: nil; py-indent-offset: 4; coding: utf-8 -*-
class ToxSave:

View File

@ -1,6 +1,8 @@
from pydenticon import Generator
# -*- mode: python; indent-tabs-mode: nil; py-indent-offset: 4; coding: utf-8 -*-
import hashlib
from pydenticon import Generator
# Typing notifications
@ -17,7 +19,7 @@ class BaseTypingNotificationHandler:
class FriendTypingNotificationHandler(BaseTypingNotificationHandler):
def __init__(self, friend_number):
def __init__(self, friend_number:int):
super().__init__()
self._friend_number = friend_number

View File

@ -21,7 +21,7 @@ class ContactProvider(tox_save.ToxSave):
# Friends
def get_friend_by_number(self, friend_number):
def get_friend_by_number(self, friend_number:int):
try:
public_key = self._tox.friend_get_public_key(friend_number)
except Exception as e:
@ -124,7 +124,7 @@ class ContactProvider(tox_save.ToxSave):
# Group peers
def get_all_group_peers(self):
return list()
return []
def get_group_peer_by_id(self, group, peer_id):
peer = group.get_peer_by_id(peer_id)

View File

@ -1,6 +1,6 @@
# -*- mode: python; indent-tabs-mode: nil; py-indent-offset: 4; coding: utf-8 -*-
import traceback
import logging
from contacts.friend import Friend
from contacts.group_chat import GroupChat
@ -13,13 +13,11 @@ import toxygen_wrapper.toxcore_enums_and_consts as enums
# LOG=util.log
global LOG
import logging
LOG = logging.getLogger('app.'+__name__)
UINT32_MAX = 2 ** 32 -1
def set_contact_kind(contact):
def set_contact_kind(contact) -> None:
bInvite = len(contact.name) == enums.TOX_PUBLIC_KEY_SIZE * 2 and \
contact.status_message == ''
bBot = not bInvite and contact.name.lower().endswith(' bot')
@ -59,7 +57,7 @@ class ContactsManager(ToxSave):
self._history = history
self._load_contacts()
def _log(self, s):
def _log(self, s) -> None:
try:
self._ms._log(s)
except: pass
@ -72,23 +70,23 @@ class ContactsManager(ToxSave):
def get_curr_contact(self):
return self._contacts[self._active_contact] if self._active_contact + 1 else None
def save_profile(self):
def save_profile(self) -> None:
data = self._tox.get_savedata()
self._profile_manager.save_profile(data)
def is_friend_active(self, friend_number):
def is_friend_active(self, friend_number:int) -> bool:
if not self.is_active_a_friend():
return False
return self.get_curr_contact().number == friend_number
def is_group_active(self, group_number):
def is_group_active(self, group_number) -> bool:
if self.is_active_a_friend():
return False
return self.get_curr_contact().number == group_number
def is_contact_active(self, contact):
def is_contact_active(self, contact) -> bool:
if self._active_contact == -1:
# LOG.debug("No self._active_contact")
return False
@ -107,7 +105,7 @@ class ContactsManager(ToxSave):
# Reconnection support
def reset_contacts_statuses(self):
def reset_contacts_statuses(self) -> None:
for contact in self._contacts:
contact.status = None
@ -441,7 +439,7 @@ class ContactsManager(ToxSave):
def add_group_peer(self, group, peer):
contact = self._contact_provider.get_group_peer_by_id(group, peer.id)
if self.check_if_contact_exists(contact.tox_id):
return
return contact
contact._kind = 'grouppeer'
self._contacts.append(contact)
contact.reset_avatar(self._settings['identicons'])
@ -651,7 +649,7 @@ class ContactsManager(ToxSave):
try:
index = list(map(lambda x: x[0], self._settings['friends_aliases'])).index(contact.tox_id)
del self._settings['friends_aliases'][index]
except:
except Exception as e:
pass
if contact.tox_id in self._settings['notes']:
del self._settings['notes'][contact.tox_id]

View File

@ -1,3 +1,5 @@
# -*- mode: python; indent-tabs-mode: nil; py-indent-offset: 4; coding: utf-8 -*-
import os
from contacts import contact, common

View File

@ -1,7 +1,8 @@
# -*- mode: python; indent-tabs-mode: nil; py-indent-offset: 4; coding: utf-8 -*-
from contacts.friend import Friend
from common.tox_save import ToxSave
class FriendFactory(ToxSave):
def __init__(self, profile_manager, settings, tox, db, items_factory):
@ -15,7 +16,7 @@ class FriendFactory(ToxSave):
friend_number = self._tox.friend_by_public_key(public_key)
return self.create_friend_by_number(friend_number)
def create_friend_by_number(self, friend_number):
def create_friend_by_number(self, friend_number:int):
aliases = self._settings['friends_aliases']
sToxPk = self._tox.friend_get_public_key(friend_number)
assert sToxPk, sToxPk

View File

@ -1,7 +1,8 @@
# -*- mode: python; indent-tabs-mode: nil; py-indent-offset: 4; coding: utf-8 -*-
import contacts.contact
from contacts.contact_menu import GroupPeerMenuGenerator
class GroupPeerContact(contacts.contact.Contact):
def __init__(self, profile_manager, message_getter, peer_number, name, widget, tox_id, group_pk, status_message=None):

View File

@ -1,7 +1,7 @@
# -*- mode: python; indent-tabs-mode: nil; py-indent-offset: 4; coding: utf-8 -*-
from common.tox_save import ToxSave
from contacts.group_peer_contact import GroupPeerContact
class GroupPeerFactory(ToxSave):
def __init__(self, tox, profile_manager, db, items_factory):

View File

@ -1,3 +1,5 @@
# -*- mode: python; indent-tabs-mode: nil; py-indent-offset: 4; coding: utf-8 -*-
import os
from os import chdir, remove, rename
from os.path import basename, getsize, exists, dirname
@ -80,9 +82,7 @@ class FileTransfer:
def get_file_id(self):
return self._file_id
# WTF
def get_file_id(self):
return self._tox.file_get_file_id(self._friend_number, self._file_number)
#? return self._tox.file_get_file_id(self._friend_number, self._file_number)
file_id = property(get_file_id)
@ -331,7 +331,7 @@ class ReceiveAvatar(ReceiveTransfer):
ihash = self.get_file_id()
with open(path, 'rb') as fl:
data = fl.read()
existing_ihash = Tox.hash(data)
existing_hash = Tox.hash(data)
if ihash == existing_hash:
self.send_control(TOX_FILE_CONTROL['CANCEL'])
self._file.close()

View File

@ -1,5 +1,6 @@
# -*- mode: python; indent-tabs-mode: nil; py-indent-offset: 4; coding: utf-8 -*-
from copy import deepcopy
import logging
from messenger.messages import *
from file_transfers.file_transfers import SendAvatar, is_inline
@ -11,7 +12,6 @@ from middleware.callbacks import LOG_ERROR, LOG_WARN, LOG_INFO, LOG_DEBUG, LOG_T
# LOG=util.log
global LOG
import logging
LOG = logging.getLogger('app.'+__name__)
log = lambda x: LOG.info(x)
@ -32,13 +32,13 @@ class FileTransfersHandler(ToxSave):
profile.avatar_changed_event.add_callback(self._send_avatar_to_contacts)
self. lBlockAvatars = []
def stop(self):
def stop(self) -> None:
self._settings['paused_file_transfers'] = self._paused_file_transfers if self._settings['resend_files'] else {}
self._settings.save()
# File transfers support
def incoming_file_transfer(self, friend_number, file_number, size, file_name):
def incoming_file_transfer(self, friend_number, file_number, size, file_name) -> None:
# main thread
"""
New transfer
@ -86,7 +86,7 @@ class FileTransfersHandler(ToxSave):
self._file_transfers_message_service.add_incoming_transfer_message(
friend, accepted, size, file_name, file_number)
def cancel_transfer(self, friend_number, file_number, already_cancelled=False):
def cancel_transfer(self, friend_number, file_number, already_cancelled=False) -> None:
"""
Stop transfer
:param friend_number: number of friend
@ -106,19 +106,19 @@ class FileTransfersHandler(ToxSave):
elif not already_cancelled:
self._tox.file_control(friend_number, file_number, TOX_FILE_CONTROL['CANCEL'])
def cancel_not_started_transfer(self, friend_number, message_id):
def cancel_not_started_transfer(self, friend_number, message_id) -> None:
friend = self._get_friend_by_number(friend_number)
if friend is None: return None
friend.delete_one_unsent_file(message_id)
def pause_transfer(self, friend_number, file_number, by_friend=False):
def pause_transfer(self, friend_number, file_number, by_friend=False) -> None:
"""
Pause transfer with specified data
"""
tr = self._file_transfers[(friend_number, file_number)]
tr.pause(by_friend)
def resume_transfer(self, friend_number, file_number, by_friend=False):
def resume_transfer(self, friend_number, file_number, by_friend=False) -> None:
"""
Resume transfer with specified data
"""
@ -128,7 +128,7 @@ class FileTransfersHandler(ToxSave):
else:
tr.send_control(TOX_FILE_CONTROL['RESUME'])
def accept_transfer(self, path, friend_number, file_number, size, inline=False, from_position=0):
def accept_transfer(self, path, friend_number, file_number, size, inline=False, from_position=0) -> None:
"""
:param path: path for saving
:param friend_number: friend number
@ -155,7 +155,7 @@ class FileTransfersHandler(ToxSave):
if inline:
self._insert_inline_before[(friend_number, file_number)] = message.message_id
def send_screenshot(self, data, friend_number):
def send_screenshot(self, data, friend_number) -> None:
"""
Send screenshot
:param data: raw data - png format
@ -163,12 +163,12 @@ class FileTransfersHandler(ToxSave):
"""
self.send_inline(data, 'toxygen_inline.png', friend_number)
def send_sticker(self, path, friend_number):
def send_sticker(self, path, friend_number) -> None:
with open(path, 'rb') as fl:
data = fl.read()
self.send_inline(data, 'sticker.png', friend_number)
def send_inline(self, data, file_name, friend_number, is_resend=False):
def send_inline(self, data, file_name, friend_number, is_resend=False) -> None:
friend = self._get_friend_by_number(friend_number)
if friend is None:
LOG_WARN("fsend_inline Error friend is None file_name: {file_name}")
@ -182,7 +182,7 @@ class FileTransfersHandler(ToxSave):
st = SendFromBuffer(self._tox, friend.number, data, file_name)
self._send_file_add_set_handlers(st, friend, file_name, True)
def send_file(self, path, friend_number, is_resend=False, file_id=None):
def send_file(self, path, friend_number, is_resend=False, file_id=None) -> None:
"""
Send file to current active friend
:param path: file path
@ -202,19 +202,19 @@ class FileTransfersHandler(ToxSave):
file_name = os.path.basename(path)
self._send_file_add_set_handlers(st, friend, file_name)
def incoming_chunk(self, friend_number, file_number, position, data):
def incoming_chunk(self, friend_number, file_number, position, data) -> None:
"""
Incoming chunk
"""
self._file_transfers[(friend_number, file_number)].write_chunk(position, data)
def outgoing_chunk(self, friend_number, file_number, position, size):
def outgoing_chunk(self, friend_number, file_number, position, size) -> None:
"""
Outgoing chunk
"""
self._file_transfers[(friend_number, file_number)].send_chunk(position, size)
def transfer_finished(self, friend_number, file_number):
def transfer_finished(self, friend_number, file_number) -> None:
transfer = self._file_transfers[(friend_number, file_number)]
friend = self._get_friend_by_number(friend_number)
if friend is None: return None
@ -231,7 +231,7 @@ class FileTransfersHandler(ToxSave):
self._file_transfers_message_service.add_inline_message(transfer, index)
del self._file_transfers[(friend_number, file_number)]
def send_files(self, friend_number):
def send_files(self, friend_number:int) -> None:
try:
friend = self._get_friend_by_number(friend_number)
if friend is None: return
@ -255,7 +255,7 @@ class FileTransfersHandler(ToxSave):
except Exception as ex:
LOG_ERROR('send_files EXCEPTION in file sending: ' + str(ex))
def friend_exit(self, friend_number):
def friend_exit(self, friend_number:int) -> None:
# RuntimeError: dictionary changed size during iteration
lMayChangeDynamically = self._file_transfers.copy()
for friend_num, file_num in lMayChangeDynamically:
@ -284,7 +284,7 @@ class FileTransfersHandler(ToxSave):
# Avatars support
def send_avatar(self, friend_number, avatar_path=None):
def send_avatar(self, friend_number, avatar_path=None) -> None:
"""
:param friend_number: number of friend who should get new avatar
:param avatar_path: path to avatar or None if reset
@ -309,7 +309,7 @@ class FileTransfersHandler(ToxSave):
LOG_WARN(f"send_avatar EXCEPTION {e}")
self.lBlockAvatars.append( (avatar_path, friend_number,) )
def incoming_avatar(self, friend_number, file_number, size):
def incoming_avatar(self, friend_number, file_number, size) -> None:
"""
Friend changed avatar
:param friend_number: friend number
@ -325,7 +325,7 @@ class FileTransfersHandler(ToxSave):
elif not size:
friend.reset_avatar(self._settings['identicons'])
def _send_avatar_to_contacts(self, _):
def _send_avatar_to_contacts(self, _) -> None:
# from a callback
friends = self._get_all_friends()
for friend in filter(self._is_friend_online, friends):
@ -333,13 +333,13 @@ class FileTransfersHandler(ToxSave):
# Private methods
def _is_friend_online(self, friend_number):
def _is_friend_online(self, friend_number:int) -> bool:
friend = self._get_friend_by_number(friend_number)
if friend is None: return None
return friend.status is not None
def _get_friend_by_number(self, friend_number):
def _get_friend_by_number(self, friend_number:int):
return self._contact_provider.get_friend_by_number(friend_number)
def _get_all_friends(self):

View File

@ -1,9 +1,12 @@
# -*- mode: python; indent-tabs-mode: nil; py-indent-offset: 4; coding: utf-8 -*-
import logging
from messenger.messenger import *
import utils.util as util
from file_transfers.file_transfers import *
global LOG
import logging
LOG = logging.getLogger('app.'+__name__)
from av.calls import LOG_ERROR, LOG_WARN, LOG_INFO, LOG_DEBUG, LOG_TRACE
@ -47,7 +50,7 @@ class FileTransfersMessagesService:
return tm
def add_inline_message(self, transfer, index):
def add_inline_message(self, transfer, index) -> None:
"""callback"""
if not self._is_friend_active(transfer.friend_number):
return
@ -57,7 +60,8 @@ class FileTransfersMessagesService:
return
count = self._messages.count()
if count + index + 1 >= 0:
self._create_inline_item(transfer.data, count + index + 1)
# assumes .data
self._create_inline_item(transfer, count + index + 1)
def add_unsent_file_message(self, friend, file_path, data):
assert friend
@ -74,7 +78,7 @@ class FileTransfersMessagesService:
# Private methods
def _is_friend_active(self, friend_number):
def _is_friend_active(self, friend_number:int) -> bool:
if not self._contacts_manager.is_active_a_friend():
return False

View File

@ -1,4 +1,4 @@
# -*- mode: python; indent-tabs-mode: nil; py-indent-offset: 4; coding: utf-8 -*-
class GroupBan:

View File

@ -1,4 +1,4 @@
# -*- mode: python; indent-tabs-mode: nil; py-indent-offset: 4; coding: utf-8 -*-
class GroupInvite:

View File

@ -1,4 +1,4 @@
# -*- mode: python; indent-tabs-mode: nil; py-indent-offset: 4; coding: utf-8 -*-
class GroupChatPeer:
"""

View File

@ -1,4 +1,5 @@
# -*- mode: python; indent-tabs-mode: nil; py-indent-offset: 4; coding: utf-8 -*-
import logging
import common.tox_save as tox_save
import utils.ui as util_ui
@ -9,7 +10,6 @@ from toxygen_wrapper.toxcore_enums_and_consts import *
from toxygen_wrapper.tox import UINT32_MAX
global LOG
import logging
LOG = logging.getLogger('app.'+'gs')
class GroupsService(tox_save.ToxSave):
@ -26,14 +26,14 @@ class GroupsService(tox_save.ToxSave):
# maybe just use self
self._tox = tox
def set_tox(self, tox):
def set_tox(self, tox) -> None:
super().set_tox(tox)
for group in self._get_all_groups():
group.set_tox(tox)
# Groups creation
def create_new_gc(self, name, privacy_state, nick, status):
def create_new_gc(self, name, privacy_state, nick, status) -> None:
try:
group_number = self._tox.group_new(privacy_state, name, nick, status)
except Exception as e:
@ -47,7 +47,7 @@ class GroupsService(tox_save.ToxSave):
group.status = constants.TOX_USER_STATUS['NONE']
self._contacts_manager.update_filtration()
def join_gc_by_id(self, chat_id, password, nick, status):
def join_gc_by_id(self, chat_id, password, nick, status) -> None:
try:
group_number = self._tox.group_join(chat_id, password, nick, status)
assert type(group_number) == int, group_number
@ -74,18 +74,18 @@ class GroupsService(tox_save.ToxSave):
# Groups reconnect and leaving
def leave_group(self, group_number):
def leave_group(self, group_number) -> None:
if type(group_number) == int:
self._tox.group_leave(group_number)
self._contacts_manager.delete_group(group_number)
def disconnect_from_group(self, group_number):
def disconnect_from_group(self, group_number) -> None:
self._tox.group_disconnect(group_number)
group = self._get_group_by_number(group_number)
group.status = None
self._clear_peers_list(group)
def reconnect_to_group(self, group_number):
def reconnect_to_group(self, group_number) -> None:
self._tox.group_reconnect(group_number)
group = self._get_group_by_number(group_number)
group.status = constants.TOX_USER_STATUS['NONE']
@ -93,7 +93,7 @@ class GroupsService(tox_save.ToxSave):
# Group invites
def invite_friend(self, friend_number, group_number):
def invite_friend(self, friend_number, group_number) -> None:
if self._tox.friend_get_connection_status(friend_number) == TOX_CONNECTION['NONE']:
title = f"Error in group_invite_friend {friend_number}"
e = f"Friend not connected friend_number={friend_number}"
@ -106,7 +106,7 @@ class GroupsService(tox_save.ToxSave):
title = f"Error in group_invite_friend {group_number} {friend_number}"
util_ui.message_box(title +'\n' +str(e), title)
def process_group_invite(self, friend_number, group_name, invite_data):
def process_group_invite(self, friend_number, group_name, invite_data) -> None:
friend = self._get_friend_by_number(friend_number)
# binary {invite_data}
LOG.debug(f"process_group_invite {friend_number} {group_name}")
@ -114,7 +114,7 @@ class GroupsService(tox_save.ToxSave):
self._group_invites.append(invite)
self._update_invites_button_state()
def accept_group_invite(self, invite, name, status, password):
def accept_group_invite(self, invite, name, status, password) -> None:
pk = invite.friend_public_key
friend = self._get_friend_by_public_key(pk)
LOG.debug(f"accept_group_invite {name}")
@ -122,7 +122,7 @@ class GroupsService(tox_save.ToxSave):
self._delete_group_invite(invite)
self._update_invites_button_state()
def decline_group_invite(self, invite):
def decline_group_invite(self, invite) -> None:
self._delete_group_invite(invite)
self._main_screen.update_gc_invites_button_state()
@ -142,7 +142,7 @@ class GroupsService(tox_save.ToxSave):
group.name = self._tox.group_get_name(group.number)
group.status_message = self._tox.group_get_topic(group.number)
def set_group_topic(self, group):
def set_group_topic(self, group) -> None:
if not group.is_self_moderator_or_founder():
return
text = util_ui.tr('New topic for group "{}":'.format(group.name))
@ -153,29 +153,29 @@ class GroupsService(tox_save.ToxSave):
self._tox.group_set_topic(group.number, topic)
group.status_message = topic
def show_group_management_screen(self, group):
def show_group_management_screen(self, group) -> None:
widgets_factory = self._get_widgets_factory()
self._screen = widgets_factory.create_group_management_screen(group)
self._screen.show()
def show_group_settings_screen(self, group):
def show_group_settings_screen(self, group) -> None:
widgets_factory = self._get_widgets_factory()
self._screen = widgets_factory.create_group_settings_screen(group)
self._screen.show()
def set_group_password(self, group, password):
def set_group_password(self, group, password) -> None:
if group.password == password:
return
self._tox.group_founder_set_password(group.number, password)
group.password = password
def set_group_peers_limit(self, group, peers_limit):
def set_group_peers_limit(self, group, peers_limit) -> None:
if group.peers_limit == peers_limit:
return
self._tox.group_founder_set_peer_limit(group.number, peers_limit)
group.peers_limit = peers_limit
def set_group_privacy_state(self, group, privacy_state):
def set_group_privacy_state(self, group, privacy_state) -> None:
is_private = privacy_state == constants.TOX_GROUP_PRIVACY_STATE['PRIVATE']
if group.is_private == is_private:
return
@ -184,13 +184,13 @@ class GroupsService(tox_save.ToxSave):
# Peers list
def generate_peers_list(self):
def generate_peers_list(self) -> None:
if not self._contacts_manager.is_active_a_group():
return
group = self._contacts_manager.get_curr_contact()
PeersListGenerator().generate(group.peers, self, self._peers_list_widget, group.tox_id)
def peer_selected(self, chat_id, peer_id):
def peer_selected(self, chat_id, peer_id) -> None:
widgets_factory = self._get_widgets_factory()
group = self._get_group_by_public_key(chat_id)
self_peer = group.get_self_peer()
@ -202,16 +202,16 @@ class GroupsService(tox_save.ToxSave):
# Peers actions
def set_new_peer_role(self, group, peer, role):
def set_new_peer_role(self, group, peer, role) -> None:
self._tox.group_mod_set_role(group.number, peer.id, role)
peer.role = role
self.generate_peers_list()
def toggle_ignore_peer(self, group, peer, ignore):
def toggle_ignore_peer(self, group, peer, ignore) -> None:
self._tox.group_toggle_ignore(group.number, peer.id, ignore)
peer.is_muted = ignore
def set_self_info(self, group, name, status):
def set_self_info(self, group, name, status) -> None:
self._tox.group_self_set_name(group.number, name)
self._tox.group_self_set_status(group.number, status)
self_peer = group.get_self_peer()
@ -221,24 +221,24 @@ class GroupsService(tox_save.ToxSave):
# Bans support
def show_bans_list(self, group):
def show_bans_list(self, group) -> None:
return
widgets_factory = self._get_widgets_factory()
self._screen = widgets_factory.create_groups_bans_screen(group)
self._screen.show()
def ban_peer(self, group, peer_id, ban_type):
def ban_peer(self, group, peer_id, ban_type) -> None:
self._tox.group_mod_ban_peer(group.number, peer_id, ban_type)
def kick_peer(self, group, peer_id):
def kick_peer(self, group, peer_id) -> None:
self._tox.group_mod_remove_peer(group.number, peer_id)
def cancel_ban(self, group_number, ban_id):
def cancel_ban(self, group_number, ban_id) -> None:
self._tox.group_mod_remove_ban(group_number, ban_id)
# Private methods
def _add_new_group_by_number(self, group_number):
def _add_new_group_by_number(self, group_number) -> None:
LOG.debug(f"_add_new_group_by_number group_number={group_number}")
self._contacts_manager.add_group(group_number)
@ -251,22 +251,22 @@ class GroupsService(tox_save.ToxSave):
def _get_all_groups(self):
return self._contacts_provider.get_all_groups()
def _get_friend_by_number(self, friend_number):
def _get_friend_by_number(self, friend_number:int):
return self._contacts_provider.get_friend_by_number(friend_number)