Anime Information Script - Nyx- - 02-26-2010
this is a python(2.6) script that gets anime infromation from anime-planet.com
i have the .py script setup to take system arguments, but the .exe will automatically start on black lagoon and you can search anime from there(so will the .py if you dont give it any system arguments). there is some serious problems on my linux partition when running the program(well not serious, but after viewing a handful of anime it would eventually close), if people want to attempt to use it on linux please give me results on if it worked or not or if there was any way for you to troubleshoot an error.
So far the .exe seems to work flawlessly on windows, the .py script requires 2 modules that arent packaged by default with python so its setup might be a little harder, but if your on linux they can both easily be downloaded through your package manager.(SEE BELOW--v)( python-lxml & python-wxgtk2.6 )
Heres a download link for VERSION 1.0(sorry about the size, py2exe had an error where i had to include all of lxml and gzip)
http://rapidshare.com/files/356379789/aInfo.exe
Code: import wx, lxml.html, urllib, sys, cStringIO, thread, time
def splitGenre(genreString):
Genres = genreString.split(', ')
Strings = []
String = ''
while True:
for genre in Genres:
if len(String) < 20:
String += genre+', '
else:
Strings.append(String[0:-2])
String = genre+', '
Strings.append(String[0:-2])
break
return Strings
def searchAnime(animeName):
site = urllib.urlopen("http://www.anime-planet.com/search.php?search_type=all&search="+animeName)
searchSource = site.read()
site.close()
searchPage = lxml.html.document_fromstring(searchSource)
searchSibling = searchPage.find_class('theme1')[0]
table = searchSibling.getnext().getnext().getnext()
searchResults = []
for tablerow in range(1,len(table)):
searchResults.append({'link':table[tablerow][0][0].attrib['href'],'name':table[tablerow][0][0].text_content().encode('utf-8').strip()})
return searchResults
def EVT_RELOAD(win,func):
win.Connect(-1,-1,111,func)
class RELOAD(wx.PyEvent):
def __init__(self, data):
wx.PyEvent.__init__(self)
self.SetEventType(111)
self.data = data
class MyApp(wx.Frame):
def __init__(self, parent, id, title):
wx.Frame.__init__(self, parent, id, title,size=(400, 400))
self.CreateStatusBar()
menubar = wx.MenuBar()
self.recMenu = wx.Menu()
idCount = 0
for anime in range(0, 5):
self.recMenu.Append(100+idCount, ' ', ' ')
idCount += 1
self.Bind(wx.EVT_MENU, self.switch, id=100,id2=105)
menubar.Append(self.recMenu, '&Recommendations')
self.SetMenuBar(menubar)
self.panel = wx.Panel(self, -1)
self.font = wx.SystemSettings_GetFont(wx.SYS_SYSTEM_FONT)
self.font.SetPointSize(10)
self.font1 = wx.SystemSettings_GetFont(wx.SYS_SYSTEM_FONT)
self.font1.SetPointSize(8)
self.font2 = wx.SystemSettings_GetFont(wx.SYS_SYSTEM_FONT)
self.font2.SetPointSize(12)
self.vbox = wx.BoxSizer(wx.VERTICAL)
self.hbox10 = wx.BoxSizer(wx.HORIZONTAL)
vbox1 = wx.BoxSizer(wx.VERTICAL)
self.picPanel = wx.Panel(self.panel, -1, size=(130, 130))
vbox1.Add(self.picPanel, 0)
self.blankImage = wx.BitmapFromImage(wx.ImageFromStream(cStringIO.StringIO(urllib.urlopen('http://www.scri8e.com/white.png').read())))
self.imageSlot = wx.StaticBitmap(self.picPanel, -1, self.blankImage)
self.hbox10.Add(vbox1, 0, wx.LEFT | wx.TOP, 10)
self.vbox2 = wx.BoxSizer(wx.VERTICAL)
self.titleSlot = wx.StaticText(self.panel, -1, ' ')
self.altTitleSlot = wx.StaticText(self.panel, -1, ' ')
self.episodeSlot = wx.StaticText(self.panel, -1, ' ')
self.studioSlot = wx.StaticText(self.panel, -1, ' ')
self.yearSlot = wx.StaticText(self.panel, -1, ' ')
self.genreSlot = wx.StaticText(self.panel, -1, ' ')
self.titleSlot.SetFont(self.font2)
self.altTitleSlot.SetFont(self.font1)
self.genreSlot.SetFont(self.font1)
self.episodeSlot.SetFont(self.font1)
self.studioSlot.SetFont(self.font1)
self.yearSlot.SetFont(self.font1)
self.vbox2.Add(self.titleSlot, 0)
self.vbox2.Add(self.altTitleSlot, 0)
self.vbox2.Add(self.episodeSlot, 0)
self.vbox2.Add(self.studioSlot, 0)
self.vbox2.Add(self.yearSlot, 0)
self.vbox2.Add(self.genreSlot, 0)
self.hbox10.Add(self.vbox2, 0, wx.TOP, 10)
self.vbox.Add(self.hbox10, 0)
hbox1 = wx.BoxSizer(wx.HORIZONTAL)
st2 = wx.StaticText(self.panel, -1, 'Description')
st2.SetFont(self.font)
hbox1.Add(st2, 0)
self.vbox.Add(hbox1, 0, wx.LEFT | wx.TOP, 10)
self.vbox.Add((-1, 5))
hbox2 = wx.BoxSizer(wx.HORIZONTAL)
self.descriptionSlot = wx.TextCtrl(self.panel, 204, style=wx.TE_MULTILINE | wx.TE_READONLY)
hbox2.Add(self.descriptionSlot, 1, wx.EXPAND)
self.vbox.Add(hbox2, 1, wx.LEFT | wx.RIGHT | wx.EXPAND, 10)
self.vbox.Add((-1, 10))
hbox3 = wx.BoxSizer(wx.HORIZONTAL)
searchButton = wx.Button(self.panel, 50, 'Search', size=(70,30))
self.Bind(wx.EVT_BUTTON, self.search, id=50)
hbox3.Add(searchButton, 0)
self.searchBox = wx.TextCtrl(self.panel, 51, size=(180, 30))
hbox3.Add(self.searchBox, 0, wx.LEFT | wx.BOTTOM | wx.EXPAND , 5)
self.vbox.Add(hbox3, 0, wx.ALIGN_RIGHT | wx.RIGHT, 10)
self.panel.SetSizer(self.vbox)
EVT_RELOAD(self, self.reload)
self.Centre()
self.Show(True)
def reload(self, event):
self.TITLE,self.ALTNAME,self.GENRES,self.DESCRIPTION,self.RECOMMENDATIONS,self.IMAGELINK,self.EPISODES,self.STUDIO,self.YEAR = event.data
self.titleSlot.SetLabel(self.TITLE)
self.altTitleSlot.SetLabel(' '+self.ALTNAME)
self.episodeSlot.SetLabel(' Eps:'+self.EPISODES)
self.studioSlot.SetLabel(' Studio: '+self.STUDIO)
self.yearSlot.SetLabel(' Year: '+self.YEAR)
self.genreSlot.SetLabel(' Tags: '+self.GENRES)
self.descriptionSlot.SetValue(self.DESCRIPTION)
self.imageSlot.SetBitmap(self.IMAGELINK)
for anime in self.RECOMMENDATIONS:
self.recMenu.Remove(100+self.RECOMMENDATIONS.index(anime))
self.recMenu.Append(100+self.RECOMMENDATIONS.index(anime), anime['name'], 'Tags:'+anime['genres'])
self.panel.Fit()
self.Fit()
def switch(self, event, *args):
EVTID = event.GetId()
choiceName = event.GetEventObject().GetMenuBar().GetLabel(event.GetId())
for dictionary in self.RECOMMENDATIONS:
if dictionary['name'] == choiceName:
thread.start_new_thread(self.getInfo, (self, dictionary['link']))
def getInfo(self, n, link):
site = urllib.urlopen('http://anime-planet.com'+link)
animeSource = site.read()
site.close()
animePage = lxml.html.document_fromstring(animeSource)
infoSibling = animePage.find_class('headerSynopsis')[0]
self.DESCRIPTION = repr(infoSibling.getnext().text_content().encode('utf-8').strip())
genres = []
for child in infoSibling.getparent().getnext()[1]:
try:
genres.append(child[0].text_content().encode('utf-8').strip())
except:
pass
genreStrings = splitGenre(', '.join(genres))
self.GENRES = '\n '.join(genreStrings)
self.TITLE = animePage.get_element_by_id('anime')[2].text_content().encode('utf-8').strip()
self.ALTNAME = ''
if animePage.get_element_by_id('anime')[2].getnext().attrib['class'] == 'aka light2':
self.ALTNAME = animePage.get_element_by_id('anime')[2].getnext().text_content().encode('utf-8').strip()
self.RECOMMENDATIONS = []
for recEntry in animePage.find_class('recEntry'):
recInfo = {}
count = 1
recGenres = []
if recEntry[1].tag == 'h2':
count = 2
try:
for li in recEntry[count][3][1]:
recGenres.append(li[0].text_content().encode('utf-8').strip())
except:
recGenres.append("No found genres for recommendation.")
recInfo['name'] = recEntry[0][0].text_content().encode('utf-8').strip()
recInfo['link'] = recEntry[0][0].attrib['href']
recInfo['genres'] = ', '.join(recGenres)
self.RECOMMENDATIONS.append(recInfo)
infoBox = animePage.find_class('box12')[0].find_class('mid')[0]
imagelink = 'http://anime-planet.com'+infoBox[0][0].attrib['src']
data = urllib.urlopen(imagelink)
stream = cStringIO.StringIO(data.read())
data.close()
self.IMAGELINK = wx.BitmapFromImage(wx.ImageFromStream(stream))
self.EPISODES = infoBox[1][0].text_content().encode('utf-8').strip().split('(')[1].split(' ')[0]
self.STUDIO = infoBox [1][1][0].text_content().encode('utf-8').strip()
self.YEAR = infoBox[1][2][0].text_content().encode('utf-8').strip()
i = (self.TITLE,self.ALTNAME,self.GENRES,self.DESCRIPTION,self.RECOMMENDATIONS,self.IMAGELINK,self.EPISODES,self.STUDIO,self.YEAR)
wx.PostEvent(n, RELOAD(i))
def search(self, event):
searchName = self.searchBox.GetValue()
firstResult = searchAnime(searchName)[0]['link']
thread.start_new_thread(self.getInfo, (self, firstResult))
app = wx.App()
app1 = MyApp(None, -1, 'Anime Information')
if len(sys.argv) > 1:
FirstSearch = searchAnime(sys.argv[1])
thread.start_new_thread(app1.getInfo, (app1, FirstSearch[0]['link']))
else:
thread.start_new_thread(app1.getInfo, (app1, '/anime/black-lagoon'))
app.MainLoop()
**you need wxpython and lxml modules to run the .py
RE: Anime Information Script - uber1337 - 02-26-2010
Great, you finished it! It looks nice, how did you work out your thread problem?(I see you didn't use threading)
RE: Anime Information Script - Nyx- - 02-26-2010
(02-26-2010, 09:46 PM)uber1337 Wrote: Great, you finished it! It looks nice, how did you work out your thread problem?(I see you didn't use threading)
ohhh its difficult but i had to create a custom wxpython event that got the information from my threaded getInfo() and it would use that to update the GUI On the same thread.
I still have the same problem I posted about in the linux section on here, but that error doesn't happen at all in windows, and i've only tested it on my linux box, so i dont know if its a global bug or something, but on windows it works, and thats what everyone uses soooo its chill ^^
heres the extracted code that just does the custom python event, i was able to get a really good example not in C++(it was in spanish, but that was only variable names since it was only a source code)
Code: def EVT_RELOAD(win,func):
win.Connect(-1,-1,111,func)
class RELOAD(wx.PyEvent):
def __init__(self, data):
wx.PyEvent.__init__(self)
self.SetEventType(111)
self.data = data
class MyApp(wx.Frame):
def __init__(self, parent, id, title):
...
EVT_RELOAD(self, self.reload)
...
def getInfo(self, n, link):#THIS GETS THREADED
...
i = (self.TITLE,self.ALTNAME,self.GENRES,self.DESCRIPTION,self.RECOMMENDATIONS,self.IMAGELINK,self.EPISODES,self.STUDIO,self.YEAR)
wx.PostEvent(n, RELOAD(i))
...
RE: Anime Information Script - uber1337 - 02-26-2010
(02-26-2010, 09:54 PM)Nyx- Wrote: ohhh its difficult but i had to create a custom wxpython event that got the information from my threaded getInfo() and it would use that to update the GUI On the same thread. Hmm that's a good idea.
The only thing I don't quite understand is this:
Code: def EVT_RELOAD(win,func):
win.Connect(-1,-1,111,func)
Oh and btw, the way you "refreshed" your GUI, is that wxPython only or can Tkinter do the same thing:
Code: class RELOAD(wx.PyEvent):
def __init__(self, data):
wx.PyEvent.__init__(self)
self.SetEventType(111)
self.data = data
RE: Anime Information Script - Nyx- - 04-05-2010
(02-26-2010, 10:15 PM)uber1337 Wrote: Hmm that's a good idea.
The only thing I don't quite understand is this:
Code: def EVT_RELOAD(win,func):
win.Connect(-1,-1,111,func)
Oh and btw, the way you "refreshed" your GUI, is that wxPython only or can Tkinter do the same thing:
Code: class RELOAD(wx.PyEvent):
def __init__(self, data):
wx.PyEvent.__init__(self)
self.SetEventType(111)
self.data = data
yea thats how the custom wxpython event is handled, its pretty confusing but i found a tutorial on it and thats what fixxed (some) of my problems. and im not 100% sure on tkinter, i've only made a few GUIs in the past with it for practice
RE: Anime Information Script - Drakeā¢ - 04-05-2010
That is very clever man. Keep it up.
RE: Anime Information Script - Fallen - 04-05-2010
Could you link us to the tutorial for the custom widgets @ Nyx-?
RE: Anime Information Script - Nyx- - 04-05-2010
(04-05-2010, 05:56 PM)Fallen Wrote: Could you link us to the tutorial for the custom widgets @ Nyx-?
it wasn't really a tutorial, it was just a spanish script with all the functions seperated out and basic enough for me to take out the parts i needed lol
this i found googling for wxpython custom events tho, and it has exactly what mine has(probably got it from same place)
http://stackoverflow.com/questions/2345608/wxpython-threading-gui-using-custom-event-handler
RE: Anime Information Script - Fallen - 04-05-2010
(04-05-2010, 06:15 PM)Nyx- Wrote: it wasn't really a tutorial, it was just a spanish script with all the functions seperated out and basic enough for me to take out the parts i needed lol
this i found googling for wxpython custom events tho, and it has exactly what mine has(probably got it from same place)
http://stackoverflow.com/questions/2345608/wxpython-threading-gui-using-custom-event-handler
Awesome thank you
RE: Anime Information Script - Sam - 04-05-2010
Is anime worth getting into? Like where is a good place to start.
|