Commit 4bcdbde2 authored by Philipp Hörist's avatar Philipp Hörist

Move httpupload into modules

parent 0eeb111a
......@@ -274,6 +274,7 @@ class ChatControl(ChatControlBase):
def update_actions(self):
win = self.parent_win.window
online = app.account_is_connected(self.account)
con = app.connections[self.account]
# Add to roster
if not isinstance(self.contact, GC_Contact) \
......@@ -297,7 +298,7 @@ class ChatControl(ChatControlBase):
httpupload = win.lookup_action(
'send-file-httpupload-' + self.control_id)
httpupload.set_enabled(
online and app.connections[self.account].httpupload)
online and con.get_module('HTTPUpload').available)
# Send file (Jingle)
jingle_conditions = (
......
......@@ -759,19 +759,19 @@ class ChatControlBase(MessageControl, ChatCommandProcessor, CommandTools):
# groupchat only supports httpupload on drag and drop
if httpupload.get_enabled():
# use httpupload
con.check_file_before_transfer(
con.get_module('HTTPUpload').check_file_before_transfer(
path, self.encryption, contact,
self.session, groupchat=True)
else:
if httpupload.get_enabled() and jingle.get_enabled():
if ft_pref == 'httpupload':
con.check_file_before_transfer(
con.get_module('HTTPUpload').check_file_before_transfer(
path, self.encryption, contact, self.session)
else:
ft = app.interface.instances['file_transfers']
ft.send_file(self.account, contact, path)
elif httpupload.get_enabled():
con.check_file_before_transfer(
con.get_module('HTTPUpload').check_file_before_transfer(
path, self.encryption, contact, self.session)
elif jingle.get_enabled():
ft = app.interface.instances['file_transfers']
......
......@@ -83,6 +83,7 @@ from gajim.common.modules.user_tune import UserTune
from gajim.common.modules.user_mood import UserMood
from gajim.common.modules.user_location import UserLocation
from gajim.common.modules.user_nickname import UserNickname
from gajim.common.modules.httpupload import HTTPUpload
from gajim.common.connection_handlers import *
from gajim.common.contacts import GC_Contact
from gajim.gtkgui_helpers import get_action
......@@ -681,6 +682,7 @@ class Connection(CommonConnection, ConnectionHandlers):
self.register_module('UserMood', UserMood, self)
self.register_module('UserLocation', UserLocation, self)
self.register_module('UserNickname', UserNickname, self)
self.register_module('HTTPUpload', HTTPUpload, self)
app.ged.register_event_handler('privacy-list-received', ged.CORE,
self._nec_privacy_list_received)
......
......@@ -53,7 +53,6 @@ from gajim.common.protocol.caps import ConnectionCaps
from gajim.common.protocol.bytestream import ConnectionSocks5Bytestream
from gajim.common.protocol.bytestream import ConnectionIBBytestream
from gajim.common.message_archiving import ConnectionArchive313
from gajim.common.httpupload import ConnectionHTTPUpload
from gajim.common.connection_handlers_events import *
from gajim.common import ged
......@@ -754,14 +753,12 @@ class ConnectionHandlersBase:
class ConnectionHandlers(ConnectionArchive313,
ConnectionSocks5Bytestream, ConnectionDisco,
ConnectionCommands, ConnectionCaps,
ConnectionHandlersBase, ConnectionJingle, ConnectionIBBytestream,
ConnectionHTTPUpload):
ConnectionHandlersBase, ConnectionJingle, ConnectionIBBytestream):
def __init__(self):
ConnectionArchive313.__init__(self)
ConnectionSocks5Bytestream.__init__(self)
ConnectionIBBytestream.__init__(self)
ConnectionCommands.__init__(self)
ConnectionHTTPUpload.__init__(self)
# Handle presences BEFORE caps
app.nec.register_incoming_event(PresenceReceivedEvent)
......@@ -819,7 +816,6 @@ ConnectionHTTPUpload):
ConnectionHandlersBase.cleanup(self)
ConnectionCaps.cleanup(self)
ConnectionArchive313.cleanup(self)
ConnectionHTTPUpload.cleanup(self)
app.ged.remove_event_handler('roster-set-received',
ged.CORE, self._nec_roster_set_received)
app.ged.remove_event_handler('roster-received', ged.CORE,
......
......@@ -2545,17 +2545,3 @@ class BlockingEvent(nec.NetworkIncomingEvent):
app.log('blocking').info(
'Blocking Push - unblocked JIDs: %s', self.unblocked_jids)
return True
class HTTPUploadStartEvent(nec.NetworkIncomingEvent):
name = 'httpupload-start'
base_network_events = []
def generate(self):
return True
class HTTPUploadProgressEvent(nec.NetworkIncomingEvent):
name = 'httpupload-progress'
base_network_events = []
def generate(self):
return True
\ No newline at end of file
# -*- coding: utf-8 -*-
#
# This file is part of Gajim.
#
# Gajim is free software; you can redistribute it and/or modify
......@@ -14,13 +12,16 @@
# You should have received a copy of the GNU General Public License
# along with Gajim. If not, see <http://www.gnu.org/licenses/>.
# XEP-0363: HTTP File Upload
import os
import sys
import threading
import ssl
import urllib
from urllib.request import Request, urlopen
from urllib.parse import urlparse, quote
from urllib.parse import urlparse
import io
import mimetypes
import logging
......@@ -31,26 +32,28 @@ from gi.repository import GLib
from gajim.common import app
from gajim.common import ged
from gajim.common.nec import NetworkIncomingEvent
from gajim.common.connection_handlers_events import InformationEvent
from gajim.common.connection_handlers_events import HTTPUploadProgressEvent
from gajim.common.connection_handlers_events import MessageOutgoingEvent
from gajim.common.connection_handlers_events import GcMessageOutgoingEvent
if sys.platform in ('win32', 'darwin'):
import certifi
log = logging.getLogger('gajim.c.httpupload')
log = logging.getLogger('gajim.c.m.httpupload')
NS_HTTPUPLOAD_0 = NS_HTTPUPLOAD + ':0'
class ConnectionHTTPUpload:
"""
Implement HTTP File Upload
(XEP-0363, https://xmpp.org/extensions/xep-0363.html)
"""
def __init__(self):
self.httpupload = False
self.encrypted_upload = False
class HTTPUpload:
def __init__(self, con):
self._con = con
self._account = con.name
self.handlers = []
self.available = False
self.component = None
self.httpupload_namespace = None
self._allowed_headers = ['Authorization', 'Cookie', 'Expires']
......@@ -81,7 +84,7 @@ class ConnectionHTTPUpload:
def handle_agent_info_received(self, event):
account = event.conn.name
if account != self.name:
if account != self._account:
return
if not app.jid_is_transport(event.jid):
......@@ -112,14 +115,14 @@ class ConnectionHTTPUpload:
log.warning('%s does not provide maximum file size', account)
else:
log.info('%s has a maximum file size of: %s MiB',
account, self.max_file_size/(1024*1024))
account, self.max_file_size / (1024 * 1024))
self.httpupload = True
for ctrl in app.interface.msg_win_mgr.get_controls(acct=self.name):
self.available = True
for ctrl in app.interface.msg_win_mgr.get_controls(acct=self._account):
ctrl.update_actions()
def handle_outgoing_stanza(self, event):
if event.conn.name != self.name:
if event.conn.name != self._account:
return
message = event.msg_iq.getTagData('body')
if message and message in self.messages:
......@@ -177,9 +180,9 @@ class ConnectionHTTPUpload:
return
if encryption is not None:
app.interface.encrypt_file(file, self.request_slot)
app.interface.encrypt_file(file, self._request_slot)
else:
self.request_slot(file)
self._request_slot(file)
@staticmethod
def raise_progress_event(status, file, seen=None, total=None):
......@@ -191,13 +194,13 @@ class ConnectionHTTPUpload:
app.nec.push_incoming_event(InformationEvent(
None, dialog_name=dialog_name, args=args))
def request_slot(self, file):
def _request_slot(self, file):
GLib.idle_add(self.raise_progress_event, 'request', file)
iq = self._build_request(file)
log.info("Sending request for slot")
app.connections[self.name].connection.SendAndCallForResponse(
iq, self.received_slot, {'file': file})
self._con.connection.SendAndCallForResponse(
iq, self._received_slot, {'file': file})
def _build_request(self, file):
iq = nbxmpp.Iq(typ='get', to=self.component)
id_ = app.get_an_id()
......@@ -230,7 +233,7 @@ class ConnectionHTTPUpload:
return stanza.getErrorMsg()
def received_slot(self, conn, stanza, file):
def _received_slot(self, conn, stanza, file):
log.info("Received slot")
if stanza.getType() == 'error':
self.raise_progress_event('close', file)
......@@ -279,11 +282,11 @@ class ConnectionHTTPUpload:
log.info('Uploading file to %s', file.put)
log.info('Please download from %s', file.get)
thread = threading.Thread(target=self.upload_file, args=(file,))
thread = threading.Thread(target=self._upload_file, args=(file,))
thread.daemon = True
thread.start()
def upload_file(self, file):
def _upload_file(self, file):
GLib.idle_add(self.raise_progress_event, 'upload', file)
try:
file.headers['User-Agent'] = 'Gajim %s' % app.version
......@@ -294,7 +297,7 @@ class ConnectionHTTPUpload:
file.put, data=file.stream, headers=file.headers, method='PUT')
log.info("Opening Urllib upload request...")
if not app.config.get_per('accounts', self.name, 'httpupload_verify'):
if not app.config.get_per('accounts', self._account, 'httpupload_verify'):
context = ssl.create_default_context()
context.check_hostname = False
context.verify_mode = ssl.CERT_NONE
......@@ -309,7 +312,7 @@ class ConnectionHTTPUpload:
file.stream.close()
log.info('Urllib upload request done, response code: %s',
transfer.getcode())
GLib.idle_add(self.upload_complete, transfer.getcode(), file)
GLib.idle_add(self._upload_complete, transfer.getcode(), file)
return
except UploadAbortedException as exc:
log.info(exc)
......@@ -326,9 +329,9 @@ class ConnectionHTTPUpload:
log.exception("Exception during upload")
error_msg = exc
GLib.idle_add(self.raise_progress_event, 'close', file)
GLib.idle_add(self.on_upload_error, file, error_msg)
GLib.idle_add(self._on_upload_error, file, error_msg)
def upload_complete(self, response_code, file):
def _upload_complete(self, response_code, file):
self.raise_progress_event('close', file)
if 200 <= response_code < 300:
log.info("Upload completed successfully")
......@@ -341,12 +344,12 @@ class ConnectionHTTPUpload:
if file.groupchat:
app.nec.push_outgoing_event(GcMessageOutgoingEvent(
None, account=self.name, jid=file.contact.jid,
None, account=self._account, jid=file.contact.jid,
message=message, automatic_message=False,
session=file.session))
else:
app.nec.push_outgoing_event(MessageOutgoingEvent(
None, account=self.name, jid=file.contact.jid,
None, account=self._account, jid=file.contact.jid,
message=message, keyID=file.keyID, type_='chat',
automatic_message=False, session=file.session))
......@@ -356,7 +359,7 @@ class ConnectionHTTPUpload:
self.raise_information_event('httpupload-response-error',
response_code)
def on_upload_error(self, file, reason):
def _on_upload_error(self, file, reason):
self.raise_progress_event('close', file)
self.raise_information_event('httpupload-error', str(reason))
......@@ -428,3 +431,8 @@ class StreamFileWithProgress:
class UploadAbortedException(Exception):
def __str__(self):
return "Upload Aborted"
class HTTPUploadProgressEvent(NetworkIncomingEvent):
name = 'httpupload-progress'
base_network_events = []
......@@ -574,6 +574,7 @@ class GroupchatControl(ChatControlBase):
contact = app.contacts.get_gc_contact(
self.account, self.room_jid, self.nick)
online = app.gc_connected[self.account][self.room_jid]
con = app.connections[self.account]
# Destroy Room
win.lookup_action('destroy-' + self.control_id).set_enabled(
......@@ -615,7 +616,7 @@ class GroupchatControl(ChatControlBase):
httpupload = win.lookup_action(
'send-file-httpupload-' + self.control_id)
httpupload.set_enabled(
online and app.connections[self.account].httpupload)
online and con.get_module('HTTPUpload').available)
win.lookup_action('send-file-' + self.control_id).set_enabled(
httpupload.get_enabled())
......
......@@ -93,8 +93,9 @@ from gajim.common import passwords
from gajim.common import logging_helpers
from gajim.common.connection_handlers_events import (
OurShowEvent, FileRequestErrorEvent, FileTransferCompletedEvent,
UpdateRosterAvatarEvent, UpdateGCAvatarEvent, UpdateRoomAvatarEvent,
HTTPUploadProgressEvent)
UpdateRosterAvatarEvent, UpdateGCAvatarEvent, UpdateRoomAvatarEvent)
from gajim.common.modules.httpupload import HTTPUploadProgressEvent
from gajim.common.connection import Connection
from gajim.common.file_props import FilesProp
from gajim import emoticons
......@@ -1142,11 +1143,12 @@ class Interface:
con = app.connections[chat_control.account]
groupchat = chat_control.type_id == message_control.TYPE_GC
for path in paths:
con.check_file_before_transfer(path,
chat_control.encryption,
chat_control.contact,
chat_control.session,
groupchat)
con.get_module('HTTPUpload').check_file_before_transfer(
path,
chat_control.encryption,
chat_control.contact,
chat_control.session,
groupchat)
def encrypt_file(self, file, callback):
app.nec.push_incoming_event(HTTPUploadProgressEvent(
......
......@@ -177,7 +177,8 @@ class ServerInfoDialog(Gtk.Dialog):
con.archiving_namespace, con.archiving_namespace,
mam_enabled),
Feature('XEP-0363: HTTP File Upload',
con.httpupload, con.httpupload_namespace, None)]
con.get_module('HTTPUpload').available,
con.get_module('HTTPUpload').httpupload_namespace, None)]
def add_info(self, info):
self.info_listbox.add(ServerInfoItem(info))
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment