Esempio n. 1
0
 def __init__(self):
     rb.Source.__init__(self)
     self.config = VkontakteConfig()
     self.initialised = False
     self.downloading = False
     self.download_queue = []
     self.__load_current_size = 0
     self.__load_total_size = 0
     self.error_msg = ''
	def __init__(self):
		rb.Source.__init__(self)
		self.config = VkontakteConfig()
		self.initialised = False
		self.downloading = False
		self.download_queue = []
		self.__load_current_size = 0
		self.__load_total_size = 0
		self.error_msg = ''
class VkontakteSource(rb.Source):
	def __init__(self):
		rb.Source.__init__(self)
		self.config = VkontakteConfig()
		self.initialised = False
		self.downloading = False
		self.download_queue = []
		self.__load_current_size = 0
		self.__load_total_size = 0
		self.error_msg = ''
		self.user_download_dir=""
	
	def initialise(self):
		shell = self.props.shell
		
		self.entry_view = rb.EntryView(shell.props.db, shell.get_player(), "", True, False)
		query_model = rhythmdb.QueryModel()
		self.props.query_model = query_model
		
		self.entry_view.append_column(rb.ENTRY_VIEW_COL_TRACK_NUMBER, False)
		self.entry_view.append_column(rb.ENTRY_VIEW_COL_TITLE, True)
		self.entry_view.append_column(rb.ENTRY_VIEW_COL_ARTIST, False)
		self.entry_view.append_column(rb.ENTRY_VIEW_COL_DURATION, False)
		self.entry_view.set_sorting_order("Title", gtk.SORT_ASCENDING)
		self.entry_view.set_columns_clickable(False)
		self.entry_view.set_model(query_model)
		self.entry_view.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
		self.entry_view.set_shadow_type(gtk.SHADOW_IN)

		#UI
		self.builder=gtk.Builder()
		self.builder.add_from_file(DATA_DIR+"/main.ui")
		#combobox with type sort
		list_store=gtk.ListStore(str)
		list_store.append(["By duration"])
		list_store.append(["By popularity"])

		self.combobox=self.builder.get_object("sort_type_combobox")
		self.combobox.set_model(list_store)
		renderer_text = gtk.CellRendererText()
		self.combobox.pack_start(renderer_text, True)
		self.combobox.add_attribute(renderer_text, "text", 0)
		self.combobox.set_active(self.config.get("sort_type")-1)
		#buttons,entry
		self.search_button=self.builder.get_object("search_button")
		pref_button=self.builder.get_object("pref_button")
		my_audio_button=self.builder.get_object("my_audio_button")
		search_entry = gtk.combo_box_entry_new_text()
		search_entry.child.set_activates_default(True)
		search_entry.connect("changed", self.on_search_entry_changed)
		#boxes
		search_entry_box=self.builder.get_object("search_entry_box")
		search_entry_box.pack_start(search_entry)
		main_box=self.builder.get_object("main_box")

		vbox = gtk.VBox()
		vbox.pack_start(main_box)
		vbox.set_child_packing(main_box, False, False, 0, gtk.PACK_START)
		vbox.pack_start(self.entry_view)
		self.add(vbox)
		self.show_all()
		#connect signals
		self.combobox.connect("changed",lambda x: self.config.set("sort_type",self.combobox.get_active()+1))
		self.search_button.connect("clicked", self.on_search_button_clicked, search_entry)
		pref_button.connect("clicked", self.on_pref_button_clicked, search_entry)
		my_audio_button.connect("clicked", self.on_my_audio_button_clicked, search_entry)
		#
		
		self.searches = {} # Dictionary of searches, with the search term as keys
		self.current_search = "" # The search term of the search results currently being shown

		ev = self.get_entry_view()
		ev.connect_object("show_popup", self.show_popup_cb, self, 0)
		
		action = gtk.Action ('CopyURL', 'Copy URL', 'Copy URL to Clipboard', "")
		action.connect ('activate', self.copy_url, shell)
		action2 = gtk.Action ('Download', 'Download', 'Download', "")
		action2.connect ('activate', self.download, shell)
		action_group = gtk.ActionGroup ('VkontakteSourceViewPopup')
		action_group.add_action (action)
		action_group.add_action (action2)
		shell.get_ui_manager().insert_action_group (action_group)
		
		popup_ui = """
<ui>
  <popup name="VkontakteSourceViewPopup">
    <menuitem name="CopyURL" action="CopyURL"/>
    <menuitem name="Download" action="Download"/>
    <separator/>
  </popup>
</ui>
"""

		self.ui_id = shell.get_ui_manager().add_ui_from_string(popup_ui)
		shell.get_ui_manager().ensure_update()
		
		self.initialised = True
		
	def do_impl_get_entry_view(self):
		return self.entry_view
	
	# rhyhtmbox api break up (0.13.2 - 0.13.3)
	def do_impl_activate(self):
		self.do_selected()

	def do_selected(self):
		if not self.initialised:
			self.initialise()
		self.search_button.grab_default()

	# rhyhtmbox api break up (0.13.2 - 0.13.3)
	def do_impl_get_status(self):
		return self.do_get_status()

	def do_get_status(self):
		if self.error_msg:
			error_msg = self.error_msg
			self.error_msg = ''
			return (error_msg, "", 1)
		if self.downloading:
			if self.__load_total_size > 0:
				# Got data
				progress = min (float(self.__load_current_size) / self.__load_total_size, 1.0)
			else:
				# Download started, no data yet received
				progress = -1.0
			str = "Downloading %s" % self.filename[:70]
			if self.download_queue:
				str += " (%s files more in queue)" % len(self.download_queue)
			return (str, "", progress)
		if self.current_search:
			if self.searches[self.current_search].is_complete():
				return (self.props.query_model.compute_status_normal("Found %d result", "Found %d results"), "", 1)
			else:
				return ("Searching for \"{0}\"".format(self.current_search), "", -1)
			
		else:
			return ("", "", 1)
			
	def do_impl_delete_thyself(self):
		if self.initialised:
			self.props.shell.props.db.entry_delete_by_type(self.props.entry_type)
		rb.Source.do_impl_delete_thyself(self)
		
	def do_impl_can_add_to_queue(self):
		return True
		
	def do_impl_can_pause(self):
		return True
		
	def on_search_button_clicked(self, button, entry):
		# Only do anything if there is text in the search entry
		if entry.get_active_text():
			entry_exists = entry.get_active_text() in self.searches
			# sometimes links become obsolete, so, re-search enabled
			self.searches[entry.get_active_text()] = VkontakteSearch(entry.get_active_text(), self.props.shell.props.db, self.props.entry_type, self.config)
			# Start the search asynchronously
			glib.idle_add(self.searches[entry.get_active_text()].start, priority=glib.PRIORITY_HIGH_IDLE)
			# do not create new item in dropdown list if already exists
			if not entry_exists:
				entry.prepend_text(entry.get_active_text())
			# Update the entry view and source so the display the query model relevant to the current search
			self.current_search = entry.get_active_text()
			self.props.query_model = self.searches[self.current_search].query_model
			if self.config.get("sort_type")==1:
				self.entry_view.set_sorting_order("Time", gtk.SORT_DESCENDING)
			else:
				self.entry_view.set_sorting_order("Track", gtk.SORT_ASCENDING)
			self.entry_view.set_model(self.props.query_model)
				


	def on_pref_button_clicked(self, button, entry):
		self.config = VkontakteConfig()
		builder_file = DATA_DIR+"/preferences.ui"
		dialog = VkontakteConfigDialog (builder_file, self.config).get_dialog()
		dialog.present()
		
	def on_my_audio_button_clicked(self, button, entry):
		entry_exists = "MY LIBRARY AT VK.COM" in self.searches
		self.searches["MY LIBRARY AT VK.COM"] = VkontakteMyLibrary(self.props.shell.props.db, self.props.entry_type,self.config)
		# Start the search asynchronously
		glib.idle_add(self.searches["MY LIBRARY AT VK.COM"].start, priority=glib.PRIORITY_HIGH_IDLE)
		# do not create new item in dropdown list if already exists
		if not entry_exists:
			entry.prepend_text("MY LIBRARY AT VK.COM")
		# Update the entry view and source so the display the query model relevant to the current search
		self.current_search = "MY LIBRARY AT VK.COM"
		self.props.query_model = self.searches["MY LIBRARY AT VK.COM"].query_model
		self.entry_view.set_model(self.props.query_model)
	

	def on_search_entry_changed(self, entry):
		if entry.get_active_text() in self.searches:
			self.current_search = entry.get_active_text()
			self.props.query_model = self.searches[self.current_search].query_model
			self.entry_view.set_model(self.props.query_model)
			
	def show_popup_cb(self, source, some_int, some_bool):
		# rhythmbox api break up (0.13.2 - 0.13.3)
		if hasattr(self, 'show_source_popup'):
			self.show_source_popup("/VkontakteSourceViewPopup")
		else:
			self.show_page_popup("/VkontakteSourceViewPopup")

	def copy_url(self, action, shell):
		# rhythmbox api break up (0.13.2 - 0.13.3)
		try:
			selected_source = shell.get_property("selected-source")
		except:
			selected_source = shell.get_property("selected-page")
		download_url = selected_source.get_entry_view().get_selected_entries()[0].get_playback_uri();
		clipboard = gtk.clipboard_get()
		clipboard.set_text(download_url)
		clipboard.store()

	def download(self, action, shell):
		# rhythmbox api break up (0.13.2 - 0.13.3)
		try:
			selected_source = shell.get_property("selected-source")
		except:
			selected_source = shell.get_property("selected-page")
		if self.config.get("allways_ask_path"):
			directory=self.query_folder()
			if directory==None:
				return
			self.user_download_dir=directory
			
		for entry in selected_source.get_entry_view().get_selected_entries():
			self.download_queue.append(entry)
		if not self.downloading:
			entry = self.download_queue.pop(0)
			self._start_download(entry)

	def query_folder(self):
 		chooser = gtk.FileChooserDialog(title="Save to folder",action=gtk.FILE_CHOOSER_ACTION_SELECT_FOLDER,
                                  buttons=(gtk.STOCK_CANCEL,gtk.RESPONSE_CANCEL,gtk.STOCK_OPEN,gtk.RESPONSE_OK))
		chooser.set_default_response(gtk.RESPONSE_OK)
		chooser.set_current_folder(self.config.get("save_to_dir"))
		response = chooser.run()
		directory=None
		if response == gtk.RESPONSE_OK:
			directory=chooser.get_current_folder()
		chooser.destroy()
		return directory

	def _start_download(self, entry):
		shell = self.props.shell
		self.download_url = entry.get_playback_uri()

		filemask = self.config.get('filemask')
		artist = shell.props.db.entry_get(entry, rhythmdb.PROP_ARTIST)[:50].replace('/', '')
		title = shell.props.db.entry_get(entry, rhythmdb.PROP_TITLE)[:50].replace('/', '')
		filemask = filemask.replace('%A', artist)
		filemask = filemask.replace('%T', title)
		if not self.config.get("allways_ask_path"):
			filemask=self.config.get("save_to_dir")+"/"+filemask
		else:

			filemask=self.user_download_dir+"/"+filemask
		self.filename = u"%s - %s" % (shell.props.db.entry_get(entry, rhythmdb.PROP_ARTIST), shell.props.db.entry_get(entry, rhythmdb.PROP_TITLE))
		self.save_location = os.path.expanduser(filemask)
		dir, file = os.path.split(self.save_location)
		if not os.path.exists(dir):
			try:
				os.makedirs(dir)
			except:
				self.error_msg = "Can't create or access directory. Check settings (Edit => Plugins => Configure)"
				self.notify_status_changed()
				return

		# Download file to the temporary folder
		self.output_file = tempfile.NamedTemporaryFile(delete=False)
		self.downloading = True
		self.notify_status_changed()

		self.downloader = rb.ChunkLoader()
		self.downloader.get_url_chunks(self.download_url, 64 * 1024, True, self.download_callback, self.output_file)


	def download_callback (self, result, total, out):
		if not result:
			# Download finished
			out.file.close()
			self.__load_current_size = 0
			self.downloading = False
			# Move temporary file to the save location
			try:
				shutil.move(out.name, self.save_location)
			except:
				self.error_msg = "Can't write to directory. Check settings (Edit => Plugins => Configure)"
				self.notify_status_changed()
				return
			if self.download_queue:
				entry = self.download_queue.pop(0)
				return self._start_download(entry)
			else:
				self.downloading = False
		elif isinstance(result, Exception):
			# Exception occured - should be handled correctly
			print 'Error during downloading process happened'
			pass

		if self.downloading:
			# Write to the file, update downloaded size
			out.file.write(result)
			self.__load_current_size += len(result)
			self.__load_total_size = total

		self.notify_status_changed()
	def on_pref_button_clicked(self, button, entry):
		self.config = VkontakteConfig()
		builder_file = DATA_DIR+"/preferences.ui"
		dialog = VkontakteConfigDialog (builder_file, self.config).get_dialog()
		dialog.present()
