Advertisement
Guest User

Traduction Vkontakte

a guest
Jul 2nd, 2011
381
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 9.17 KB | None | 0 0
  1. # - encoding: utf8 -
  2. #
  3. # Copyright © 2010 Alexey Grunichev
  4. #
  5. # This program is free software: you can redistribute it and/or modify
  6. # it under the terms of the GNU General Public License as published by
  7. # the Free Software Foundation, either version 3 of the License, or
  8. # (at your option) any later version.
  9. #
  10. # This program is distributed in the hope that it will be useful,
  11. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13. # GNU General Public License for more details.
  14. #
  15. # You should have received a copy of the GNU General Public License
  16. # along with this program.  If not, see <http://www.gnu.org/licenses/>.
  17.  
  18. import rb, rhythmdb
  19. import gobject, gtk, glib, os
  20. import shutil, tempfile
  21. from VkontakteSearch import VkontakteSearch
  22. from VkontakteConfig import VkontakteConfig
  23. import rhythmdb
  24.    
  25. class VkontakteSource(rb.Source):
  26.     def __init__(self):
  27.         rb.Source.__init__(self)
  28.         self.config = VkontakteConfig()
  29.         self.initialised = False
  30.         self.downloading = False
  31.         self.download_queue = []
  32.         self.__load_current_size = 0
  33.         self.__load_total_size = 0
  34.         self.error_msg = ''
  35.    
  36.     def initialise(self):
  37.         shell = self.props.shell
  38.        
  39.         self.entry_view = rb.EntryView(shell.props.db, shell.get_player(), "", True, False)
  40.        
  41.         query_model = rhythmdb.QueryModel()
  42.         self.props.query_model = query_model
  43.        
  44.         self.entry_view.append_column(rb.ENTRY_VIEW_COL_TITLE, True)
  45.         self.entry_view.append_column(rb.ENTRY_VIEW_COL_ARTIST, False)
  46.         self.entry_view.append_column(rb.ENTRY_VIEW_COL_DURATION, False)
  47.         self.entry_view.set_sorting_order("Title", gtk.SORT_ASCENDING)
  48.         self.entry_view.set_model(query_model)
  49.         self.entry_view.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
  50.         self.entry_view.set_shadow_type(gtk.SHADOW_IN)
  51.        
  52.         # Set up the search bar and button UI. This could probably be done in a better way.
  53.         search_entry = gtk.combo_box_entry_new_text()
  54.         self.search_button = gtk.Button("Recherche")
  55.         alignment = gtk.Alignment()
  56.         alignment.add(self.search_button)
  57.         hbox = gtk.HBox()
  58.         hbox.pack_start(search_entry)
  59.         hbox.pack_start(alignment)
  60.         hbox.set_child_packing(search_entry, True, True, 0, gtk.PACK_START)
  61.         hbox.set_child_packing(alignment, True, True, 2, gtk.PACK_START)
  62.         vbox = gtk.VBox()
  63.         vbox.pack_start(hbox)
  64.         vbox.set_child_packing(hbox, False, False, 2, gtk.PACK_START)
  65.         vbox.pack_start(self.entry_view)
  66.         self.add(vbox)
  67.         self.show_all()
  68.        
  69.         self.search_button.connect("clicked", self.on_search_button_clicked, search_entry)
  70.         search_entry.child.set_activates_default(True)
  71.         search_entry.connect("changed", self.on_search_entry_changed)
  72.         self.search_button.set_flags(gtk.CAN_DEFAULT)
  73.        
  74.         self.searches = {} # Dictionary of searches, with the search term as keys
  75.         self.current_search = "" # The search term of the search results currently being shown
  76.  
  77.         ev = self.get_entry_view()
  78.         ev.connect_object("show_popup", self.show_popup_cb, self, 0)
  79.        
  80.         action = gtk.Action ('CopyURL', 'Copier le lien', 'Copier le lien dans le presse-papier', "")
  81.         action.connect ('activate', self.copy_url, shell)
  82.         action2 = gtk.Action ('Download', 'Télécharger', 'Télécharger', "")
  83.         action2.connect ('activate', self.download, shell)
  84.         action_group = gtk.ActionGroup ('VkontakteSourceViewPopup')
  85.         action_group.add_action (action)
  86.         action_group.add_action (action2)
  87.         shell.get_ui_manager().insert_action_group (action_group)
  88.        
  89.         popup_ui = """
  90. <ui>
  91.  <popup name="VkontakteSourceViewPopup">
  92.    <menuitem name="CopyURL" action="CopyURL"/>
  93.    <menuitem name="Download" action="Download"/>
  94.    <separator/>
  95.  </popup>
  96. </ui>
  97. """
  98.  
  99.         self.ui_id = shell.get_ui_manager().add_ui_from_string(popup_ui)
  100.         shell.get_ui_manager().ensure_update()
  101.        
  102.         self.initialised = True
  103.        
  104.     def do_impl_get_entry_view(self):
  105.         return self.entry_view
  106.    
  107.     def do_impl_activate(self):
  108.         if not self.initialised:
  109.             self.initialise()
  110.         self.search_button.grab_default()
  111.            
  112.     def do_impl_get_status(self):
  113.         if self.error_msg:
  114.             error_msg = self.error_msg
  115.             self.error_msg = ''
  116.             return (error_msg, "", 1)
  117.         if self.downloading:
  118.             if self.__load_total_size > 0:
  119.                 # Got data
  120.                 progress = min (float(self.__load_current_size) / self.__load_total_size, 1.0)
  121.             else:
  122.                 # Download started, no data yet received
  123.                 progress = -1.0
  124.             str = "Téléchargement : %s" % self.filename[:70]
  125.             if self.download_queue:
  126.                 str += " (%s fichiers en attente)" % len(self.download_queue)
  127.             return (str, "", progress)
  128.         if self.current_search:
  129.             if self.searches[self.current_search].is_complete():
  130.                 return (self.props.query_model.compute_status_normal("%d résultat trouvé", "%d résultats trouvés"), "", 1)
  131.             else:
  132.                 return ("Recherche \"{0}\"".format(self.current_search), "", -1)
  133.            
  134.         else:
  135.             return ("", "", 1)
  136.            
  137.     def do_impl_delete_thyself(self):
  138.         if self.initialised:
  139.             self.props.shell.props.db.entry_delete_by_type(self.props.entry_type)
  140.         rb.Source.do_impl_delete_thyself(self)
  141.        
  142.     def do_impl_can_add_to_queue(self):
  143.         return True
  144.        
  145.     def do_impl_can_pause(self):
  146.         return True
  147.        
  148.     def on_search_button_clicked(self, button, entry):
  149.         # Only do anything if there is text in the search entry
  150.         if entry.get_active_text():
  151.             entry_exists = entry.get_active_text() in self.searches
  152.             # sometimes links become obsolete, so, re-search enabled
  153.             self.searches[entry.get_active_text()] = VkontakteSearch(entry.get_active_text(), self.props.shell.props.db, self.props.entry_type)
  154.             # Start the search asynchronously
  155.             glib.idle_add(self.searches[entry.get_active_text()].start, priority=glib.PRIORITY_HIGH_IDLE)
  156.             # do not create new item in dropdown list if already exists
  157.             if not entry_exists:
  158.                 entry.prepend_text(entry.get_active_text())
  159.             # Update the entry view and source so the display the query model relevant to the current search
  160.             self.current_search = entry.get_active_text()
  161.             self.props.query_model = self.searches[self.current_search].query_model
  162.             self.entry_view.set_model(self.props.query_model)
  163.            
  164.     def on_search_entry_changed(self, entry):
  165.         if entry.get_active_text() in self.searches:
  166.             self.current_search = entry.get_active_text()
  167.             self.props.query_model = self.searches[self.current_search].query_model
  168.             self.entry_view.set_model(self.props.query_model)
  169.            
  170.     def show_popup_cb(self, source, some_int, some_bool):
  171.         self.show_source_popup("/VkontakteSourceViewPopup")
  172.  
  173.     def copy_url(self, action, shell):
  174.         download_url = shell.get_property("selected-source").get_entry_view().get_selected_entries()[0].get_playback_uri();
  175.         clipboard = gtk.clipboard_get()
  176.         clipboard.set_text(download_url)
  177.         clipboard.store()
  178.  
  179.     def download(self, action, shell):
  180.         for entry in shell.get_property("selected-source").get_entry_view().get_selected_entries():
  181.             self.download_queue.append(entry)
  182.         if not self.downloading:
  183.             entry = self.download_queue.pop(0)
  184.             self._start_download(entry)
  185.  
  186.     def _start_download(self, entry):
  187.         shell = self.props.shell
  188.         self.download_url = entry.get_playback_uri()
  189.  
  190.         filemask = self.config.get('filemask')
  191.         artist = shell.props.db.entry_get(entry, rhythmdb.PROP_ARTIST)[:50].replace('/', '')
  192.         title = shell.props.db.entry_get(entry, rhythmdb.PROP_TITLE)[:50].replace('/', '')
  193.         filemask = filemask.replace('%A', artist)
  194.         filemask = filemask.replace('%T', title)
  195.  
  196.         self.filename = u"%s - %s" % (shell.props.db.entry_get(entry, rhythmdb.PROP_ARTIST), shell.props.db.entry_get(entry, rhythmdb.PROP_TITLE))
  197.         self.save_location = os.path.expanduser(filemask)
  198.         dir, file = os.path.split(self.save_location)
  199.         if not os.path.exists(dir):
  200.             try:
  201.                 os.makedirs(dir)
  202.             except:
  203.                 self.error_msg = "Impossible de créer ou d'accéder au répertoire. Vérifiez les paramètres (Édition => Greffons => Configurer...)"
  204.                 self.notify_status_changed()
  205.                 return
  206.  
  207.         # Download file to the temporary folder
  208.         self.output_file = tempfile.NamedTemporaryFile(delete=False)
  209.         self.downloading = True
  210.         self.notify_status_changed()
  211.  
  212.         self.downloader = rb.ChunkLoader()
  213.         self.downloader.get_url_chunks(self.download_url, 64*1024, True, self.download_callback, self.output_file)
  214.  
  215.  
  216.     def download_callback (self, result, total, out):
  217.         if not result:
  218.             # Download finished
  219.             out.file.close()
  220.             self.__load_current_size = 0
  221.             self.downloading = False
  222.             # Move temporary file to the save location
  223.             try:
  224.                 shutil.move(out.name, self.save_location)
  225.             except:
  226.                 self.error_msg = "Impossible d'écrire dans le répertoire. Vérifiez les paramètres (Édition => Greffons => Configurer...)"
  227.                 self.notify_status_changed()
  228.                 return
  229.             if self.download_queue:
  230.                 entry = self.download_queue.pop(0)
  231.                 return self._start_download(entry)
  232.             else:
  233.                 self.downloading = False
  234.         elif isinstance(result, Exception):
  235.             # Exception occured - should be handled correctly
  236.             print 'Erreur durant le processus de téléchargement'
  237.             pass
  238.  
  239.         if self.downloading:
  240.             # Write to the file, update downloaded size
  241.             out.file.write(result)
  242.             self.__load_current_size += len(result)
  243.             self.__load_total_size = total
  244.  
  245.         self.notify_status_changed()
  246.        
  247.  
  248. gobject.type_register(VkontakteSource)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement