# GAMVL - Get AOL Music Videos Leech # # Software created by Sean Colyer # http://seancolyer.com # sean@colyer.org # Powered by search of http://fernyb.net # This code distributed under GPL V 2.0 # see http://www.gnu.org/licenses/old-licenses/gpl-2.0.html for full terms. # import wx, os, urllib2, Queue, time from threading import * from subprocess import Popen def newQuery (searchTerm): request = urllib2.Request('http://fernyb.net/phpGAMV/search.aol.videos.php?searchVideo=' + searchTerm, None , fakeHeader) response = urllib2.urlopen(request) page = response.read() videos = [] #parses through the returned page by unique identifiers in order to establish the list of videos while page.find('bold;color:#333333;\'>') is not -1: page = page[page.find('bold;color:#333333;\'>')+21:-1] artist = page[0:page.find('')] videoID = page[page.find('retrieveVideo(')+14:page.find(', "videourl')] page = page[page.find('color:#ff0099;\'>')+16:-1] video = page[0:page.find('')] artist = artist.replace('/','-') video = video.replace('/','-') #Remove ' unfortunately this might mess up names, but only way to ensure VLC will properly transcode artists = artist.replace('\'','') video = video.replace('\'','') title = artist + ' - ' + video tempDict = {title:videoID} videos.insert(0,tempDict) return videos def getStream(videoID): request = urllib2.Request('http://fernyb.net/phpGAMV/getvideo.php?videoid=' + videoID, None, fakeHeader) page = urllib2.urlopen(request).read() url = page[page.find('value=\'')+7:page.find('\' style=')] return url class EncodeThread(Thread): def __init__(self): self.q = Queue.Queue() Thread.__init__(self) def add(self,newVid): self.q.put(newVid) #VLCStyle == 0 == Mac/*Nix, VLCStyle == 1 == Windows, VLC seems to be very tempermental def run(self): global transQueue while True: if self.q.empty(): transQueue = 0 time.sleep(10) else: transQueue = 1 current = self.q.get() if VLCStyle is 0: frame.SetStatusText('Transcoding ' + current) os.system('\'' + VLCLoc + '\' -I dummy -v "' + os.path.join(musicVideoDir , current) + '.mov" :sout="#transcode{vcodec=mp4v,vb=1024,acodec=mp4a,ab=128,scale=1,channels=2,deinterlace,audio-sync}:standard{access=file,mux=mp4,url=\'' + os.path.join(musicVideoDir , current) + '-Ipod.mp4\'}" vlc:quit --sout-transcode-width=320 --sout-transcode-height=240 --aspect-ratio "4:3"') if not transQueue and not copyQueue: frame.SetStatusText('Completed') if VLCStyle is 1: frame.SetStatusText('Transcoding ' + current) Popen('"' + VLCLoc + '" -vvv "' + os.path.join(musicVideoDir , current) + '.mov" :sout="#transcode{vcodec=mp4v,vb=1024,acodec=mp4a,ab=128,scale=1,channels=2,deinterlace,audio-sync}:standard{access=file,mux=mp4,url=\'' + os.path.join(musicVideoDir , current) + '-Ipod.mp4\'}" vlc:quit --sout-transcode-width=320 --sout-transcode-height=240 --aspect-ratio "4:3"') if not transQueue and not copyQueue: frame.SetStatusText('Completed') if copies is 0: os.remove(os.path.join(musicVideoDir, current)+ '.mov') #---------TRANSCODE THREAD------------------------------------------------------------- ID_RESULT = 200 def EVT_RESULT(self,event): self.Connect(-1,-1,ID_RESULT,event) class ResultEvent(wx.PyEvent): def __init__(self,eid): wx.PyEvent.__init__(self) self.SetEventType(ID_RESULT) self.eid=eid class workThread(Thread): def __init__(self,window,selectedVideos): Thread.__init__(self) self.window = window self.thread = None self.selectedVideos = selectedVideos self._want_abort = 0 self.setDaemon(1) self.start() def run(self): while not self.selectedVideos.empty(): video = self.selectedVideos.get() stream = video.values()[0] video = video.keys()[0] if not os.path.isfile(os.path.join(musicVideoDir,video) + '.mov') or overwrite: currentStream = getStream(stream) if currentStream.find('http:') is not -1: frame.SetStatusText('Copying ' + video + ' to ' + musicVideoDir) movieOut = open(os.path.join(musicVideoDir,video) + '.mov', "wb") moviePageFile = (urllib2.urlopen(urllib2.Request(currentStream,None,fakeHeader))).read() movieOut.write(moviePageFile) movieOut.close() if not os.path.isfile(os.path.join(musicVideoDir,video) + '-Ipod.mp4') or overwrite: if ipodEncode: #Create new thread or add to queue of existing thread, this thread for downloading and a new one for transcoding if self.thread is None: self.thread = EncodeThread() self.thread.add(video) self.thread.start() else: self.thread.add(video) #FIXME: Bad Current Stream #else: # frame.SetStatusText('Failed to properly retrieve URL of '+ video + ', moving on to next song.') wx.PostEvent(self.window,ResultEvent(201)) def add(self,newVids): while not newVids.empty(): self.selectedVideos.put(newVids.get()) #------------------------------------------------------------------------------------ ID_ABOUT = 100 ID_SETVLC = 101 ID_EXIT = 999 class GAMVPanel(wx.Panel): vids =[] def __init__(self, parent, id): wx.Panel.__init__(self, parent, id) searchStr = "" self.thread = None self.button = wx.Button(self,7,"Select a Target Directory",wx.Point(5,10)) wx.EVT_BUTTON(self,7,self.EvtClick) self.lblname = wx.StaticText(self, -1, "Search :",wx.Point(5,35)) self.search = wx.SearchCtrl(self, 1,searchStr,wx.Point(60,35),wx.Size(200,-1),style=wx.TE_PROCESS_ENTER) wx.EVT_TEXT_ENTER(self, 1, self.EvtEnter) self.videos = wx.CheckListBox(self,5,wx.Point(10,60),wx.Size(380,280)) self.go = wx.Button(self, 10, "Go/Queue!", wx.Point(60, 450)) wx.EVT_BUTTON(self, 10, self.EvtClick) self.selectall = wx.Button(self,51,"Select All", wx.Point(10,350)) wx.EVT_BUTTON(self, 51, self.EvtClick) self.deselectall = wx.Button(self,50,"De-Select All", wx.Point(100,350)) wx.EVT_BUTTON(self, 50, self.EvtClick) self.over = wx.CheckBox(self, 70, "Overwrite copies?" , wx.Point(250,10)) wx.EVT_CHECKBOX(self,70,self.EvtCheckBox) self.ipod = wx.CheckBox(self, 60,"Transcode for iPod? (VLC Required)",wx.Point(10,380)) wx.EVT_CHECKBOX(self,60,self.EvtCheckBox) #Transcode Thread finishes EVT_RESULT(self,self.EvtResult) def EvtEnter(self,event): self.videos.Clear() self.vids = newQuery(event.GetString()) for n in self.vids: self.videos.InsertItems(n.keys(),pos=0) def EvtClick(self,event): if event.GetId() is 7: dd = wx.DirDialog(self,"Choose a Destination Directory for Videos: ") if dd.ShowModal() == wx.ID_OK: global musicVideoDir musicVideoDir = dd.GetPath() if event.GetId() is 10: selectedVideos = Queue.Queue() for n in range(len(self.vids)): if(self.videos.IsChecked(n)): selectedVideos.put(self.vids[len(self.vids)-n-1]) if self.thread: self.thread.add(selectedVideos) if not self.thread: global copyQueue copyQueue = 1 self.thread = workThread(self,selectedVideos) if event.GetId() is 50 or event.GetId() is 51: for n in range(len(self.vids)): self.videos.Check(n,event.GetId()%50) def EvtResult(self, event): global copyQueue copyQueue = 0 if not transQueue: frame.SetStatusText('Completed') self.thread = None def EvtCheckBox(self, event): if event.GetId() is 60: global ipodEncode ipodEncode = self.ipod.IsChecked() if self.ipod.IsChecked(): self.copy = wx.CheckBox(self, 61,"Keep original and iPod copy?",wx.Point(10,400)) wx.EVT_CHECKBOX(self,61,self.EvtCheckBox) if not self.ipod.IsChecked(): self.copy.Destroy() if event.GetId() is 61: global copies copies = self.copy.IsChecked() if event.GetId() is 70: global overwrite overwrite = self.over.IsChecked() #-------------END GAMVPanel -------------------------------------------------------------- def EvtExit(event): frame.Close(True) def EvtAbout(event): about = wx.MessageDialog(frame, "GAMV - Get AOL Music Video Leech \nPowered by fernyb.net's GAMV. Written by Sean Colyer.") about.ShowModal() about.Destroy() def EvtSetVLC(event): global VLCLoc loc = wx.FileDialog(frame, "VLC Location ") loc.ShowModal() VLCLoc = os.path.join(loc.GetDirectory(),loc.GetFilename()) loc.Destroy() fakeHeader = {'User-agent' : 'Mozilla/4.0 (compatible; MSIE 6.0; AOL 9.0; Windows NT 5.1)'} app = wx.PySimpleApp() musicVideoDir ='' VLCLoc = '' VLCStyle = 0 copies = 0 ipodEncode = 0 overwrite = 0 copyQueue = 0 transQueue = 0 if os.name == 'posix': VLCLoc = '/Applications/VLC.app/Contents/MacOS/clivlc' VLCStyle = 0 if os.name == 'nt': VLCLoc = 'C:\Program Files\VideoLan\VLC\\vlc.exe' VLCStyle = 1 frame = wx.Frame(None, -1, "GAMV Search",wx.Point(100,100),wx.Size(400,550)) GAMVPanel(frame,-1) fileMenu = wx.Menu() fileMenu.Append(ID_ABOUT, "&About","Information") fileMenu.Append(ID_SETVLC, "&Set VLC Location", "Set VLC Location for iPod Transcoding") fileMenu.AppendSeparator() fileMenu.Append(ID_EXIT,"&Exit","Quit") menuBar = wx.MenuBar() menuBar.Append(fileMenu,"&File") wx.EVT_MENU(frame, ID_EXIT, EvtExit) wx.EVT_MENU(frame, ID_ABOUT, EvtAbout) wx.EVT_MENU(frame, ID_SETVLC, EvtSetVLC) frame.SetMenuBar(menuBar) frame.CreateStatusBar() frame.Show(1) app.MainLoop()