Commit 1f034751 authored by Martin's avatar Martin

Imported upstream master from 2017-10-17

parent b10ffc99
This diff is collapsed.
......@@ -30,6 +30,7 @@
import os
import base64
import binascii
import operator
import hashlib
......@@ -69,7 +70,6 @@ METACONTACTS_ARRIVED = 'metacontacts_arrived'
ROSTER_ARRIVED = 'roster_arrived'
DELIMITER_ARRIVED = 'delimiter_arrived'
PRIVACY_ARRIVED = 'privacy_arrived'
BLOCKING_ARRIVED = 'blocking_arrived'
PEP_CONFIG = 'pep_config'
......@@ -446,7 +446,11 @@ class ConnectionVcard:
avatar_sha = None
photo_decoded = None
else:
photo_decoded = base64.b64decode(photo.encode('utf-8'))
try:
photo_decoded = base64.b64decode(photo.encode('utf-8'))
except binascii.Error as error:
app.log('avatar').warning('Invalid Avatar: %s', error)
return None, None
avatar_sha = hashlib.sha1(photo_decoded).hexdigest()
return avatar_sha, photo_decoded
......@@ -1463,15 +1467,6 @@ ConnectionHandlersBase, ConnectionJingle, ConnectionIBBytestream):
# connection process, we don't take the risk
self.privacy_rules_supported = False
self._continue_connection_request_privacy()
elif self.awaiting_answers[id_][0] == BLOCKING_ARRIVED:
del self.awaiting_answers[id_]
if iq_obj.getType() == 'result':
list_node = iq_obj.getTag('blocklist')
if not list_node:
return
self.blocked_contacts = []
for i in list_node.iterTags('item'):
self.blocked_contacts.append(i.getAttr('jid'))
elif self.awaiting_answers[id_][0] == PEP_CONFIG:
del self.awaiting_answers[id_]
if iq_obj.getType() == 'error':
......@@ -1511,6 +1506,7 @@ ConnectionHandlersBase, ConnectionJingle, ConnectionIBBytestream):
def _nec_private_storate_bookmarks_received(self, obj):
if obj.conn.name != self.name:
return
app.log('bookmarks').info('Received Bookmarks (PrivateStorage)')
resend_to_pubsub = False
bm_jids = [b['jid'] for b in self.bookmarks]
for bm in obj.bookmarks:
......@@ -1518,7 +1514,7 @@ ConnectionHandlersBase, ConnectionJingle, ConnectionIBBytestream):
self.bookmarks.append(bm)
# We got a bookmark that was not in pubsub
resend_to_pubsub = True
if self.pubsub_supported and resend_to_pubsub:
if resend_to_pubsub:
self.store_bookmarks('pubsub')
def _nec_private_storate_rosternotes_received(self, obj):
......@@ -2089,8 +2085,17 @@ ConnectionHandlersBase, ConnectionJingle, ConnectionIBBytestream):
def _BlockingSetCB(self, con, iq_obj):
log.debug('_BlockingSetCB')
app.nec.push_incoming_event(BlockingEvent(None, conn=self,
stanza=iq_obj))
app.nec.push_incoming_event(
BlockingEvent(None, conn=self, stanza=iq_obj))
reply = nbxmpp.Iq(typ='result', attrs={'id': iq_obj.getID()},
to=iq_obj.getFrom(), frm=iq_obj.getTo(), xmlns=None)
self.connection.send(reply)
raise nbxmpp.NodeProcessed
def _BlockingResultCB(self, con, iq_obj):
log.debug('_BlockingResultCB')
app.nec.push_incoming_event(
BlockingEvent(None, conn=self, stanza=iq_obj))
raise nbxmpp.NodeProcessed
def _nec_blocking(self, obj):
......@@ -2098,13 +2103,21 @@ ConnectionHandlersBase, ConnectionJingle, ConnectionIBBytestream):
return
if obj.unblock_all:
self.blocked_contacts = []
elif obj.blocklist:
self.blocked_contacts = obj.blocklist
else:
for jid in obj.blocked_jids:
if jid not in self.blocked_contacts:
self.blocked_contacts.append(jid)
contact_list = app.contacts.get_contacts(self.name, jid)
for contact in contact_list:
contact.show = 'offline'
for jid in obj.unblocked_jids:
if jid in self.blocked_contacts:
self.blocked_contacts.remove(jid)
# Send a presence Probe to get the current Status
probe = nbxmpp.Presence(jid, 'probe', frm=self.get_own_jid())
self.connection.send(probe)
def _nec_stream_other_host_received(self, obj):
if obj.conn.name != self.name:
......@@ -2198,3 +2211,5 @@ ConnectionHandlersBase, ConnectionJingle, ConnectionIBBytestream):
nbxmpp.NS_PUBKEY_PUBKEY)
con.RegisterHandler('iq', self._BlockingSetCB, 'set',
nbxmpp.NS_BLOCKING)
con.RegisterHandler('iq', self._BlockingResultCB, 'result',
nbxmpp.NS_BLOCKING)
......@@ -24,6 +24,7 @@
from calendar import timegm
import datetime
import hashlib
import binascii
import base64
import hmac
import logging
......@@ -599,7 +600,11 @@ class PubsubAvatarReceivedEvent(nec.NetworkIncomingEvent):
log.warning('Received malformed avatar data via pubsub')
log.warning(self.stanza)
return
self.data = base64.b64decode(self.data.encode('utf-8'))
try:
self.data = base64.b64decode(self.data.encode('utf-8'))
except binascii.Error as err:
log.warning('Received malformed avatar data via pubsub: %s' % err)
return
return True
......@@ -2787,20 +2792,37 @@ class BlockingEvent(nec.NetworkIncomingEvent):
base_network_events = []
def init(self):
self.blocklist = []
self.blocked_jids = []
self.unblocked_jids = []
self.unblock_all = False
def generate(self):
block_list = self.stanza.getTag(
'blocklist', namespace=nbxmpp.NS_BLOCKING)
if block_list is not None:
for item in block_list.getTags('item'):
self.blocklist.append(item.getAttr('jid'))
app.log('blocking').info(
'Blocklist Received: %s', self.blocklist)
return True
block_tag = self.stanza.getTag('block', namespace=nbxmpp.NS_BLOCKING)
if block_tag:
if block_tag is not None:
for item in block_tag.getTags('item'):
self.blocked_jids.append(item.getAttr('jid'))
unblock_tag = self.stanza.getTag('unblock',
namespace=nbxmpp.NS_BLOCKING)
if unblock_tag:
if not unblock_tag.getTags('item'): # unblock all
app.log('blocking').info(
'Blocking Push - blocked JIDs: %s', self.blocked_jids)
unblock_tag = self.stanza.getTag(
'unblock', namespace=nbxmpp.NS_BLOCKING)
if unblock_tag is not None:
if not unblock_tag.getTags('item'):
self.unblock_all = True
app.log('blocking').info('Blocking Push - unblocked all')
return True
for item in unblock_tag.getTags('item'):
self.unblocked_jids.append(item.getAttr('jid'))
app.log('blocking').info(
'Blocking Push - unblocked JIDs: %s', self.unblocked_jids)
return True
......@@ -76,7 +76,10 @@ else:
if base is None or base[0] != '/':
base = os.path.expanduser('~/.local/share')
localedir = os.path.join(base, "locale")
locale.bindtextdomain(APP, localedir)
if hasattr(locale, 'bindtextdomain'):
locale.bindtextdomain(APP, localedir)
gettext.install(APP, localedir)
if gettext._translations:
......
......@@ -203,6 +203,7 @@ class ConnectionPubSub:
def _nec_pubsub_bookmarks_received(self, obj):
if obj.conn.name != self.name:
return
app.log('bookmarks').info('Received Bookmarks (PubSub)')
bm_jids = [b['jid'] for b in self.bookmarks]
for bm in obj.bookmarks:
if bm['jid'] not in bm_jids:
......
......@@ -354,7 +354,7 @@ class GroupchatControl(ChatControlBase):
img.set_from_icon_name('bookmark-new', Gtk.IconSize.MENU)
widget.set_sensitive(
app.connections[self.account].private_storage_supported or \
(app.connections[self.account].pubsub_supported and \
(app.connections[self.account].pep_supported and \
app.connections[self.account].pubsub_publish_options_supported))
widget.show()
......@@ -971,7 +971,7 @@ class GroupchatControl(ChatControlBase):
notify_menuitem.set_active(app.config.get_per('rooms', self.contact.jid,
'notify_on_all_messages'))
conn = app.connections[self.account]
if not conn.private_storage_supported and (not conn.pubsub_supported or \
if not conn.private_storage_supported and (not conn.pep_supported or \
not conn.pubsub_publish_options_supported):
bookmark_room_menuitem.set_sensitive(False)
if app.gc_connected[self.account][self.room_jid]:
......@@ -2613,7 +2613,12 @@ class GroupchatControl(ChatControlBase):
item = xml.get_object('block_menuitem')
item2 = xml.get_object('unblock_menuitem')
if helpers.jid_is_blocked(self.account, fjid):
if not app.connections[self.account].privacy_rules_supported:
item2.set_no_show_all(True)
item.set_no_show_all(True)
item.hide()
item2.hide()
elif helpers.jid_is_blocked(self.account, fjid):
item.set_no_show_all(True)
item.hide()
id_ = item2.connect('activate', self.on_unblock, nick)
......
......@@ -2381,7 +2381,7 @@ class RosterWindow:
else:
try:
w.window.destroy()
except AttributeError:
except (AttributeError, RuntimeError):
w.destroy()
def close_all(self, account, force=False):
......@@ -2844,7 +2844,7 @@ class RosterWindow:
on_response_ok = (remove, list_))
def _nec_blocking(self, obj):
if obj.unblock_all:
if obj.unblock_all or obj.blocklist:
jids = app.contacts.get_jid_list(obj.conn.name)
self._idle_draw_jids_of_account(jids, obj.conn.name)
else:
......@@ -3755,7 +3755,7 @@ class RosterWindow:
'quit_on_roster_x_button') and ((app.interface.systray_enabled and\
app.config.get('trayicon') == 'always') or app.config.get(
'allow_hide_roster')):
self.window.hide()
self.window.iconify()
elif event.get_state() & Gdk.ModifierType.CONTROL_MASK and event.keyval == \
Gdk.KEY_i:
treeselection = self.tree.get_selection()
......
......@@ -119,6 +119,7 @@ class ServerInfoDialog(Gtk.Dialog):
Feature('XEP-0045: Multi-User Chat', con.muc_jid, None),
Feature('XEP-0054: vcard-temp', con.vcard_supported, None),
Feature('XEP-0163: Personal Eventing Protocol', con.pep_supported, None),
Feature('XEP-0163: #publish-options', con.pubsub_publish_options_supported, None),
Feature('XEP-0191: Blocking Command', con.blocking_supported, nbxmpp.NS_BLOCKING),
Feature('XEP-0198: Stream Management', con.sm.enabled, nbxmpp.NS_STREAM_MGMT),
Feature('XEP-0280: Message Carbons', con.carbons_enabled, nbxmpp.NS_CARBONS),
......
......@@ -26,6 +26,7 @@
from gi.repository import Gtk
from gi.repository import Gdk
import os
import sys
from gajim import dialogs
from gajim import config
......@@ -85,6 +86,8 @@ class StatusIcon:
if not self.status_icon:
self.status_icon = Gtk.StatusIcon()
self.statusicon_size = '16'
if sys.platform == 'darwin':
self.statusicon_size = '24'
self.status_icon.set_property('has-tooltip', True)
self.status_icon.connect('activate', self.on_status_icon_left_clicked)
self.status_icon.connect('popup-menu',
......
......@@ -36,6 +36,7 @@ from gi.repository import GLib
from gi.repository import Gdk
from gi.repository import GdkPixbuf
import base64
import binascii
import time
import locale
import os
......@@ -210,7 +211,12 @@ class VcardWindow:
photo_encoded = vcard[i]['BINVAL']
if photo_encoded == '':
continue
photo_decoded = base64.b64decode(photo_encoded.encode('utf-8'))
try:
photo_decoded = base64.b64decode(
photo_encoded.encode('utf-8'))
except binascii.Error as error:
app.log('avatar').warning('Invalid Avatar: %s', error)
continue
pixbuf = gtkgui_helpers.get_pixbuf_from_data(photo_decoded)
if pixbuf is None:
continue
......
from .acronyms_expander import AcronymsExpanderPlugin
{"afaik": "as far as I know",
"afaict": "as far as I can tell",
"afk": "away from keyboard",
"atm": "at the moment",
"bbiab": "be back in a bit",
"bbiaf": "be back in a few (minutes)",
"bbl": "be back later",
"bbs": "be back soon",
"b/c": "because",
"bf": "boyfriend",
"bfo": "blinding flash of the obvious",
"brb": "be right back",
"bsod": "blue screen of death",
"btw": "by the way",
"ciao": "Italian for goodbye",
"ctrn": "can't talk right now",
"cul8r": "see you later",
"cya": "see ya",
"dhtb": "don't have the bandwidth",
"f2f": "face to face",
"fubar": "fucked up beyond all recognition",
"fwiw": "for what it's worth",
"fyi": "for your information",
"gmta": "great minds think alike",
"iam": "in a meeting",
"ianal": "I am not a lawyer",
"ihmb": "I hate my boss",
"iirc": "if I recall correctly",
"imho": "in my humble opinion",
"imo": "in my opinion",
"iow": "in other words",
"irl": "in real life",
"<g>": "grin",
"*g*": "grin",
"gf": "girlfriend",
"gmta": "great minds think alike",
"g2g": "got to go",
"jid": "jabber identifier",
"j/k": "just kidding",
"ok": "okay",
"lol": "laugh out loud",
"l8r": "later",
"msg": "message",
"n/m": "never mind",
"n/p": "no problem",
"oAo": "over and out!",
"omg": "oh my god",
"oob": "out of band",
"otoh": "on the other hand",
"oww": "oops, wrong window!",
"otp": "on the phone",
"pita": "pain in the ass",
"pov": "point of view",
"pw": "password",
"rotfl": "rolling on the floor laughing",
"rsn": "real soon now",
"rtfm": "read the friendly manual",
"slap": "sounds like a plan",
"thx": "thanks",
"tia": "thanks in advance",
"tla": "three-letter arconym",
"ttfn": "ta ta for now",
"ttyl": "talk to you later",
"wb": "welcome back",
"wfm": "works for me",
"wtf": "what the fuck?!",
"wtg": "way to go!",
"xfer": "transfer",
"ymmv": "your mileage may vary",}
# -*- coding: utf-8 -*-
## This file is part of Gajim.
##
## Gajim is free software; you can redistribute it and/or modify
## it under the terms of the GNU General Public License as published
## by the Free Software Foundation; version 3 only.
##
## Gajim is distributed in the hope that it will be useful,
## but WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
## GNU General Public License for more details.
##
## You should have received a copy of the GNU General Public License
## along with Gajim. If not, see <http://www.gnu.org/licenses/>.
##
'''
Acronyms expander plugin.
:author: Mateusz Biliński <mateusz@bilinski.it>
:since: 9th June 2008
:copyright: Copyright (2008) Mateusz Biliński <mateusz@bilinski.it>
:license: GPL
'''
import sys
import os
from gi.repository import Gtk
from gi.repository import GObject
from gajim.plugins import GajimPlugin
from gajim.plugins.helpers import log, log_calls
class AcronymsExpanderPlugin(GajimPlugin):
@log_calls('AcronymsExpanderPlugin')
def init(self):
self.description = _('Replaces acronyms (or other strings) '
'with given expansions/substitutes.')
self.config_dialog = None
self.gui_extension_points = {
'chat_control_base': (self.connect_with_chat_control_base,
self.disconnect_from_chat_control_base)
}
self.config_default_values = {
'INVOKER': (' ', ''),
'ACRONYMS': ({'/slap': '/me slaps',
'PS-': 'plug-in system',
'G-': 'Gajim',
'GNT-': 'https://dev.gajim.org/gajim/gajim/issues',
'GW-': 'https://dev.gajim.org/gajim/gajim/wikis/home',
},
''),
}
if 'ACRONYMS' not in self.config:
myAcronyms = self.get_own_acronyms_list()
self.config['ACRONYMS'].update(myAcronyms)
@log_calls('AcronymsExpanderPlugin')
def get_own_acronyms_list(self):
data_file = self.local_file_path('acronyms')
if not os.path.isfile(data_file):
return {}
data = open(data_file, 'r')
acronyms = eval(data.read())
data.close()
return acronyms
@log_calls('AcronymsExpanderPlugin')
def textbuffer_live_acronym_expander(self, tb):
"""
@param tb gtk.TextBuffer
"""
#assert isinstance(tb,gtk.TextBuffer)
ACRONYMS = self.config['ACRONYMS']
INVOKER = self.config['INVOKER']
t = tb.get_text(tb.get_start_iter(), tb.get_end_iter(), True)
#log.debug('%s %d'%(t, len(t)))
if t and t[-1] == INVOKER:
#log.debug('changing msg text')
base, sep, head=t[:-1].rpartition(INVOKER)
log.debug('%s | %s | %s'%(base, sep, head))
if head in ACRONYMS:
head = ACRONYMS[head]
#log.debug('head: %s'%(head))
t = ''.join((base, sep, head, INVOKER))
#log.debug("setting text: '%s'"%(t))
GObject.idle_add(tb.set_text, t)
@log_calls('AcronymsExpanderPlugin')
def connect_with_chat_control_base(self, chat_control):
d = {}
tv = chat_control.msg_textview
tb = tv.get_buffer()
h_id = tb.connect('changed', self.textbuffer_live_acronym_expander)
d['h_id'] = h_id
chat_control.acronyms_expander_plugin_data = d
return True
@log_calls('AcronymsExpanderPlugin')
def disconnect_from_chat_control_base(self, chat_control):
d = chat_control.acronyms_expander_plugin_data
tv = chat_control.msg_textview
tv.get_buffer().disconnect(d['h_id'])
[info]
name: Acronyms Expander
short_name: acronyms_expander
version: 0.1
description: Replaces acronyms (or other strings) with given expansions/substitutes.
authors: Mateusz Biliński <mateusz@bilinski.it>
homepage: http://blog.bilinski.it
......@@ -73,7 +73,8 @@ function install_deps {
mingw-w64-"${ARCH}"-"${PYTHON_ID}"-pip \
mingw-w64-"${ARCH}"-gstreamer \
mingw-w64-"${ARCH}"-adwaita-icon-theme \
mingw-w64-"${ARCH}"-sqlite3
mingw-w64-"${ARCH}"-sqlite3 \
mingw-w64-"${ARCH}"-goocanvas
build_pip install setuptools_scm
......
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