Author: duncan
Date: Mon Apr 16 18:51:07 2007
New Revision: 9465
Modified:
branches/rel-1/freevo/ChangeLog
branches/rel-1/freevo/src/util/fxdimdb.py
branches/rel-1/freevo/src/video/plugins/imdb.py
Log:
[ 1683101 ] add fetching tv series episode info to imdb plugin
Patch from Christian Lyra applied
Modified: branches/rel-1/freevo/ChangeLog
==============================================================================
--- branches/rel-1/freevo/ChangeLog (original)
+++ branches/rel-1/freevo/ChangeLog Mon Apr 16 18:51:07 2007
@@ -24,6 +24,7 @@
* Added VIDEO_SEND_XINE_CMD event to send specific commands to xine
(F#1683699)
* Updated and fixed German translations (B#1672040)
* Updated and fixed video selection of audio, subtitles and chapters
(B#1677364)
+ * Updated IMDB download to extract season and episode from TV programs
(F#1683101)
* Updated ivtv record to work with SECAM-DK (F#1694182)
* Updated mplayer to allow the bottom field first and XvMC settings
(F#1694186,F#1683423)
* Updated rss feed for better url detection (B#1675373)
Modified: branches/rel-1/freevo/src/util/fxdimdb.py
==============================================================================
--- branches/rel-1/freevo/src/util/fxdimdb.py (original)
+++ branches/rel-1/freevo/src/util/fxdimdb.py Mon Apr 16 18:51:07 2007
@@ -94,6 +94,10 @@
self.fxdfile = None # filename, full path, WITHOUT extension
+ self.season = None # used if the file is a tv serie
+ self.episode = None # used if the file is a tv serie
+ self.newid = None # used if the file is a tv serie
+
self.append = False
self.device = None
self.regexp = None
@@ -168,12 +172,35 @@
return self.imdb_id_list
- def setImdbId(self, id):
+ def setImdbId(self, id, season, episode):
"""id (number)
Set an imdb_id number for object, and fetch data"""
+
self.imdb_id = id
- url = 'http://us.imdb.com/Title?%s' % id
+ self.season = season
+ self.episode = episode
+
+ if self.season and self.episode:
+ # This is a tv serie, lets use a special search
+ url = 'http://us.imdb.com/title/tt%s/episodes' % id
+ req = urllib2.Request(url, txdata, txheaders)
+
+ try:
+ idpage = urllib2.urlopen(req)
+ except urllib2.HTTPError, error:
+ raise FxdImdb_Net_Error("IMDB unreachable" + error)
+ return None
+
+ newid = self.findepisode(idpage)
+
+ if newid:
+ self.imdb_id = newid
+ self.newid = newid
+ idpage.close()
+
+ # do the standard search
+ url = 'http://us.imdb.com/Title?%s' % self.imdb_id
req = urllib2.Request(url, txdata, txheaders)
try:
@@ -183,6 +210,7 @@
return None
self.parsedata(idpage, id)
+
idpage.close()
@@ -338,6 +366,27 @@
else:
name = filename
+
+
+ # is this a serie with season and episode number?
+ # if so we will remember season and episode but will take it off from
name
+
+ # find SeasonXepisodeNumber
+ m = re.compile('([0-9]+)[xX]([0-9]+)')
+ res = m.search(name)
+ if res:
+ name = re.sub('%s.*' % res.group(0), '', name)
+ self.season = str(int(res.group(1)))
+ self.episode = str(int(res.group(2)))
+
+ # find S<season>E<episode>
+ m = re.compile('[sS]([0-9]+)[eE]([0-9]+)')
+ res = m.search(name)
+ if res:
+ name = re.sub('%s.*' % res.group(0), '', name)
+ self.season = str(int(res.group(1)))
+ self.episode = str(int(res.group(2)))
+
name = vfs.basename(vfs.splitext(name)[0])
name = re.sub('([a-z])([A-Z])', point_maker, name)
name = re.sub('([a-zA-Z])([0-9])', point_maker, name)
@@ -596,7 +645,7 @@
continue
yrm = y.findall(item.next.next)
#print yrm
-
+
id = idm.group(1)
name = item.string
year = len(yrm) > 0 and yrm[0] or '0000'
@@ -609,6 +658,29 @@
print self.imdb_id_list
return self.imdb_id_list
+ def findepisode(self, results):
+ """results (imdb html page)
+ Returns a new id for setImdbId with tv serie episode data"""
+
+ newid = None
+
+ try:
+ soup = BeautifulSoup(results.read(), convertEntities='xml')
+ except UnicodeDecodeError:
+ print "Unicode error; check that /usr/lib/python2.x/site.py has
the correct default encoding"
+ pass
+
+ m = re.compile('.*Season %s, Episode %s.*\/tt([0-9]+)' % (self.season,
self.episode))
+
+ for episode in soup.findAll('h4'):
+ info = m.search(str(episode))
+ if not info:
+ continue
+ newid = info.group(1)
+ break
+
+ return(newid)
+
def parsedata(self, results, id=0):
"""results (imdb html page), imdb_id
Returns tuple of (title, info(dict), image_urls)"""
@@ -631,8 +703,18 @@
# self.info['image'] = image['src']
self.title = title.next.strip()
- self.info['title'] = self.title
- self.info['year'] = title.find('a').string.strip()
+
+ #is this a serie? series pages a little different
+ if self.newid:
+ self.title = self.title + " - %sx%s - %s" % (self.season, \
+ self.episode, title.find('em').string.strip() )
+ self.info['title'] = self.title
+ y = title.find('em').next.next.string.strip()
+ self.info['year'] = y[1:-1]
+
+ else:
+ self.info['title'] = self.title
+ self.info['year'] = title.find('a').string.strip()
# Find the <div> with class info, each <h5> under this provides info
for info in main.findAll('div', {'class' : 'info'}):
@@ -743,7 +825,7 @@
# Format of an impawards.com image URL:
# http://www.impawards.com/<year>/posters/<title>.jpg
- #
+ #
# Some special characters like: blanks, ticks, ':', ','... have to be
replaced
imp_image_name = title.lower()
imp_image_name = imp_image_name.replace(u' ', u'_')
@@ -756,11 +838,11 @@
# build up an array with all kind of image urls
imp_image_urls = [ ]
imp_base_url = 'http://www.impawards.com/%s/posters' % year
-
+
# add the normal poster URL to image_urls
imp_image_url = '%s/%s.jpg' % (imp_base_url, imp_image_name)
imp_image_urls += [ imp_image_url ]
-
+
# add the xxl poster URL to image_urls
imp_image_url = '%s/%s_xlg.jpg' % (imp_base_url, imp_image_name)
imp_image_urls += [ imp_image_url ]
@@ -775,7 +857,7 @@
# check for valid URLs and add them to self.image_urls
for imp_image_url in imp_image_urls:
-
+
#print "IMPAWARDS: Checking image URL %s" % imp_image_url
try:
imp_req = urllib2.Request(imp_image_url, txdata, txheaders)
@@ -861,7 +943,10 @@
# remove leading and trailing spaces
s = s.strip()
# remove leading and trailing quotes
- s = s.strip('\'"')
+ #s = s.strip('\'"')
+ # remove quotes
+ s = re.sub('"', '', s)
+
if s[:5] == u'"':
s = s[5:]
if s[-5:] == u'"':
@@ -874,6 +959,7 @@
s = s.replace(u"&", u"&")
# ... but this is wrong for &#
s = s.replace(u"&#", u"&#")
+
return s
except:
return Unicode(line)
Modified: branches/rel-1/freevo/src/video/plugins/imdb.py
==============================================================================
--- branches/rel-1/freevo/src/video/plugins/imdb.py (original)
+++ branches/rel-1/freevo/src/video/plugins/imdb.py Mon Apr 16 18:51:07 2007
@@ -15,7 +15,7 @@
#
# -----------------------------------------------------------------------
# Freevo - A Home Theater PC framework
-# Copyright (C) 2002 Krister Lagerstrom, et al.
+# Copyright (C) 2002 Krister Lagerstrom, et al.
# Please see the file freevo/Docs/CREDITS for a complete list of authors.
#
# This program is free software; you can redistribute it and/or modify
@@ -52,9 +52,11 @@
if not config.USE_NETWORK:
self.reason = 'no network'
return
+ self.season = None
+ self.episode = None
plugin.ItemPlugin.__init__(self)
-
+
def imdb_get_disc_searchstring(self, item):
name = item.media.label
name = re.sub('([a-z])([A-Z])', point_maker, name)
@@ -63,7 +65,7 @@
for r in config.IMDB_REMOVE_FROM_LABEL:
name = re.sub(r, '', name)
parts = re.split('[\._ -]', name)
-
+
name = ''
for p in parts:
if p:
@@ -72,7 +74,7 @@
return name[:-1]
else:
return ''
-
+
def actions(self, item):
self.item = item
@@ -84,7 +86,7 @@
self.disc_set = False
return [ ( self.imdb_search , _('Search IMDB for this file'),
'imdb_search_or_cover_search') ]
-
+
elif item.mode in ('dvd', 'vcd') and item.info.has_key('tracks'):
self.disc_set = True
s = self.imdb_get_disc_searchstring(self.item)
@@ -100,7 +102,7 @@
'imdb_search_or_cover_search') ]
return []
-
+
def imdb_search(self, arg=None, menuw=None):
"""
search imdb for this item
@@ -111,14 +113,14 @@
box.show()
items = []
-
+
try:
duplicates = []
if self.disc_set:
self.searchstring = self.item.media.label
else:
self.searchstring = self.item.name
-
+
for id,name,year,type in fxd.guessImdb(self.searchstring,
self.disc_set):
try:
for i in self.item.parent.play_items:
@@ -133,6 +135,10 @@
self.imdb_create_fxd, (id, year)))
except UnicodeError, e:
print e
+ # if filename had a season/episode lets� grab it
+ self.season = fxd.season
+ self.episode = fxd.episode
+
except Exception, e:
print 'imdb_search:', e
box.destroy()
@@ -141,7 +147,7 @@
time.sleep(2)
box.destroy()
return
-
+
# for d in duplicates:
# items = [ menu.MenuItem('Add to "%s"' % d.name,
# self.imdb_add_to_fxd, (d, 'add')),
@@ -153,7 +159,7 @@
self.imdb_create_fxd(arg=items[0].arg, menuw=menuw)
return
- if items:
+ if items:
moviemenu = menu.Menu(_('IMDB Query'), items)
menuw.pushmenu(moviemenu)
return
@@ -176,12 +182,12 @@
back = 1
if menuw.menustack[-2].selected != self.item:
back = 2
-
+
# maybe we called the function directly because there was only one
# entry and we called it with an event
if menuw.menustack[-1].selected == self.item:
back = 0
-
+
# update the directory
if directory.dirwatcher:
directory.dirwatcher.scan()
@@ -189,25 +195,26 @@
# go back in menustack
for i in range(back):
menuw.delete_menu()
-
-
+
+
def imdb_create_fxd(self, arg=None, menuw=None):
"""
create fxd file for the item
"""
fxd = FxdImdb()
-
+
box = PopupBox(text=_('getting data...'))
box.show()
#if this exists we got a cdrom/dvdrom
- if self.item.media and self.item.media.devicename:
+ if self.item.media and self.item.media.devicename:
devicename = self.item.media.devicename
else:
devicename = None
-
- fxd.setImdbId(arg[0])
-
+
+ # restore season/episode if we have it
+ fxd.setImdbId(arg[0], self.season, self.episode)
+
if self.disc_set:
fxd.setDiscset(devicename, None)
else:
@@ -235,10 +242,10 @@
"""
#if this exists we got a cdrom/dvdrom
- if self.item.media and self.item.media.devicename:
+ if self.item.media and self.item.media.devicename:
devicename = self.item.media.devicename
else: devicename = None
-
+
fxd = FxdImdb()
fxd.setFxdFile(arg[0].fxd_file)
@@ -256,6 +263,6 @@
part = [ makePart('Variant 1', 'f1'), part ]
fxd.setVariants(part)
-
+
fxd.writeFxd()
self.imdb_menu_back(menuw)
-------------------------------------------------------------------------
This SF.net email is sponsored by DB2 Express
Download DB2 Express C - the FREE version of DB2 express and take
control of your XML. No limits. Just data. Click to get it now.
http://sourceforge.net/powerbar/db2/
_______________________________________________
Freevo-cvslog mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/freevo-cvslog