class VkontakteSource(rb.Source):
	def __init__(self):
		rb.Source.__init__(self)
		self.config = VkontakteConfig()
		self.initialised = False
		self.downloading = False
		self.download_queue = []
		self.__load_current_size = 0
		self.__load_total_size = 0
		self.error_msg = ''
	
	def initialise(self):
		shell = self.props.shell
		
		self.entry_view = rb.EntryView(shell.props.db, shell.get_player(), "", True, False)
		
		query_model = rhythmdb.QueryModel()
		self.props.query_model = query_model
		
		self.entry_view.append_column(rb.ENTRY_VIEW_COL_TITLE, True)
		self.entry_view.append_column(rb.ENTRY_VIEW_COL_ARTIST, False)
		self.entry_view.append_column(rb.ENTRY_VIEW_COL_DURATION, False)
		self.entry_view.set_sorting_order("Title", gtk.SORT_ASCENDING)
		self.entry_view.set_model(query_model)
		self.entry_view.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
		self.entry_view.set_shadow_type(gtk.SHADOW_IN)
		
		# Set up the search bar and button UI. This could probably be done in a better way.
		search_entry = gtk.combo_box_entry_new_text()
		self.search_button = gtk.Button("Search")
		alignment = gtk.Alignment()
		alignment.add(self.search_button)
		hbox = gtk.HBox()
		hbox.pack_start(search_entry)
		hbox.pack_start(alignment)
		hbox.set_child_packing(search_entry, True, True, 0, gtk.PACK_START)
		hbox.set_child_packing(alignment, True, True, 2, gtk.PACK_START)
		vbox = gtk.VBox()
		vbox.pack_start(hbox)
		vbox.set_child_packing(hbox, False, False, 2, gtk.PACK_START)
		vbox.pack_start(self.entry_view)
		self.add(vbox)
		self.show_all()
		
		self.search_button.connect("clicked", self.on_search_button_clicked, search_entry)
		search_entry.child.set_activates_default(True)
		search_entry.connect("changed", self.on_search_entry_changed)
		self.search_button.set_flags(gtk.CAN_DEFAULT)
		
		self.searches = {} # Dictionary of searches, with the search term as keys
		self.current_search = "" # The search term of the search results currently being shown

		ev = self.get_entry_view()
		ev.connect_object("show_popup", self.show_popup_cb, self, 0)
		
		action = gtk.Action ('CopyURL', 'Copy URL', 'Copy URL to Clipboard', "")
		action.connect ('activate', self.copy_url, shell)
		action2 = gtk.Action ('Download', 'Download', 'Download', "")
		action2.connect ('activate', self.download, shell)
		action_group = gtk.ActionGroup ('VkontakteSourceViewPopup')
		action_group.add_action (action)
		action_group.add_action (action2)
		shell.get_ui_manager().insert_action_group (action_group)
		
		popup_ui = """
<ui>
  <popup name="VkontakteSourceViewPopup">
    <menuitem name="CopyURL" action="CopyURL"/>
    <menuitem name="Download" action="Download"/>
    <separator/>
  </popup>
</ui>
"""

		self.ui_id = shell.get_ui_manager().add_ui_from_string(popup_ui)
		shell.get_ui_manager().ensure_update()
		
		self.initialised = True
		
	def do_impl_get_entry_view(self):
		return self.entry_view
	
	def do_impl_activate(self):
		if not self.initialised:
			self.initialise()
		self.search_button.grab_default()
			
	def do_impl_get_status(self):
		if self.error_msg:
			error_msg = self.error_msg
			self.error_msg = ''
			return (error_msg, "", 1)
		if self.downloading:
			if self.__load_total_size > 0:
				# Got data
				progress = min (float(self.__load_current_size) / self.__load_total_size, 1.0)
			else:
				# Download started, no data yet received
				progress = -1.0
			str = "Downloading %s" % self.filename[:70]
			if self.download_queue:
				str += " (%s files more in queue)" % len(self.download_queue)
			return (str, "", progress)
		if self.current_search:
			if self.searches[self.current_search].is_complete():
				return (self.props.query_model.compute_status_normal("Found %d result", "Found %d results"), "", 1)
			else:
				return ("Searching for \"{0}\"".format(self.current_search), "", -1)
			
		else:
			return ("", "", 1)
			
	def do_impl_delete_thyself(self):
		if self.initialised:
			self.props.shell.props.db.entry_delete_by_type(self.props.entry_type)
		rb.Source.do_impl_delete_thyself(self)
		
	def do_impl_can_add_to_queue(self):
		return True
		
	def do_impl_can_pause(self):
		return True
		
	def on_search_button_clicked(self, button, entry):
		# Only do anything if there is text in the search entry
		if entry.get_active_text():
			entry_exists = entry.get_active_text() in self.searches
			# sometimes links become obsolete, so, re-search enabled
			self.searches[entry.get_active_text()] = VkontakteSearch(entry.get_active_text(), self.props.shell.props.db, self.props.entry_type)
			# Start the search asynchronously
			glib.idle_add(self.searches[entry.get_active_text()].start, priority=glib.PRIORITY_HIGH_IDLE)
			# do not create new item in dropdown list if already exists
			if not entry_exists:
				entry.prepend_text(entry.get_active_text())
			# Update the entry view and source so the display the query model relevant to the current search
			self.current_search = entry.get_active_text()
			self.props.query_model = self.searches[self.current_search].query_model
			self.entry_view.set_model(self.props.query_model)
			
	def on_search_entry_changed(self, entry):
		if entry.get_active_text() in self.searches:
			self.current_search = entry.get_active_text()
			self.props.query_model = self.searches[self.current_search].query_model
			self.entry_view.set_model(self.props.query_model)
			
	def show_popup_cb(self, source, some_int, some_bool):
		self.show_source_popup("/VkontakteSourceViewPopup")

	def copy_url(self, action, shell):
		download_url = shell.get_property("selected-source").get_entry_view().get_selected_entries()[0].get_playback_uri();
		clipboard = gtk.clipboard_get()
		clipboard.set_text(download_url)
		clipboard.store()

	def download(self, action, shell):
		for entry in shell.get_property("selected-source").get_entry_view().get_selected_entries():
			self.download_queue.append(entry)
		if not self.downloading:
			entry = self.download_queue.pop(0)
			self._start_download(entry)

	def _start_download(self, entry):
		shell = self.props.shell
		self.download_url = entry.get_playback_uri()

		filemask = self.config.get('filemask')
		artist = shell.props.db.entry_get(entry, rhythmdb.PROP_ARTIST)[:50].replace('/', '')
		title = shell.props.db.entry_get(entry, rhythmdb.PROP_TITLE)[:50].replace('/', '')
		filemask = filemask.replace('%A', artist)
		filemask = filemask.replace('%T', title)

		self.filename = u"%s - %s" % (shell.props.db.entry_get(entry, rhythmdb.PROP_ARTIST), shell.props.db.entry_get(entry, rhythmdb.PROP_TITLE))
		self.save_location = os.path.expanduser(filemask)
		dir, file = os.path.split(self.save_location)
		if not os.path.exists(dir):
			try:
				os.makedirs(dir)
			except:
				self.error_msg = "Can't create or access directory. Check settings (Edit => Plugins => Configure)"
				self.notify_status_changed()
				return

		# Download file to the temporary folder
		self.output_file = tempfile.NamedTemporaryFile(delete=False)
		self.downloading = True
		self.notify_status_changed()

		self.downloader = rb.ChunkLoader()
		self.downloader.get_url_chunks(self.download_url, 64*1024, True, self.download_callback, self.output_file)


	def download_callback (self, result, total, out):
		if not result:
			# Download finished
			out.file.close()
			self.__load_current_size = 0
			self.downloading = False
			# Move temporary file to the save location
			try:
				shutil.move(out.name, self.save_location)
			except:
				self.error_msg = "Can't write to directory. Check settings (Edit => Plugins => Configure)"
				self.notify_status_changed()
				return
			if self.download_queue:
				entry = self.download_queue.pop(0)
				return self._start_download(entry)
			else:
				self.downloading = False
		elif isinstance(result, Exception):
			# Exception occured - should be handled correctly
			print 'Error during downloading process happened'
			pass

		if self.downloading:
			# Write to the file, update downloaded size
			out.file.write(result)
			self.__load_current_size += len(result)
			self.__load_total_size = total

		self.notify_status_changed()
