Beispiel #1
0
 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()
Beispiel #2
0
    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)
Beispiel #3
0
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
Beispiel #4
0
 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("&","&amp;")
             stderr = ''.join(process.stderr.readlines()).replace("&","&amp;")
             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)
Beispiel #5
0
 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
Beispiel #6
0
 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...")))       
Beispiel #7
0
 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)
Beispiel #8
0
 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()
Beispiel #9
0
 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()
Beispiel #10
0
 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("&","&amp;")
     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)
Beispiel #11
0
 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...")))
Beispiel #12
0
 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...")))                                     
Beispiel #13
0
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
Beispiel #14
0
 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("&","&amp;")
         stderr = ''.join(process.stderr.readlines()).replace("&","&amp;")
         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)
Beispiel #15
0
 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()
Beispiel #16
0
    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("&", "&amp;")
            stderr = ''.join(process.stderr.readlines()).replace("&", "&amp;")
            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)
Beispiel #17
0
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 
Beispiel #18
0
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
Beispiel #19
0
    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
Beispiel #20
0
##
## 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)
Beispiel #21
0
## 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)
Beispiel #22
0
    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("&","&amp;"),
                                              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("&","&amp;"),
                                  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