Daniel Brötzmann pushed to branch master at gajim / gajim

Commits:

5 changed files:

Changes:

  • gajim/common/jingle_ft.py
    ... ... @@ -74,13 +74,13 @@ class State(IntEnum):
    74 74
     
    
    75 75
     
    
    76 76
     class JingleFileTransfer(JingleContent):
    
    77
    -
    
    78 77
         def __init__(self,
    
    79 78
                      session: JingleSession,
    
    79
    +                 file_props: FileProp,
    
    80 80
                      transport: Optional[JingleTransport] = None,
    
    81
    -                 file_props: Optional[FileProp] = None,
    
    82 81
                      use_security: bool = False,
    
    83
    -                 senders: Optional[str] = None):
    
    82
    +                 senders: Optional[str] = None
    
    83
    +                 ) -> None:
    
    84 84
     
    
    85 85
             JingleContent.__init__(self, session, transport, senders)
    
    86 86
             log.info("transport value: %s", transport)
    
    ... ... @@ -99,29 +99,31 @@ def __init__(self,
    99 99
             self.callbacks['transport-reject'] += [self.__on_transport_reject]
    
    100 100
             self.callbacks['transport-info'] += [self.__on_transport_info]
    
    101 101
             self.callbacks['iq-result'] += [self.__on_iq_result]
    
    102
    +
    
    102 103
             self.use_security = use_security
    
    103 104
             self.x509_fingerprint = None
    
    104 105
             self.file_props = file_props
    
    105 106
             self.weinitiate = self.session.weinitiate
    
    106 107
             self.werequest = self.session.werequest
    
    107
    -        if self.file_props is not None:
    
    108
    -            if self.session.werequest:
    
    109
    -                self.file_props.sender = self.session.peerjid
    
    110
    -                self.file_props.receiver = self.session.ourjid
    
    111
    -            else:
    
    112
    -                self.file_props.sender = self.session.ourjid
    
    113
    -                self.file_props.receiver = self.session.peerjid
    
    114
    -            self.file_props.session_type = 'jingle'
    
    115
    -            self.file_props.sid = session.sid
    
    116
    -            self.file_props.transfered_size = []
    
    117
    -            self.file_props.transport_sid = self.transport.sid
    
    118
    -        log.info("FT request: %s", file_props)
    
    108
    +
    
    119 109
             if transport is None:
    
    120 110
                 self.transport = JingleTransportSocks5()
    
    121 111
             self.transport.set_connection(session.connection)
    
    122 112
             self.transport.set_file_props(self.file_props)
    
    123 113
             self.transport.set_our_jid(session.ourjid)
    
    124 114
             log.info('ourjid: %s', session.ourjid)
    
    115
    +
    
    116
    +        if self.session.werequest:
    
    117
    +            self.file_props.sender = self.session.peerjid
    
    118
    +            self.file_props.receiver = self.session.ourjid
    
    119
    +        else:
    
    120
    +            self.file_props.sender = self.session.ourjid
    
    121
    +            self.file_props.receiver = self.session.peerjid
    
    122
    +        self.file_props.session_type = 'jingle'
    
    123
    +        self.file_props.sid = session.sid
    
    124
    +        self.file_props.transfered_size = []
    
    125
    +        self.file_props.transport_sid = self.transport.sid
    
    126
    +
    
    125 127
             self.session = session
    
    126 128
             self.media = 'file'
    
    127 129
             self.nominated_cand = {}
    

  • gajim/common/jingle_transport.py
    ... ... @@ -16,8 +16,8 @@
    16 16
     Handles Jingle Transports (currently only ICE-UDP)
    
    17 17
     """
    
    18 18
     
    
    19
    -from typing import Any  # pylint: disable=unused-import
    
    20
    -from typing import Dict  # pylint: disable=unused-import
    
    19
    +from typing import Any
    
    20
    +from typing import Optional
    
    21 21
     
    
    22 22
     import logging
    
    23 23
     import socket
    
    ... ... @@ -29,11 +29,13 @@
    29 29
     from nbxmpp.util import generate_id
    
    30 30
     
    
    31 31
     from gajim.common import app
    
    32
    +from gajim.common.client import Client
    
    33
    +from gajim.common.file_props import FileProp
    
    32 34
     
    
    33 35
     log = logging.getLogger('gajim.c.jingle_transport')
    
    34 36
     
    
    37
    +transports: dict[str, Any] = {}
    
    35 38
     
    
    36
    -transports = {}  # type: Dict[str, Any]
    
    37 39
     
    
    38 40
     def get_jingle_transport(node):
    
    39 41
         namespace = node.getNamespace()
    
    ... ... @@ -59,15 +61,15 @@ class JingleTransport:
    59 61
         __slots__ = ['type_', 'candidates', 'remote_candidates', 'connection',
    
    60 62
                      'file_props', 'ourjid', 'sid']
    
    61 63
     
    
    62
    -    def __init__(self, type_):
    
    64
    +    def __init__(self, type_: TransportType) -> None:
    
    63 65
             self.type_ = type_
    
    64 66
             self.candidates = []
    
    65 67
             self.remote_candidates = []
    
    66 68
     
    
    67
    -        self.connection = None
    
    68
    -        self.file_props = None
    
    69
    -        self.ourjid = None
    
    70
    -        self.sid = None
    
    69
    +        self.connection: Optional[Client] = None
    
    70
    +        self.file_props: Optional[FileProp] = None
    
    71
    +        self.ourjid: Optional[str] = None
    
    72
    +        self.sid: Optional[str] = None
    
    71 73
     
    
    72 74
         def _iter_candidates(self):
    
    73 75
             for candidate in self.candidates:
    
    ... ... @@ -96,20 +98,21 @@ def parse_transport_stanza(self, transport):
    96 98
             """
    
    97 99
             return []
    
    98 100
     
    
    99
    -    def set_connection(self, conn):
    
    101
    +    def set_connection(self, conn: Client) -> None:
    
    100 102
             self.connection = conn
    
    101 103
             if not self.sid:
    
    102 104
                 self.sid = generate_id()
    
    103 105
     
    
    104
    -    def set_file_props(self, file_props):
    
    106
    +    def set_file_props(self, file_props: FileProp) -> None:
    
    105 107
             self.file_props = file_props
    
    106 108
     
    
    107
    -    def set_our_jid(self, jid):
    
    109
    +    def set_our_jid(self, jid: str) -> None:
    
    108 110
             self.ourjid = jid
    
    109 111
     
    
    110
    -    def set_sid(self, sid):
    
    112
    +    def set_sid(self, sid: str) -> None:
    
    111 113
             self.sid = sid
    
    112 114
     
    
    115
    +
    
    113 116
     class JingleTransportSocks5(JingleTransport):
    
    114 117
         """
    
    115 118
         Socks5 transport in jingle scenario
    

  • gajim/common/modules/jingle.py
    ... ... @@ -28,6 +28,8 @@
    28 28
     #   * config:
    
    29 29
     #     - codecs
    
    30 30
     
    
    31
    +from typing import Optional
    
    32
    +
    
    31 33
     import logging
    
    32 34
     
    
    33 35
     import nbxmpp
    
    ... ... @@ -36,8 +38,8 @@
    36 38
     
    
    37 39
     from gajim.common import helpers
    
    38 40
     from gajim.common import jingle_xtls
    
    41
    +from gajim.common.file_props import FileProp
    
    39 42
     from gajim.common.modules.base import BaseModule
    
    40
    -
    
    41 43
     from gajim.common.jingle_session import JingleSession
    
    42 44
     from gajim.common.jingle_session import JingleStates
    
    43 45
     from gajim.common.jingle_ft import JingleFileTransfer
    
    ... ... @@ -74,14 +76,14 @@ def __init__(self, con):
    74 76
             ]
    
    75 77
     
    
    76 78
             # dictionary: sessionid => JingleSession object
    
    77
    -        self._sessions = {}
    
    79
    +        self._sessions: dict[str, JingleSession] = {}
    
    78 80
     
    
    79 81
             # dictionary: (jid, iq stanza id) => JingleSession object,
    
    80 82
             # one time callbacks
    
    81 83
             self.__iq_responses = {}
    
    82 84
             self.files = []
    
    83 85
     
    
    84
    -    def delete_jingle_session(self, sid):
    
    86
    +    def delete_jingle_session(self, sid: str) -> None:
    
    85 87
             """
    
    86 88
             Remove a jingle session from a jingle stanza dispatcher
    
    87 89
             """
    
    ... ... @@ -204,7 +206,11 @@ def start_audio_video(self, jid):
    204 206
             jingle_session.start_session()
    
    205 207
             return jingle_session.sid
    
    206 208
     
    
    207
    -    def start_file_transfer(self, jid, file_props, request=False):
    
    209
    +    def start_file_transfer(self,
    
    210
    +                            jid: str,
    
    211
    +                            file_props: FileProp,
    
    212
    +                            request: bool = False
    
    213
    +                            ) -> Optional[str]:
    
    208 214
             logger.info("start file transfer with file: %s", file_props)
    
    209 215
             contact = self._con.get_module('Contacts').get_contact(jid)
    
    210 216
             use_security = contact.supports(Namespace.JINGLE_XTLS)
    
    ... ... @@ -222,7 +228,9 @@ def start_file_transfer(self, jid, file_props, request=False):
    222 228
             elif contact.supports(Namespace.JINGLE_IBB):
    
    223 229
                 transport = JingleTransportIBB()
    
    224 230
             else:
    
    225
    -            transport = None
    
    231
    +            logger.error('No suitable transport method available for %s',
    
    232
    +                         contact.jid)
    
    233
    +            return
    
    226 234
     
    
    227 235
             senders = 'initiator'
    
    228 236
             if request:
    

  • gajim/common/socks5.py
    ... ... @@ -689,9 +689,12 @@ def write_next(self):
    689 689
                     raise e
    
    690 690
                 except OpenSSL.SSL.SysCallError:
    
    691 691
                     return self._on_send_exception()
    
    692
    -            except Exception as e:
    
    692
    +            except socket.error as err:
    
    693 693
                     if e.errno not in (EINTR, ENOBUFS, EWOULDBLOCK):
    
    694 694
                         return self._on_send_exception()
    
    695
    +            except Exception as err:
    
    696
    +                return self._on_send_exception()
    
    697
    +
    
    695 698
                 self.size += lenn
    
    696 699
                 current_time = time.time()
    
    697 700
                 self.file_props.elapsed_time += current_time - \
    

  • gajim/gtk/filetransfer.py
    ... ... @@ -17,6 +17,10 @@
    17 17
     # You should have received a copy of the GNU General Public License
    
    18 18
     # along with Gajim. If not, see <http://www.gnu.org/licenses/>.
    
    19 19
     
    
    20
    +from __future__ import annotations
    
    21
    +
    
    22
    +from typing import Optional
    
    23
    +
    
    20 24
     import os
    
    21 25
     import time
    
    22 26
     import logging
    
    ... ... @@ -48,6 +52,7 @@
    48 52
     from gajim.common.modules.bytestream import is_transfer_paused
    
    49 53
     from gajim.common.modules.bytestream import is_transfer_stopped
    
    50 54
     from gajim.common.modules.contacts import BareContact
    
    55
    +from gajim.common import types
    
    51 56
     
    
    52 57
     from .dialogs import DialogButton
    
    53 58
     from .dialogs import ConfirmationDialog
    
    ... ... @@ -390,12 +395,20 @@ def _on_yes():
    390 395
                                    text=_('_Download Again'),
    
    391 396
                                    callback=_on_yes)]).show()
    
    392 397
     
    
    393
    -    def show_file_send_request(self, account, contact):
    
    398
    +    def show_file_send_request(self,
    
    399
    +                               account: str,
    
    400
    +                               contact: types.BareContact
    
    401
    +                               ) -> None:
    
    394 402
             send_callback = partial(self.send_file, account, contact)
    
    395 403
             SendFileDialog(contact, send_callback, self.window)
    
    396 404
     
    
    397
    -    def send_file(self, account, contact, resource_jid, file_path,
    
    398
    -                  file_desc=''):
    
    405
    +    def send_file(self,
    
    406
    +                  account: str,
    
    407
    +                  contact: types.BareContact,
    
    408
    +                  resource_jid: JID,
    
    409
    +                  file_path: str,
    
    410
    +                  file_desc: str = ''
    
    411
    +                  ) -> bool:
    
    399 412
             """
    
    400 413
             Start the real transfer(upload) of the file
    
    401 414
             """
    
    ... ... @@ -403,11 +416,15 @@ def send_file(self, account, contact, resource_jid, file_path,
    403 416
                 pritext = _('Gajim can not read this file')
    
    404 417
                 sextext = _('Another process is using this file.')
    
    405 418
                 ErrorDialog(pritext, sextext)
    
    406
    -            return
    
    419
    +            return False
    
    407 420
     
    
    408 421
             file_name = os.path.split(file_path)[1]
    
    409
    -        file_props = self.get_send_file_props(account, contact, file_path,
    
    410
    -                                              file_name, file_desc)
    
    422
    +        file_props = self.get_send_file_props(
    
    423
    +            account,
    
    424
    +            resource_jid,
    
    425
    +            file_path,
    
    426
    +            file_name,
    
    427
    +            file_desc)
    
    411 428
             if file_props is None:
    
    412 429
                 return False
    
    413 430
     
    
    ... ... @@ -682,13 +699,19 @@ def get_iter_by_sid(self, typ, sid):
    682 699
                     return iter_
    
    683 700
                 iter_ = self.model.iter_next(iter_)
    
    684 701
     
    
    685
    -    def __convert_date(self, epoch):
    
    702
    +    @staticmethod
    
    703
    +    def __convert_date(epoch: float) -> str:
    
    686 704
             # Converts date-time from seconds from epoch to iso 8601
    
    687 705
             dt = datetime.utcfromtimestamp(epoch)
    
    688 706
             return dt.isoformat() + 'Z'
    
    689 707
     
    
    690
    -    def get_send_file_props(self, account, contact, file_path, file_name,
    
    691
    -                            file_desc=''):
    
    708
    +    def get_send_file_props(self,
    
    709
    +                            account: str,
    
    710
    +                            resource_jid: JID,
    
    711
    +                            file_path: str,
    
    712
    +                            file_name: str,
    
    713
    +                            file_desc: str = ''
    
    714
    +                            ) -> Optional[FileProp]:
    
    692 715
             """
    
    693 716
             Create new file_props object and set initial file transfer
    
    694 717
             properties in it
    
    ... ... @@ -696,15 +719,20 @@ def get_send_file_props(self, account, contact, file_path, file_name,
    696 719
             if os.path.isfile(file_path):
    
    697 720
                 stat = os.stat(file_path)
    
    698 721
             else:
    
    699
    -            ErrorDialog(_('Invalid File'), _('File: ') + file_path)
    
    722
    +            ErrorDialog(
    
    723
    +                _('Invalid File'),
    
    724
    +                _('File: %s') % file_path)
    
    700 725
                 return None
    
    726
    +
    
    701 727
             if stat[6] == 0:
    
    702 728
                 ErrorDialog(
    
    703 729
                     _('Invalid File'),
    
    704 730
                     _('It is not possible to send empty files'))
    
    705 731
                 return None
    
    732
    +
    
    706 733
             file_props = FilesProp.getNewFileProp(
    
    707
    -            account, sid=helpers.get_random_string())
    
    734
    +            account,
    
    735
    +            sid=helpers.get_random_string())
    
    708 736
             mod_date = os.path.getmtime(file_path)
    
    709 737
             file_props.file_name = file_path
    
    710 738
             file_props.name = file_name
    
    ... ... @@ -714,7 +742,7 @@ def get_send_file_props(self, account, contact, file_path, file_name,
    714 742
             file_props.elapsed_time = 0
    
    715 743
             file_props.size = stat[6]
    
    716 744
             file_props.sender = account
    
    717
    -        file_props.receiver = contact
    
    745
    +        file_props.receiver = str(resource_jid)
    
    718 746
             file_props.tt_account = account
    
    719 747
             return file_props
    
    720 748