!C99Shell v. 2.0 [PHP 7 Update] [25.02.2019]!

Software: Apache/2.2.16 (Debian). PHP/5.3.3-7+squeeze19 

uname -a: Linux mail.tri-specialutilitydistrict.com 2.6.32-5-amd64 #1 SMP Tue May 13 16:34:35 UTC
2014 x86_64
 

uid=33(www-data) gid=33(www-data) groups=33(www-data) 

Safe-mode: OFF (not secure)

/usr/lib/totem/plugins/opensubtitles/   drwxr-xr-x
Free 129.9 GB of 142.11 GB (91.41%)
Home    Back    Forward    UPDIR    Refresh    Search    Buffer    Encoder    Tools    Proc.    FTP brute    Sec.    SQL    PHP-code    Update    Feedback    Self remove    Logout    


Viewing file:     opensubtitles.py (21.45 KB)      -rw-r--r--
Select action/file-type:
(+) | (+) | (+) | Code (+) | Session (+) | (+) | SDB (+) | (+) | (+) | (+) | (+) | (+) |
import totem
import gobject, gtk, gio, gconf
gobject.threads_init()
import xmlrpclib
import threading
import xdg.BaseDirectory
from os import sep, path, mkdir
import gettext
import pango

from hash import hashFile

D_ = gettext.dgettext

USER_AGENT = 'Totem'
OK200 = '200 OK'
TOTEM_REMOTE_COMMAND_REPLACE = 14

SUBTITLES_EXT = [
    "asc",
    "txt",
        "sub",
        "srt",
        "smi",
        "ssa",
        "ass",
]

# Map of the language codes used by opensubtitles.org's API to their human-readable name
LANGUAGES_STR = [(D_('iso_639_3', 'Albanian'), 'sq'),
         (D_('iso_639_3', 'Arabic'), 'ar'),
         (D_('iso_639_3', 'Armenian'), 'hy'),
         (D_('iso_639_3', 'Neo-Aramaic, Assyrian'), 'ay'),
         (D_('iso_639_3', 'Bosnian'), 'bs'),
         (_('Brasilian Portuguese'), 'pb'),
         (D_('iso_639_3', 'Bulgarian'), 'bg'),
         (D_('iso_639_3', 'Catalan'), 'ca'),
         (D_('iso_639_3', 'Chinese'), 'zh'),
         (D_('iso_639_3', 'Croatian'), 'hr'),
         (D_('iso_639_3', 'Czech'), 'cs'),
         (D_('iso_639_3', 'Danish'), 'da'),
         (D_('iso_639_3', 'Dutch'), 'nl'),
         (D_('iso_639_3', 'English'), 'en'),
         (D_('iso_639_3', 'Esperanto'), 'eo'),
         (D_('iso_639_3', 'Estonian'), 'et'),
         (D_('iso_639_3', 'Finnish'), 'fi'),
         (D_('iso_639_3', 'French'), 'fr'),
         (D_('iso_639_3', 'Galician'), 'gl'),
         (D_('iso_639_3', 'Georgian'), 'ka'),
         (D_('iso_639_3', 'German'), 'de'),
         (D_('iso_639_3', 'Greek, Modern (1453-)'), 'el'),
         (D_('iso_639_3', 'Hebrew'), 'he'),
         (D_('iso_639_3', 'Hindi'), 'hi'),
         (D_('iso_639_3', 'Hungarian'), 'hu'),
         (D_('iso_639_3', 'Icelandic'), 'is'),
         (D_('iso_639_3', 'Indonesian'), 'id'),
         (D_('iso_639_3', 'Italian'), 'it'),
         (D_('iso_639_3', 'Japanese'), 'ja'),
         (D_('iso_639_3', 'Kazakh'), 'kk'),
         (D_('iso_639_3', 'Korean'), 'ko'),
         (D_('iso_639_3', 'Latvian'), 'lv'),
         (D_('iso_639_3', 'Lithuanian'), 'lt'),
         (D_('iso_639_3', 'Luxembourgish'), 'lb'),
         (D_('iso_639_3', 'Macedonian'), 'mk'),
         (D_('iso_639_3', 'Malay (macrolanguage)'), 'ms'),
         (D_('iso_639_3', 'Norwegian'), 'no'),
         (D_('iso_639_3', 'Occitan (post 1500)'), 'oc'),
         (D_('iso_639_3', 'Persian'), 'fa'),
         (D_('iso_639_3', 'Polish'), 'pl'),
         (D_('iso_639_3', 'Portuguese'), 'pt'),
         (D_('iso_639_3', 'Romanian'), 'ro'),
         (D_('iso_639_3', 'Russian'), 'ru'),
         (D_('iso_639_3', 'Serbian'), 'sr'),
         (D_('iso_639_3', 'Slovak'), 'sk'),
         (D_('iso_639_3', 'Slovenian'), 'sl'),
         (D_('iso_639_3', 'Spanish'), 'es'),
         (D_('iso_639_3', 'Swedish'), 'sv'),
         (D_('iso_639_3', 'Thai'), 'th'),
         (D_('iso_639_3', 'Turkish'), 'tr'),
         (D_('iso_639_3', 'Ukrainian'), 'uk'),
         (D_('iso_639_3', 'Vietnamese'), 'vi'),]