Esempio n. 6
0
class VkontakteSource(rb.Source):
    def __init__(self):
        rb.Source.__init__(self)
        self.config = VkontakteConfig()
        self.initialised = False
        self.downloading = False
        self.download_queue = []
        self.__load_current_size = 0
        self.__load_total_size = 0
        self.error_msg = ''

    def initialise(self):
        shell = self.props.shell

        self.entry_view = rb.EntryView(shell.props.db, shell.get_player(), "",
                                       True, False)

        query_model = rhythmdb.QueryModel()
        self.props.query_model = query_model

        self.entry_view.append_column(rb.ENTRY_VIEW_COL_TITLE, True)
        self.entry_view.append_column(rb.ENTRY_VIEW_COL_ARTIST, False)
        self.entry_view.append_column(rb.ENTRY_VIEW_COL_DURATION, False)
        self.entry_view.set_sorting_order("Title", gtk.SORT_ASCENDING)
        self.entry_view.set_model(query_model)
        self.entry_view.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
        self.entry_view.set_shadow_type(gtk.SHADOW_IN)

        # Set up the search bar and button UI. This could probably be done in a better way.
        search_entry = gtk.combo_box_entry_new_text()
        self.search_button = gtk.Button("Search")
        alignment = gtk.Alignment()
        alignment.add(self.search_button)
        hbox = gtk.HBox()
        hbox.pack_start(search_entry)
        hbox.pack_start(alignment)
        hbox.set_child_packing(search_entry, True, True, 0, gtk.PACK_START)
        hbox.set_child_packing(alignment, True, True, 2, gtk.PACK_START)
        vbox = gtk.VBox()
        vbox.pack_start(hbox)
        vbox.set_child_packing(hbox, False, False, 2, gtk.PACK_START)
        vbox.pack_start(self.entry_view)
        self.add(vbox)
        self.show_all()

        self.search_button.connect("clicked", self.on_search_button_clicked,
                                   search_entry)
        search_entry.child.set_activates_default(True)
        search_entry.connect("changed", self.on_search_entry_changed)
        self.search_button.set_flags(gtk.CAN_DEFAULT)

        self.searches = {
        }  # Dictionary of searches, with the search term as keys
        self.current_search = ""  # The search term of the search results currently being shown

        ev = self.get_entry_view()
        ev.connect_object("show_popup", self.show_popup_cb, self, 0)

        action = gtk.Action('CopyURL', 'Copy URL', 'Copy URL to Clipboard', "")
        action.connect('activate', self.copy_url, shell)
        action2 = gtk.Action('Download', 'Download', 'Download', "")
        action2.connect('activate', self.download, shell)
        action_group = gtk.ActionGroup('VkontakteSourceViewPopup')
        action_group.add_action(action)
        action_group.add_action(action2)
        shell.get_ui_manager().insert_action_group(action_group)

        popup_ui = """
<ui>
  <popup name="VkontakteSourceViewPopup">
    <menuitem name="CopyURL" action="CopyURL"/>
    <menuitem name="Download" action="Download"/>
    <separator/>
  </popup>
</ui>
"""

        self.ui_id = shell.get_ui_manager().add_ui_from_string(popup_ui)
        shell.get_ui_manager().ensure_update()

        self.initialised = True

    def do_impl_get_entry_view(self):
        return self.entry_view

    # rhyhtmbox api break up (0.13.2 - 0.13.3)
    def do_impl_activate(self):
        self.do_selected()

    def do_selected(self):
        if not self.initialised:
            self.initialise()
        self.search_button.grab_default()

    # rhyhtmbox api break up (0.13.2 - 0.13.3)
    def do_impl_get_status(self):
        return self.do_get_status()

    def do_get_status(self):
        if self.error_msg:
            error_msg = self.error_msg
            self.error_msg = ''
            return (error_msg, "", 1)
        if self.downloading:
            if self.__load_total_size > 0:
                # Got data
                progress = min(
                    float(self.__load_current_size) / self.__load_total_size,
                    1.0)
            else:
                # Download started, no data yet received
                progress = -1.0
            str = "Downloading %s" % self.filename[:70]
            if self.download_queue:
                str += " (%s files more in queue)" % len(self.download_queue)
            return (str, "", progress)
        if self.current_search:
            if self.searches[self.current_search].is_complete():
                return (self.props.query_model.compute_status_normal(
                    "Found %d result", "Found %d results"), "", 1)
            else:
                return ("Searching for \"{0}\"".format(self.current_search),
                        "", -1)

        else:
            return ("", "", 1)

    def do_impl_delete_thyself(self):
        if self.initialised:
            self.props.shell.props.db.entry_delete_by_type(
                self.props.entry_type)
        rb.Source.do_impl_delete_thyself(self)

    def do_impl_can_add_to_queue(self):
        return True

    def do_impl_can_pause(self):
        return True

    def on_search_button_clicked(self, button, entry):
        # Only do anything if there is text in the search entry
        if entry.get_active_text():
            entry_exists = entry.get_active_text() in self.searches
            # sometimes links become obsolete, so, re-search enabled
            self.searches[entry.get_active_text()] = VkontakteSearch(
                entry.get_active_text(), self.props.shell.props.db,
                self.props.entry_type)
            # Start the search asynchronously
            glib.idle_add(self.searches[entry.get_active_text()].start,
                          priority=glib.PRIORITY_HIGH_IDLE)
            # do not create new item in dropdown list if already exists
            if not entry_exists:
                entry.prepend_text(entry.get_active_text())
            # Update the entry view and source so the display the query model relevant to the current search
            self.current_search = entry.get_active_text()
            self.props.query_model = self.searches[
                self.current_search].query_model
            self.entry_view.set_model(self.props.query_model)

    def on_search_entry_changed(self, entry):
        if entry.get_active_text() in self.searches:
            self.current_search = entry.get_active_text()
            self.props.query_model = self.searches[
                self.current_search].query_model
            self.entry_view.set_model(self.props.query_model)

    def show_popup_cb(self, source, some_int, some_bool):
        # rhythmbox api break up (0.13.2 - 0.13.3)
        if hasattr(self, 'show_source_popup'):
            self.show_source_popup("/VkontakteSourceViewPopup")
        else:
            self.show_page_popup("/VkontakteSourceViewPopup")

    def copy_url(self, action, shell):
        # rhythmbox api break up (0.13.2 - 0.13.3)
        try:
            selected_source = shell.get_property("selected-source")
        except:
            selected_source = shell.get_property("selected-page")
        download_url = selected_source.get_entry_view().get_selected_entries(
        )[0].get_playback_uri()
        clipboard = gtk.clipboard_get()
        clipboard.set_text(download_url)
        clipboard.store()

    def download(self, action, shell):
        # rhythmbox api break up (0.13.2 - 0.13.3)
        try:
            selected_source = shell.get_property("selected-source")
        except:
            selected_source = shell.get_property("selected-page")
        for entry in selected_source.get_entry_view().get_selected_entries():
            self.download_queue.append(entry)
        if not self.downloading:
            entry = self.download_queue.pop(0)
            self._start_download(entry)

    def _start_download(self, entry):
        shell = self.props.shell
        self.download_url = entry.get_playback_uri()

        filemask = self.config.get('filemask')
        artist = shell.props.db.entry_get(entry,
                                          rhythmdb.PROP_ARTIST)[:50].replace(
                                              '/', '')
        title = shell.props.db.entry_get(entry,
                                         rhythmdb.PROP_TITLE)[:50].replace(
                                             '/', '')
        filemask = filemask.replace('%A', artist)
        filemask = filemask.replace('%T', title)

        self.filename = u"%s - %s" % (
            shell.props.db.entry_get(entry, rhythmdb.PROP_ARTIST),
            shell.props.db.entry_get(entry, rhythmdb.PROP_TITLE))
        self.save_location = os.path.expanduser(filemask)
        dir, file = os.path.split(self.save_location)
        if not os.path.exists(dir):
            try:
                os.makedirs(dir)
            except:
                self.error_msg = "Can't create or access directory. Check settings (Edit => Plugins => Configure)"
                self.notify_status_changed()
                return

        # Download file to the temporary folder
        self.output_file = tempfile.NamedTemporaryFile(delete=False)
        self.downloading = True
        self.notify_status_changed()

        self.downloader = rb.ChunkLoader()
        self.downloader.get_url_chunks(self.download_url, 64 * 1024, True,
                                       self.download_callback,
                                       self.output_file)

    def download_callback(self, result, total, out):
        if not result:
            # Download finished
            out.file.close()
            self.__load_current_size = 0
            self.downloading = False
            # Move temporary file to the save location
            try:
                shutil.move(out.name, self.save_location)
            except:
                self.error_msg = "Can't write to directory. Check settings (Edit => Plugins => Configure)"
                self.notify_status_changed()
                return
            if self.download_queue:
                entry = self.download_queue.pop(0)
                return self._start_download(entry)
            else:
                self.downloading = False
        elif isinstance(result, Exception):
            # Exception occured - should be handled correctly
            print 'Error during downloading process happened'
            pass

        if self.downloading:
            # Write to the file, update downloaded size
            out.file.write(result)
            self.__load_current_size += len(result)
            self.__load_total_size = total

        self.notify_status_changed()
Esempio n. 7
0
    def __init__(self):
        self.config = VkontakteConfig()

        rb.Plugin.__init__(self)