diff --git a/emoticons_pack/__init__.py b/emoticons_pack/__init__.py new file mode 100644 index 0000000..496821a --- /dev/null +++ b/emoticons_pack/__init__.py @@ -0,0 +1 @@ +from .emoticons_pack import EmoticonsPackPlugin diff --git a/emoticons_pack/config_dialog.ui b/emoticons_pack/config_dialog.ui new file mode 100644 index 0000000..691da97 --- /dev/null +++ b/emoticons_pack/config_dialog.ui @@ -0,0 +1,405 @@ + + + + + Plug-in decription should be displayed here. This text will be erased during PluginsWindow initialization. + + + False + + + 600 + 350 + True + True + 340 + True + + + True + False + + + True + True + 6 + never + + + True + True + 1 + + + none + + + + + + + True + True + 0 + + + + + + + + False + False + + + + + True + False + 5 + 6 + + + True + False + 0 + empty + True + end + + + + + + False + True + 0 + + + + + True + False + 6 + + + True + False + Authors: + + + False + True + 0 + + + + + True + False + 0 + 6 + <empty> + True + end + + + True + True + 1 + + + + + False + True + 1 + + + + + True + False + 6 + + + True + False + Converted by: + + + False + True + 0 + + + + + True + False + 0 + 6 + <empty> + True + end + + + True + True + 1 + + + + + False + True + 2 + + + + + True + False + + + True + False + Homepage: + + + False + True + 0 + + + + + button + False + True + True + True + False + none + False + 0 + + + True + True + 1 + + + + + False + True + 3 + + + + + True + False + + + True + False + + + True + False + Description: + + + False + True + 0 + + + + + True + False + + + + + + True + True + 1 + + + + + False + True + 0 + + + + + True + True + in + + + + + + True + True + 1 + + + + + True + True + 4 + + + + + True + False + + + True + False + end + + + False + True + False + True + 22 + False + + + + True + False + + + True + False + gtk-info + + + False + False + 0 + + + + + True + False + 0 + Legend + + + True + True + 1 + + + + + + + True + True + end + 0 + True + + + + + True + True + end + 0 + + + + + True + False + end + + + False + True + False + False + True + False + + + + True + False + + + True + False + gtk-refresh + + + True + True + 0 + + + + + True + False + 0 + Install/Upgrade + + + True + True + 1 + + + + + + + False + False + 0 + + + + + False + False + end + 1 + + + + + False + False + 5 + + + + + True + False + + + + + + diff --git a/emoticons_pack/contents.ini b/emoticons_pack/contents.ini new file mode 100644 index 0000000..7524e51 --- /dev/null +++ b/emoticons_pack/contents.ini @@ -0,0 +1,89 @@ +[MacThemes2] +icon: Smile.png +description: + Mac Themes 2 Smilies
+ + +authors: David Lanham +homepage: https://trac.gajim.org/wiki/MacThemes2 + +[Citters Emoticons from Psi] +icon: smile.png +description: + Citters Emoticons from Psi
+ + +converter: churchyard (JID: churchyard@njs.netlab.cz) +homepage: https://trac.gajim.org/wiki/cittersemoticons + +[Google Talk Emoticons] +icon: equal_smile.gif +description: + Google Talk Emoticons
+ + +converter: Chris Cook +homepage: https://trac.gajim.org/wiki/gtalkemoticons + +[ICQ6 Emoticons] +icon: Smiley1.gif +description: + ICQ6 Emoticons
+ + +homepage: https://trac.gajim.org/wiki/ICQ6-emotions + +[Kolobok Animated Emoticons] +icon: ab.gif +description: + Kolobok Animated Emoticons
+ + +homepage: https://trac.gajim.org/wiki/kolobok-animated-emoticons + +[Pidgin Emoticons] +icon: smile.png +description: + Pidgin Emoticons
+ + +homepage: https://trac.gajim.org/wiki/PidginEmoticons + +[Psynova qip's theme] +icon: ab.gif +authors: zOrg +description: + Psynova qip's theme
+ + +homepage: https://trac.gajim.org/wiki/psynovaemoticons + +[Yahoo Emoticons] +icon: equal_smile.gif +description: + Yahoo Emoticons
+ + +homepage: https://trac.gajim.org/wiki/YahooEmoticons + +[Nekomoticons] +icon: s01.jpg +authors: somik (http://somik.deviantart.com/) +converter: Dotterian (http://dotterian.ru/) +description: + Nekomoticons
+ + +homepage: https://trac.gajim.org/wiki/Nekomoticons + +[Trollicons] +icon: Happy-EverythingWentBetterThanExpected.png +authors: Sagar Pandya + Chris Li + Jonathan E. Chen +converter: Matthieu L. +description: + Trollicons (Rage Icons for Gajim)
+ + +homepage: https://github.com/sagargp/trollicons/blob/master/readme.md#downloads diff --git a/emoticons_pack/emoticons_pack.png b/emoticons_pack/emoticons_pack.png new file mode 100644 index 0000000..7aec288 Binary files /dev/null and b/emoticons_pack/emoticons_pack.png differ diff --git a/emoticons_pack/emoticons_pack.py b/emoticons_pack/emoticons_pack.py new file mode 100644 index 0000000..a099d48 --- /dev/null +++ b/emoticons_pack/emoticons_pack.py @@ -0,0 +1,361 @@ +# -*- coding: utf-8 -*- +## + +from gi.repository import Gtk +from gi.repository import GdkPixbuf +from gi.repository import Pango +from gi.repository import GObject +import io +import configparser +import os +import zipfile +import tempfile +from shutil import rmtree +import sys +import imp + +from common import gajim +from plugins import GajimPlugin +from plugins.helpers import log_calls +from htmltextview import HtmlTextView +from conversation_textview import ConversationTextview +from dialogs import WarningDialog, HigDialog + +( + C_PIXBUF, + C_NAME, + C_DESCRIPTION, + C_AUTHORS, + C_CONVERTER, + C_HOMEPAGE, + C_UPGRADE) = range(7) + + +class EmoticonsPackPlugin(GajimPlugin): + + @log_calls('EmoticonsPackPlugin') + def init(self): + self.description = _('Install emoticons') + self.config_dialog = None # EmoticonsPackPluginConfigDialog(self) + self.window = None + self.model = None + self.connected_ids = {} + self.tmp_dir = '' + + @log_calls('EmoticonsPackPlugin') + def activate(self): + self.pl_menuitem = gajim.interface.roster.xml.get_object( + 'plugins_menuitem') + self.id_ = self.pl_menuitem.connect_after('activate', self.on_activate) + if 'plugins' in gajim.interface.instances: + self.on_activate(None) + + @log_calls('EmoticonsPackPlugin') + def deactivate(self): + self.pl_menuitem.disconnect(self.id_) + if hasattr(self, 'page_num'): + self.notebook.remove_page(self.notebook.page_num(self.hpaned)) + self.notebook.set_current_page(0) + for id_, widget in list(self.connected_ids.items()): + widget.disconnect(id_) + del self.page_num + + def on_activate(self, widget): + if 'plugins' not in gajim.interface.instances: + return + if hasattr(self, 'page_num'): + # 'Available' tab exists + return + self.installed_plugins_model = gajim.interface.instances[ + 'plugins'].installed_plugins_model + self.notebook = gajim.interface.instances['plugins'].plugins_notebook + id_ = self.notebook.connect( + 'switch-page', self.on_notebook_switch_page) + self.connected_ids[id_] = self.notebook + self.window = gajim.interface.instances['plugins'].window + id_ = self.window.connect('destroy', self.on_win_destroy) + self.connected_ids[id_] = self.window + self.Gtk_BUILDER_FILE_PATH = self.local_file_path('config_dialog.ui') + self.xml = Gtk.Builder() + self.xml.set_translation_domain('gajim_plugins') + self.xml.add_objects_from_file(self.Gtk_BUILDER_FILE_PATH, ['hpaned2']) + self.hpaned = self.xml.get_object('hpaned2') + self.page_num = self.notebook.append_page(self.hpaned, Gtk.Label(_( + 'Emoticons'))) + + widgets_to_extract = ( + 'set_name', 'available_treeview', 'homepage_linkbutton', + 'inslall_upgrade_button', 'authors_label', 'converter_label',) + + for widget_name in widgets_to_extract: + setattr(self, widget_name, self.xml.get_object(widget_name)) + + self.model = Gtk.ListStore( + GdkPixbuf.Pixbuf, GObject.TYPE_STRING, + GObject.TYPE_STRING, GObject.TYPE_STRING, + GObject.TYPE_STRING, GObject.TYPE_STRING, GObject.TYPE_BOOLEAN) + self.available_treeview.set_model(self.model) + self.available_treeview.set_rules_hint(True) + self.model.set_sort_column_id(1, Gtk.SortType.ASCENDING) + + #self.progressbar.set_property('no-show-all', True) + renderer = Gtk.CellRendererText() + col = Gtk.TreeViewColumn(_('Name')) + cell = Gtk.CellRendererPixbuf() + col.pack_start(cell, False) + col.add_attribute(cell, 'pixbuf', C_PIXBUF) + col.pack_start(renderer, True) + col.add_attribute(renderer, 'text', C_NAME) + col.set_property('expand', True) + col.set_sizing(Gtk.TreeViewColumnSizing.GROW_ONLY) + self.available_treeview.append_column(col) + + renderer = Gtk.CellRendererToggle() + renderer.set_property('activatable', True) + renderer.connect('toggled', self.available_plugins_toggled_cb) + col = Gtk.TreeViewColumn( + _('Install /\nUpgrade'), renderer, active=C_UPGRADE) + col.set_property('expand', False) + col.set_resizable(False) + self.available_treeview.append_column(col) + + selection = self.available_treeview.get_selection() + selection.connect( + 'changed', self.available_plugins_treeview_selection_changed) + selection.set_mode(Gtk.SelectionMode.SINGLE) + + self.plugin_description_textview = ConversationTextview(None) + sw = self.xml.get_object('scrolledwindow1') + sw.add(self.plugin_description_textview.tv) + self.xml.connect_signals(self) + self.window.show_all() + + def on_legend_button_clicked(self, widget): + self.xml.get_object('scrolledwindow1').get_children()[0].destroy() + + treeview_selection = self.available_treeview.get_selection() + model, iter = treeview_selection.get_selected() + name = model.get_value(iter, C_NAME) + + label = self.xml.get_object('label2') + if label.get_text() == 'Legend': + label.set_text('Description') + sys.path.append(os.path.join(self.tmp_dir, name)) + + import emoticons + imp.reload(emoticons) + + self.plugin_description_textview = Gtk.TextView() + sw = self.xml.get_object('scrolledwindow1') + sw.add(self.plugin_description_textview) + sw.show_all() + + buff = self.plugin_description_textview.get_buffer() + for icon in emoticons.emoticons: + icon_file = os.path.join(self.tmp_dir, name, icon) + with open(icon_file, 'rb') as _file: + data = _file.read() + pbl = GdkPixbuf.PixbufLoader() + pbl.write(data) + pbl.close() + buff.insert_pixbuf(buff.get_end_iter(), pbl.get_pixbuf()) + text = ' , '.join(emoticons.emoticons[icon]) + buff.insert(buff.get_end_iter(), text + '\n', -1) + + self.plugin_description_textview.set_property('sensitive', True) + sys.path.remove(os.path.join(self.tmp_dir, name)) + + else: + self.plugin_description_textview = ConversationTextview(None) + sw = self.xml.get_object('scrolledwindow1') + sw.add(self.plugin_description_textview.tv) + sw.show_all() + label.set_text('Legend') + desc = _(model.get_value(iter, C_DESCRIPTION)) + if not desc.startswith('' + \ + desc + ' ' + desc = desc.replace('preview.image', ('file:' + os.path.join( + self.tmp_dir, name, 'preview.png'))) + self.plugin_description_textview.tv.display_html( + desc, self.plugin_description_textview) + self.plugin_description_textview.tv.set_property('sensitive', True) + + def dict_to_html(self, dict_): + desc = '' + for icon in dict_: + acr = ' , '.join(dict_[icon]) + desc += ' '+ icon + ' '+ acr + '\n' + return desc + + def on_inslall_upgrade_clicked(self, widget): + self.inslall_upgrade_button.set_property('sensitive', False) + self.errors = '' + + def on_error(func, path, error): + if func == os.path.islink: + # if symlink + os.unlink(path) + return + # access is denied or other + # WarningDialog(_('Can\'t remove dir'), error[1], self.window) + self.errors += str(error[1]) + + name_list = [] + for i in range(len(self.model)): + if self.model[i][C_UPGRADE]: + name_list.append(self.model[i][C_NAME]) + for name in name_list: + # remove dirs + target_dir = os.path.join(gajim.MY_EMOTS_PATH, name) + if os.path.isdir(target_dir): + rmtree(target_dir, False, on_error) + + # unzip new files + zip_file = os.path.join(self.__path__, 'emoticons_pack.zip') + with zipfile.ZipFile(zip_file, 'r') as myzip: + namelist = myzip.namelist() + for n in namelist: + if not n.startswith(name): + continue + try: + icon_file = myzip.extract(n, path=gajim.MY_EMOTS_PATH) + except Exception as e: + self.errors += str(e) + # unset all checkbattons + for i in range(len(self.model)): + self.model[i][C_UPGRADE] = False + + if self.errors: + WarningDialog( + _('Not fully installed'), + 'Access is denied or other', self.window) + else: + # show dialog + dialog = HigDialog( + None, Gtk.MessageType.INFO, Gtk.ButtonsType.OK, '', + _('All selected emoticons installed(upgraded)')) + dialog.set_modal(False) + dialog.set_transient_for(self.window) + dialog.popup() + + def on_win_destroy(self, widget): + if hasattr(self, 'page_num'): + del self.page_num + + def available_plugins_toggled_cb(self, cell, path): + is_active = self.model[path][C_UPGRADE] + self.model[path][C_UPGRADE] = not is_active + dir_list = [] + for i in range(len(self.model)): + if self.model[i][C_UPGRADE]: + dir_list.append(self.model[i][C_NAME]) + if not dir_list: + self.inslall_upgrade_button.set_property('sensitive', False) + else: + self.inslall_upgrade_button.set_property('sensitive', True) + + def on_notebook_switch_page(self, widget, page, page_num): + tab_label_text = self.notebook.get_tab_label_text(self.hpaned) + if tab_label_text != (_('Emoticons')): + return + + self.model.clear() + self.fill_table() + self.select_root_iter() + + def fill_table(self): + conf = configparser.ConfigParser() + # read metadata from contents.ini + contents_path = os.path.join(self.__path__, 'contents.ini') + with open(contents_path) as _file: + conf.read_file(_file) + for section in conf.sections(): + # get icon + filename = conf.get(section, 'icon') + filename = os.path.join(section, filename) + zip_file = os.path.join(self.__path__, 'emoticons_pack.zip') + with zipfile.ZipFile(zip_file, 'r') as myzip: + icon_file = myzip.open(filename, mode='r') + data = icon_file.read() + pbl = GdkPixbuf.PixbufLoader() + pbl.set_size(16, 16) + pbl.write(data) + pbl.close() + icon = pbl.get_pixbuf() + + self.model.append( + [icon, section, + conf.get(section, 'description'), + conf.get(section, 'authors', fallback=_('Unknown')), + conf.get(section, 'converter', fallback=_('Unknown')), + conf.get(section, 'homepage'), False]) + conf.remove_section(section) + + def available_plugins_treeview_selection_changed(self, treeview_selection): + model, iter = treeview_selection.get_selected() + label = self.xml.get_object('label2') + label.set_text(_('Legend')) + if iter: + set_name = model.get_value(iter, C_NAME) + if os.path.isdir(self.tmp_dir): + rmtree(self.tmp_dir, True) + self.tmp_dir = tempfile.mkdtemp() + # unzip new files + zip_file = os.path.join(self.__path__, 'emoticons_pack.zip') + with zipfile.ZipFile(zip_file, 'r') as myzip: + namelist = myzip.namelist() + for n in namelist: + if not n.startswith(set_name): + continue + myzip.extract(n, path=self.tmp_dir) + + self.set_name.set_text(set_name) + self.authors_label.set_text(model.get_value(iter, C_AUTHORS)) + self.converter_label.set_text(model.get_value(iter, C_CONVERTER)) + self.homepage_linkbutton.set_uri( + model.get_value(iter, C_HOMEPAGE)) + self.homepage_linkbutton.set_label( + model.get_value(iter, C_HOMEPAGE)) + label = self.homepage_linkbutton.get_children()[0] + label.set_ellipsize(Pango.EllipsizeMode.END) + self.homepage_linkbutton.set_property('sensitive', True) + + self.xml.get_object('scrolledwindow1').get_children()[0].destroy() + self.plugin_description_textview = ConversationTextview(None) + sw = self.xml.get_object('scrolledwindow1') + sw.add(self.plugin_description_textview.tv) + sw.show_all() + desc = _(model.get_value(iter, C_DESCRIPTION)) + if not desc.startswith('' + \ + desc + ' ' + else: + desc = desc.replace('preview.image', ('file:' + os.path.join( + self.tmp_dir, set_name, 'preview.png'))) + self.plugin_description_textview.tv.display_html( + desc, self.plugin_description_textview) + self.plugin_description_textview.tv.set_property('sensitive', True) + else: + self._clear_available_plugin_info() + + def _clear_available_plugin_info(self): + self.set_name.set_text('') + self.authors_label.set_text('') + self.homepage_linkbutton.set_uri('') + self.homepage_linkbutton.set_label('') + self.homepage_linkbutton.set_property('sensitive', False) + + desc_textbuffer = self.plugin_description_textview.tv.get_buffer() + desc_textbuffer.set_text('') + self.plugin_description_textview.tv.set_property('sensitive', False) + + def select_root_iter(self): + if hasattr(self, 'page_num'): + selection = self.available_treeview.get_selection() + if selection.count_selected_rows() == 0: + root_iter = self.model.get_iter_first() + selection.select_iter(root_iter) + scr_win = self.xml.get_object('scrolledwindow2') + scr_win.get_vadjustment().set_value(0) + #GObject.idle_add(self.available_treeview.grab_focus) diff --git a/emoticons_pack/emoticons_pack.zip b/emoticons_pack/emoticons_pack.zip new file mode 100644 index 0000000..a5fb1e8 Binary files /dev/null and b/emoticons_pack/emoticons_pack.zip differ diff --git a/emoticons_pack/manifest.ini b/emoticons_pack/manifest.ini new file mode 100644 index 0000000..f74e636 --- /dev/null +++ b/emoticons_pack/manifest.ini @@ -0,0 +1,8 @@ +[info] +name: Emoticons pack +short_name: emoticons_pack +version: 0.0.0 +description: Install emoticons +authors: Denis Fomin +homepage: http://trac-plugins.gajim.org/wiki/PluginInstallerPlugin +min_gajim_version: 0.15.10