# Map of ISO 639-1 language codes to the codes used by opensubtitles.org's API
LANGUAGES =     {'sq':'alb',
         'ar':'ara',
         'hy':'arm',
         'ay':'ass',
         'bs':'bos',
         'pb':'pob',
         'bg':'bul',
         'ca':'cat',
         'zh':'chi',
         'hr':'hrv',
         'cs':'cze',
         'da':'dan',
         'nl':'dut',
         'en':'eng',
         'eo':'epo',
         'et':'est',
         'fi':'fin',
         'fr':'fre',
         'gl':'glg',
         'ka':'geo',
         'de':'ger',
         'el':'ell',
         'he':'heb',
         'hi':'hin',
         'hu':'hun',
         'is':'ice',
         'id':'ind',
         'it':'ita',
         'ja':'jpn',
         'kk':'kaz',
         'ko':'kor',
         'lv':'lav',
         'lt':'lit',
         'lb':'ltz',
         'mk':'mac',
         'ms':'may',
         'no':'nor',
         'oc':'oci',
         'fa':'per',
         'pl':'pol',
         'pt':'por',
         'ro':'rum',
         'ru':'rus',
         'sr':'scc',
         'sk':'slo',
         'sl':'slv',
         'es':'spa',
         'sv':'swe',
         'th':'tha',
         'tr':'tur',
         'uk':'ukr',
         'vi':'vie',}

class SearchThread(threading.Thread):
    """
    This is the thread started when the dialog is searching for subtitles
    """
    def __init__(self, model):
        self.model = model
        self._done = False
        self._lock = threading.Lock()
        threading.Thread.__init__(self)

    def run(self):
        self.model.lock.acquire(True)
        self.model.results = self.model.os_search_subtitles()
        self.model.lock.release()
        self._done = True
    
    @property
    def done(self):
        """ Thread-safe property to know whether the query is done or not """
        self._lock.acquire(True)
        res = self._done
        self._lock.release()
        return res

class DownloadThread(threading.Thread):
    """
    This is the thread started when the dialog is downloading the subtitles.
    """
    def __init__(self, model, subtitle_id):
        self.model = model
        self.subtitle_id = subtitle_id
        self._done = False
        self._lock = threading.Lock()
        threading.Thread.__init__(self)

    def run(self):
        self.model.lock.acquire(True)
        self.model.subtitles = self.model.os_download_subtitles(self.subtitle_id)
        self.model.lock.release()
        self._done = True
    
    @property
    def done(self):
        """ Thread-safe property to know whether the query is done or not """
        self._lock.acquire(True)
        res = self._done
        self._lock.release()
        return res

# OpenSubtitles.org API abstraction

