def on_btn_remove_clicked(self, widget, *args): """ Clear the selected files in the tree. Also remove them from the core """ self.log.info("Clearing the selected files in the tree/core") # Get selected filenames selected_mp3_files = self.mp3_tree.get_selected_mp3_files() # If some of them are pending to update, ask the user what to do selected_pending_to_update = self.mp3_tree.pending_files_to_update(selected_mp3_files) remove_them = False if len(selected_pending_to_update) > 0: user_answer = message.question(_("Cleaning mp3 files"), _("Some selected <i>mp3</i> files are pending to update. Clean selected files anyway?"), self.GMusicTagger) if user_answer: remove_them = True else: remove_them = True # Finally if all agree, remove the selected files if remove_them: self.mp3_tree.remove_selected_iters() # Refresh the row APIC self.flush_active_row_mp3_apic()
def initialize_generic_tagging(self): """ Initialize all about the generic tag mode """ # Set Year SpinButton self.spinbutton_year = gtk.SpinButton() self.spinbutton_year.set_digits(0) year = int(time.strftime('%Y',time.localtime())) self.spinbutton_year.set_range(year-150,year+20) self.spinbutton_year.set_value(year) self.spinbutton_year.set_numeric(True) self.spinbutton_year.set_increments(1,1) self.spinbutton_year.show() self.hbox_generic_tag_TYER.pack_start(self.spinbutton_year) # Set Genre Combobox self.genre_model = listmodel.GenreListStore() self.cmbentry_genre = gtk.ComboBoxEntry(self.genre_model,0) genre_tooltip = _("Select the genre from the list or type your own") self.cmbentry_genre.set_tooltip_markup(genre_tooltip) self.cmbentry_genre.show() self.hbox_generic_tag_TCON.pack_start(self.cmbentry_genre) # Set Filename Combobox self.filename_model = listmodel.FilenameListStore() self.cmbentry_filename = gtk.ComboBoxEntry(self.filename_model,0) filename_tooltip = _("""Modify the <i>mp3</i> filename combining the frame markups (%artist,%title,%album and %trck) or by selecting a preconfigured template from the list bellow""") self.cmbentry_filename.set_tooltip_markup(filename_tooltip) self.cmbentry_filename.show() self.hbox_generic_tag_FILE.pack_start(self.cmbentry_filename) if self.config["generic-tag"]["active-at-start"]: self.on_btn_generic_tag_clicked(self.btn_generic_tag)
def selectMp3Files(parent=None,path=os.path.expanduser("~").decode(env.LOCALE_ENCODE)): """ Opens a FileChooserDialog with a mp3/m3u filter to choose one o more files Returns the selected files in a list """ mp3filter = gtk.FileFilter() mp3filter.set_name(_("Mp3 Files")) mp3filter.add_pattern("*.mp3") mp3filter.add_pattern("*.MP3") dialog = gtk.FileChooserDialog(_("Choose your files to edit"), parent, gtk.FILE_CHOOSER_ACTION_OPEN, (gtk.STOCK_CANCEL,gtk.RESPONSE_CANCEL, gtk.STOCK_OK,gtk.RESPONSE_OK)) dialog.set_select_multiple(True) dialog.add_filter(mp3filter) dialog.set_current_folder(path) response = dialog.run() if response == gtk.RESPONSE_OK: selected_mp3files = dialog.get_filenames() else: selected_mp3files = [] dialog.destroy() return selected_mp3files
def on_btn_play_clicked(self, btn_play): """ Get the seletect tracks on the tree and play them with the defined mp3 player (default 'totem') """ title = _("Music player") try: self.log.info("Play selected tracks") selected_track_list = self.mp3_tree.get_selected_mp3_files() selected_tracks = '' if len(selected_track_list) > 0: selected_tracks = '"' + '" "'.join(selected_track_list) + '"' play_command = "%s %s" % (self.config['music']['player'], selected_tracks) process = subprocess.Popen(play_command, shell = True, stdout = subprocess.PIPE, stderr = subprocess.PIPE) # Wait a bit to kwnon if the process failed inmediatily time.sleep(0.2) returncode = process.poll() if returncode: error_message = _("Cannot open music player:\n\n") stdout = ''.join(process.stdout.readlines()).replace("&","&") stderr = ''.join(process.stderr.readlines()).replace("&","&") error_message = "%s%s%s" % (error_message, stdout, stderr) message.error(title, error_message, self.GMusicTagger) except: self.log.exception("Error running music player") exception_message = _("Error running music player") message.exception(title, exception_message, self.GMusicTagger)
def on_GMusicTagger_delete_event(self, widget, *args): """ Check if one or more files are pending to be updated. Then, ask to the user for cancel or continue exiting the program """ stop_exit = False if self.mp3_tree.is_any_pending_to_update(): self.log.warning("Some files still pending for update. Continue?") user_answer = message.question(_("Exiting..."), _("Some files are pending to update. Continue exiting?"), self.GMusicTagger) if not user_answer: stop_exit = True return stop_exit
def on_btn_update_clicked(self, widget, *args): """ Retrieve the selected tracks on the tree and update the mp3 tag of each one. Also rename the file if the column 'file' has been changed. """ self.lock_app() total_updated = self.mp3_tree.update_selected_iters() self.unlock_app() # Show finish notification if total_updated and self.config['misc']['show-notifications']: notifier.show_notification(_("Update complete"), "%03d %s" % (total_updated, _("MP3 files updated...")))
def on_btn_fill_clicked(self, widget, *args): """ Apply the selected generic tag frames to the selected files on the tree """ self.log.debug("Apply generic tag button clicked") apply_generic_tag = message.question(_("Apply generic tag"), _("The generic tag is going to be applied on all the <i>mp3</i> files selected. Are you sure?"), self.GMusicTagger) if apply_generic_tag: self.log.info("Applying the selected generic tag frames") generic_tag_values = self.get_generic_tag_frame_values() self.mp3_tree.apply_generic_tag_on_selected(generic_tag_values)
def cancel_message(self): """ Shows a cancel message and the progressbar at 100% """ self.set_fraction(1.0) self.set_text(_("Action cancelled...")) while gtk.events_pending(): gtk.main_iteration()
def __init__(self): """ """ # VBox initialize gtk.VBox.__init__(self) # Utility widgets self.progressbar = ProgressBar() self.label = gtk.Label() self.label.set_ellipsize(pango.ELLIPSIZE_END) self.cancel_button = gtk.Button() self.cancel_button.set_relief(gtk.RELIEF_NONE) self.cancel_button.set_tooltip_text(_("Cancel this action")) stock_cancel_image = gtk.Image() stock_cancel_image.set_from_stock(gtk.STOCK_CANCEL,gtk.ICON_SIZE_BUTTON) self.cancel_button.set_image(stock_cancel_image) self.cancel_button.connect("clicked",self.__on_cancel_button_clicked) # Horizontal Container self.hbox = gtk.HBox() self.hbox.pack_start(self.progressbar,expand=True,fill=True) self.hbox.pack_start(self.cancel_button,expand=False,fill=False,padding=5) # Pack all the widgets self.pack_start(self.label,expand=False,fill=False,padding=10) self.pack_start(self.hbox,expand=False,fill=False) # Perform a show on all widget and hide them self.show_all() self.hide()
def show_mp3_update_tooltip_if(self,mp3 = None): """ If the Mp3 path is pending to be update the show the save markup """ tooltip_text = _("The Mp3 file <b><i>%s</i></b> was modified. Update it.") % mp3 tooltip_text = tooltip_text.replace("&","&") if mp3 and self.mp3_tree.pending_to_update(mp3): self.image_edited_mp3.set_property('visible',True) self.image_edited_mp3.set_tooltip_markup(tooltip_text) else: self.image_edited_mp3.set_property('visible',False)
def drag_data_received_data(self, treeview, context, x, y, selection, info, etime): """ Drop data received. Handle it """ self.log.info("Drag data received") model = treeview.get_model() drop_info = treeview.get_dest_row_at_pos(x, y) dropped_mp3files = uriparser.get_mp3_files_from_uri_data(selection.data) if len(dropped_mp3files) > 0: # Append the new files in the tree self.lock_app() total_added = self.mp3_tree.add_iters(dropped_mp3files) self.unlock_app() # Show finish notification if total_added and self.config['misc']['show-notifications']: notifier.show_notification(_("Load complete"), "%03d %s" %(total_added, _("MP3 files added...")))
def on_btn_add_clicked(self, widget, *args): """ Open a FileChooserDialog and gets the selected Mp3 files from it """ self.log.info("Showing the open files dialog") # Opens the mp3 files selection dialog selected_mp3files = filechooser.selectMp3Files(self.GMusicTagger, self.config['music']['start-folder']) if len(selected_mp3files) > 0: # Append the new files in the tree self.lock_app() total_added = self.mp3_tree.add_iters(selected_mp3files) self.unlock_app() # Show finish notification if total_added and self.config['misc']['show-notifications']: notifier.show_notification(_("Load complete"), "%03d %s" %(total_added, _("MP3 files added...")))
def selectCoverFile(parent=None,path=os.path.expanduser("~").decode(env.LOCALE_ENCODE)): """ Opens a FileChooserDialog with an image filter to choose one file. Returns the selected file """ coverfilter = gtk.FileFilter() coverfilter.set_name(_("Image Files")) coverfilter.add_pattern("*.png") coverfilter.add_pattern("*.PNG") coverfilter.add_pattern("*.jpg") coverfilter.add_pattern("*.JPG") coverfilter.add_pattern("*.jpeg") coverfilter.add_pattern("*.JPEG") coverfilter.add_pattern("*.bmp") coverfilter.add_pattern("*.BMP") dialog = gtk.FileChooserDialog(_("Choose your cover file"), parent, gtk.FILE_CHOOSER_ACTION_OPEN, (gtk.STOCK_CANCEL,gtk.RESPONSE_CANCEL, gtk.STOCK_OK,gtk.RESPONSE_OK)) dialog.set_select_multiple(False) dialog.add_filter(coverfilter) dialog.set_current_folder(path) # Sets the Preview Image Widget preview = gtk.Image() dialog.set_preview_widget(preview) dialog.set_use_preview_label(False) dialog.connect("update-preview", update_preview_cb, preview) response = dialog.run() if response == gtk.RESPONSE_OK: selected_cover = dialog.get_filename() else: selected_cover = "" dialog.destroy() return selected_cover
def on_btn_test_music_player_program_clicked (self, btn_test_music_player_program): """ """ play_command = self.entry_music_player_program.get_text() process = subprocess.Popen(play_command, shell = True, stdout = subprocess.PIPE, stderr = subprocess.PIPE) # Wait a bit to kwnon if the process failed inmediatily time.sleep(0.2) returncode = process.poll() title = _("Music player test") if returncode: error_message = _("Cannot open music player:\n\n") stdout = ''.join(process.stdout.readlines()).replace("&","&") stderr = ''.join(process.stderr.readlines()).replace("&","&") error_message = "%s%s%s" % (error_message, stdout, stderr) message.error(title, error_message, self.dialog_settings) else: ok_message = _("The player '%s' works!") % play_command message.info(title, ok_message, self.dialog_settings)
def next_fraction(self): """ Refresh the progressbar fraction setting the new fraction value of the sequence """ text = "%d%s" % (round(self.actual_fraction*100), _("% Complete")) self.set_text(text) self.set_fraction(self.actual_fraction) self.actual_fraction += self.fraction_increment if self.actual_fraction > 1.0: self.actual_fraction = 1.0 while gtk.events_pending(): gtk.main_iteration()
def on_btn_test_music_player_program_clicked( self, btn_test_music_player_program): """ """ play_command = self.entry_music_player_program.get_text() process = subprocess.Popen(play_command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) # Wait a bit to kwnon if the process failed inmediatily time.sleep(0.2) returncode = process.poll() title = _("Music player test") if returncode: error_message = _("Cannot open music player:\n\n") stdout = ''.join(process.stdout.readlines()).replace("&", "&") stderr = ''.join(process.stderr.readlines()).replace("&", "&") error_message = "%s%s%s" % (error_message, stdout, stderr) message.error(title, error_message, self.dialog_settings) else: ok_message = _("The player '%s' works!") % play_command message.info(title, ok_message, self.dialog_settings)
def saveCoverFileAs(parent=None, path=os.path.expanduser("~").decode(env.LOCALE_ENCODE), filename="Mp3Cover.jpg"): """ Opens a filechooser dialog to set the name of the image to save """ dialog = gtk.FileChooserDialog(_("Save you cover as..."), parent, gtk.FILE_CHOOSER_ACTION_SAVE, (gtk.STOCK_CANCEL,gtk.RESPONSE_CANCEL, gtk.STOCK_OK,gtk.RESPONSE_OK)) dialog.set_current_folder(path) dialog.set_current_name(filename) response = dialog.run() if response == gtk.RESPONSE_OK: cover_save_as = dialog.get_filename() else: cover_save_as = "" dialog.destroy() return cover_save_as
import gtk import core.env as env from core.env import _ import core.mp3storage as mp3storage import ui.message as message import ui.listmodel as listmodel # Sets logger APPLOG = logging.getLogger(__name__) # All tree tooltip MP3TREE_TOOLTIP_MARKUP = _("""<b><i>Drop</i></b> files or directories in the tree to load Mp3 Files. <b><i>Select/Unselect</i></b> the mp3 file by toggling the check button on its column. <b><i>Click</i></b> on any field to edit it.""") # Cancel Action sleep time CANCEL_ACTION_SLEEP = 2.0 class Mp3Tree(gtk.TreeView): def __init__(self, app_config): gtk.TreeView.__init__(self) self.get_selection().set_mode(gtk.SELECTION_SINGLE) self.set_tooltip_markup(MP3TREE_TOOLTIP_MARKUP) # Publicate the Application Configuration self.config = app_config # Create the Mp3 Storage
def update_selected_iters(self): """ Retrieve all the mp3 paths selected with changes pending to update and update them tags. Rename the files if File column have changes. """ APPLOG.info("Update selected mp3 paths with pending changes") # Initialize updates counter total_files_updated = 0 # Gets the mp3 paths to update selected_mp3_paths = self.get_selected_mp3_files() mp3_paths_to_update = self.mp3_store.pending_files_to_update(selected_mp3_paths) if mp3_paths_to_update: # Initialize the progressbar self.progressbarbox.set_property('visible',True) self.progressbarbox.set_new_bar(len(mp3_paths_to_update)) for mp3 in mp3_paths_to_update: # Check if the action is not cancelled if not self.progressbarbox.cancel_action: # Refresh the progressbar self.progressbarbox.next(_("Updating %s...") % mp3) # Update Mp3 tag and rename the filename is_updated = self.mp3_store.update(mp3) # Rename Mp3 file is_renamed = False new_mp3 = self.mp3_store.rename(mp3) if new_mp3: is_renamed = True if mp3 != new_mp3: self.update_mp3_path(mp3,new_mp3) mp3 = new_mp3 if is_updated and is_renamed: self.mp3_store.remove_for_update(mp3) APPLOG.info("'%s' successfully saved" % mp3) total_files_updated += 1 elif not is_updated: APPLOG.info("'%s' not saved" % mp3) message.error(_("Save Mp3 changes"), _("Error while saving Mp3 %s metadata") % mp3, self.get_toplevel()) elif not is_renamed: APPLOG.info("'%s' not renamed" % mp3) message.error(_("Save Mp3 changes"), _("Error while renaming Mp3 %s") % mp3, self.get_toplevel()) else: APPLOG.warning("Save process cancelled") self.progressbarbox.cancel_message() time.sleep(CANCEL_ACTION_SLEEP) break # Hide the progressbar self.progressbarbox.set_property('visible',False) else: APPLOG.info("No changes pending on the selected mp3 files") message.info(_("Update Mp3 files"), _("No changes pending on the selected Mp3 Files."), self.get_toplevel()) return total_files_updated
## ## You should have received a copy of the GNU General Public License ## along with this program; if not, write to the Free Software ## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ############################################################################### import core.env as env from core.env import _ import ui.message as message def show_notification(title, message): print "%s -> %s" % (title, message) try: import pynotify if pynotify.init(env.APP_NAME): def show_notification(title, message): notification = pynotify.Notification(title, message) notification.set_icon_from_pixbuf(env.GMUSICTAGGER_BUF) notification.set_urgency(pynotify.URGENCY_LOW) notification.show() except ImportError: error_title = _("GMusicTagger: Notifier module") error_message = _("Cannot start notification module.\n") + \ _("Try installing 'python-notify' package") message.error(error_title, error_message)
## You should have received a copy of the GNU General Public License ## along with this program; if not, write to the Free Software ## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ############################################################################### import core.env as env from core.env import _ import ui.message as message def show_notification(title, message): print "%s -> %s" % (title, message) try: import pynotify if pynotify.init(env.APP_NAME): def show_notification(title, message): notification = pynotify.Notification(title, message) notification.set_icon_from_pixbuf(env.GMUSICTAGGER_BUF) notification.set_urgency(pynotify.URGENCY_LOW) notification.show() except ImportError: error_title = _("GMusicTagger: Notifier module") error_message = _("Cannot start notification module.\n") + _("Try installing 'python-notify' package") message.error(error_title, error_message)
def add_iters(self,mp3_files): """ Insert the new mp3 files in the Tree ListStore """ APPLOG.info("Add new iters on the Mp3 Tree") # Initialize addition counter total_files_added = 0 # Initialize the progressbar self.progressbarbox.set_property('visible',True) self.progressbarbox.set_new_bar(len(mp3_files)) # Append the files in the Tree ListStore for mp3 in mp3_files: # Check if the action is not cancelled if not self.progressbarbox.cancel_action: # Refresh the progressbar self.progressbarbox.next(_("Loading %s...") % mp3) # Add Mp3 File in the storage Core and read it added_mp3 = self.mp3_store.add_item(mp3) if added_mp3: if added_mp3 < 2: try: mp3_audio_file = self.mp3_store.get_metadata(mp3) mp3_tag = mp3_audio_file.getTag() # Gets Filename by the path basename and without ext filename = os.path.basename(mp3) i = filename.rindex('.') filename = filename[:i] # Retrieve the complex tags (Genre and Comments) try: genre = mp3_tag.getGenre() if genre: genre_name = genre.getName() else: genre_name = u'' except eyeD3.tag.GenreException: genre_name = '' comments = mp3_tag.getComments() if len(comments) > 0: comment_string = comments[0].comment else: comment_string = u'' # Retrieve all text fields of the MP3 tag # and sets the tree fields col_selec = self.config['misc']['auto-select-when-added'] col_file = filename col_num = self.getTrackNumString(mp3_tag.getTrackNum()) col_title = mp3_tag.getTitle() col_artist = mp3_tag.getArtist('TPE1') col_band = mp3_tag.getArtist('TPE2') col_performer = mp3_tag.getArtist('TPE3') col_remix = mp3_tag.getArtist('TPE4') col_compositor = mp3_tag.getArtist('TCOM') col_album = mp3_tag.getAlbum() col_year = mp3_tag.getYear() col_genre = genre_name col_comments = comment_string col_duration = mp3_audio_file.getPlayTimeString() col_bitrate = mp3_audio_file.getBitRateString() col_path = mp3 iter_tuple_values = (col_selec, col_file, col_num, col_title, col_artist, col_band, col_performer, col_remix, col_compositor, col_album, col_year, col_genre, self.genre_model, col_comments, col_duration, col_bitrate, col_path) self.model.append(iter_tuple_values) total_files_added += 1 except: APPLOG.exception("Reading Tag from %s" % mp3) message.exception(_("Reading Mp3 tags"), _("Error reading Mp3 Tag from '%s'\n") % os.path.basename(mp3).replace("&","&"), self.get_toplevel()) self.mp3_store.remove_items([mp3]) else: message.error(_("Initialize Mp3 Tag"), _("Error adding Mp3 File '%s'.\nCheck the app log.") % os.path.basename(mp3).replace("&","&"), self.get_toplevel()) else: APPLOG.warning("Load process cancelled") self.progressbarbox.cancel_message() time.sleep(CANCEL_ACTION_SLEEP) break # Hide the progressbar self.progressbarbox.set_property('visible',False) return total_files_added