Moved metadata functions to their own module.
[pyTivo/TheBayer.git] / metadata.py
blob44771e28657e082d9881ce1b04ce3436c48b6428
1 import os
2 import subprocess
3 from datetime import datetime
4 from xml.dom import minidom
6 from lrucache import LRUCache
8 import config
10 # Something to strip
11 TRIBUNE_CR = ' Copyright Tribune Media Services, Inc.'
13 tivo_cache = LRUCache(50)
15 def tag_data(element, tag):
16 for name in tag.split('/'):
17 new_element = element.getElementsByTagName(name)
18 if not new_element:
19 return ''
20 element = new_element[0]
21 if not element.firstChild:
22 return ''
23 return element.firstChild.data
25 def _vtag_data(element, tag):
26 for name in tag.split('/'):
27 new_element = element.getElementsByTagName(name)
28 if not new_element:
29 return []
30 element = new_element[0]
31 elements = element.getElementsByTagName('element')
32 return [x.firstChild.data for x in elements if x.firstChild]
34 def _tag_value(element, tag):
35 item = element.getElementsByTagName(tag)
36 if item:
37 value = item[0].attributes['value'].value
38 name = item[0].firstChild.data
39 return name[0] + value[0]
41 def from_text(full_path):
42 metadata = {}
43 path, name = os.path.split(full_path)
44 for metafile in [os.path.join(path, 'default.txt'), full_path + '.txt',
45 os.path.join(path, '.meta', name) + '.txt']:
46 if os.path.exists(metafile):
47 for line in file(metafile):
48 if line.strip().startswith('#') or not ':' in line:
49 continue
50 key, value = [x.strip() for x in line.split(':', 1)]
51 if key.startswith('v'):
52 if key in metadata:
53 metadata[key].append(value)
54 else:
55 metadata[key] = [value]
56 else:
57 metadata[key] = value
58 return metadata
60 def basic(full_path):
61 base_path, title = os.path.split(full_path)
62 mtime = os.stat(full_path).st_mtime
63 if (mtime < 0):
64 mtime = 0
65 originalAirDate = datetime.fromtimestamp(mtime)
67 metadata = {'title': '.'.join(title.split('.')[:-1]),
68 'originalAirDate': originalAirDate.isoformat()}
70 metadata.update(from_text(full_path))
72 return metadata
74 def from_tivo(full_path):
75 if full_path in tivo_cache:
76 return tivo_cache[full_path]
78 metadata = {}
80 tdcat_path = config.get_bin('tdcat')
81 tivo_mak = config.get_server('tivo_mak')
82 if tdcat_path and tivo_mak:
83 tcmd = [tdcat_path, '-m', tivo_mak, '-2', full_path]
84 tdcat = subprocess.Popen(tcmd, stdout=subprocess.PIPE)
85 xmldoc = minidom.parse(tdcat.stdout)
86 showing = xmldoc.getElementsByTagName('showing')[0]
87 program = showing.getElementsByTagName('program')[0]
89 items = {'description': 'program/description',
90 'title': 'program/title',
91 'episodeTitle': 'program/episodeTitle',
92 'episodeNumber': 'program/episodeNumber',
93 'seriesTitle': 'program/series/seriesTitle',
94 'originalAirDate': 'program/originalAirDate',
95 'isEpisode': 'program/isEpisode',
96 'movieYear': 'program/movieYear',
97 'partCount': 'partCount',
98 'partIndex': 'partIndex'}
100 for item in items:
101 data = tag_data(showing, item)
102 if data:
103 metadata[item] = data
105 vItems = ['vActor', 'vChoreographer', 'vDirector',
106 'vExecProducer', 'vProgramGenre', 'vGuestStar',
107 'vHost', 'vProducer', 'vWriter']
109 for item in vItems:
110 data = _vtag_data(program, item)
111 if data:
112 metadata[item] = data
114 sb = showing.getElementsByTagName('showingBits')
115 if sb:
116 metadata['showingBits'] = sb[0].attributes['value'].value
118 for tag in ['starRating', 'mpaaRating', 'colorCode']:
119 value = _tag_value(program, tag)
120 if value:
121 metadata[tag] = value
123 rating = _tag_value(showing, 'tvRating')
124 if rating:
125 metadata['tvRating'] = 'x' + rating[1]
127 if 'description' in metadata:
128 desc = metadata['description']
129 metadata['description'] = desc.replace(TRIBUNE_CR, '')
131 tivo_cache[full_path] = metadata
133 return metadata