class OpenSubtitlesModel(object):
    """
    This contains the logic of the opensubtitles service.
    """
    def __init__(self, server):
        self.server = server
        self.token = None

        try:
            import locale
            self.lang = LANGUAGES[locale.getlocale()[0].split('_')[0]]
        except:
            self.lang = 'eng'
        self.hash = None
        self.size = 0

        self.lock = threading.Lock()
        self.results = []
        self.subtitles = ''

        self.message = ''

    def os_login(self, username='', password=''):
        """
        Logs into the opensubtitles web service and gets a valid token for
        the comming comunications. If we are already logged it only checks
        the if the token is still valid.

        @rtype : bool
        """
        result = None
        self.message = ''

        if self.token:
            # We have already logged-in before, check the connection
            try:
                result = self.server.NoOperation(self.token)
            except:
                pass
            if result and result['status'] != OK200:
                return True
        try:
            result = self.server.LogIn(username, password, self.lang, USER_AGENT)
        except:
            pass
        if result and result.get('status') == OK200:
            self.token = result.get('token')
            if self.token:
                return True

        self.message = _('Could not contact the OpenSubtitles website')

        return False

    def os_search_subtitles(self):
        """

        """
        self.message = ''
        if self.os_login():
            searchdata = {'sublanguageid': self.lang, 
                          'moviehash'    : self.hash, 
                          'moviebytesize': str(self.size)}
            try:
                result = self.server.SearchSubtitles(self.token, [searchdata])
            except xmlrpclib.ProtocolError:
                self.message = _('Could not contact the OpenSubtitles website')

            if result.get('data'):
                return result['data']
            else:
                self.message = _('No results found')

        return None

    def os_download_subtitles(self, subtitleId):
        """
        """
        self.message = ''
        if self.os_login():
            try:
                result = self.server.DownloadSubtitles(self.token, [subtitleId])
            except xmlrpclib.ProtocolError:
                self.message = _('Could not contact the OpenSubtitles website')

            if result and result.get('status') == OK200:
                try:
                    subtitle64 = result['data'][0]['data']
                except:
                    self.message = _('Could not contact the OpenSubtitles website')
                    return None

                import StringIO, gzip, base64
                subtitleDecoded = base64.decodestring(subtitle64)
                subtitleGzipped = StringIO.StringIO(subtitleDecoded)
                subtitleGzippedFile = gzip.GzipFile(fileobj=subtitleGzipped)

                return subtitleGzippedFile.read()

        return None


