def savePoster(self, posterUrl, localId): hiresFilename = path(smewt.dirs.user_data_dir, 'images', '%s_hires.jpg' % localId, createdir=True) loresFilename = path(smewt.dirs.user_data_dir, 'images', '%s_lores.jpg' % localId) # TODO: use requests instead of urlopen open(hiresFilename, 'wb').write(urlopen(posterUrl).read()) # NOTE: we do the resizing here because if we leave it to the browser, # it will use a fast resampling algorithm, which will be of lower # quality than what we achieve here # lores = 80px high width, height = 60, 80 header_msg = 'Creating %dx%d screenshot' % (width, height) log.info('%s for %s...', header_msg, hiresFilename) im = Image.open(hiresFilename) log.debug('%s: resizing...', header_msg) im.thumbnail((width, height), Image.ANTIALIAS) log.debug('%s: saving to png...', header_msg) im.save(loresFilename, "PNG") log.debug('%s: done!', header_msg) return ('/user/images/%s_lores.jpg' % localId, '/user/images/%s_hires.jpg' % localId)
def downloadSubtitles(self, requested): # list all available subtitles lang = self.language.alpha2 with subliminal.Pool(4) as p: paths, languages, services, order = get_defaults(requested.keys(), [lang], self.services, None, languages_as=language_list) cache_dir = path(smewt.dirs.user_cache_dir, 'subliminal_cache/', createdir=True) subs = p.list_subtitles(requested.keys(), languages, services = services, cache_dir = cache_dir) if not subs: raise SmewtException('No subtitles could be found for files: %s' % requested.keys()) # set the correct filenames for the subs to be downloaded for video, subs_candidates in subs.items(): subtitleFilename = requested[video.path] for s in subs_candidates: s.path = subtitleFilename # pick the best subtitles from this list # taken from subliminal/async.py for video, subtitles in subs.iteritems(): subtitles.sort(key=lambda s: key_subtitles(s, video, languages, services, order), reverse=True) # download the subtitles tasks = create_download_tasks(subs, languages, multi=False) return p.consume_task_list(tasks)
def gen(path, filename): width, height = 200, 150 log.info("Creating %dx%d screenshot for %s..." % (width, height, path)) filename = utils.path(smewt.dirs.user_data_dir, "speeddial", filename, createdir=True) cmd = 'webkit2png -g 1000 600 "http://localhost:6543%s"' % path screenshot, _ = subprocess.Popen(shlex.split(cmd), stdout=subprocess.PIPE).communicate() im = Image.open(StringIO(screenshot)) im.thumbnail((width, height), Image.ANTIALIAS) im.save(filename, "PNG")
def __init__(self): super(SmewtDaemon, self).__init__() # Note: put log file in data dir instead of log dir so that it is # accessible through the user/ folder static view self.logfile = utils.path(smewt.dirs.user_data_dir, "Smewt.log") setupLogging(filename=self.logfile, with_time=True, with_thread=True) if smewt.config.PERSISTENT_CACHE: self.loadCache() # get a TaskManager for all the import tasks self.taskManager = TaskManager() # get our main graph DB self.loadDB() # get our collections: series and movies for now self.episodeCollection = Collection( name="Series", # import episodes and their subtitles too validFiles=[Episode.isValidEpisode, Subtitle.isValidSubtitle], mediaTagger=EpisodeTagger, dataGraph=self.database, taskManager=self.taskManager, ) self.movieCollection = Collection( name="Movie", # import movies and their subtitles too validFiles=[Movie.isValidMovie, Subtitle.isValidSubtitle], mediaTagger=MovieTagger, dataGraph=self.database, taskManager=self.taskManager, ) if config.REGENERATE_THUMBNAILS: # launch the regeneration of the thumbnails, but only after everything # is setup and we are able to serve requests Timer(3, self.regenerateSpeedDialThumbnails).start() if self.database.config.get("tvuMldonkeyPlugin"): # load up the feed watcher self.feedWatcher = FeedWatcher(self) # FIXME: this should go into a plugin.init() method from smewt.plugins import mldonkey mldonkey.send_command("vm") # do not rescan as it would be too long and we might delete some files that # are on an unaccessible network share or an external HDD self.taskManager.add(FuncTask("Update collections", self.updateCollections))
def loadDB(self): dbfile = smewt.settings.get("database_file") if not dbfile: dbfile = utils.path(smewt.dirs.user_data_dir, "Smewt.database", createdir=True) smewt.settings.set("database_file", dbfile) log.info("Loading database from: %s", dbfile) self.database = VersionedMediaGraph() try: self.database.load(dbfile) except: log.warning("Could not load database %s", dbfile)
def downloadSubtitles(self, requested): # list all available subtitles lang = self.language.alpha2 with subliminal.Pool(4) as p: paths, languages, services, order = get_defaults( requested.keys(), [lang], self.services, None, languages_as=language_list) cache_dir = path(smewt.dirs.user_cache_dir, 'subliminal_cache/', createdir=True) subs = p.list_subtitles(requested.keys(), languages, services=services, cache_dir=cache_dir) if not subs: raise SmewtException( 'No subtitles could be found for files: %s' % requested.keys()) # set the correct filenames for the subs to be downloaded for video, subs_candidates in subs.items(): subtitleFilename = requested[video.path] for s in subs_candidates: s.path = subtitleFilename # pick the best subtitles from this list # taken from subliminal/async.py for video, subtitles in subs.iteritems(): subtitles.sort(key=lambda s: key_subtitles( s, video, languages, services, order), reverse=True) # download the subtitles tasks = create_download_tasks(subs, languages, multi=False) return p.consume_task_list(tasks)
def action(request): action = request.matchdict['action'] log.debug('Action: %s - params = %s', action, request.params) try: if action == 'rescan_collections': SMEWTD_INSTANCE.rescanCollections() return 'OK' elif action == 'update_collections': SMEWTD_INSTANCE.updateCollections() return 'OK' elif action == 'clear_collections': SMEWTD_INSTANCE.clearDB() return 'Collections cleared!' elif action == 'clear_cache': SMEWTD_INSTANCE.clearCache() return 'Cache cleared!' elif action == 'subscribe': SMEWTD_INSTANCE.feedWatcher.addFeed(request.params['feed']) return 'OK' elif action == 'unsubscribe': SMEWTD_INSTANCE.feedWatcher.removeFeed(request.params['feed']) return 'OK' elif action == 'update_feed': SMEWTD_INSTANCE.feedWatcher.updateFeedUrl(request.params['feed']) return 'OK' elif action == 'set_last_update': SMEWTD_INSTANCE.feedWatcher.setLastUpdateUrlIndex(request.params['feed'], int(request.params['index'])) return 'OK' elif action == 'check_feeds': def bg_task(): SMEWTD_INSTANCE.feedWatcher.checkAllFeeds() threading.Thread(target=bg_task).start() return 'OK' elif action == 'clear_event_log': EventServer.events.clear() return 'OK' elif action == 'mldonkey_start': if mldonkey.start(): return 'OK' else: return 'Could not find mldonkey executable...' elif action == 'mldonkey_stop': mldonkey.stop() return 'OK' elif action == 'set_watched': title = unicode(request.params['title']) watched = from_js(request.params['watched']) SMEWTD_INSTANCE.database.find_one(Movie, title=title).watched = watched return 'OK' elif action == 'set_collection_folders': folders = json.loads(request.params['folders']) get_collection(request.params['collection']).setFolders(folders) return 'OK' elif action == 'add_collection_folder': get_collection(request.params['collection']).addFolder() return 'OK' elif action == 'delete_collection_folder': index = int(request.params['index']) get_collection(request.params['collection']).deleteFolder(index) return 'OK' elif action == 'classify_incoming_files': # add as task to the task manager to be able to see progress config = SMEWTD_INSTANCE.database.config incoming = config.get('incomingFolder', '') if not os.path.exists(incoming): msg = 'Incoming folder doesn\'t exist: %s' % incoming log.warning(msg) return msg # find the root folder for moving episodes for c in config.collections: if c.name == 'Series': try: series_folder = json.loads(c.folders)[0][0] except IndexError: return 'OK' result = [] for f in utils.dirwalk(incoming): info = guessit.guess_file_info(f, 'autodetect') if info['type'].startswith('episode'): path = utils.path(series_folder, info['series'], 'Season %d' % info['season'], os.path.basename(f), createdir=True) # FIXME: add as task in the task manager log.info('Moving %s to %s...', os.path.basename(f), path) shutil.copy(f, path) os.remove(f) result.append('Moved %s' % os.path.basename(f)) return '\n'.join(result) or 'OK' elif action == 'regenerate_thumbnails': SMEWTD_INSTANCE.regenerateSpeedDialThumbnails() return 'OK' elif action == 'get_subtitles': title = urllib2.unquote(request.params['title']) return get_subtitles(request.params['type'], title) elif action == 'play_movie': title = urllib2.unquote(request.params['title']) movie = SMEWTD_INSTANCE.database.find_one(Movie, title=title) play_video(movie, sublang=request.params.get('sublang')) return 'OK' elif action == 'play_episode': db = SMEWTD_INSTANCE.database series_name = urllib2.unquote(request.params['series']) series = db.find_one(Series, title=series_name) ep = db.find_one(Episode, series=series, season=int(request.params['season']), episodeNumber=int(request.params['episodeNumber'])) play_video(ep, sublang=request.params.get('sublang')) return 'OK' elif action == 'play_file': filename = urllib2.unquote(request.params['filename']) play_file(filename) return 'OK' elif action == 'set_last_viewed_tab': title = urllib2.unquote(request.params['title']) video = SMEWTD_INSTANCE.database.find_one(Metadata, title=title) video.lastViewedTab = int(request.params['tab']) return 'OK' elif action == 'post_comment': db = SMEWTD_INSTANCE.database movie = db.find_one(Movie, title = urllib2.unquote(request.params['title'])) db.Comment(metadata = movie, author = request.params['author'], date = int(time.time()), text = request.params['contents']) return 'OK' elif action == 'video_pause': mplayer.pause() return 'OK' elif action == 'video_stop': mplayer.stop() return 'OK' elif action == 'video_fback': mplayer.fast_back() return 'OK' elif action == 'video_back': mplayer.back() return 'OK' elif action == 'video_fwd': mplayer.forward() return 'OK' elif action == 'video_ffwd': mplayer.fast_forward() return 'OK' elif action == 'quit': # surely there's a better way to do this... def timebomb(): time.sleep(1) subprocess.call(['kill', '-2', str(os.getpid())]) threading.Thread(target=timebomb).start() return 'OK' else: return 'Error: unknown action: %s' % action except SmewtException as e: return str(e)
def _cacheFilename(self): return utils.path(smewt.dirs.user_cache_dir, "Smewt.cache", createdir=True)
from smewt.base.utils import path import smewt import json import atexit import logging log = logging.getLogger(__name__) """This module automatically loads (resp. saves) a single python dictionary when it is loaded (resp. when the python interpreter exits). This dictionary can contain anything, but it needs to be JSON-serializable. """ SETTINGS_FILENAME = path(smewt.dirs.user_data_dir, 'Smewt_preferences.json', createdir=True) settings = {} def load(): global settings try: settings = json.load(open(SETTINGS_FILENAME)) log.debug('Successfully loaded settings from file: %s', SETTINGS_FILENAME) except: pass def save(): json.dump(settings, open(SETTINGS_FILENAME, 'w')) log.debug('Successfully saved settings to file: %s', SETTINGS_FILENAME)