]> git.pld-linux.org Git - packages/griffith.git/blob - Kodi.py
import other fields as notes
[packages/griffith.git] / Kodi.py
1 # -*- coding: utf-8 -*-
2
3 __revision__ = '$Id: $'
4
5 # Copyright (c) 2015
6
7 # This program is free software; you can redistribute it and/or modify
8 # it under the terms of the GNU General Public License as published by
9 # the Free Software Foundation; either version 2 of the License, or
10 # (at your option) any later version.
11 #
12 # This program is distributed in the hope that it will be useful,
13 # but WITHOUT ANY WARRANTY; without even the implied warranty of
14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 # GNU Library General Public License for more details.
16 #
17 # You should have received a copy of the GNU General Public License
18 # along with this program; if not, write to the Free Software
19 # 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
20
21 # You may use and distribute this software under the terms of the
22 # GNU General Public License, version 2 or later
23
24 from plugins.imp import ImportPlugin as IP
25 import os
26 import gutils
27 import string
28 from xml.dom import minidom, Node
29 from lxml import etree
30 import zipfile
31 from shutil import rmtree
32 from tempfile import mkdtemp
33
34 import logging
35 log = logging.getLogger("Griffith")
36
37 """
38 Supports importing videodb.xml exported as single file from Kodi/XBMC.
39
40 http://kodi.wiki/view/Import-export_library
41 http://kodi.wiki/view/HOW-TO:Backup_the_video_library
42
43 See lib/plugins/imp/__init__.py for workflow how importer invokes methods from importer plugins
44 """
45 class ImportPlugin(IP):
46     description  = 'Kodi/XBMC MovieDB importer'
47     author       = 'Elan Ruusamäe'
48     email        = 'glen@pld-linux.org'
49     version      = '1.0'
50     file_filters = 'videodb.xml'
51     mime_types   = None
52
53     fileversion  = None
54     xml          = None
55     items        = None
56     itemindex    = 0
57
58     # used by get_movie_details method
59     # griffith field => kodi field
60     # griffith field is actual SQL column in 'movies' table
61     field_map = {
62         'title': 'title',
63         'o_title': 'originaltitle',
64         'year': 'year',
65         'runtime': 'runtime',
66         'rating': 'rating',
67         'plot': 'plot',
68         'director': 'director',
69         'studio': 'studio',
70         'country': 'country',
71         'classification': 'mpaa',
72         # while the trailer field exists, it is not useful for griffith
73         # as it's something like: "plugin://plugin.video.youtube/?action=play_video&videoid=..."
74         # however youtube urls can be probably fixed.
75         'trailer': 'trailer',
76     }
77
78     # rest of the stuff to insert into notes field
79     notes_map = {
80         _('Id') : 'id',
81         _('Play count'): 'playcount',
82         _('Date added'): 'dateadded',
83         _('Last played'): 'lastplayed',
84         _('Collection'): 'set',
85         _('Premiered'): 'premiered',
86         _('Aired'): 'aired',
87     }
88
89     def initialize(self):
90         if not IP.initialize(self):
91             return False
92         self.edit = False
93         return True
94
95     def set_source(self, name):
96         IP.set_source(self, name)
97         self.filename = name
98         self.fileversion = self.read_fileversion()
99         if self.fileversion == None:
100             gutils.error(_('The format of the file is not supported.'))
101             return False
102         return True
103
104     def clear(self):
105         """clear plugin state before next source file"""
106         IP.clear(self)
107         if self.xml:
108             self.xml = None
109             self.fileversion = None
110             self.items = None
111             self.itemindex = 0
112
113     def destroy(self):
114         """close all resources"""
115         IP.destroy(self)
116
117     def read_fileversion(self):
118         version = None
119         try:
120             self.xml = etree.parse(self.filename)
121             version = self.xml.xpath('/videodb/version')[0].text
122         except Exception, e:
123             log.error(str(e))
124         log.info('Found file version %s' % version)
125         return version
126
127     def count_movies(self):
128         """Returns number of movies in file which is about to be imported"""
129         if not self.xml:
130             log.error('No XML object')
131             return 0
132
133         count = 0
134
135         try:
136             count = int(self.xml.xpath('count(/videodb/movie)'))
137         except Exception, e:
138             log.exception(e)
139
140         log.info('%s movies for import' % count)
141         return count
142
143     def get_movie_details(self):
144         """Returns dictionary with movie details"""
145         if not self.xml:
146             log.error('XML not opened')
147             return None
148
149         if not self.items:
150             self.items = self.xml.xpath('/videodb/movie')
151             self.itemindex = 0
152
153         # don't bother for empty db (shouldn't happen really)
154         if not self.items or len(self.items) < 1:
155             return None
156
157         # no more items
158         if self.itemindex >= len(self.items):
159             return None
160
161         item = self.items[self.itemindex]
162
163         # fill details
164         details = {}
165         for k,v in self.field_map.items():
166             details[k] = item.findtext(v)
167
168         # if playcount set, means it's seen
169         details['seen'] = int(item.find('playcount').text) > 0
170
171         # genre can be multiple items, join by comma
172         details['genre'] = ', '.join(n.text for n in item.findall('genre'))
173
174         # build text for 'cast' field
175         cast = []
176         for actor in item.findall('actor'):
177             cast.append('%s as %s' % (actor.findtext('name'), actor.findtext('role')))
178
179         if cast:
180             details['cast'] = "\n".join(cast)
181
182         # put rest of information into notes field
183         notes = []
184         for k,v in self.notes_map.items():
185             v = item.findtext(v)
186             if v:
187                 notes.append('%s: %s' % (k, v))
188
189         # credits can have multiple values, handle separately
190         credits = ', '.join(n.text for n in item.findall('credits'))
191         if credits:
192             notes.append(_('Credits: %s') % credits)
193
194         if notes:
195             details['notes'] = "\n".join(notes)
196
197         # increment for next iteration
198         self.itemindex = self.itemindex + 1
199
200         return details
This page took 0.101672 seconds and 4 git commands to generate.