Exaile 'Add Directory' Plugin

Exaile is my favorite music player for Linux, and it makes a LOT of hours on my computer. But there's one thing that annoyed me, you couldn't select multiple directories, and add all tracks in it to the playlist.

But Exaile has a great plugin system, so I created a plugin for it. You can now choose File -> Open Directory, select the directories you want to add, and all files in the selected directories will be added to (optionally new) playlist. This function differs from the built in 'Import directory' feature, because the Import Directory function can only import one directory.

To install it, place the file in the ~/.exaile/plugins directory.

Download Download script as zip

Tag Tags: python exaile plugin

Source

  • adddir.py
  1. """
  2.     Add Directory Plugin
  3.    
  4.     With this plugin you can select folders instead of files to add
  5.     to your playlist.
  6.    
  7.     Created By Lucas van Dijk <info@return.net> (http://www.retun1.net)
  8. """
  9.  
  10. import gtk
  11. from xl import xlmisc
  12. from xl import media, library
  13. import xl.plugins as plugins
  14. from gettext import gettext as _
  15. import os, os.path
  16.  
  17. PLUGIN_NAME = _("Add Directory")
  18. PLUGIN_AUTHORS = ['Lucas van Dijk <info@return1.net> (http://www.return1.net)']
  19. PLUGIN_VERSION = '0.1'
  20. PLUGIN_DESCRIPTION = _("With this plugin you can select folders instead of files to add to your playlist.")
  21. PLUGIN_ENABLED = False
  22.  
  23. b = gtk.Button()
  24. PLUGIN_ICON = b.render_icon(gtk.STOCK_OPEN, gtk.ICON_SIZE_MENU)
  25. b.destroy()
  26.  
  27. def initialize():
  28.     """
  29.         Called when the plugin is enabled
  30.     """
  31.    
  32.     # Add Menu entry
  33.     try:
  34.         menu_item = gtk.MenuItem(_('Open Directory'))   
  35.         menu_item.connect('activate', on_add_dir)
  36.         menu_item.set_name('add_dir_plugin_item')
  37.        
  38.         menubar = APP.xml.get_widget('file_menu_menu') 
  39.         menubar.insert(menu_item, 3)
  40.        
  41.         menu_item.show()
  42.     except Exception, e:
  43.         print e
  44.     return True
  45.  
  46. def destroy():
  47.     """
  48.         Called when the plugin is disabled
  49.     """
  50.     menubar = APP.xml.get_widget('file_menu_menu')
  51.     for child in menubar.get_children():
  52.         if child.get_name() == 'add_dir_plugin_item':
  53.             menubar.remove(child)
  54.            
  55. class TrackDataEx(library.TrackData):
  56.     """
  57.         This subclass allows merging of 2 TrackData instances
  58.     """
  59.    
  60.     def append(self, tracks):
  61.         if isinstance(tracks, library.TrackData):
  62.             for track in tracks:
  63.                 library.TrackData.append(self, track)
  64.         else:
  65.             library.TrackData.append(self, tracks)
  66.        
  67.  
  68. def on_add_dir(item, event = None)
  69.     dialog = gtk.FileChooserDialog(_("Choose directories"), APP.window, gtk.FILE_CHOOSER_ACTION_SELECT_FOLDER, (gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL, gtk.STOCK_OPEN, gtk.RESPONSE_OK))
  70.        
  71.     hbox = gtk.HBox(True)
  72.    
  73.     new_tab = gtk.CheckButton(_("Open in new tab"))
  74.     recurse = gtk.CheckButton(_("Rucursive"))
  75.     recurse.set_active(True)
  76.    
  77.     hbox.pack_start(new_tab)
  78.     hbox.pack_start(recurse)
  79.     hbox.show_all()
  80.    
  81.     dialog.set_extra_widget(hbox)
  82.     dialog.set_current_folder(APP.get_last_dir())
  83.     dialog.set_select_multiple(True)
  84.  
  85.     music = gtk.FileFilter()
  86.     music.set_name(_("Music Files"))
  87.     all = gtk.FileFilter()
  88.     all.set_name(_("All Files"))
  89.  
  90.     for ext in media.SUPPORTED_MEDIA:
  91.         music.add_pattern('*' + ext)
  92.        
  93.     all.add_pattern('*')
  94.  
  95.     dialog.add_filter(music)
  96.     dialog.add_filter(all)
  97.  
  98.     result = dialog.run()
  99.     dialog.hide()
  100.    
  101.     if result == gtk.RESPONSE_OK:
  102.         paths = dialog.get_filenames()
  103.         dir = dialog.get_current_folder()
  104.         if dir: # dir is None when the last view is a search
  105.             APP.last_open_dir = dir
  106.         APP.status.set_first(_("Populating playlist..."))   
  107.        
  108.         songs = TrackDataEx()
  109.         for dir in paths:
  110.             songs_to_append = import_dir(dir, new_tab.get_active(), recurse.get_active())
  111.            
  112.             if songs_to_append:
  113.                 songs.append(songs_to_append)
  114.        
  115.         if songs:
  116.             if new_tab.get_active():
  117.                 APP.new_page(_("Playlist"), songs)
  118.             else:
  119.                 APP.playlist_manager.append_songs(songs)
  120.                
  121. def import_dir(dir, new_tab, recurse):
  122.     songs = TrackDataEx()
  123.     count = 0
  124.    
  125.     for file in os.listdir(dir):
  126.         path = os.path.join(dir, file)
  127.        
  128.         if os.path.isdir(path):
  129.             if recurse:
  130.                 songs_to_append = import_dir(path, new_tab, recurse)
  131.                 if songs_to_append:
  132.                     songs.append(songs_to_append)
  133.         else:
  134.             (f, ext) = os.path.splitext(path)
  135.             if ext in media.SUPPORTED_MEDIA:
  136.                 if count >= 10:
  137.                     xlmisc.finish()
  138.                     count = 0
  139.                 tr = library.read_track(APP.db, APP.all_songs, path)
  140.  
  141.                 count += 1
  142.                 if tr:
  143.                     songs.append(tr)   
  144.     return songs
  145.