SHARE
TWEET

bsc-v2.py

charles95 Apr 29th, 2015 766 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. #!/usr/bin/python
  2.  
  3. # this script can installed to the current user account by running the following commands:
  4.  
  5. # sudo apt-get install python-nautilus python-mutagen python-pyexiv2 python-kaa-metadata
  6. # mkdir ~/.local/share/nautilus-python/extensions/
  7. # cp bsc-v2.py ~/.local/share/nautilus-python/extensions/
  8. # chmod a+x ~/.local/share/nautilus-python/extensions/bsc-v2.py
  9.  
  10. # alternatively, you can be able to place the script in:
  11. # /usr/share/nautilus-python/extensions/
  12.  
  13. # change log:
  14. # geb666: original bsc.py, based on work by Giacomo Bordiga
  15. # jmdsdf: version 2 adds extra ID3 and EXIF tag support
  16. # jmdsdf: added better error handling for ID3 tags, added mp3 length support, distinguished
  17. #         between exif image size and true image size
  18. # SabreWolfy: set consistent hh:mm:ss format, fixed bug with no ID3 information
  19. #             throwing an unhandled exception
  20. # jmdsdf: fixed closing file handles with mpinfo (thanks gueba)
  21. # jmdsdf: fixed closing file handles when there's an exception (thanks Pitxyoki)
  22. # jmdsdf: added video parsing (work based on enbeto, thanks!)
  23. # jmdsdf: added FLAC audio parsing through kaa.metadata (thanks for the idea l-x-l)
  24. # jmdsdf: added trackno, added mkv file support (thanks ENigma885)
  25. # jmdsdf: added date/album for flac/video (thanks eldon.t)
  26. # jmdsdf: added wav file support thru pyexiv2
  27. # jmdsdf: added sample rate file support thru mutagen and kaa (thanks for the idea N'ko)
  28. # jmdsdf: fix with tracknumber for FLAC, thanks l-x-l
  29. # draxus: support for pdf files
  30. # arun (engineerarun@gmail.com): made changes to work with naulitus 3.x
  31. # Andrew@webupd8.org: get EXIF support to work with Nautilus 3
  32. # cehlgn added MP4 Audio support (mp4,m4a,Apple lossles)
  33. # added close file for exif
  34. # Charles Bos: change 'import Image' to 'from PIL import Image' to fix import error
  35.  
  36. import os
  37. import urllib
  38. #import nautilus
  39. from gi.repository import Nautilus, GObject, Gtk, GdkPixbuf
  40. # for id3 support
  41. from mutagen.easyid3 import EasyID3
  42. from mutagen.mp3 import MPEGInfo
  43. # for exif support
  44. import pyexiv2
  45. # for reading videos. for future improvement, this can also read mp3!
  46. import kaa.metadata
  47. # for reading image dimensions
  48. from PIL import Image
  49. # for reading pdf
  50. try:
  51.         from pyPdf import PdfFileReader
  52. except:
  53.         pass
  54. # for mp4 AUDIO handling (Including ALAC *.m4a Apple Lossless)
  55. try:
  56.         from mutagen.mp4 import MP4
  57.         import mutagen.easymp4
  58.         from mutagen.easymp4 import EasyMP4
  59. except:
  60.         pass
  61.  
  62.  
  63. class ColumnExtension(GObject.GObject, Nautilus.ColumnProvider, Nautilus.InfoProvider):
  64.         def __init__(self):
  65.                 pass
  66.  
  67.         def get_columns(self):
  68.                 return (
  69.                         Nautilus.Column(name="NautilusPython::title_column",attribute="title",label="Title",description="Song title"),
  70.                         Nautilus.Column(name="NautilusPython::album_column",attribute="album",label="Album",description="Album"),
  71.                         Nautilus.Column(name="NautilusPython::artist_column",attribute="artist",label="Artist",description="Artist"),
  72.                         Nautilus.Column(name="NautilusPython::tracknumber_column",attribute="tracknumber",label="Track",description="Track number"),
  73.                         Nautilus.Column(name="NautilusPython::genre_column",attribute="genre",label="Genre",description="Genre"),
  74.                         Nautilus.Column(name="NautilusPython::date_column",attribute="date",label="Date",description="Date"),
  75.                         Nautilus.Column(name="NautilusPython::bitrate_column",attribute="bitrate",label="Bitrate",description="Audio Bitrate in kilo bits per second"),
  76.                         Nautilus.Column(name="NautilusPython::samplerate_column",attribute="samplerate",label="Sample rate",description="Sample rate in Hz"),
  77.                         Nautilus.Column(name="NautilusPython::length_column",attribute="length",label="Length",description="Length of audio"),
  78.                         Nautilus.Column(name="NautilusPython::exif_datetime_original_column",attribute="exif_datetime_original",label="EXIF Dateshot ",description="Get the photo capture date from EXIF data"),
  79.                         Nautilus.Column(name="NautilusPython::exif_software_column",attribute="exif_software",label="EXIF Software",description="EXIF - software used to save image"),
  80.                         Nautilus.Column(name="NautilusPython::exif_flash_column",attribute="exif_flash",label="EXIF flash",description="EXIF - flash mode"),
  81.                         Nautilus.Column(name="NautilusPython::exif_pixeldimensions_column",attribute="exif_pixeldimensions",label="EXIF Image Size",description="Image size - pixel dimensions as reported by EXIF data"),
  82.                         Nautilus.Column(name="NautilusPython::pixeldimensions_column",attribute="pixeldimensions",label="Image Size",description="Image/video size - actual pixel dimensions"),
  83.                         Nautilus.Column(name="NautilusPython::format_column",attribute="format",label="Format",description="Mpeg Audio Format"),
  84.                         Nautilus.Column(name="NautilusPython::mp3version_column",attribute="version",label="Version",description="Version"),
  85.                         Nautilus.Column(name="NautilusPython::composer_column",attribute="composer",label="Composer",description="Composer"),
  86.                         Nautilus.Column(name="NautilusPython::liricist_column",attribute="liricist",label="Liricist",description="Liricist"),
  87. )
  88.  
  89.         def update_file_info(self, file):
  90.                 # set defaults to blank
  91.                 for x in EasyID3.valid_keys.keys():
  92.                         file.add_string_attribute(x, '')
  93.                 file.add_string_attribute('bitrate', '')
  94.                 file.add_string_attribute('samplerate', '')
  95.                 file.add_string_attribute('length', '')
  96.                 file.add_string_attribute('exif_datetime_original', '')
  97.                 file.add_string_attribute('exif_software', '')
  98.                 file.add_string_attribute('exif_flash', '')
  99.                 file.add_string_attribute('exif_pixeldimensions', '')
  100.                 file.add_string_attribute('pixeldimensions', '')
  101.                 file.add_string_attribute('format', '')
  102.  
  103.                 if file.get_uri_scheme() != 'file':
  104.                         return
  105.  
  106.                 # strip file:// to get absolute path
  107.                 filename = urllib.unquote(file.get_uri()[7:])
  108.                
  109.                 # mp3 handling
  110.                 if file.is_mime_type('audio/mpeg'):
  111.                         # attempt to read ID3 tag
  112.                         try:
  113.                                 audio = EasyID3(filename)
  114.                                 # sometimes the audio variable will not have one of these items defined, that's why
  115.                                 # there is this long try / except attempt
  116.                                 for x in EasyID3.valid_keys.keys():
  117.                                         val = "[n/a]"
  118.                                         if audio.has_key(x):
  119.                                                 val = audio[x][0]
  120.                                                 if x == "tracknumber": val = "%3s" % (val)
  121.                                         file.add_string_attribute(x, val)
  122.                         except:
  123.                                 # [SabreWolfy] some files have no ID3 tag and will throw this exception:
  124.                                 for x in EasyID3.valid_keys.keys():
  125.                                         file.add_string_attribute(x, "[no ID3]")
  126.                                
  127.                         # try to read MP3 information (bitrate, length, samplerate)
  128.                         try:
  129.                                 mpfile = open (filename)
  130.                                 mpinfo = MPEGInfo (mpfile)
  131.                                 file.add_string_attribute('bitrate', str(mpinfo.bitrate/1000) + " Kbps")
  132.                                 file.add_string_attribute('samplerate', str(mpinfo.sample_rate) + " Hz")
  133.                                 # [SabreWolfy] added consistent formatting of times in format hh:mm:ss
  134.                                 # [SabreWolfy[ to allow for correct column sorting by length
  135.                                 mp3length = "%02i:%02i:%02i" % ((int(mpinfo.length/3600)), (int(mpinfo.length/60%60)), (int(mpinfo.length%60)))
  136.                                
  137.                                 try: mpgfmt = "MPEG%d Layer%d" % (mpinfo.version,mpinfo.layer)
  138.                                 except:mpgfmt = "[n/a]"
  139.                                
  140.                                 mpfile.close()
  141.                                 file.add_string_attribute('length', mp3length)
  142.                                 file.add_string_attribute('format', mpgfmt)
  143.                         except:
  144.                                 file.add_string_attribute('bitrate', "[n/a]")
  145.                                 file.add_string_attribute('length', "[n/a]")
  146.                                 file.add_string_attribute('samplerate', "[n/a]")
  147.                                 file.add_string_attribute('format', "[n/a]")
  148.                                 try:
  149.                                         mpfile.close()
  150.                                 except: pass
  151.        
  152.                 # image handling
  153.                 if file.is_mime_type('image/jpeg') or file.is_mime_type('image/png') or file.is_mime_type('image/gif') or file.is_mime_type('image/bmp'):
  154.                         # EXIF handling routines
  155.                         try:
  156.                                 metadata = pyexiv2.ImageMetadata(filename)
  157.                                 metadata.read()
  158.                                 exif_datetimeoriginal = metadata['Exif.Photo.DateTimeOriginal']
  159.                                 exif_imagesoftware = metadata['Exif.Image.Software']
  160.                                 exif_photoflash = metadata['Exif.Photo.Flash']
  161.                                 exif_pixelydimension = metadata['Exif.Photo.PixelYDimension']
  162.                                 exif_pixelxdimension = metadata['Exif.Photo.PixelXDimension']
  163.                                 file.add_string_attribute('exif_datetime_original',str(exif_datetimeoriginal.raw_value))
  164.                                 file.add_string_attribute('exif_software',str(exif_imagesoftware.raw_value))
  165.                                 file.add_string_attribute('exif_flash',str(exif_photoflash.raw_value))
  166.                                 file.add_string_attribute('exif_pixeldimensions',str(exif_pixelydimension.raw_value)+'x'+str(exif_pixelxdimension.raw_value))
  167.                         except:
  168.                                 # no exif data?
  169.                                 file.add_string_attribute('exif_datetime_original',"")
  170.                                 file.add_string_attribute('exif_software',"")
  171.                                 file.add_string_attribute('exif_flash',"")
  172.                                 file.add_string_attribute('exif_pixeldimensions',"")
  173.                         # try read image info directly
  174.                         try:
  175.                                 im = Image.open(filename)
  176.                                 file.add_string_attribute('pixeldimensions',str(im.size[0])+'x'+str(im.size[1]))
  177.                                 try: im.close()
  178.                                 except: pass
  179.                         except:
  180.                                 file.add_string_attribute('pixeldimensions',"[image read error]")
  181.  
  182.                 # video/flac handling
  183.                 if file.is_mime_type('video/x-msvideo') | file.is_mime_type('video/mpeg') | file.is_mime_type('video/x-ms-wmv') | file.is_mime_type('video/mp4') | file.is_mime_type('audio/x-flac') | file.is_mime_type('video/x-flv') | file.is_mime_type('video/x-matroska') | file.is_mime_type('audio/x-wav'):
  184.                         try:
  185.                                 info=kaa.metadata.parse(filename)
  186.                                 try: file.add_string_attribute('length',"%02i:%02i:%02i" % ((int(info.length/3600)), (int(info.length/60%60)), (int(info.length%60))))
  187.                                 except: file.add_string_attribute('length','[n/a]')
  188.                                 try: file.add_string_attribute('pixeldimensions', str(info.video[0].width) + 'x'+ str(info.video[0].height))
  189.                                 except: file.add_string_attribute('pixeldimensions','[n/a]')
  190.                                 try: file.add_string_attribute('bitrate',str(round(info.audio[0].bitrate/1000)))
  191.                                 except: file.add_string_attribute('bitrate','[n/a]')
  192.                                 try: file.add_string_attribute('samplerate',str(int(info.audio[0].samplerate))+' Hz')
  193.                                 except: file.add_string_attribute('samplerate','[n/a]')
  194.                                 try: file.add_string_attribute('title', info.title)
  195.                                 except: file.add_string_attribute('title', '[n/a]')
  196.                                 try: file.add_string_attribute('artist', info.artist)
  197.                                 except: file.add_string_attribute('artist', '[n/a]')
  198.                                 try: file.add_string_attribute('genre', info.genre)
  199.                                 except: file.add_string_attribute('genre', '[n/a]')
  200.                                 try: file.add_string_attribute('tracknumber',info.trackno)
  201.                                 except: file.add_string_attribute('tracknumber', '[n/a]')
  202.                                 try: file.add_string_attribute('date',info.userdate)
  203.                                 except: file.add_string_attribute('date', '[n/a]')                                     
  204.                                 try: file.add_string_attribute('album',info.album)
  205.                                 except: file.add_string_attribute('album', '[n/a]')
  206.                         except:
  207.                                 file.add_string_attribute('length','error')
  208.                                 file.add_string_attribute('pixeldimensions','error')
  209.                                 file.add_string_attribute('bitrate','error')
  210.                                 file.add_string_attribute('samplerate','error')
  211.                                 file.add_string_attribute('title','error')
  212.                                 file.add_string_attribute('artist','error')
  213.                                 file.add_string_attribute('genre','error')
  214.                                 file.add_string_attribute('track','error')
  215.                                 file.add_string_attribute('date','error')
  216.                                 file.add_string_attribute('album','error')
  217.                
  218.                 # pdf handling
  219.                 if file.is_mime_type('application/pdf'):
  220.                         try:
  221.                                 f = open(filename, "rb")
  222.                                 pdf = PdfFileReader(f)
  223.                                 try: file.add_string_attribute('title', pdf.getDocumentInfo().title)
  224.                                 except: file.add_string_attribute('title', "[n/a]")
  225.                                 try: file.add_string_attribute('artist', pdf.getDocumentInfo().author)
  226.                                 except: file.add_string_attribute('artist', "[n/a]")
  227.                                 f.close()
  228.                         except:
  229.                                 file.add_string_attribute('title', "[no info]")
  230.                                 file.add_string_attribute('artist', "[no info]")
  231.  
  232.                 # mp4 AUDIO handling (Including ALAC *.m4a Apple Lossless)
  233.                 if file.is_mime_type('audio/mp4'):
  234.                         # attempt to read MP4 tag
  235.                         try:
  236.                                 audio = EasyMP4(filename)
  237.                                 # sometimes the audio variable will not have one of these items defined, that's why
  238.                                 # there is this long try / except attempt
  239.                                 try: file.add_string_attribute('title', "".join(audio["title"]))
  240.                                 except: file.add_string_attribute('title', [n/a])
  241.                                 try: file.add_string_attribute('album', "".join(audio["album"]))
  242.                                 except: file.add_string_attribute('album', "[n/a]")
  243.                                 try: file.add_string_attribute('artist', "".join(audio["artist"]))
  244.                                 except: file.add_string_attribute('artist', "[n/a]")
  245.                                 try: file.add_string_attribute('tracknumber', "".join(audio["tracknumber"]))
  246.                                 except: file.add_string_attribute('tracknumber', "[n/a]")
  247.                                 try: file.add_string_attribute('genre', "".join(audio["genre"]))
  248.                                 except: file.add_string_attribute('genre', "[n/a]")
  249.                                 try: file.add_string_attribute('date', "".join(audio["date"]))
  250.                                 except: file.add_string_attribute('date', "[n/a]")
  251.                         except:
  252.                                 # some files have no MP4 tag and will throw this exception:
  253.                                 file.add_string_attribute('title', "[no MP4 Tag]")
  254.                                 file.add_string_attribute('album', "[no MP4 Tag]")
  255.                                 file.add_string_attribute('artist', "[no MP4 Tag]")
  256.                                 file.add_string_attribute('tracknumber', "[no MP4 Tag]")
  257.                                 file.add_string_attribute('genre', "[no MP4 Tag]")
  258.                                 file.add_string_attribute('date', "[no MP4 Tag]")
  259.  
  260.  
  261.                 #try to read MP4 information (bitrate, length, samplerate)
  262.                 try:
  263.                         m4info=MP4(filename)
  264.                         try: file.add_string_attribute('length', "%02i:%02i:%02i" % ((int(m4info.info.length/3600)), (int(m4info.info.length/60%60)), (int(m4info.info.length%60))))
  265.                         except: file.add_string_attribute('length', "[n/a]")   
  266.                         try: file.add_string_attribute('bitrate', str(m4info.info.bitrate))
  267.                         except: file.add_string_attribute('bitrate', "[n/a]")
  268.                         try: file.add_string_attribute('samplerate', str(m4info.info.sample_rate))
  269.                         except: file.add_string_attribute('samplerate', "[n/a]")
  270.                 except:
  271.                         file.add_string_attribute('bitrate', "error")
  272.                         file.add_string_attribute('length', "error")
  273.                         file.add_string_attribute('samplerate', "error")
  274.                                        
  275.                 self.get_columns()
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
 
Top