def replace_code_block(tb, s_tag, s_code, e_tag, e_code): iter_range_full = (tb.get_iter_at_mark(s_tag), tb.get_iter_at_mark(e_tag)) text_full = iter_range_full[0].get_text(iter_range_full[1]) log.debug("full text to remove: %s.", text_full) tb.begin_user_action() language, code_start = detect_language(tb, s_code) code_start = s_code if code_start is None else code_start line_break = check_line_break(tb, code_start, e_code) code = to_iter(tb, code_start).get_text(to_iter(tb, e_code)) log.debug("full text to encode: %s.", code) # Delete code between and including tags tb.delete(to_iter(tb, s_tag), to_iter(tb, e_tag)) insert_formatted_code(tb, language, code, mark=s_tag, line_break=line_break) tb.end_user_action()
def connect_with_chat_control(self, control): control_data = {} tv = control.conv_textview.tv control_data['connection'] = tv.get_buffer().connect( 'changed', self.on_change) log.debug("connection: %s.", str(control_data['connection'])) control.syntax_highlighter_plugin_data = control_data
def print_special_text(self, tv, special_text, other_tags, graphics=True, iter_=None): conv_textview = tv textview = tv.tv # geo:48.2057365,16.3435941 if not special_text.startswith('geo:'): return buffer_ = textview.get_buffer() if not iter_: iter_ = buffer_.get_end_iter() # Show URL, until image is loaded (if ever) ttt = buffer_.get_tag_table() repl_start = buffer_.create_mark(None, iter_, True) buffer_.insert_with_tags(iter_, special_text, *[(ttt.lookup(t) if isinstance(t, str) else t) for t in ["url"]]) repl_end = buffer_.create_mark(None, iter_, True) zoom = 17 size = 200 color = 'blue' coordinates = special_text.split(':')[1] lat = coordinates.split(',')[0] lon = coordinates.split(',')[1] if not (len(lat) == 10 and len(lon) == 10): return filename = coordinates.replace(',', '_').replace('.', '-') filepath = os.path.join(self.thumbpath, filename) url = 'https://maps.googleapis.com/maps/api/staticmap?center={}' \ '&zoom={}&size={}x{}&markers=color:{}' \ '|label:S|{}'.format(coordinates, zoom, size, size, color, coordinates) weburl = 'https://www.google.at/maps/place/{}'.format(coordinates) log.debug(url) if os.path.exists(filepath): gajim.thread_interface( self.load_thumbnail, [filepath], self.updatechat, [weburl, repl_start, repl_end, textview]) else: gajim.thread_interface( self.download, [url, filepath], self.updatechat, [weburl, repl_start, repl_end, textview]) # Don't print the URL in the message window (in the calling function) conv_textview.plugin_modified = True
def inject(self, msg, appdata=None): log.debug('inject(appdata=%s)', appdata) msg = unicode(msg) account = self.user.accountname stanza = common.xmpp.Message(to=self.peer, body=msg, typ='chat') if appdata is not None: session = appdata.get('session', None) if session is not None: stanza.setThread(session.thread_id) gajim.connections[account].connection.send(stanza, now=True)
def inject(self, msg, appdata=None): log.debug('inject(appdata=%s)', appdata) msg = unicode(msg) account = self.user.accountname stanza = nbxmpp.Message(to=self.peer, body=msg, typ='chat') if appdata is not None: session = appdata.get('session', None) if session is not None: stanza.setThread(session.thread_id) add_message_processing_hints(stanza) gajim.connections[account].connection.send(stanza, now=True)
def handle_message_received(self, event): oob_node = event.stanza.getTag('x', namespace=nbxmpp.NS_X_OOB) oob_url = None oob_desc = None if oob_node: oob_url = oob_node.getTagData('url') oob_desc = oob_node.getTagData('desc') if oob_url and oob_url == event.msgtxt and (not oob_desc or oob_desc == ""): log.debug( "Detected oob tag containing same url as the message text, deleting oob tag..." ) event.stanza.delChild(oob_node)
def _get_img_direct(self, attrs): """ Download an image. This function should be launched in a separated thread. """ mem, alt, max_size = '', '', 2 * 1024 * 1024 if 'max_size' in attrs: max_size = attrs['max_size'] try: req = urllib2.Request(attrs['src']) req.add_header('User-Agent', 'Gajim ' + gajim.version) f = urllib2.urlopen(req) except Exception, ex: log.debug('Error loading image %s ' % attrs['src'] + str(ex)) pixbuf = None alt = attrs.get('alt', 'Broken image')
def updatechat(self, data, weburl, repl_start, repl_end, textview): if data: try: log.debug(weburl) eb = gtk.EventBox() eb.connect('button-press-event', self.on_button_press_event, weburl) eb.connect('enter-notify-event', self.on_enter_event, textview) eb.connect('leave-notify-event', self.on_leave_event, textview) # this is threadsafe # (gtk textview is NOT threadsafe by itself!!) def add_to_textview(): try: # textview closed in the meantime etc. buffer_ = repl_start.get_buffer() iter_ = buffer_.get_iter_at_mark(repl_start) buffer_.insert(iter_, "\n") anchor = buffer_.create_child_anchor(iter_) # Use weburl as tooltip for image img = TextViewImage(anchor, weburl) loader = gtk.gdk.PixbufLoader() loader.write(data) loader.close() pixbuf = loader.get_pixbuf() img.set_from_pixbuf(pixbuf) eb.add(img) eb.show_all() textview.add_child_at_anchor(eb, anchor) buffer_.delete(iter_, buffer_.get_iter_at_mark(repl_end)) except: pass return False # add to mainloop --> make call threadsafe gobject.idle_add(add_to_textview) except Exception: # URL is already displayed log.error('Could not display image for URL: %s' % weburl) raise else: # If image could not be downloaded, URL is already displayed log.error('Could not download image for URL: %s -- %s' % weburl)
def retrieve_path(self, directory, fname): server = self.config['http_server'] if not server: server = self.config_default_values['http_server'][0] if not urlparse.urlparse(server).scheme: server = 'https://' + server if urlparse.urlparse(server).scheme != 'https': log.warn('Warning: not using HTTPS is a ' 'very serious security issue!') location = posixpath.join(directory, fname) uri = urlparse.urljoin(server, location) log.debug('Fetching {}'.format(uri)) request = urllib2.urlopen(uri) manifest_buffer = io.BytesIO(request.read()) return manifest_buffer
def inject(self, msg, appdata=None): log.debug('inject(appdata=%s)', appdata) msg = unicode(msg) account = self.user.accountname if not nb_xmpp: stanza = common.xmpp.Message(to=self.peer, body=msg, typ='chat') else: stanza = nbxmpp.Message(to=self.peer, body=msg, typ='chat') if appdata is not None: session = appdata.get('session', None) if session is not None: stanza.setThread(session.thread_id) conn = gajim.connections[account] if conn.carbons_enabled: stanza.addChild(name='private', namespace=nbxmpp.NS_CARBONS) conn.connection.send(stanza, now=True)
def scan_dir_for_plugins(path, scan_dirs=True): ''' Scans given directory for plugin classes. :param path: directory to scan for plugins :type path: unicode :return: list of found plugin classes (subclasses of `GajimPlugin` :rtype: [] of class objects :note: currently it only searches for plugin classes in '\*.py' files present in given direcotory `path` (no recursion here) :todo: add scanning packages :todo: add scanning zipped modules ''' print "Entered into scan_dir_for_plugins" from plugins.plugins_i18n import _ plugins_found = [] conf = ConfigParser.ConfigParser() fields = ('name', 'short_name', 'version', 'description', 'authors', 'homepage') if not os.path.isdir(path): return plugins_found dir_list = os.listdir(path) sys.path.insert(0, path) print 433, dir_list for elem_name in dir_list: file_path = os.path.join(path, elem_name) module = None if os.path.isfile(file_path) and fnmatch.fnmatch( file_path, '*.py'): module_name = os.path.splitext(elem_name)[0] print 442, module_name try: module = __import__(module_name) except ValueError, value_error: log.debug(value_error) except ImportError, import_error: log.debug(import_error)
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)
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()) # 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)
def detect_language(tb, start_mark): language = None new_start = None if not start_mark is None: next_chars = None lang_iter = tb.get_iter_at_mark(start_mark) first_word_end = lang_iter.copy() first_word_end.forward_word_end() first_word_last_char = first_word_end.get_char() next_chars_iter = first_word_end.copy() next_chars_iter.forward_chars(2) next_chars = first_word_end.get_text(next_chars_iter) log.debug("first_word_last_char: %s.", first_word_last_char) if first_word_last_char == "@" and next_chars != "@@": language = lang_iter.get_text(first_word_end) log.debug("language: >>%s<<", language) first_word_end.forward_char() new_start = tb.create_mark(None, first_word_end, True) return (language, new_start)
def scan_dir_for_plugins(path, scan_dirs=True): ''' Scans given directory for plugin classes. :param path: directory to scan for plugins :type path: unicode :return: list of found plugin classes (subclasses of `GajimPlugin` :rtype: [] of class objects :note: currently it only searches for plugin classes in '\*.py' files present in given direcotory `path` (no recursion here) :todo: add scanning packages :todo: add scanning zipped modules ''' from plugins.plugins_i18n import _ plugins_found = [] conf = ConfigParser.ConfigParser() fields = ('name', 'short_name', 'version', 'description', 'authors', 'homepage') if not os.path.isdir(path): return plugins_found dir_list = os.listdir(path) sys.path.insert(0, path) for elem_name in dir_list: file_path = os.path.join(path, elem_name) module = None if os.path.isfile(file_path) and fnmatch.fnmatch(file_path, '*.py'): module_name = os.path.splitext(elem_name)[0] try: module = __import__(module_name) except ValueError, value_error: log.debug(value_error) except ImportError, import_error: log.debug(import_error)
def on_run(self): no_map = None if not self.is_active: pres_keys = sorted(self.plugin.config['presets'].keys()) for key in pres_keys: self.preset_liststore.append((key, )) for name in self.plugin.config_default_values: if name == 'presets': continue if name == 'preview_provider': self.xml.get_object(name).set_active(self.plugin.config[name]) continue widget = self.xml.get_object(name) widget.set_text(str(self.plugin.config[name])) try: import osmgpsmap if osmgpsmap.__version__ < '0.6': no_map = True log.debug('python-osmgpsmap < 0.6 detected') except: no_map = True log.debug('python-osmgpsmap not detected') log.debug('python-osmgpsmap > 0.5 detected') if not no_map and not self.is_active: from layers import DummyLayer vbox = self.xml.get_object('vbox1') vbox.set_size_request(400, -1) self.osm = osmgpsmap.GpsMap() self.osm.layer_add( osmgpsmap.GpsMapOsd(show_dpad=True, show_zoom=True)) self.osm.layer_add(DummyLayer()) lat = self.plugin.config['lat'] lon = self.plugin.config['lon'] if not self.is_valid_coord(lat, lon): self.lat = self.lon = 0.0 self.xml.get_object('lat').set_text('0.0') self.xml.get_object('lon').set_text('0.0') self.osm.set_center_and_zoom(self.lat, self.lon, 12) self.path_to_image = os.path.abspath( gtkgui_helpers.get_icon_path('gajim', 16)) self.icon = gtk.gdk.pixbuf_new_from_file_at_size( self.path_to_image, 16, 16) self.osm.connect('button_release_event', self.map_clicked) vbox.pack_start(self.osm, expand=True, fill=True, padding=6) label = gtk.Label( _('Click the right mouse button to specify the location, \n' 'middle mouse button to show / ' 'hide the contacts on the map')) vbox.pack_start(label, expand=False, fill=False, padding=6) self.is_active = True self.images = [] self.osm_image = self.osm.image_add(self.lat, self.lon, self.icon) self.xml.get_object('lat').connect('changed', self.on_lon_changed) self.xml.get_object('lon').connect('changed', self.on_lon_changed)
def on_run(self): no_map = None if not self.is_active: pres_keys = sorted(self.plugin.config['presets'].keys()) for key in pres_keys: self.preset_liststore.append((key,)) for name in self.plugin.config_default_values: if name == 'presets': continue widget = self.xml.get_object(name) widget.set_text(str(self.plugin.config[name])) try: import osmgpsmap if osmgpsmap.__version__ < '0.6': no_map = True log.debug('python-osmgpsmap < 0.6 detected') except: no_map = True log.debug('python-osmgpsmap not detected') log.debug('python-osmgpsmap > 0.5 detected') if not no_map and not self.is_active: from layers import DummyLayer vbox = self.xml.get_object('vbox1') vbox.set_size_request(400, -1) self.osm = osmgpsmap.GpsMap() self.osm.layer_add(osmgpsmap.GpsMapOsd(show_dpad=True, show_zoom=True)) self.osm.layer_add(DummyLayer()) lat = self.plugin.config['lat'] lon = self.plugin.config['lon'] if not self.is_valid_coord(lat, lon): self.lat = self.lon = 0.0 self.xml.get_object('lat').set_text('0.0') self.xml.get_object('lon').set_text('0.0') self.osm.set_center_and_zoom(self.lat, self.lon, 12) self.path_to_image = os.path.abspath(gtkgui_helpers.get_icon_path( 'gajim', 16)) self.icon = gtk.gdk.pixbuf_new_from_file_at_size( self.path_to_image, 16, 16) self.osm.connect('button_release_event', self.map_clicked) vbox.pack_start(self.osm, expand=True, fill=True, padding=6) label = gtk.Label( _('Click the right mouse button to specify the location, \n' 'middle mouse button to show / ' 'hide the contacts on the map')) vbox.pack_start(label, expand=False, fill=False, padding=6) self.is_active = True self.images = [] self.osm_image = self.osm.image_add(self.lat, self.lon, self.icon) self.xml.get_object('lat').connect('changed', self.on_lon_changed) self.xml.get_object('lon').connect('changed', self.on_lon_changed)
def _get_http_head_direct(self, url): log.debug('Get head request direct for URL: %s' % url) try: req = urllib2.Request(url) req.get_method = lambda: 'HEAD' req.add_header('User-Agent', 'Gajim %s' % gajim.version) f = urllib2.urlopen(req) except Exception, ex: log.debug('Could not get head response for URL: %s' % url) log.debug("%s" % str(ex)) return ('', 0)
def _get_http_head_proxy(self, url, proxy): log.debug('Get head request with proxy for URL: %s' % url) if not gajim.HAVE_PYCURL: log.error('PYCURL not installed') return ('', 0) import pycurl from cStringIO import StringIO headers = '' try: b = StringIO() c = pycurl.Curl() c.setopt(pycurl.URL, url.encode('utf-8')) c.setopt(pycurl.FOLLOWLOCATION, 1) # Make a HEAD request: c.setopt(pycurl.CUSTOMREQUEST, 'HEAD') c.setopt(pycurl.NOBODY, 1) c.setopt(pycurl.HEADER, 1) c.setopt(pycurl.MAXFILESIZE, 2000000) c.setopt(pycurl.WRITEFUNCTION, b.write) c.setopt(pycurl.USERAGENT, 'Gajim ' + gajim.version) # set proxy c.setopt(pycurl.PROXY, proxy['host'].encode('utf-8')) c.setopt(pycurl.PROXYPORT, proxy['port']) if proxy['useauth']: c.setopt(pycurl.PROXYUSERPWD, proxy['user'].encode('utf-8')\ + ':' + proxy['pass'].encode('utf-8')) c.setopt(pycurl.PROXYAUTH, pycurl.HTTPAUTH_ANY) if proxy['type'] == 'http': c.setopt(pycurl.PROXYTYPE, pycurl.PROXYTYPE_HTTP) elif proxy['type'] == 'socks5': c.setopt(pycurl.PROXYTYPE, pycurl.PROXYTYPE_SOCKS5) x = c.perform() c.close() headers = b.getvalue() except pycurl.error, ex: log.debug('Could not get head response for URL: %s' % url) log.debug("%s" % str(ex)) return ('', 0)
def insert_formatted_code(tb, language, code, mark=None, line_break=False): lexer = None if language is None: log.info( "No Language specified. Falling back to default lexer: %s.", str(self.config['default_lexer'])) lexer = get_lexer(self.config['default_lexer']) else: log.debug("Using lexer for %s.", str(language)) lexer = get_lexer_with_fallback(language, self.config['default_lexer']) if lexer is None: it = tb.get_iter_at_mark(mark) tb.insert(it, '\n') else: tokens = pygments.lex(code, lexer) if line_break: log.debug("Inserting newline before code.") it = tb.get_iter_at_mark(mark) tb.insert(it, '\n') it.forward_char() tb.move_mark(mark, it) formatter = GTKFormatter(start_mark=mark) pygments.format(tokens, formatter, tb) endmark = formatter.get_last_mark() if line_break and not endmark is None: it = tb.get_iter_at_mark(endmark) tb.insert(it, '\n') log.debug("Inserting newline after code.") return tb
def download(self, url, filepath): """ Download a file. This function should be launched in a separated thread. """ log.debug('Getting map thumbnail ..') try: req = urllib2.Request(url) req.add_header('User-Agent', 'Gajim') f = urllib2.urlopen(req) except Exception as ex: log.debug('Error loading file %s ' % str(ex)) else: try: temp = f.read() with open(filepath, "wb") as local_file: local_file.write(temp) local_file.closed log.debug('Saved map thumbnail ..') except Exception as ex: log.exception('Error: ') if temp: return temp
def _sessionAcceptCB(self, stanza, content, error, action): log.debug('session accepted') self.session.connection.dispatch( 'WHITEBOARD_ACCEPTED', (self.session.peerjid, self.session.sid))
def getPolicy(self, key): ret = self.user.plugin.get_flags(self.user.accountname, self.jid)[key] log.debug('getPolicy(key=%s) = %s', key, ret) return ret
module = __import__(module_name) except ValueError, value_error: log.debug(value_error) except ImportError, import_error: log.debug(import_error) elif os.path.isdir(file_path) and scan_dirs: module_name = elem_name if module_name in sys.modules: # do not load the module twice continue file_path += os.path.sep try: module = __import__(module_name) except ValueError, value_error: log.debug(value_error) except ImportError, import_error: log.debug(import_error) print 463, module if module is None: continue manifest_path = os.path.join(os.path.dirname(file_path), 'manifest.ini') print 469, manifest_path if scan_dirs and (not os.path.isfile(manifest_path)): print 471, "continue..." continue log.debug('Attributes processing started')
module = __import__(module_name) except ValueError, value_error: log.debug(value_error) except ImportError, import_error: log.debug(import_error) elif os.path.isdir(file_path) and scan_dirs: module_name = elem_name if module_name in sys.modules: # do not load the module twice continue file_path += os.path.sep try: module = __import__(module_name) except ValueError, value_error: log.debug(value_error) except ImportError, import_error: log.debug(import_error) if module is None: continue manifest_path = os.path.join(os.path.dirname(file_path), 'manifest.ini') if scan_dirs and (not os.path.isfile(manifest_path)): continue log.debug('Attributes processing started') for module_attr_name in [attr_name for attr_name in dir(module) if not (attr_name.startswith('__') or attr_name.endswith('__'))]:
def show_image(self): """ Latex -> PNG -> TextBuffer """ def fg_str(fmt): try: return [{ 'hex': '+level-colors', 'tex': '-fg' }[fmt], gajim.interface.get_fg_color(fmt)] except KeyError: # interface may not be available when we test latex at startup return [] except AttributeError: # interface may not be available when we test latext at startup return { 'hex': ['+level-colors', '0x000000'], 'tex': ['-fg', 'rgb 0.0 0.0 0.0'] }[fmt] try: tmpdir = mkdtemp(prefix='gajim_tex') tmpfd, tmppng = mkstemp(prefix='gajim_tex', suffix='.png') os.close(tmpfd) except Exception: msg = 'Could not create temporary files for Latex plugin' log.debug(msg) self.show_error( _('latex error: %s\n===ORIGINAL CODE====\n%s') % (msg, self.code[2:len(self.code) - 2])) return False tmpfile = os.path.join(tmpdir, 'gajim_tex') # build latex string write_latex(tmpfile + '.tex', self.code[2:len(self.code) - 2]) # convert TeX to dvi exitcode = try_run( ['latex', '--interaction=nonstopmode', tmpfile + '.tex'], tmpdir) if exitcode == 0: # convert dvi to png log.debug('DVI OK') exitcode = try_run(['dvipng', '-bg', 'Transparent'] + fg_str('tex')\ + ['-T', 'tight', '-D', self.png_dpi, tmpfile + '.dvi', '-o', tmpfile + '.png'], tmpdir) if exitcode: # dvipng failed, try convert log.debug('dvipng failed, try convert') exitcode = try_run(['convert'] + fg_str('hex') + [ '-trim', '-density', self.png_dpi, tmpfile + '.dvi', tmpfile + '.png' ], tmpdir) # remove temp files created by us and TeX extensions = ['.tex', '.log', '.aux', '.dvi'] for ext in extensions: try: os.remove(tmpfile + ext) except Exception: pass if exitcode == 0: log.debug('PNG OK') os.rename(tmpfile + '.png', tmppng) else: log.debug('PNG FAILED') os.remove(tmppng) os.rmdir(tmpdir) self.show_error( _('Convertion to image failed\n===ORIGINAL CODE====' '\n%s') % self.code[2:len(self.code) - 2]) return False log.debug('Loading PNG %s' % tmppng) try: gtk.gdk.threads_enter() pixbuf = gtk.gdk.pixbuf_new_from_file(tmppng) log.debug('png loaded') iter_mark = self.buffer_.get_iter_at_mark(self.mark) iter_end = iter_mark.copy().forward_search( 'Processing LaTeX', gtk.TEXT_SEARCH_TEXT_ONLY)[1] log.debug('Delete old Text') self.buffer_.delete(iter_mark, iter_end) log.debug('Insert pixbuf') self.buffer_.insert_pixbuf(iter_end, pixbuf) except gobject.GError: self.show_error(_('Cannot open %s for reading') % tmppng) log.debug('Cant open %s for reading' % tmppng) finally: gtk.gdk.threads_leave() os.remove(tmppng)
def _sessionAcceptCB(self, stanza, content, error, action): log.debug('session accepted') self.session.connection.dispatch('WHITEBOARD_ACCEPTED', (self.session.peerjid, self.session.sid))
def scan_dir_for_plugins(path, scan_dirs=True): ''' Scans given directory for plugin classes. :param path: directory to scan for plugins :type path: str :return: list of found plugin classes (subclasses of `GajimPlugin` :rtype: [] of class objects :note: currently it only searches for plugin classes in '\*.py' files present in given direcotory `path` (no recursion here) :todo: add scanning packages :todo: add scanning zipped modules ''' from plugins.plugins_i18n import _ plugins_found = [] conf = configparser.ConfigParser() fields = ('name', 'short_name', 'version', 'description', 'authors', 'homepage') if not os.path.isdir(path): return plugins_found dir_list = os.listdir(path) sys.path.insert(0, path) for elem_name in dir_list: file_path = os.path.join(path, elem_name) if os.path.isfile(file_path) and fnmatch.fnmatch(file_path, '*.py'): module_name = os.path.splitext(elem_name)[0] elif os.path.isdir(file_path) and scan_dirs: module_name = elem_name file_path += os.path.sep manifest_path = os.path.join(os.path.dirname(file_path), 'manifest.ini') if scan_dirs and (not os.path.isfile(manifest_path)): continue # read metadata from manifest.ini conf.remove_section('info') conf_file = open(manifest_path) conf.read_file(conf_file) conf_file.close() try: min_v = conf.get('info', 'min_gajim_version') except Exception: min_v = None try: max_v = conf.get('info', 'max_gajim_version') except Exception: max_v = None gajim_v = gajim.config.get('version') gajim_v = gajim_v.split('-', 1)[0] gajim_v = gajim_v.split('.') if min_v: min_v = min_v.split('.') if gajim_v < min_v: continue if max_v: max_v = max_v.split('.') if gajim_v > max_v: continue module = None if module_name in sys.modules: # do not load the module twice continue try: module = __import__(module_name) except ValueError as value_error: log.debug(str(value_error)) except ImportError as import_error: log.debug(str(import_error)) if module is None: continue log.debug('Attributes processing started') for module_attr_name in [attr_name for attr_name in dir(module) if not (attr_name.startswith('__') or attr_name.endswith('__'))]: module_attr = getattr(module, module_attr_name) log.debug('%s : %s' % (module_attr_name, module_attr)) try: if not issubclass(module_attr, GajimPlugin) or \ module_attr is GajimPlugin: continue log.debug('is subclass of GajimPlugin') module_attr.__path__ = os.path.abspath( os.path.dirname(file_path)) for option in fields: if conf.get('info', option) is '': raise configparser.NoOptionError('field empty') if option == 'description': setattr(module_attr, option, _(conf.get('info', option))) continue setattr(module_attr, option, conf.get('info', option)) plugins_found.append(module_attr) except TypeError: # set plugin localization try: module_attr._ = _ except AttributeError: pass except configparser.NoOptionError: # all fields are required log.debug('%s : %s' % (module_attr_name, 'wrong manifest file. all fields are required!')) except configparser.NoSectionError: # info section are required log.debug('%s : %s' % (module_attr_name, 'wrong manifest file. info section are required!')) except configparser.MissingSectionHeaderError: # info section are required log.debug('%s : %s' % (module_attr_name, 'wrong manifest file. section are required!')) return plugins_found
def scan_dir_for_plugins(path, scan_dirs=True): r''' Scans given directory for plugin classes. :param path: directory to scan for plugins :type path: str :return: list of found plugin classes (subclasses of `GajimPlugin` :rtype: [] of class objects :note: currently it only searches for plugin classes in '\*.py' files present in given direcotory `path` (no recursion here) :todo: add scanning packages :todo: add scanning zipped modules ''' from plugins.plugins_i18n import _ plugins_found = [] conf = configparser.ConfigParser() fields = ('name', 'short_name', 'version', 'description', 'authors', 'homepage') if not os.path.isdir(path): return plugins_found dir_list = os.listdir(path) sys.path.insert(0, path) for elem_name in dir_list: file_path = os.path.join(path, elem_name) if os.path.isfile(file_path) and fnmatch.fnmatch( file_path, '*.py'): module_name = os.path.splitext(elem_name)[0] elif os.path.isdir(file_path) and scan_dirs: module_name = elem_name file_path += os.path.sep manifest_path = os.path.join(os.path.dirname(file_path), 'manifest.ini') if scan_dirs and (not os.path.isfile(manifest_path)): continue # read metadata from manifest.ini conf.remove_section('info') with open(manifest_path, encoding='utf-8') as conf_file: try: conf.read_file(conf_file) except configparser.Error: log.warning(("Plugin {plugin} not loaded, error loading" " manifest").format(plugin=elem_name), exc_info=True) continue min_v = conf.get('info', 'min_gajim_version', fallback=None) max_v = conf.get('info', 'max_gajim_version', fallback=None) gajim_v = gajim.config.get('version').split('-', 1)[0] gajim_v_cmp = parse_version(gajim_v) if min_v and gajim_v_cmp < parse_version(min_v): log.warning(('Plugin {plugin} not loaded, newer version of' 'gajim required: {gajim_v} < {min_v}').format( plugin=elem_name, gajim_v=gajim_v, min_v=min_v)) continue if max_v and gajim_v_cmp > parse_version(max_v): log.warning(('Plugin {plugin} not loaded, plugin incompatible ' 'with current version of gajim: ' '{gajim_v} > {max_v}').format(plugin=elem_name, gajim_v=gajim_v, max_v=max_v)) continue module = None if module_name in sys.modules: # do not load the module twice continue try: module = __import__(module_name) except Exception as error: log.warning( "While trying to load {plugin}, exception occurred".format( plugin=elem_name), exc_info=sys.exc_info()) continue if module is None: continue log.debug('Attributes processing started') for module_attr_name in [ attr_name for attr_name in dir(module) if not ( attr_name.startswith('__') or attr_name.endswith('__')) ]: module_attr = getattr(module, module_attr_name) log.debug('%s : %s' % (module_attr_name, module_attr)) try: if not issubclass(module_attr, GajimPlugin) or \ module_attr is GajimPlugin: continue log.debug('is subclass of GajimPlugin') module_attr.__path__ = os.path.abspath( os.path.dirname(file_path)) for option in fields: if conf.get('info', option) is '': raise configparser.NoOptionError('field empty') if option == 'description': setattr(module_attr, option, _(conf.get('info', option))) continue setattr(module_attr, option, conf.get('info', option)) plugins_found.append(module_attr) except TypeError: # set plugin localization try: module_attr._ = _ except AttributeError: pass except configparser.NoOptionError: # all fields are required log.debug( '%s : %s' % (module_attr_name, 'wrong manifest file. all fields are required!')) except configparser.NoSectionError: # info section are required log.debug( '%s : %s' % (module_attr_name, 'wrong manifest file. info section are required!')) except configparser.MissingSectionHeaderError: # info section are required log.debug('%s : %s' % (module_attr_name, 'wrong manifest file. section are required!')) return plugins_found
def load_thumbnail(self, filepath): with open(filepath, 'rb') as f: data = f.read() f.closed log.debug('Load map thumbnail') return data
def create_path(self, folder): if os.path.exists(folder): return log.debug("creating folder '%s'" % folder) os.mkdir(folder, 0o700)
demandimport.enable() demandimport.ignore += ['_imp'] log = logging.getLogger('gajim.plugin_system.url_image_preview') try: if os.name == 'nt': from cryptography.hazmat.backends.openssl import backend else: from cryptography.hazmat.backends import default_backend from cryptography.hazmat.primitives.ciphers import Cipher from cryptography.hazmat.primitives.ciphers import algorithms from cryptography.hazmat.primitives.ciphers.modes import GCM decryption_available = True except Exception as e: log.debug('Cryptography Import Error: ' + str(e)) log.debug('Decryption/Encryption disabled') decryption_available = False ACCEPTED_MIME_TYPES = ('image/png', 'image/jpeg', 'image/gif', 'image/raw', 'image/svg+xml') class UrlImagePreviewPlugin(GajimPlugin): @log_calls('UrlImagePreviewPlugin') def init(self): self.config_dialog = UrlImagePreviewPluginConfigDialog(self) self.events_handlers = {} self.events_handlers['message-received'] = ( ged.PRECORE, self.handle_message_received) self.gui_extension_points = {
def print_special_text(self, tv, special_text, other_tags, graphics=True, iter_=None): conv_textview = tv textview = tv.tv # geo:48.2057365,16.3435941 if not special_text.startswith('geo:'): return buffer_ = textview.get_buffer() if not iter_: iter_ = buffer_.get_end_iter() textview.plugin_modified = True # Show URL, until image is loaded (if ever) ttt = buffer_.get_tag_table() repl_start = buffer_.create_mark(None, iter_, True) buffer_.insert_with_tags( iter_, special_text, *[(ttt.lookup(t) if isinstance(t, str) else t) for t in ["url"]]) repl_end = buffer_.create_mark(None, iter_, True) zoom = 17 size = 250 color = 'blue' coordinates = special_text.split(':')[1] lat = coordinates.split(',')[0] lon = coordinates.split(',')[1] filename = coordinates.replace(',', '_').replace('.', '-') filepath = os.path.join(self.thumbpath, filename) provider = self.config['preview_provider'] # Google if provider == 0: url = 'https://maps.googleapis.com/maps/api/staticmap?center={}' \ '&zoom={}&size={}x{}&markers=color:{}' \ '|label:S|{}'.format(coordinates, zoom, size, size, color, coordinates) weburl = 'https://www.google.at/maps/place/{}'.format(coordinates) else: # Mapquest / OSM apikey = 'F7x36jLVv2hiANVAXmhwvUB044XvGASh' url = 'https://open.mapquestapi.com/staticmap/v4/' \ 'getmap?key={}¢er={}&zoom={}&size={},{}&type=map' \ '&imagetype=png&pois={},{}&scalebar=false' \ .format(apikey, coordinates, zoom, size, size, color, coordinates) weburl = 'http://www.openstreetmap.org/' \ '?mlat={}&mlon={}#map={}/{}/{}&layers=N' \ .format(lat, lon, zoom, lat, lon) log.debug(url) if os.path.exists(filepath): gajim.thread_interface(self.load_thumbnail, [filepath], self.updatechat, [weburl, repl_start, repl_end, textview]) else: gajim.thread_interface(self.download, [url, filepath], self.updatechat, [weburl, repl_start, repl_end, textview]) # Don't print the URL in the message window (in the calling function) conv_textview.plugin_modified = True
def disconnect_from_chat_control(self, control): control_data = control.syntax_highlighter_plugin_data tv = control.conv_textview.tv log.debug("disconnected: %s.", str(control_data['connection'])) tv.get_buffer().disconnect(control_data['connection'])
def show_image(self): """ Latex -> PNG -> TextBuffer """ def fg_str(fmt): try: return [{'hex' : '+level-colors', 'tex' : '-fg'}[fmt], gajim.interface.get_fg_color(fmt)] except KeyError: # interface may not be available when we test latex at startup return [] except AttributeError: # interface may not be available when we test latext at startup return {'hex': ['+level-colors', '0x000000'], 'tex': ['-fg', 'rgb 0.0 0.0 0.0']}[fmt] try: tmpdir = mkdtemp(prefix='gajim_tex') tmpfd, tmppng = mkstemp(prefix='gajim_tex', suffix='.png') os.close(tmpfd) except Exception: msg = 'Could not create temporary files for Latex plugin' log.debug(msg) self.show_error(_('latex error: %s\n===ORIGINAL CODE====\n%s') % ( msg, self.code[2:len(self.code)-2])) return False tmpfile = os.path.join(tmpdir, 'gajim_tex') # build latex string write_latex(tmpfile + '.tex', self.code[2:len(self.code)-2]) # convert TeX to dvi exitcode = try_run(['latex', '--interaction=nonstopmode', tmpfile + '.tex'], tmpdir) if exitcode == 0: # convert dvi to png log.debug('DVI OK') exitcode = try_run(['dvipng', '-bg', 'Transparent'] + fg_str('tex')\ + ['-T', 'tight', '-D', self.png_dpi, tmpfile + '.dvi', '-o', tmpfile + '.png'], tmpdir) if exitcode: # dvipng failed, try convert log.debug('dvipng failed, try convert') exitcode = try_run(['convert'] + fg_str('hex') + ['-trim', '-density', self.png_dpi, tmpfile + '.dvi', tmpfile + '.png'], tmpdir) # remove temp files created by us and TeX extensions = ['.tex', '.log', '.aux', '.dvi'] for ext in extensions: try: os.remove(tmpfile + ext) except Exception: pass if exitcode == 0: log.debug('PNG OK') os.rename(tmpfile + '.png', tmppng) else: log.debug('PNG FAILED') os.remove(tmppng) os.rmdir(tmpdir) self.show_error(_('Convertion to image failed\n===ORIGINAL CODE====' '\n%s') % self.code[2:len(self.code)-2]) return False log.debug('Loading PNG %s' % tmppng) try: gtk.gdk.threads_enter() pixbuf = gtk.gdk.pixbuf_new_from_file(tmppng) log.debug('png loaded') iter_mark = self.buffer_.get_iter_at_mark(self.mark) iter_end = iter_mark.copy().forward_search('Processing LaTeX', gtk.TEXT_SEARCH_TEXT_ONLY)[1] log.debug('Delete old Text') self.buffer_.delete(iter_mark, iter_end) log.debug('Insert pixbuf') self.buffer_.insert_pixbuf(iter_end, pixbuf) except gobject.GError: self.show_error(_('Cannot open %s for reading') % tmppng) log.debug('Cant open %s for reading' % tmppng) finally: gtk.gdk.threads_leave() os.remove(tmppng)