def __init__(self, contact_jid,): id_ = gajim.get_an_id() attrs = {'id': id_} Iq.__init__(self, typ='get', attrs=attrs, to=contact_jid) items = Node('items', attrs={'node': NS_DEVICE_LIST}) pubsub = PubsubNode(items) self.addChild(node=pubsub)
def __init__(self, contact_jid, device_id): id_ = gajim.get_an_id() attrs = {'id': id_} Iq.__init__(self, typ='get', attrs=attrs, to=contact_jid) items = Node('items', attrs={'node': NS_BUNDLES + str(device_id)}) pubsub = PubsubNode(items) self.addChild(node=pubsub)
def make_candidate(self, candidate): types = { farstream.CANDIDATE_TYPE_HOST: "host", farstream.CANDIDATE_TYPE_SRFLX: "srflx", farstream.CANDIDATE_TYPE_PRFLX: "prflx", farstream.CANDIDATE_TYPE_RELAY: "relay", farstream.CANDIDATE_TYPE_MULTICAST: "multicast", } attrs = { "component": candidate.component_id, "foundation": "1", # hack "generation": "0", "ip": candidate.ip, "network": "0", "port": candidate.port, "priority": int(candidate.priority), # hack "id": gajim.get_an_id(), } if candidate.type in types: attrs["type"] = types[candidate.type] if candidate.proto == farstream.NETWORK_PROTOCOL_UDP: attrs["protocol"] = "udp" else: # we actually don't handle properly different tcp options in jingle attrs["protocol"] = "tcp" return nbxmpp.Node("candidate", attrs=attrs)
def __init__(self, contact_jid,): id_ = gajim.get_an_id() attrs = {'id': id_} Iq.__init__(self, typ='get', attrs=attrs, to=contact_jid) items = Node('items', attrs={'node': NS_DEVICE_LIST, 'max_items': 1}) pubsub = PubsubNode(items) self.addChild(node=pubsub)
def make_candidate(self, candidate): types = { Farstream.CandidateType.HOST: 'host', Farstream.CandidateType.SRFLX: 'srflx', Farstream.CandidateType.PRFLX: 'prflx', Farstream.CandidateType.RELAY: 'relay', Farstream.CandidateType.MULTICAST: 'multicast' } attrs = { 'component': candidate.component_id, 'foundation': '1', # hack 'generation': '0', 'ip': candidate.ip, 'network': '0', 'port': candidate.port, 'priority': int(candidate.priority), # hack 'id': gajim.get_an_id() } if candidate.type in types: attrs['type'] = types[candidate.type] if candidate.proto == Farstream.NetworkProtocol.UDP: attrs['protocol'] = 'udp' else: # we actually don't handle properly different tcp options in jingle attrs['protocol'] = 'tcp' return nbxmpp.Node('candidate', attrs=attrs)
def __init__(self, state_bundle, device_id): id_ = gajim.get_an_id() attrs = {'id': id_} Iq.__init__(self, typ='set', attrs=attrs) bundle_node = self.make_bundle_node(state_bundle) publish = PublishNode(NS_BUNDLES + str(device_id), bundle_node) pubsub = PubsubNode(publish) self.addChild(node=pubsub)
def query_info(stanza): global last_info_query for item in stanza.getTag("query").getTags("item"): id_ = gajim.get_an_id() iq = nbxmpp.Iq( typ='get', to=item.getAttr("jid"), queryNS="http://jabber.org/protocol/disco#info") iq.setID(id_) last_info_query[chat_control.account] = time.time() gajim.connections[chat_control.account].connection.send(iq)
def __init__(self, device_list): id_ = gajim.get_an_id() attrs = {'id': id_} Iq.__init__(self, typ='set', attrs=attrs) list_node = Node('list') for device in device_list: list_node.addChild('device').setAttr('id', device) publish = PublishNode(NS_DEVICE_LIST, list_node) pubsub = PubsubNode(publish) self.addChild(node=pubsub)
def __init__(self, device_list): assert isinstance(device_list, list) assert len(device_list) > 0 id_ = gajim.get_an_id() attrs = {'id': id_} Iq.__init__(self, typ='set', attrs=attrs) list_node = Node('list', attrs={'xmlns': NS_OMEMO}) for device in device_list: list_node.addChild('device').setAttr('id', device) publish = PublishNode(NS_DEVICE_LIST, list_node) pubsub = PubsubNode(publish) self.addChild(node=pubsub)
def __init__(self, device_list): assert isinstance(device_list, list) assert len(device_list) > 0 id_ = gajim.get_an_id() attrs = {'id': id_} Iq.__init__(self, typ='set', attrs=attrs) list_node = Node('list', attrs={'xmlns': NS_DEVICE_LIST}) for device in device_list: list_node.addChild('device').setAttr('id', device) publish = PublishNode(NS_DEVICE_LIST, list_node) pubsub = PubsubNode(publish) self.addChild(node=pubsub)
def make_candidate(self, candidate): types = {farstream.CANDIDATE_TYPE_HOST: 'host', farstream.CANDIDATE_TYPE_SRFLX: 'srflx', farstream.CANDIDATE_TYPE_PRFLX: 'prflx', farstream.CANDIDATE_TYPE_RELAY: 'relay', farstream.CANDIDATE_TYPE_MULTICAST: 'multicast'} attrs = { 'component': candidate.component_id, 'foundation': '1', # hack 'generation': '0', 'ip': candidate.ip, 'network': '0', 'port': candidate.port, 'priority': int(candidate.priority), # hack 'id': gajim.get_an_id() } if candidate.type in types: attrs['type'] = types[candidate.type] if candidate.proto == farstream.NETWORK_PROTOCOL_UDP: attrs['protocol'] = 'udp' else: # we actually don't handle properly different tcp options in jingle attrs['protocol'] = 'tcp' return nbxmpp.Node('candidate', attrs=attrs)
def upload_complete(response_code): if response_code == 0: return # Upload was aborted if response_code >= 200 and response_code < 300: log.info("Upload completed successfully") xhtml = None is_image = mime_type.split('/', 1)[0] == 'image' if (not isinstance(self.chat_control, chat_control.ChatControl) or not self.chat_control.gpg_is_active) and \ self.dialog_type == 'image' and is_image and not self.encrypted_upload: progress_messages.put(_('Calculating (possible) image thumbnail...')) thumb = None quality_steps = (100, 80, 60, 50, 40, 35, 30, 25, 23, 20, 18, 15, 13, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1) with open(path_to_file, 'rb') as content_file: thumb = urllib2.quote(base64.standard_b64encode(content_file.read()), '') if thumb and len(thumb) < max_thumbnail_size: quality = 100 log.info("Image small enough (%d bytes), not resampling" % len(thumb)) elif pil_available: log.info("PIL available, using it for image downsampling") try: for quality in quality_steps: thumb = Image.open(path_to_file) thumb.thumbnail((max_thumbnail_dimension, max_thumbnail_dimension), Image.ANTIALIAS) output = BytesIO() thumb.save(output, format='JPEG', quality=quality, optimize=True) thumb = output.getvalue() output.close() thumb = urllib2.quote(base64.standard_b64encode(thumb), '') log.debug("pil thumbnail jpeg quality %d produces an image of size %d..." % (quality, len(thumb))) if len(thumb) < max_thumbnail_size: break except: thumb = None else: thumb = None if not thumb: log.info("PIL not available, using GTK for image downsampling") temp_file = None try: with open(path_to_file, 'rb') as content_file: thumb = content_file.read() loader = gtk.gdk.PixbufLoader() loader.write(thumb) loader.close() pixbuf = loader.get_pixbuf() scaled_pb = self.get_pixbuf_of_size(pixbuf, max_thumbnail_dimension) handle, temp_file = tempfile.mkstemp(suffix='.jpeg', prefix='gajim_httpupload_scaled_tmp', dir=gajim.TMP) log.debug("Saving temporary jpeg image to '%s'..." % temp_file) os.close(handle) for quality in quality_steps: scaled_pb.save(temp_file, "jpeg", {"quality": str(quality)}) with open(temp_file, 'rb') as content_file: thumb = content_file.read() thumb = urllib2.quote(base64.standard_b64encode(thumb), '') log.debug("gtk thumbnail jpeg quality %d produces an image of size %d..." % (quality, len(thumb))) if len(thumb) < max_thumbnail_size: break except: thumb = None finally: if temp_file: os.unlink(temp_file) if thumb: if len(thumb) > max_thumbnail_size: log.info("Couldn't compress image enough, not sending any thumbnail") else: log.info("Using thumbnail jpeg quality %d (image size: %d bytes)" % (quality, len(thumb))) xhtml = '<body><br/><a href="%s"> <img alt="%s" src="data:image/png;base64,%s"/> </a></body>' % \ (get.getData(), get.getData(), thumb) progress_window.close_dialog() id_ = gajim.get_an_id() def add_oob_tag(): pass if self.encrypted_upload: keyAndIv = '#' + binascii.hexlify(iv) + binascii.hexlify(key) self.chat_control.send_message(message=get.getData() + keyAndIv, xhtml=None) else: self.chat_control.send_message(message=get.getData(), xhtml=xhtml) self.chat_control.msg_textview.grab_focus() else: progress_window.close_dialog() log.error("got unexpected http upload response code: " + str(response_code)) ErrorDialog(_('Could not upload file'), _('Got unexpected http response code from server: ') + str(response_code), transient_for=self.chat_control.parent_win.window)
def on_file_dialog_ok(self, widget, path_to_file=None): global jid_to_servers try: self.encrypted_upload = self.encryption_activated() except Exception as e: log.debug(e) self.encrypted_upload = False if not path_to_file: path_to_file = self.dlg.get_filename() if not path_to_file: self.dlg.destroy() return path_to_file = gtkgui_helpers.decode_filechooser_file_paths( (path_to_file,))[0] self.dlg.destroy() if not os.path.exists(path_to_file): return if self.encrypted_upload: filesize = os.path.getsize(path_to_file) + TAGSIZE # in bytes else: filesize = os.path.getsize(path_to_file) invalid_file = False msg = '' if os.path.isfile(path_to_file): stat = os.stat(path_to_file) if stat[6] == 0: invalid_file = True msg = _('File is empty') else: invalid_file = True msg = _('File does not exist') if invalid_file: ErrorDialog(_('Could not open file'), msg, transient_for=self.chat_control.parent_win.window) return mime_type = mimetypes.MimeTypes().guess_type(path_to_file)[0] if not mime_type: mime_type = 'application/octet-stream' # fallback mime type log.info("Detected MIME Type of file: " + str(mime_type)) progress_messages = Queue(8) progress_window = ProgressWindow(_('HTTP Upload'), _('Requesting HTTP Upload Slot...'), progress_messages, self.plugin) def upload_file(stanza): slot = stanza.getTag("slot") if not slot: progress_window.close_dialog() log.error("got unexpected stanza: "+str(stanza)) error = stanza.getTag("error") if error and error.getTag("text"): ErrorDialog(_('Could not request upload slot'), _('Got unexpected response from server: %s') % str(error.getTagData("text")), transient_for=self.chat_control.parent_win.window) else: ErrorDialog(_('Could not request upload slot'), _('Got unexpected response from server (protocol mismatch??)'), transient_for=self.chat_control.parent_win.window) return try: if self.encrypted_upload: key = os.urandom(32) iv = os.urandom(16) data = StreamFileWithProgress(path_to_file, "rb", progress_window.update_progress, self.encrypted_upload, key, iv) else: data = StreamFileWithProgress(path_to_file, "rb", progress_window.update_progress) except: progress_window.close_dialog() ErrorDialog(_('Could not open file'), _('Exception raised while opening file (see error log for more information)'), transient_for=self.chat_control.parent_win.window) raise # fill error log with useful information put = slot.getTag("put") get = slot.getTag("get") if not put or not get: progress_window.close_dialog() log.error("got unexpected stanza: " + str(stanza)) ErrorDialog(_('Could not request upload slot'), _('Got unexpected response from server (protocol mismatch??)'), transient_for=self.chat_control.parent_win.window) return def upload_complete(response_code): if response_code == 0: return # Upload was aborted if response_code >= 200 and response_code < 300: log.info("Upload completed successfully") xhtml = None is_image = mime_type.split('/', 1)[0] == 'image' if (not isinstance(self.chat_control, chat_control.ChatControl) or not self.chat_control.gpg_is_active) and \ self.dialog_type == 'image' and is_image and not self.encrypted_upload: progress_messages.put(_('Calculating (possible) image thumbnail...')) thumb = None quality_steps = (100, 80, 60, 50, 40, 35, 30, 25, 23, 20, 18, 15, 13, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1) with open(path_to_file, 'rb') as content_file: thumb = urllib2.quote(base64.standard_b64encode(content_file.read()), '') if thumb and len(thumb) < max_thumbnail_size: quality = 100 log.info("Image small enough (%d bytes), not resampling" % len(thumb)) elif pil_available: log.info("PIL available, using it for image downsampling") try: for quality in quality_steps: thumb = Image.open(path_to_file) thumb.thumbnail((max_thumbnail_dimension, max_thumbnail_dimension), Image.ANTIALIAS) output = BytesIO() thumb.save(output, format='JPEG', quality=quality, optimize=True) thumb = output.getvalue() output.close() thumb = urllib2.quote(base64.standard_b64encode(thumb), '') log.debug("pil thumbnail jpeg quality %d produces an image of size %d..." % (quality, len(thumb))) if len(thumb) < max_thumbnail_size: break except: thumb = None else: thumb = None if not thumb: log.info("PIL not available, using GTK for image downsampling") temp_file = None try: with open(path_to_file, 'rb') as content_file: thumb = content_file.read() loader = gtk.gdk.PixbufLoader() loader.write(thumb) loader.close() pixbuf = loader.get_pixbuf() scaled_pb = self.get_pixbuf_of_size(pixbuf, max_thumbnail_dimension) handle, temp_file = tempfile.mkstemp(suffix='.jpeg', prefix='gajim_httpupload_scaled_tmp', dir=gajim.TMP) log.debug("Saving temporary jpeg image to '%s'..." % temp_file) os.close(handle) for quality in quality_steps: scaled_pb.save(temp_file, "jpeg", {"quality": str(quality)}) with open(temp_file, 'rb') as content_file: thumb = content_file.read() thumb = urllib2.quote(base64.standard_b64encode(thumb), '') log.debug("gtk thumbnail jpeg quality %d produces an image of size %d..." % (quality, len(thumb))) if len(thumb) < max_thumbnail_size: break except: thumb = None finally: if temp_file: os.unlink(temp_file) if thumb: if len(thumb) > max_thumbnail_size: log.info("Couldn't compress image enough, not sending any thumbnail") else: log.info("Using thumbnail jpeg quality %d (image size: %d bytes)" % (quality, len(thumb))) xhtml = '<body><br/><a href="%s"> <img alt="%s" src="data:image/png;base64,%s"/> </a></body>' % \ (get.getData(), get.getData(), thumb) progress_window.close_dialog() id_ = gajim.get_an_id() def add_oob_tag(): pass if self.encrypted_upload: keyAndIv = '#' + binascii.hexlify(iv) + binascii.hexlify(key) self.chat_control.send_message(message=get.getData() + keyAndIv, xhtml=None) else: self.chat_control.send_message(message=get.getData(), xhtml=xhtml) self.chat_control.msg_textview.grab_focus() else: progress_window.close_dialog() log.error("got unexpected http upload response code: " + str(response_code)) ErrorDialog(_('Could not upload file'), _('Got unexpected http response code from server: ') + str(response_code), transient_for=self.chat_control.parent_win.window) def uploader(): progress_messages.put(_('Uploading file via HTTP...')) try: headers = {'User-Agent': 'Gajim %s' % gajim.version, 'Content-Type': mime_type} request = urllib2.Request(put.getData().encode("utf-8"), data=data, headers=headers) request.get_method = lambda: 'PUT' log.debug("opening urllib2 upload request...") transfer = urllib2.urlopen(request, timeout=30) log.debug("urllib2 upload request done, response code: " + str(transfer.getcode())) return transfer.getcode() except UploadAbortedException: log.info("Upload aborted") except: progress_window.close_dialog() ErrorDialog(_('Could not upload file'), _('Got unexpected exception while uploading file (see error log for more information)'), transient_for=self.chat_control.parent_win.window) raise # fill error log with useful information return 0 log.info("Uploading file to '%s'..." % str(put.getData())) log.info("Please download from '%s' later..." % str(get.getData())) gajim.thread_interface(uploader, [], upload_complete) is_supported = gajim.get_jid_from_account(self.chat_control.account) in jid_to_servers and \ gajim.connections[self.chat_control.account].connection != None log.info("jid_to_servers of %s: %s ; connection: %s" % (gajim.get_jid_from_account(self.chat_control.account), str(jid_to_servers[gajim.get_jid_from_account(self.chat_control.account)]), str(gajim.connections[self.chat_control.account].connection))) if not is_supported: progress_window.close_dialog() log.error("upload component vanished, account got disconnected??") ErrorDialog(_('Your server does not support http uploads or you just got disconnected.\nPlease try to reconnect or reopen the chat window to fix this.'), transient_for=self.chat_control.parent_win.window) return # create iq for slot request id_ = gajim.get_an_id() iq = nbxmpp.Iq( typ='get', to=jid_to_servers[gajim.get_jid_from_account(self.chat_control.account)], queryNS=None ) iq.setID(id_) request = iq.addChild( name="request", namespace=NS_HTTPUPLOAD ) filename = request.addChild( name="filename", ) filename.addData(os.path.basename(path_to_file)) size = request.addChild( name="size", ) size.addData(filesize) content_type = request.addChild( name="content-type", ) content_type.addData(mime_type) # send slot request and register callback log.debug("sending httpupload slot request iq...") iq_ids_to_callbacks[str(id_)] = upload_file gajim.connections[self.chat_control.account].connection.send(iq) self.chat_control.msg_textview.grab_focus()
def update_button_state(self, chat_control): global jid_to_servers global iq_ids_to_callbacks global last_info_query if gajim.connections[chat_control.account].connection == None and \ gajim.get_jid_from_account(chat_control.account) in jid_to_servers: # maybe don't delete this and detect vanished upload components when actually trying to upload something log.info("Deleting %s from jid_to_servers (disconnected)" % gajim.get_jid_from_account(chat_control.account)) del jid_to_servers[gajim.get_jid_from_account(chat_control.account)] #pass # query info at most every 60 seconds in case something goes wrong if (not chat_control.account in last_info_query or \ last_info_query[chat_control.account] + 60 < time.time()) and \ not gajim.get_jid_from_account(chat_control.account) in jid_to_servers and \ gajim.account_is_connected(chat_control.account): log.info("Account %s: Using dicovery to find jid of httpupload component" % chat_control.account) id_ = gajim.get_an_id() iq = nbxmpp.Iq( typ='get', to=gajim.get_server_from_jid(gajim.get_jid_from_account(chat_control.account)), queryNS="http://jabber.org/protocol/disco#items" ) iq.setID(id_) def query_info(stanza): global last_info_query for item in stanza.getTag("query").getTags("item"): id_ = gajim.get_an_id() iq = nbxmpp.Iq( typ='get', to=item.getAttr("jid"), queryNS="http://jabber.org/protocol/disco#info" ) iq.setID(id_) last_info_query[chat_control.account] = time.time() gajim.connections[chat_control.account].connection.send(iq) iq_ids_to_callbacks[str(id_)] = query_info gajim.connections[chat_control.account].connection.send(iq) #send disco query to main server jid id_ = gajim.get_an_id() iq = nbxmpp.Iq( typ='get', to=gajim.get_server_from_jid(gajim.get_jid_from_account(chat_control.account)), queryNS="http://jabber.org/protocol/disco#info" ) iq.setID(id_) last_info_query[chat_control.account] = time.time() gajim.connections[chat_control.account].connection.send(iq) for base in self.controls: if base.chat_control == chat_control: is_supported = gajim.get_jid_from_account(chat_control.account) in jid_to_servers and \ gajim.connections[chat_control.account].connection != None log.info("Account %s: httpupload is_supported: %s" % (str(chat_control.account), str(is_supported))) if not is_supported: text = _('Your server does not support http uploads') image_text = text else: text = _('Send file via http upload') image_text = _('Send image via http upload') base.button.set_sensitive(is_supported) base.button.set_tooltip_text(text) base.image_button.set_sensitive(is_supported) base.image_button.set_tooltip_text(image_text)