class OpenSubtitles(totem.Plugin):
    def __init__(self):
        totem.Plugin.__init__(self)
        self.dialog = None
        self.gconf_client = gconf.client_get_default()
        self.GCONF_BASE_DIR = "/apps/totem/plugins/opensubtitles/"
        self.GCONF_LANGUAGE = "language"

    # totem.Plugin methods

    def activate(self, totem_object):
        """
        Called when the plugin is activated.
        Here the sidebar page is initialized(set up the treeview, connect 
        the callbacks, ...) and added to totem.

        @param totem_object:
        @type  totem_object: {totem.TotemObject}
        """
        self.totem = totem_object
    self.filename = None

        self.manager = self.totem.get_ui_manager()
        self.os_append_menu()

        self.totem.connect('file-opened', self.on_totem__file_opened)
        self.totem.connect('file-closed', self.on_totem__file_closed)

    # Obtain the ServerProxy and init the model
        server = xmlrpclib.Server('http://api.opensubtitles.org/xml-rpc')
        self.model = OpenSubtitlesModel(server)

    def deactivate(self, totem):
        if self.dialog:
            self.dialog.destroy()
        self.dialog = None
    
        self.os_delete_menu()

    # UI related code

    def os_build_dialog(self, action, totem_object):
        builder = self.load_interface("opensubtitles.ui", 
                                       True, 
                                       self.totem.get_main_window(), 
                                       self)

        # Obtain all the widgets we need to initialize
        combobox =       builder.get_object('language_combobox')
        languages =      builder.get_object('language_model')
        self.progress =  builder.get_object('progress_bar')
        self.treeview =  builder.get_object('subtitle_treeview')
        self.liststore = builder.get_object('subtitle_model')
        self.dialog =    builder.get_object('subtitles_dialog')
    self.find_button = builder.get_object('find_button')
    self.apply_button = builder.get_object('apply_button')
    self.close_button = builder.get_object('close_button')

        # Set up and populate the languages combobox
        renderer = gtk.CellRendererText()
        sorted_languages = gtk.TreeModelSort(languages)
        sorted_languages.set_sort_column_id(0, gtk.SORT_ASCENDING)
        combobox.set_model(sorted_languages)
        combobox.pack_start(renderer, True)
        combobox.add_attribute(renderer, 'text', 0)

        self.model.lang = self.gconf_get_str (self.GCONF_BASE_DIR + self.GCONF_LANGUAGE, self.model.lang)
        for lang in LANGUAGES_STR:
            it = languages.append(lang)
            if LANGUAGES[lang[1]] == self.model.lang:
                parentit = sorted_languages.convert_child_iter_to_iter (None, it)
                combobox.set_active_iter(parentit)

        # Set up the results treeview 
        renderer = gtk.CellRendererText()
        self.treeview.set_model(self.liststore)
        self.treeview.set_headers_visible(False)
        renderer.set_property('ellipsize', pango.ELLIPSIZE_END)
        column = gtk.TreeViewColumn(_("Subtitles"), renderer, text=0)
        column.set_resizable(True)
        column.set_expand(True)
        self.treeview.append_column(column)
    # translators comment:
    # This is the file-type of the subtitle file detected
        column = gtk.TreeViewColumn(_("Format"), renderer, text=1)
        column.set_resizable(False)
        self.treeview.append_column(column)
    # translators comment:
    # This is a rating of the quality of the subtitle
        column = gtk.TreeViewColumn(_("Rating"), renderer, text=2)
        column.set_resizable(False)
        self.treeview.append_column(column)

    self.apply_button.set_sensitive(False)

        self.apply_button.connect('clicked', self.on_apply_clicked)
        self.find_button.connect('clicked', self.on_find_clicked)
        self.close_button.connect('clicked', self.on_close_clicked)

    # Set up signals

        combobox_changed_id = combobox.connect('changed', self.on_combobox__changed)
    self.dialog.connect ('delete-event', self.dialog.hide_on_delete)
    self.dialog.set_transient_for (self.totem.get_main_window())
    self.dialog.set_position (gtk.WIN_POS_CENTER_ON_PARENT)

    # Connect the callbacks
    self.dialog.connect ('key-press-event', self.on_window__key_press_event)
        self.treeview.get_selection().connect('changed', self.on_treeview__row_change)
        self.treeview.connect('row-activated', self.on_treeview__row_activate)

    def os_show_dialog(self, action, totem_object):
        if not self.dialog:
            self.os_build_dialog(action, totem_object)

        filename = self.totem.get_current_mrl()
        if not self.model.results or filename != self.filename:
            self.filename = filename

        self.dialog.show_all()

    self.progress.set_fraction(0.0)

    def os_append_menu(self):
        """
        """
    
        self.os_action_group = gtk.ActionGroup('OpenSubtitles')

        self.action = gtk.Action('opensubtitles',
                             _('_Download Movie Subtitles...'),
                             _("Download movie subtitles from OpenSubtitles"),
                             '')

        self.os_action_group.add_action(self.action)

        self.manager.insert_action_group(self.os_action_group, 0)

        self.menu_id = self.manager.new_merge_id()
        self.manager.add_ui(self.menu_id,
                             '/tmw-menubar/view/subtitles/subtitle-download-placeholder',
                             'opensubtitles',
                             'opensubtitles',
                             gtk.UI_MANAGER_MENUITEM,
                             False
                            )
        self.action.set_visible(True)

        self.manager.ensure_update()

        self.action.connect('activate', self.os_show_dialog, self.totem)

        self.action.set_sensitive(self.totem.is_playing() and
                  self.os_check_allowed_scheme() and
                                  not self.os_check_is_audio())

    def os_check_allowed_scheme(self):
        scheme = gio.File(self.totem.get_current_mrl()).get_uri_scheme()
        if scheme == 'dvd' or scheme == 'http' or scheme == 'dvb' or scheme == 'vcd':
            return False
        return True

    def os_check_is_audio(self):
        # FIXME need to use something else here
        # I think we must use video widget metadata but I don't found a way 
    # to get this info from python
        filename = self.totem.get_current_mrl()
        if gio.content_type_guess(filename).split('/')[0] == 'audio':
            return True
        return False

    def os_delete_menu(self):
        self.manager.remove_action_group(self.os_action_group)
        self.manager.remove_ui(self.menu_id)

    def os_get_results(self):
        """
        """
        self.liststore.clear()
    self.treeview.set_headers_visible(False)
        self.model.results = []
        self.apply_button.set_sensitive(False)
    self.find_button.set_sensitive(False)        

        self.dialog.window.set_cursor(gtk.gdk.Cursor(gtk.gdk.WATCH))

        thread = SearchThread(self.model)
        thread.start()
        gobject.idle_add(self.os_populate_treeview)

        self.progress.set_text(_('Searching subtitles...'))
        gobject.timeout_add(350, self.os_progress_bar_increment, thread)

    def os_populate_treeview(self):
        """
        """
        if self.model.lock.acquire(False) == False:
            return True

        if self.model.results:
            self.apply_button.set_sensitive(True)
            for subData in self.model.results:
        if not SUBTITLES_EXT.count(subData['SubFormat']):
            continue
                self.liststore.append([subData['SubFileName'], subData['SubFormat'], subData['SubRating'], subData['IDSubtitleFile'],])
            self.treeview.set_headers_visible(True)
        else:
            self.apply_button.set_sensitive(False)

        self.model.lock.release()

        self.dialog.window.set_cursor(None)

        return False

    def os_save_selected_subtitle(self, filename=None):
        """
        """
        self.dialog.window.set_cursor(gtk.gdk.Cursor(gtk.gdk.WATCH))

        model, rows = self.treeview.get_selection().get_selected_rows()
        if rows:
            iter = model.get_iter(rows[0])
            subtitle_id = model.get_value(iter, 3)
            subtitle_format = model.get_value(iter, 1)

            gfile = None

            if not filename:
                directory = gio.File(xdg.BaseDirectory.xdg_cache_home + sep + 'totem' + sep + 'subtitles' + sep) 
                if not directory.query_exists():
                    if not path.exists (xdg.BaseDirectory.xdg_cache_home + sep + 'totem' + sep):
                        mkdir (xdg.BaseDirectory.xdg_cache_home + sep + 'totem' + sep)
                    if not path.exists (xdg.BaseDirectory.xdg_cache_home + sep + 'totem' + sep + 'subtitles' + sep):
                        mkdir (xdg.BaseDirectory.xdg_cache_home + sep + 'totem' + sep + 'subtitles' + sep)
                    # FIXME: We can't use this function until we depend on GLib (PyGObject) 2.18
                    # directory.make_directory_with_parents()

                file = gio.File(self.filename)
                movie_name = file.get_basename().rpartition('.')[0]
                filename = directory.get_uri() + sep + movie_name + '.' + subtitle_format

            self.model.subtitles = ''

            thread = DownloadThread(self.model, subtitle_id)
            thread.start()
            gobject.idle_add(self.os_save_subtitles, filename)

            self.progress.set_text(_('Downloading the subtitles...'))
            gobject.timeout_add(350, self.os_progress_bar_increment, thread)
        else:
            #warn user!
            pass

    def os_save_subtitles(self, filename):
        if self.model.lock.acquire(False) == False:
            return True

        if self.model.subtitles:
            # Delete all previous cached subtitle for this file 
            for ext in SUBTITLES_EXT:
        fp = gio.File(filename[:-3] + ext)
        if fp.query_exists():
                    fp.delete()

            fp = gio.File(filename)
            suburi = fp.get_uri ()

            subFile  = fp.replace('', False)
            subFile.write(self.model.subtitles)
            subFile.close()

        self.model.lock.release()

        self.dialog.window.set_cursor(None)

        if suburi:
            self.totem.set_current_subtitle(suburi)

        return False

    def os_progress_bar_increment(self, thread):

        if not thread.done:
            self.progress.pulse()
            return True

        if self.model.message:
            self.progress.set_text(self.model.message)
        else:
            self.progress.set_text('')
    
    self.progress.set_fraction(0.0)
    self.find_button.set_sensitive(True)
        self.apply_button.set_sensitive(False)
        self.treeview.set_sensitive(True)
        return False

    def os_download_and_apply(self):
        self.apply_button.set_sensitive(False)
        self.find_button.set_sensitive(False)
        self.action.set_sensitive(False)
        self.treeview.set_sensitive(False)
        self.os_save_selected_subtitle()

    # Callbacks

    def on_window__key_press_event(self, widget, event):
        if event.keyval == gtk.keysyms.Escape:
            self.dialog.destroy()
            self.dialog = None
            return True
        return False

    def on_treeview__row_change(self, selection):
        if selection.count_selected_rows() > 0:
            self.apply_button.set_sensitive(True)
        else:
            self.apply_button.set_sensitive(False)

    def on_treeview__row_activate(self, path, column, data):
    self.os_download_and_apply()

    def on_totem__file_opened(self, totem, filename):
        """
        """
        # Check if allows subtitles
    if self.os_check_allowed_scheme() and not self.os_check_is_audio():
            self.action.set_sensitive(True)
        if self.dialog:
            self.find_button.set_sensitive(True)
        self.filename = self.totem.get_current_mrl()
        self.liststore.clear()
            self.treeview.set_headers_visible(False)
            self.apply_button.set_sensitive(False)
        self.results = [] 
    else:
            self.action.set_sensitive(False)
        if self.dialog and self.dialog.is_active():
                self.liststore.clear()
            self.treeview.set_headers_visible(False)
            self.apply_button.set_sensitive(False)
            self.find_button.set_sensitive(False)

    def on_totem__file_closed(self, totem):
        self.action.set_sensitive(False)
        if self.dialog:
        self.apply_button.set_sensitive(False)
        self.find_button.set_sensitive(False)

    def on_combobox__changed(self, combobox):
        iter = combobox.get_active_iter()
        self.model.lang = LANGUAGES[combobox.get_model().get_value(iter, 1)]
        self.gconf_set_str(self.GCONF_BASE_DIR + self.GCONF_LANGUAGE,
                           self.model.lang)

    def on_close_clicked(self, data):
        self.dialog.destroy()
        self.dialog = None

    def on_apply_clicked(self, data):
    self.os_download_and_apply()

    def on_find_clicked(self, data):
        self.apply_button.set_sensitive(False)
        self.find_button.set_sensitive(False)
        self.filename = self.totem.get_current_mrl()
        self.model.hash , self.model.size = hashFile(self.filename)

        self.os_get_results()

    def gconf_get_str(self, key, default = ""):
        val = self.gconf_client.get(key)
        
        if val is not None and val.type == gconf.VALUE_STRING:
            return val.get_string()
        else:
            return default

    def gconf_set_str(self, key, val):
        self.gconf_client.set_string(key, val)


:: Command execute ::

Enter:
 
Select:
 

:: Search ::
  - regexp 

:: Upload ::
 
[ Read-Only ]

:: Make Dir ::
 
[ Read-Only ]
:: Make File ::
 
[ Read-Only ]

:: Go Dir ::
 
:: Go File ::
 

--[ c99shell v. 2.0 [PHP 7 Update] [25.02.2019] maintained by KaizenLouie | C99Shell Github | Generation time: 0.009 ]--