SHOW:
|
|
- or go back to the newest paste.
| 1 | # -*- coding: utf-8 -*- | |
| 2 | """ | |
| 3 | xchat_mplayer by Csigaa, mostly rewritten by Pierre Collignon (03/2011) | |
| 4 | Edited by Daniel Gimpelevich to prevent failure on missing ID3 tags | |
| 5 | Prints a nice "now playing" message on the current irc chan | |
| 6 | /!\ You need mediainfo to run this script /!\ | |
| 7 | ||
| 8 | This rewrite breaks the first dev's wish of never using external cmds, but | |
| 9 | we need these infos! | |
| 10 | ||
| 11 | NOTE FOR PASTEBIN: save the file as xchat_mplayer.py to your xchat directory | |
| 12 | ||
| 13 | Contact: [email protected] and [email protected] and [email protected] | |
| 14 | ||
| 15 | License: Beer-ware (by phk) ;p | |
| 16 | ---------------------------------------------------------------------------- | |
| 17 | "THE BEER-WARE LICENSE" (Revision 42): | |
| 18 | Csigaa wrote this file. As long as you retain this notice you | |
| 19 | can do whatever you want with this stuff. If we meet some day, and you think | |
| 20 | this stuff is worth it, you can buy me a beer in return | |
| 21 | ---------------------------------------------------------------------------- | |
| 22 | ||
| 23 | """ | |
| 24 | ||
| 25 | __module_name__ = "xchat_mplayer" | |
| 26 | - | __module_version__ = "1.05 Fork 1.2" |
| 26 | + | __module_version__ = "1.05 Fork 1.3" |
| 27 | __module_description__ = "XChat-MPlayer 'now playing' script by Csigaa and P.C, edited by DonkeyHotei" | |
| 28 | ||
| 29 | import xchat | |
| 30 | import os | |
| 31 | import re | |
| 32 | import subprocess as sub | |
| 33 | ||
| 34 | if os.name != 'posix': | |
| 35 | raise NotImplementedError,'non-POSIX systems are not supported' | |
| 36 | ||
| 37 | # Reads the mediainfo bits by actually calling the command | |
| 38 | def readMediaInfo(path): | |
| 39 | rawData = sub.Popen('mediainfo ' + path.replace("(","\\(").replace(")","\\)").replace(" ","\\ "), shell = True, stdout = sub.PIPE).communicate()[0];
| |
| 40 | lines = rawData.split('\n');
| |
| 41 | hashTable = {};
| |
| 42 | currentCategory = ''; | |
| 43 | for line in lines: | |
| 44 | keyValue = line.split(':');
| |
| 45 | value = ''; | |
| 46 | if len(keyValue) == 1: | |
| 47 | if len(keyValue[0]) > 0: | |
| 48 | currentCategory = keyValue[0]; | |
| 49 | hashTable[currentCategory] = {};
| |
| 50 | else: | |
| 51 | hashTable[currentCategory][keyValue[0].strip()] = keyValue[1].strip(); | |
| 52 | return hashTable; | |
| 53 | ||
| 54 | def getEntry(category,tag,hashTable): | |
| 55 | try: | |
| 56 | result = hashTable[category][tag] | |
| 57 | except KeyError: | |
| 58 | result = '' | |
| 59 | return result; | |
| 60 | ||
| 61 | def buildDescription(hashTable): | |
| 62 | artist = getEntry('General','Performer',hashTable);
| |
| 63 | track = getEntry('General','Track name',hashTable);
| |
| 64 | duration = getEntry('General','Duration',hashTable);
| |
| 65 | bitrate = getEntry('General','Overall bit rate',hashTable);
| |
| 66 | frequency = getEntry('Audio','Sampling rate',hashTable);
| |
| 67 | album = getEntry('General','Album',hashTable);
| |
| 68 | albumDate = getEntry('General','Recorded date',hashTable);
| |
| 69 | fileSize = getEntry('General','File size',hashTable);
| |
| 70 | completeName = artist + ' - ' + track; | |
| 71 | if completeName == ' - ': | |
| 72 | - | completeName = getEntry('General','Complete name',hashTable)
|
| 72 | + | completeName = os.readlink(getEntry('General','Complete name',hashTable))
|
| 73 | completeName = completeName.split('/')
| |
| 74 | completeName = completeName.pop() | |
| 75 | profile = ''; | |
| 76 | if 'Format profile' in hashTable['Audio']: | |
| 77 | profile = ' ' + hashTable['Audio']['Format profile'] + ' '; | |
| 78 | mode = ''; | |
| 79 | if 'Mode' in hashTable['Audio']: | |
| 80 | mode = ' ' + hashTable['Audio']['Mode'] + ' '; | |
| 81 | wholeFormat = hashTable['Audio']['Format'] + profile + mode; | |
| 82 | ||
| 83 | completeDesc = '♪♪♪ ' + completeName + ' : ' + duration + ' : ' + bitrate + ' : ' + wholeFormat + ' ♪♪♪ ' + frequency + ' ♪♪♪ ' + album + ' (' + albumDate + ')' + ' ♪♪♪ ';
| |
| 84 | return completeDesc; | |
| 85 | ||
| 86 | def getFilename(): | |
| 87 | # Get the video file name (identified by naming pattern) from procfs | |
| 88 | ||
| 89 | # list&walk the directory contents | |
| 90 | proclist = sorted(os.listdir('/proc'))
| |
| 91 | for proc in os.listdir('/proc'):
| |
| 92 | # if it is a directory with a name of digits only | |
| 93 | if os.path.isdir('/proc/'+proc) and re.match('[0-9]+',proc):
| |
| 94 | try: | |
| 95 | exe = os.readlink('/proc/'+proc+'/exe').split('/')
| |
| 96 | # if executable name is 'mplayer' | |
| 97 | exe_name = exe.pop() | |
| 98 | if exe_name == 'mplayer' or exe_name == 'mplayer2': | |
| 99 | filelist = os.listdir('/proc/' + proc + '/fd')
| |
| 100 | # walk the list of open files | |
| 101 | for file in filelist: | |
| 102 | try: | |
| 103 | - | path = os.readlink('/proc/' + proc + '/fd/' + file)
|
| 103 | + | path = '/proc/' + proc + '/fd/' + file |
| 104 | - | if re.match('.*(avi|mpg|mkv|mp4|nuv|ogg|ogm|wmv|iso|img|mp3|flac)$', path, re.I):
|
| 104 | + | if re.match('.*(avi|mpg|mkv|mp4|nuv|ogg|ogm|wmv|iso|img|mp3|flac)$', os.readlink(path), re.I):
|
| 105 | # if filename found, return | |
| 106 | return path; | |
| 107 | except: | |
| 108 | # if link not readable, skip | |
| 109 | continue | |
| 110 | except: | |
| 111 | # if process directory not readable, skip | |
| 112 | continue | |
| 113 | return None | |
| 114 | ||
| 115 | def getVersion(): | |
| 116 | try: | |
| 117 | import commands | |
| 118 | try: | |
| 119 | # release version, begins with number (incl. optional rc sign with maximum 2 digits); if no match, exception occurs (empty list - 0 index is out of range) | |
| 120 | ver = re.findall('^MPlayer\s\d[.]\d+\w{0,4}',commands.getoutput('mplayer'))[0]
| |
| 121 | except: | |
| 122 | # SVN version, begins with 'SVN' (revision number maximum 6 digits) | |
| 123 | ver = re.findall('^MPlayer\sSVN-r\d{0,6}',commands.getoutput('mplayer'))[0]
| |
| 124 | return ver | |
| 125 | except: | |
| 126 | # if any error occured above, return only the player name | |
| 127 | return 'MPlayer' | |
| 128 | ||
| 129 | def mplayer_msg(world,world_eol,userdata): | |
| 130 | fileName = getFilename(); | |
| 131 | if type(fileName).__name__ != 'NoneType': | |
| 132 | - | irccmd = 'me is now playing ' + buildDescription(readMediaInfo(getFilename())) + 'with ' + getVersion() + ' for Linux d[O_o]b'; |
| 132 | + | irccmd = 'me is now playing ' + buildDescription(readMediaInfo(getFilename())) + 'with ' + getVersion() + ' for Linux d[O_o]b'; |
| 133 | xchat.command(irccmd) | |
| 134 | else: | |
| 135 | print 'You are not playing anything !'; | |
| 136 | return xchat.EAT_ALL | |
| 137 | ||
| 138 | xchat.hook_command('mplayer', mplayer_msg)
| |
| 139 | xchat.prnt('XChat-MPlayer '+__module_version__+' loaded - use /mplayer to print now playing message') |