Daniel Danopia Posted May 20, 2010 Share Posted May 20, 2010 What happened to you dumping mplayer? :P BTW, Linux doesn't have/need program extensions, but the most common one that I've seen is .i386 or .x86_64 Quote Link to comment Share on other sites More sharing options...
Zimmer Posted May 20, 2010 Author Share Posted May 20, 2010 mplayer had much more stable playback and there was a lot of hacks to get wx Media Player working, so with the revised playback organization with the backend code, it was a LOT easier to use mplayer. Notice though it still does not support scrobbling :(. Quote Link to comment Share on other sites More sharing options...
Elementix Posted May 21, 2010 Share Posted May 21, 2010 Trying the sharky program today, I was able to listen to songs but it seems like the download selected button doesn't work. Nothing gets added to the queue. Is there a fix for this? Quote Link to comment Share on other sites More sharing options...
Zimmer Posted May 21, 2010 Author Share Posted May 21, 2010 Ya, that has had some major errors It does download Also when you play a song it downloads it (so there is not need to click the download button if you played that song) Quote Link to comment Share on other sites More sharing options...
GrooveDude Posted May 24, 2010 Share Posted May 24, 2010 Hi all GrooveShark gurus. I've written a small java api to grooveshark and I'm noticed that when using the "getSearch..." method I get crappy song ids back. If I use tinysong to give me the song id I can download the song perfectly. I noticed that groovewalrus (tnx btw for an super program) uses tinyosng. Is tinysong to be perfered? Quote Link to comment Share on other sites More sharing options...
Zimmer Posted May 24, 2010 Author Share Posted May 24, 2010 tinysong, what is that? I just use the JSON api and it has been working fine. Quote Link to comment Share on other sites More sharing options...
GrooveDude Posted May 25, 2010 Share Posted May 25, 2010 http://tinysong.com/s/bob+dylan (for example) which is what goovewalrus uses. This gives you a page of format: http://tinysong.com/gGgN; 8637707; Blowing In The Wind; 138; Bob Dylan; 209948; Bob Dylan; http://tinysong.com/ktXq; 304051; House Of The Risin' Sun; 138; Bob Dylan; 209948; Bob Dylan; http://tinysong.com/gC8F; 2780646; Jokerman; 138; Bob Dylan; 209948; Bob Dylan; http://tinysong.com/ktXd; 10437640; Everyone Must Get Stoned; 138; Bob Dylan; 209948; Bob Dylan; http://tinysong.com/6HR3; 8014340; Fixin' to Die; 138; Bob Dylan; 209948; Bob Dylan; http://tinysong.com/7gLe; 22130287; Like a Rolling Stone (live); 138; Bob Dylan; 209948; Bob Dylan; http://tinysong.com/6HRg; 8601216; House of the Rising Sun; 138; Bob Dylan; 209948; Bob Dylan; http://tinysong.com/dOIA; 185832; Blowin In The Wind; 138; Bob Dylan; 187269; Bob Dylan's Greatest Hits; http://tinysong.com/6HRa; 7605302; Song to Woody; 138; Bob Dylan; 209948; Bob Dylan;http://tinysong.com/ktX8; 303990; In My Time Of Dyin'; 138; Bob Dylan; 209948; Bob Dylan; Now you can search direct to grooveshark by sending a message with method "getSearchResults". This works gives you a page there are zillions of more options (like rank etc) per song. However if I use the songIDs from that search I get songs which is gibbrish, if i use the songID from teh tinysong search I get the correct song. Quote Link to comment Share on other sites More sharing options...
kaputtmacher Posted May 25, 2010 Share Posted May 25, 2010 (edited) im having the same problem as mrs_sheep im using htmlunit for the communication, but when i send my json request, like: {"method":"getCommunicationToken","header":{"session":"6ee9e3d3a6a885306c59d22736a7c406","clientRevision":"20100412.02","client":"gslite","uuid":"72CE6638-6F0F-4A0F-B9AF-36B63299022F"},"parameters":{"secretKey":"531619cee4e544839638fef531ae3f36"}} i just get {"header":{"session":"8e28ca85830e02580f1ca231daded8f0","alerts":[{"AlertID":"2","Text":"woot","Type":"1","Target":"1","TSExpires":null},{"AlertID":"3","Text":"woot","Type":"1","Target":"1","TSExpires":null}]},"result":"4bfbabf92eff1"} does anyone have an idea what this could be or how to fix it? i even sniffed the json string from firefox and used it in my IDE while debugging (of course firefox was open at this time and not 10 seconds past until i send the IDE request), to see if this may helps, but it doesnt so i think there's something else going on edit: ignore the different session, my error - they are now equal (request+response), but still the same error edit #2: @Zimmer could you help me a little bit? i just downloaded your tool and i see that there's something going on in the log with that json result. Or could you offer me the current source? :) my mistake... didnt notice that sha thing... Edited May 25, 2010 by kaputtmacher Quote Link to comment Share on other sites More sharing options...
TornadoChaser Posted May 25, 2010 Share Posted May 25, 2010 (edited) FYI... I use Grooveshark's search and not tinysong simply because it returns more results (200 vs 32max), however, it seems that tingsong somehow filters out songs that don't work on Grooveshark's main site... for example, if you search "linkin park" on Grooveshark's website and try playing the first two entries for the song "In the end" they will not work... tinysong, though, will not even return these songs as valid SongIDs... y this is the case tho I do not know... Edited May 25, 2010 by TornadoChaser Quote Link to comment Share on other sites More sharing options...
Zimmer Posted May 26, 2010 Author Share Posted May 26, 2010 Ya I did that neither return song keys json. So it might do it based on wether they have song keys. Quote Link to comment Share on other sites More sharing options...
GrooveDude Posted May 26, 2010 Share Posted May 26, 2010 So how do you find out which songs taht work out of the 200? Is it this "verified" flag? Quote Link to comment Share on other sites More sharing options...
Zimmer Posted May 26, 2010 Author Share Posted May 26, 2010 I just check the json. If it's empty then I don't add it to the song keys or servers and so it is essentially skipped . I am thinking of adding some checking when I return the search results or something like that. Quote Link to comment Share on other sites More sharing options...
pking55 Posted May 29, 2010 Share Posted May 29, 2010 (edited) New Release of Sharky Download here for all systems (note for mac replace mplayer.exe with mplayer.app and for linux replace mplayer.exe with whatever mplayer binary you use (and name it mplayer, no extenstion (cause unlike windows or mac I don't know the executable extension (plus they probably vary)) http://www.mediafire.com/download.php?ti3njknyuwy How do I get this working with Linux? I have wxPython installed, but I can't figure out which file I am supposed to run. Also, you can't name the mplayer binary as "mplayer" as it conflicts with the mplayer directory. I tried Sharky.exe in wine as well, and it launched, but it won't let me check any boxes (and it fails with an error when I try to "Play Selected"). Thanks for the app in any case, I hope we get can this working on Linux :) Edited May 29, 2010 by pking55 Quote Link to comment Share on other sites More sharing options...
kaputtmacher Posted May 29, 2010 Share Posted May 29, 2010 im now listening to the music with my own little app (and dont need that damn flash).. but im a little bit afraid... does anyone here have had problems because of their TOS? Quote Link to comment Share on other sites More sharing options...
kaputtmacher Posted May 31, 2010 Share Posted May 31, 2010 @zimmer you did not implement some methods (eg. logoutUser, mark*, ...) - do you think they check for those to get some informations who is using his own client? Quote Link to comment Share on other sites More sharing options...
The-Master Posted May 31, 2010 Share Posted May 31, 2010 Hi, I have exactly the same problem like kaputtmacher in post #158, what is the solution? Quote Link to comment Share on other sites More sharing options...
kaputtmacher Posted May 31, 2010 Share Posted May 31, 2010 the solution is that what you see is ok ^^ ignore the w00t, the result is correct, with that you can continue creating the token (take a look at nettech wiki) Quote Link to comment Share on other sites More sharing options...
The-Master Posted May 31, 2010 Share Posted May 31, 2010 thx, its working perfect now :D Quote Link to comment Share on other sites More sharing options...
Zimmer Posted May 31, 2010 Author Share Posted May 31, 2010 (edited) Oops thought I had both linux (and macosx) and windows versions in there, I will upload the new version. Also can you paste the grooveshark.log (in the app folder) here Edited May 31, 2010 by Zimmer Quote Link to comment Share on other sites More sharing options...
GrooveDude Posted June 2, 2010 Share Posted June 2, 2010 Hi all I got a GrooveShark plugin going for PS3 Media Server. http://ps3mediaserver.org/forum/viewtopic....f=12&t=6861 (Streaming is cool) Quote Link to comment Share on other sites More sharing options...
Zimmer Posted June 5, 2010 Author Share Posted June 5, 2010 New Version http://www.mediafire.com/?1hwzmmjzivm --------- Fixes some bugs Adds updating And other minor features Quote Link to comment Share on other sites More sharing options...
winnernet5000 Posted June 6, 2010 Share Posted June 6, 2010 I'm completely ignorant on a lot of this stuff but I have a lot of admiration for this project and I thought I'd try to help. That said please bear with me as I'm not knowledgeable about Python at all. For the New version I simply downloaded it and the previous sharky.exe. I then moved the files from "Sharky Version 6.4.2010.1.7z" into the older ~10MB folder and overwrote the files. I think this is how you would update but I'm not positive at all. Anyway: These were my experiences: -I would search for a song and get a list of results -I couldn't download the songs however -When I selected one song to play it did indeed play correctly (black mplayer window in the background and a "player" window saying "loading audio" with a bar indicating progress. -When I selected two songs to play it only played one and then stopped. Just a quick suggestion: I'm not sure if it is possible but ideally the player window would be able to be moved behind sharky itself so in the future we could be playing something and continue adding things to the queue. If I can help in any other way by testing builds or whatever please tell me! I'd love to help. Thanks for your work. Quote Link to comment Share on other sites More sharing options...
Zimmer Posted June 6, 2010 Author Share Posted June 6, 2010 Ok thanks for the suggestions also please post the grooveshark.log (in the application folder) Quote Link to comment Share on other sites More sharing options...
美国人 Posted June 7, 2010 Share Posted June 7, 2010 I ran Sharky on Fedora 13 after running: su -c "yum install p7zip python-simplejson python-httplib2 wxPython python-twisted PyYAML python-BeautifulSoup" 7za x Sharky\ Version\ 6.4.2010.1.7z cd Sharky\ Version\ 6.4.2010.1 python Twisted_Grooveshark_Gui.py I use VLC instead of mplayer so I decided to see if i could download the song instead. The download failed though. I attached grooveshark.log in this post: http://pastebay.com/102337 Quote Link to comment Share on other sites More sharing options...
Zimmer Posted June 7, 2010 Author Share Posted June 7, 2010 (edited) It seems your using an older version of twisted Update. If you were having issue replace your Twisted_Grooveshark_GUI.py file with this (this WILL NOT work with Sharky.exe) Please note this may not FIX the issue, if so please re post the log. Thank You and sorry for the inconvenience #!/usr/bin/python #python imports import sys import os import urllib #Twisted Stuff import twisted from twisted.internet import wxreactor wxreactor.install() from twisted.internet import reactor from twisted.python import log #wx python libaries import wx from wx.lib.mixins.listctrl import CheckListCtrlMixin, ListCtrlAutoWidthMixin from SimpleDialog import SimpleDialog # app libaries from Settings import Settings from Player import Player, DownloadManager, URLObject from twisted_Grooveshark import Grooveshark, EmptyJSONList from twisted_update import update, CurrentVersion, NoUpdate LEGAL = '''\ This application could be considered illegal for a number of reasons, please contact a lawyer for further information. We (the authors) are not responsible for any legal (or any other) trouble that results from the use of this application. ''' VERSION = '2010.6.4.1' class StandardError(Exception):     '''Standard Error for anything that doesn't fit for another error, or that error would be extremely specific.''' class SettingsError(Exception):     ''' An Error for Settings''' class StartGroovesharkError(Exception):     '''Error Starting Grooveshark''' #Begin WX CODE # Defined subclass for list types in popular and search tabs class CheckListCtrl(wx.ListCtrl, CheckListCtrlMixin, ListCtrlAutoWidthMixin):     'This class is for the check box list in both the popular and search tabs'     def __init__(self, parent, size, pos):         wx.ListCtrl.__init__(self, parent, -1, style=wx.LC_REPORT, size = size, pos = pos)         CheckListCtrlMixin.__init__(self)         ListCtrlAutoWidthMixin.__init__(self) # About Me Panel class AboutMe(wx.Panel):     def __init__(self, parent, size, pos):         log.msg('Setting up about page')         log.msg('__init__ of wx.Panel')         wx.Panel.__init__(self, parent, -1, size = size, pos = pos)         # Grooveshark Image         log.msg('Creating image')         image = wx.Image('grooveshark_about.png', wx.BITMAP_TYPE_ANY)         height = image.GetHeight()         width = image.GetWidth()         image = image.Scale(height/7.0, width/7.0)         height = image.GetHeight()         width = image.GetWidth()         log.msg('wx.StaticBitmap - Grooveshark Icon')         wx.StaticBitmap(self, -1, image.ConvertToBitmap(), pos = (250 - (width/2.0),100 - (height/2.0)))         wx.StaticText(self, -1, '    Author: Zimmer', pos = (200, 175))         wx.StaticText(self, -1, '  App Name: Sharky', pos = (200, 190)) #Searh Panel class Search(wx.Panel):     def __init__(self, parent, size, pos):         log.msg('Accessing Grooveshark and Settings')         self.settings = parent.s         self.g = parent.g         log.msg('__init__ of wx.Panel')         wx.Panel.__init__(self, parent, -1, size = size, pos = pos)         #Search Bar         log.msg('Setting up Search Bar and Search Button')         self.search_bar = wx.TextCtrl(self, -1, size = (400, 20), pos = (20,10), style = wx.TE_PROCESS_ENTER)         self.search_bar.SetValue('Search')         #Search Button         self.search_button = wx.Button(self, -1, size = (60,20), pos = (425, 10), label = 'Search')         #Search Result Listings         log.msg('Creating CheckListCtrl')         self.search_results = CheckListCtrl(self, size =(465,160), pos = (20,50))         self.search_results.InsertColumn(0, ' ', width = 20)         self.search_results.InsertColumn(1, 'Song Name', width = 170)         self.search_results.InsertColumn(2, 'Album Name', width = 170)         self.search_results.InsertColumn(3, 'Artist', width = 100)         #Play and Download Buttons         log.msg('Creating Play and Download Button')         self.play = wx.Button(self, -1, "Play Selected", size = (100,20), pos = (275, 215))         self.download = wx.Button(self, -1, "Download Selected", size = (100,20), pos = (385, 215))         #info text         log.msg('Creating info text and search progress gauge')         self.info_text = wx.StaticText(self, -1, 'Please Input a Search Above', pos = (20, 35))         #progress bar         self.prog_bar = wx.Gauge(self, -1, 1, (220, 30), (100, 15))         self.prog_bar.Hide()         self.timer = wx.Timer(self)         # Bind Events         log.msg('binding search tab events')         self.Bind(wx.EVT_TIMER, self.on_timer)         self.Bind(wx.EVT_TEXT_ENTER, self.on_search, self.search_bar)         self.Bind(wx.EVT_BUTTON, self.on_search, self.search_button)         self.Bind(wx.EVT_BUTTON, self.on_play, self.play)         self.Bind(wx.EVT_BUTTON, self.on_download, self.download)         self.Bind(wx.EVT_LIST_ITEM_FOCUSED, self.on_list_item_focus)     def on_list_item_focus(self, event):         print 'on_focus called'         print event.GetLabel()         print event.GetPoint()         print event.GetIndex()             def start_grooveshark(self):         grooveshark_dialog = Start_Grooveshark(self.GetParent())         r = grooveshark_dialog.ShowModal()         if r == wx.ID_CLOSE:             # ask to retry             r = self.grooveshark_retry()             if r == wx.ID_YES:                 self.start_grooveshark()             else:                 self.GetParent().ChangeSelection(0)         else:             self.settings.grooveshark_started = True                     def grooveshark_retry(self):         log.msg('Asking User if they want to try and get all the Grooveshark Data again.')         g_dlg = SimpleDialog(self, 'Could not start Grooveshark\nTry Again?\n\n Note: Grooveshark cannot be used if you click no  \nuntil you click retry in the about tab.', 'Retry?', wx.YES_NO | wx.ICON_QUESTION)         result = g_dlg.ShowModal()         if result == wx.ID_YES:             log.msg('User Clicked Yes')             return wx.ID_YES         elif result == wx.ID_NO:             log.msg('User Clicked No')             return wx.ID_NO         else:             log.msg('Listen We Have Problems, when asking the user whether or not to retry getting grooveshark data, the user neither pressed YES OR NO')        # HELPER METHOD     def start_progress_bar(self):         self.timer.Start(50)         self.prog_bar.Show()     def stop_progress_bar(self):         self.timer.Stop()         self.prog_bar.Hide()     def error(self, error):         self.info_text.SetLabel('Error: %s' % error)     def set_info_text(self, information):         self.info_text.SetLabel(information)     def search_error(self, error):         self.error('Could not complete search. Check log for details.')         self.stop_progress_bar()         log.msg('******Search Error******')         log.err(error)         log.msg('=================')         log.msg('\n')     def play_error(self, error):         self.set_info_text('There was an error during playback or while preparing for playback. Check log for details.')         log.msg('******Playback Error******')         log.err(error)         log.msg('=================\n')     def download_error(self, error):         self.set_info_text('There was an error downloading.')         log.msg('******Playback Error******')         log.err(error)         log.msg('=================\n') # /HELPER METHODS #Events     def on_timer(self, event):         self.prog_bar.Pulse()     def on_search(self, event):         #Start Progress Bar         self.start_progress_bar()         #Notify the user         self.set_info_text('Searching...')         #         log.msg('Search String: %s' % self.search_bar.GetValue())         #Callbacks         search = self.search_bar.GetValue().lower()         d = self.g.search(search)         d.addCallback(self.display_search)         d.addErrback(self.search_error)     def on_play(self, event):         log.msg('User Clicked Play Button.')         if self.settings.mplayer == 'download':             dlg = SimpleDialog(None, 'Please download MPlayer and put it in either the application folder, or set where MPlayer in the Options Tab', 'MPlayer Error', style = wx.OK)             result = dlg.ShowModal()             print 'Result (AFTER) %s' % result         else:             log.msg('Getting Checked Songs')             # get checked songs             try:                 song_names, ids = self.get_checked_songs()             except StandardError:                 log.err()                 dlg = SimpleDialog(None, 'Error: Unable to start playback due to an unknow error, please try again.\n\nSorry for the inconvience', 'Playback Error', style = wx.OK)                 dlg.ShowModal()             else:#if there was success                 log.msg('Got checked songs: %s' % len(song_names))                 d = self.g.get_song_urls(ids)# passes stream data                 d.addCallback(self.stream_handler, song_names)                 d.addErrback(self.play_error)     def on_download(self, event):         log.msg('User Clicked Download Button.')         log.msg('Getting Checked Songs')         #get checked songs         try:             song_names, ids = self.get_checked_songs()         except StandardError:             # Stops it so it doesn't error saying that None is unpackable, but we have already dealt with the error so we don't need to do anything here either.             pass         else:#if there was success             log.msg('Got checked songs: %s' % len(song_names))             d = self.g.get_song_urls(ids)# passes stream data             d.addCallback(self.download_handler, song_names)             d.addErrback(self.download_error)     def stream_handler(self, _data, song_names):         # _data is a tuple of the urls and data, check we have atleast one url         if len(_data[0]) < 1:             dlg = SimpleDialog(None, 'Error contacting grooveshark.com, can not continue.', 'Playback Error', style = wx.OK)             dlg.ShowModal()         else:             print 'Preceding'             print _data             keys, urls = _data             # Test whether if all of the values in urls are skips             if all( ['SKIP' == url for url in urls] ):                 # if we need to skip them all then                 dlg = SimpleDialog(None, 'Invalid Search Entry. Grooveshark sometimes returns a song that no longer exists.', 'Playback Error', style = wx.OK)                 dlg.ShowModal()             else:                 # files, urls                 files = []                 for file_name in song_names:                     files.append(os.path.join(self.settings.music_folder, file_name + '.mp3'))                 p = Player(self)                 dm = DownloadManager()                 for url, file, data in zip(urls, files, keys):                     p.load_url(url = 'http://' + url + '/stream.php', filename = file, method = 'POST', postdata = 'streamKey=%s' % data.encode('ascii'), headers = {'content-type': 'application/x-www-form-urlencoded'})                 for urlobject in p.playback_queue:                     dm.add_urlobject(urlobject)                     self.GetParent().GetParent().downloads.add_url(urlobject)                 dm.start_downloads()                 wx.CallLater(10000, p.Show)     def download_handler(self, _data, song_names):         # _data is a tuple of the urls and data, check we have atleast one url         if len(_data[0]) < 1:             dlg = SimpleDialog(None, 'Error contacting grooveshark.com, can not continue.', 'Playback Error', style = wx.OK)             dlg.ShowModal()         else:                        keys, urls = _data             if all( ['SKIP' == url for url in urls] ):                 # if we need to skip them all then                 dlg = SimpleDialog(None, 'Invalid Search Entry. Grooveshark sometimes returns a song that no longer exists.', 'Download Error', style = wx.OK)                 dlg.ShowModal()             else:                 files = []                 for file_name in song_names:                     files.append(os.path.join(self.settings.music_folder, file_name + '.mp3'))                 dm = DownloadManager()                 for url, file, data in zip(urls, files, keys):                     urlobject = URLObject('http://' + url + '/stream.php', file, 'POST', postdata = 'streamKey=%s' % data.encode('ascii'), headers = {'content-type': 'application/x-www-form-urlencoded'})                     dm.add_urlobject(urlobject)                     self.GetParent().GetParent().downloads.add_url(urlobject)                 dm.start_downloads()         # /events # /processing methods (used by event methods)     def display_search(self, search_results):         log.msg('Displaying Search Results')         log.msg('Deleting any old results.')         self.search_results.DeleteAllItems()#Deletes any items that where there prevouisly         log.msg('Deleted old results.')         self.song_ids = []         self.song_names = []         log.msg('Enumerating through results.')         print type(search_results)         print len(search_results)         for n,i in enumerate(search_results):             index = self.search_results.InsertStringItem(n+1, str(n+1)+'.')             try:                 self.search_results.SetStringItem(index, 1, i['Name'])             except UnicodeEncodeError:                 self.search_results.SetStringItem(index, 1, repr(i['Name'])[2:-1])             self.search_results.SetStringItem(index, 2, i['AlbumName'])             try:                 self.search_results.SetStringItem(index, 3, i['ArtistName'])             except TypeError:                 self.search_results.SetStringItem(index, 1, '')             self.song_ids.append(i['SongID'])             self.song_names.append(i['Name'])         log.msg('Done Displaying Results.')         self.timer.Stop()         self.prog_bar.Hide()         log.msg('Stopping Progress Bar.')         self.set_info_text('Done.')         log.msg('Done with search results.')     def get_checked_songs(self):         item_count = self.search_results.GetItemCount()         checked_song_ids = []         checked_song_names = []         log.msg('Item Count (Number of Songs): %s' % item_count)         for i in xrange(item_count):             if self.search_results.IsChecked(i):                 checked_song_ids.append(self.song_ids[i])                 checked_song_names.append(self.song_names[i])         #Check that the item amounts are equal         if not len(checked_song_ids) == len(checked_song_names):             #We got problems             log.msg('******Error******')             log.msg('The number of ids and the number of song names does not equal each other.')             log.msg('Name(s): %s' % len(checked_songs_names))             log.msg('Id(s):  %s' % len(checked_songs_ids))             log.msg('=================')             log.msg('\n')             self.error('An unknown error occured.')             raise StandardError('An unknown error occured')         if len(checked_song_ids) < 1 and len(checked_song_names) < 1:             log.msg('******Error******')             log.msg('No Songs checked selected.')             log.msg('=================')             log.msg('\n')             self.error('No items checked.')             raise StandardError('No items checked')         else:             return checked_song_names, checked_song_ids         class Main(wx.Frame):     def __init__(self, parent, id, title):         wx.Frame.__init__(self, parent = parent, id = id, title = title, size = (500,300))         log.startLogging(sys.stdout)         self.s = Settings()         log.startLogging(open(self.s.log_file, 'wb'))         log.msg('Started Logging')         log.msg('Using Twisted Version: %s' % twisted.version)         log.msg('Starting Grooveshark and Started Settings.')         self.g = Grooveshark() # start up grooveshark         #Create notebook         log.msg('Setting up Notebook')         self.notebook = wx.Notebook(self)         self.notebook.g = self.g         #Sets Settings to also notebook for parent referance         self.notebook.s = self.s         #Tabs         log.msg('Adding Tabs (About)')         log.msg('Creating Instances of AboutMe')         self.about = AboutMe(self.notebook, (500,300), (0,0))         self.search = Search(self.notebook, (500,300), (0,0))         self.options = OptionsPanel(self.notebook, (500,300), (0,0))         self.downloads = DownloadListCtrl(self.notebook, (500,300), (0, 0))         log.msg('Adding it as tab to Notebook')         self.notebook.AddPage(self.about, 'About')         self.notebook.AddPage(self.search, 'Search')         self.notebook.AddPage(self.options, 'Options')         self.notebook.AddPage(self.downloads, 'Downloads')         #App Cleanup         self.Bind(wx.EVT_CLOSE, self.stop_reactor)         self.Bind(wx.EVT_NOTEBOOK_PAGE_CHANGED, self.tab_change)         #Show Dialog         #self.run_twisted()         log.msg('Starting Twisted')         # if reactor.running:             # log.msg('Twisted is running.')             # self.s.twisted_running = True         # else:             # log.msg('Twisted is not running')             # self.s.twisted_running = False             # dlg = SimpleDialog(None, 'Error: Network backend not running. This is not your fault, please try restarting this application and try again. \nSorry For the Inconvience.', 'Error', wx.OK | wx.ICON_ERROR)             # dlg.ShowModal()         if not self.s.eula:             dlg = SimpleDialog(None, LEGAL, 'Legal: Eula Agreement.', style = wx.YES_NO)             if dlg.ShowModal() == wx.ID_YES:                 log.msg('User agreed to the eula.')                 self.s.eula = True             else:                 log.msg('User did not agree to the eula.')                 self.Destroy()         # only do this if the eula has been agreed to         if self.s.eula:             # check for updates             d = update(VERSION)             d.addCallback(self.new_version)             d.addErrback(self.current_version)             def new_version(self, version):         # Got a new version         log.msg('Found New New Version: %s' % str(version))         dlg = SimpleDialog(None, 'New Version!\nVersion: %s' % version, 'New Version', style = wx.OK)         dlg.ShowModal()                     def current_version(self, error):         try:             error.raiseException()         except CurrentVersion:             log.msg('Got Current Version')         except NoUpdate:             log.msg('Got Newer Version Huh')         except:             log.msg('Uknown Error; Unable to update')             log.err()     def tab_change(self, event):         log.msg('Tab Changed')         log.msg('Tab Changed to: %s' % self.notebook.GetCurrentPage())         # start Grooveshark         if type(self.notebook.GetCurrentPage()) == Search:# if the class is an instance of Search             log.msg('Switched to Search Tab')             if self.s.grooveshark_started:                 log.msg('Grooveshark is started')             else:                 log.msg('Grooveshark is not started. Starting.')                 self.notebook.GetCurrentPage().start_grooveshark()     def stop_reactor(self, event):         log.msg('Stopping Reactor')         #Stop Reactor         reactor.stop()         log.msg('Destroying Window')         #Destroy Windows         self.Destroy()         log.msg('Quiting')         log.msg('\n\n')#Add Two lines so it is easy to distinguish between two app instances         #Quit         sys.exit() #Twisted Support     def run_twisted(self):          reactor.startRunning(installSignalHandlers=0)         timerid = wx.NewId()         self.timer = wx.Timer(self, timerid)         wx.EVT_TIMER(self, timerid, self.OnTimer)         self.timer.Start(10, False)     def OnTimer(self, event):         reactor.runUntilCurrent()         reactor.doIteration(0) #End Twisted Support class Start_Grooveshark(wx.Dialog):#Starts Grooveshark and gets the basics like the session, uuid, and token     def __init__(self, parent):         print type(parent)         wx.Dialog.__init__(self, parent = parent, id = -1, title = 'Starting Grooveshark', style = wx.SYSTEM_MENU)         self.s = parent.s         self.info_text = wx.StaticText(self, -1, 'Getting Groooveshark Data.', pos = (5,10))         self.info_text.Wrap(385)         if not reactor.running:             log.msg('\n\n ERROR ERROR ERROR \n TWISTED IS !NOT! RUNNING \ ERROR ERROR ERROR \n\n ')             dial = SimpleDialog(None, 'Error: Network backend not running. This is not your fault, please try restarting this application and try again. \nSorry For the Inconvience.', 'Error', wx.OK | wx.ICON_ERROR)             dial.ShowModal()         else:             self.g = parent.g             d=self.session()             d.addCallback(self.session_complete)             d.addErrback(self.error)     def session(self):         log.msg('Getting Grooveshark Session.')         d = self.g.session_and_country()         return d     def update_info(self, text):         log.msg('Updating Grooveshark Info: %s' % repr(text))         self.info_text.SetLabel(text)         self.info_text.Wrap(385)     def error(self, error):         log.msg('******Error******')         log.err(error)         log.msg('****End Error****')         self.update_info('Error: %s' % error.getErrorMessage())         self.SetReturnCode(wx.ID_CLOSE)         self.count = 5         wx.CallLater(1000, self.countdown)     def countdown(self):         original_text = self.info_text.GetLabel().replace('\n\n\tClosing in (%s)' % (self.count + 1), '')         self.update_info(original_text + '\n\n\tClosing in (%s)' % self.count)         self.count = self.count -1         if self.count >= 0:             wx.CallLater(1000, self.countdown)         else:             self.Destroy()     def session_complete(self, vars):         log.msg('Session: %s' % vars['sessionID'])         log.msg('Country ID: %s' % urllib.unquote(vars['country']))         # get token         d = self.g.get_token()         d.addCallback(self.token_complete)         d.addErrback(self.error)     def token_complete(self, token):         log.msg('token_complete')         self.update_info('Got Token. Done.')         wx.CallLater(100, self.Destroy)     def grooveshark_retry(self):         log.msg('Asking User if they want to try and get all the Grooveshark Data again.')         g_dlg = SimpleDialog(self, 'Could not start Grooveshark\nTry Again?\n\n Note: Grooveshark cannot be used if you click no  \nuntil you click retry in the about tab.', 'Retry?', wx.YES_NO | wx.ICON_QUESTION)         result = g_dlg.ShowModal()         if result == wx.ID_YES:             log.msg('User Clicked Yes')             return wx.ID_YES         else:             log.msg('User Clicked No')             return wx.ID_NO         class DownloadListCtrl(wx.Panel):     def __init__(self, parent, size, pos):         wx.Panel.__init__(self, parent, -1, size = size, pos = pos)         print 'ListCtrl Size: %s' % str(size)         self.list=wx.ListCtrl(self, -1, style=wx.LC_REPORT|wx.SUNKEN_BORDER, pos = (0, 0), size = (size[0] - 18, size[1] - 63))         self.list.Show(True)         self.list.InsertColumn(0, "URL")         self.list.InsertColumn(1, "Path")         self.list.InsertColumn(2, "Percent Downloaded")         self.list.InsertColumn(3, "State")         self.downloads = []     def add_url(self, urlobject):         download_item = DownloadItem(urlobject)         # insert don't append so we can use the index as the index for the list ctrl also         self.downloads.append(download_item)         print 'GETITEMCOUNT %s' % self.list.GetItemCount()         position = self.list.InsertStringItem(self.list.GetItemCount(), urlobject.url)         self.list.SetStringItem(position, 1, urlobject.path)         self.list.SetStringItem(position, 2, '0%')         if urlobject.started:             self.list.SetStringItem(position, 3, 'Downloading')         else:             self.list.SetStringItem(position, 3, 'Waiting')         download_item.add_size_callback(self.update_percent)                     def update_state(self, state, download_item):         position = self.downloads.index(download_item)         self.list.SetStringItem(position, 3, state)     def update_percent(self, percent, download_item):         position = self.downloads.index(download_item)         self.list.SetStringItem(position, 2,  '%.1f%%' % percent )         if percent == 100:             self.list.SetStringItem(position, 3, 'Done')     class DownloadItem(object):     def __init__(self, urlobject):         self.urlobject = urlobject         self.url = urlobject.url         self.path = urlobject.path         self.started = urlobject.started         self.size_callbacks = []         self.percent = None         urlobject.add_size_callback(self.data_received)         def data_received(self, data_length):         print 'Received Data'         for callback in self.size_callbacks:             if self.urlobject.total_amount is not None and not self.urlobject.total_amount == 0:                 self.percent = (float(data_length) / float(self.urlobject.total_amount)) * 100             callback(self.percent, self)         def add_size_callback(self, callback):         assert callable(callback)         # update the callback         if self.percent is not None:             callback(self.percent)         self.size_callbacks.append(callback)         class OptionsPanel(wx.Panel):     def __init__(self, parent, size, pos):         wx.Panel.__init__(self, parent, -1, size = size, pos = pos)         self.s = self.GetParent().s                 #Save Path         self.change_path_text = wx.StaticText(self, -1, 'Change Save Path:', pos = (20,3))         self.display_path = wx.TextCtrl(self, -1, self.s.music_folder, pos = (110,21), size = (300, -1))         self.save_button  = wx.Button(self, -1, 'Change', pos = (20,20))                 #Mplayer         self.change_mplayer_text = wx.StaticText(self, -1, 'Change MPlayer Path:', pos = (20,45))         self.display_mplayer_path = wx.TextCtrl(self, -1, self.s.mplayer, pos = (110,66), size = (300, -1))         self.mplayer_button  = wx.Button(self, -1, 'Change', pos = (20,65))         # Download Percent         self.download_percent_text = wx.StaticText(self, -1, 'Change Playback Buffer (%):', pos = (20, 90))         self.download_percent_display = wx.TextCtrl(self, -1, '%s' % int( self.s.download_percent * 100 ), pos = (150, 110), size = (25, -1))         self.download_percent_set_button = wx.Button(self, -1, 'Set Playback Buffer', pos = (20, 110))         #Binds         self.Bind(wx.EVT_BUTTON, self.change_save_path, self.save_button)         self.Bind(wx.EVT_BUTTON, self.change_mplayer_path, self.mplayer_button)         self.Bind(wx.EVT_BUTTON, self.set_playback_buffer, self.download_percent_set_button)         # self.Bind(wx.EVT_BUTTON, self.change_buffer, self.change_buffer)     def change_save_path(self, event):         self.save_dlg = wx.DirDialog(self, 'Select save folder.', 'C:/', name = 'save_dialog')         result = self.save_dlg.ShowModal()         if result == wx.ID_OK:             print 'Changed Path; OK'             self.s.music_folder = self.save_dlg.GetPath().replace('\\', '/')+'/'             self.display_path.SetValue(self.s.music_folder)         if result == wx.ID_CANCEL:             pass #User did not select a path, or they select the path and then hit cancel     def change_mplayer_path(self, event):         self.mplayer_dlg = wx.FileDialog(self, 'Select MPlayer executable.', 'C:/')         result = self.mplayer_dlg.ShowModal()         if result == wx.ID_OK:             print 'Changed MPlayer; OK'             input_path = self.mplayer_dlg.GetDirectory().replace('\\', '/') + '/' + self.mplayer_dlg.GetFilename()             if os.path.exists(input_path):                 self.s.mplayer = input_path                 self.display_mplayer_path.SetValue(self.s.mplayer)             else:                 print 'Path does not exist'             def set_playback_buffer(self, event):         self.s.download_percent = int( self.download_percent_display.GetValue() ) / 100.0         print 'Buffer: %i' % self.download_percent_display.GetValue() if __name__ == '__main__':     app = wx.App(redirect = False)     app_window = Main(parent = None, id = -1, title = 'Sharky')     app_window.Show()     app.SetTopWindow(app_window)     reactor.registerWxApp(app)     reactor.run() Edited June 7, 2010 by Zimmer Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.