Ejemplo n.º 1
0
    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)
Ejemplo n.º 2
0
    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)
Ejemplo n.º 3
0
    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)
Ejemplo n.º 4
0
 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")
Ejemplo n.º 5
0
    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))
Ejemplo n.º 6
0
    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)
Ejemplo n.º 7
0
    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)
Ejemplo n.º 8
0
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)
Ejemplo n.º 9
0
 def _cacheFilename(self):
     return utils.path(smewt.dirs.user_cache_dir, "Smewt.cache", createdir=True)
Ejemplo n.º 10
0
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)