Example #1
0
    def _lock(self):
        """Creates the database lock, returns an exception if it
        already exists"""
        if self.config['debug_disable_lock']:
            return

        if os.path.isfile(self.lock_file):
            raise utils.DataFatal("Database is locked by another process. "
                            "If you\'re sure there's no other process is using it, "
                            "remove the file ~/.trackma/lock")

        f = open(self.lock_file, 'w')
        f.close()
Example #2
0
    def __init__(self, messenger, config, account, mediatype):
        """Checks if the config is correct and creates an API object."""
        self.msg = messenger
        self.config = config
        self.msg.info(self.name, "Initializing...")

        # Get filenames
        userfolder = "%s.%s" % (account['username'], account['api'])
        self.userconfig_file = utils.to_data_path(userfolder, 'user.json')

        # Handle userconfig and media type to load
        self._load_userconfig()
        if mediatype:
            self.userconfig['mediatype'] = mediatype
            self._save_userconfig()

        # Import the API
        libbase = account['api']
        libname = "lib{0}".format(libbase)
        try:
            modulename = "trackma.lib.{0}".format(libname)
            __import__(modulename)
            apimodule = sys.modules[modulename]
        except ImportError as e:
            raise utils.DataFatal("Couldn't import API module: %s" % e)

        # Instance API
        libclass = getattr(apimodule, libname)
        self.api = libclass(self.msg, account, self.userconfig)

        # Get API version
        self.api_version = self.api.api_info['version']

        # Set mediatype
        mediatype = self.userconfig.get('mediatype')
        self.msg.info(self.name, "Using %s (%s)" % (libname, mediatype))

        # Get filenames
        self.queue_file = utils.to_data_path(userfolder,
                                             '%s.queue' % mediatype)
        self.info_file = utils.to_data_path(userfolder, '%s.info' % mediatype)
        self.cache_file = utils.to_data_path(userfolder, '%s.list' % mediatype)
        self.meta_file = utils.to_data_path(userfolder, '%s.meta' % mediatype)
        self.lock_file = utils.to_data_path(userfolder, 'lock')

        # Connect signals
        self.api.connect_signal('show_info_changed', self.info_update)
        self.api.connect_signal('userconfig_changed', self.userconfig_update)
Example #3
0
 def connect_signal(self, signal, callback):
     try:
         self.signals[signal] = callback
     except KeyError:
         raise utils.DataFatal("Invalid signal.")
Example #4
0
    def start(self):
        """
        Starts the engine.
        This function should be called before doing anything with the engine,
        as it initializes the data handler.
        """
        if self.loaded:
            raise utils.TrackmaError("Already loaded.")

        # Start the data handler
        try:
            (self.api_info, self.mediainfo) = self.data_handler.start()
        except utils.DataError as e:
            raise utils.DataFatal(str(e))
        except utils.APIError as e:
            raise utils.APIFatal(str(e))

        # Load redirection file if supported
        api = self.api_info['shortname']
        mediatype = self.data_handler.userconfig['mediatype']
        if redirections.supports(api, mediatype):
            if utils.file_exists(utils.to_config_path('anime-relations.txt')):
                fname = utils.to_config_path('anime-relations.txt')
                self.msg.debug(self.name, "Using user-provided redirection file.")
            else:
                fname = utils.to_data_path('anime-relations.txt')
                if self.config['redirections_time'] and (
                        not utils.file_exists(fname) or
                        utils.file_older_than(fname, self.config['redirections_time'] * 86400)):
                    self.msg.info(self.name, "Syncing redirection file...")
                    self.msg.debug(self.name, "Syncing from: %s" % self.config['redirections_url'])
                    utils.sync_file(fname, self.config['redirections_url'])

            if not utils.file_exists(fname):
                self.msg.debug(self.name, "Defaulting to repo provided redirections file.")
                fname = utils.DATADIR + '/anime-relations/anime-relations.txt'

            self.msg.info(self.name, "Parsing redirection file...")
            try:
                self.redirections = redirections.parse_anime_relations(fname, api)
            except Exception as e:
                self.msg.warn(self.name, "Error parsing anime-relations.txt!")
                self.msg.debug(self.name, "{}".format(e))

        # Rescan library if necessary
        if self.config['library_autoscan']:
            try:
                self.scan_library()
            except utils.TrackmaError as e:
                self.msg.warn(
                    self.name, "Can't auto-scan library: {}".format(e))

        # Load hook files
        if self.config['use_hooks']:
            hooks_dir = utils.to_config_path('hooks')
            if os.path.isdir(hooks_dir):
                import pkgutil

                self.msg.info(self.name, "Importing user hooks...")
                for loader, name, ispkg in pkgutil.iter_modules([hooks_dir]):
                    # List all the hook files in the hooks folder, import them
                    # and call the init() function if they have them
                    # We build the list "hooks available" with the loaded modules
                    # for later calls.
                    try:
                        self.msg.debug(
                            self.name, "Importing hook {}...".format(name))
                        module = loader.find_module(name).load_module(name)
                        if hasattr(module, 'init'):
                            module.init(self)
                        self.hooks_available.append(module)
                    except ImportError:
                        self.msg.warn(
                            self.name, "Error importing hook {}.".format(name))
                        import traceback
                        exc_type, exc_value, exc_traceback = sys.exc_info()
                        for line in traceback.format_exception(exc_type, exc_value, exc_traceback):
                            self.msg.debug(self.name, line.rstrip())

        # Start tracker
        if self.mediainfo.get('can_play') and self.config['tracker_enabled']:
            self.msg.debug(self.name, "Initializing tracker...")
            try:
                TrackerClass = self._get_tracker_class(
                    self.config['tracker_type'])

                self.tracker = TrackerClass(self.msg,
                                            self._get_tracker_list(),
                                            self.config,
                                            self.searchdirs,
                                            self.redirections,
                                            )
                self.tracker.connect_signal('detected', self._tracker_detected)
                self.tracker.connect_signal('removed', self._tracker_removed)
                self.tracker.connect_signal('playing', self._tracker_playing)
                self.tracker.connect_signal('update', self._tracker_update)
                self.tracker.connect_signal(
                    'unrecognised', self._tracker_unrecognised)
                self.tracker.connect_signal('state', self._tracker_state)
            except ImportError:
                self.msg.warn(self.name, "Couldn't import specified tracker: {}".format(
                    self.config['tracker_type']))

        self.loaded = True
        return True
Example #5
0
    def start(self):
        """
        Starts the engine.
        This function should be called before doing anything with the engine,
        as it initializes the data handler.
        """
        if self.loaded:
            raise utils.TrackmaError("Already loaded.")

        # Start the data handler
        try:
            (self.api_info, self.mediainfo) = self.data_handler.start()
        except utils.DataError as e:
            raise utils.DataFatal(str(e))
        except utils.APIError as e:
            raise utils.APIFatal(str(e))

        # Rescan library if necessary
        if self.config['library_autoscan']:
            try:
                self.scan_library()
            except utils.TrackmaError as e:
                self.msg.warn(self.name,
                              "Can't auto-scan library: {}".format(e))

        # Start tracker
        if self.mediainfo.get('can_play') and self.config['tracker_enabled']:
            # Choose the tracker we want to tart
            if self.config['tracker_type'] == 'plex':
                from trackma.tracker.plex import PlexTracker
                TrackerClass = PlexTracker
            elif os.name == 'nt':
                from trackma.tracker.win32 import Win32Tracker
                TrackerClass = Win32Tracker
            else:
                # Try trackers in this order: pyinotify, inotify, polling
                try:
                    from trackma.tracker.pyinotify import pyinotifyTracker
                    TrackerClass = pyinotifyTracker
                except ImportError:
                    try:
                        from trackma.tracker.inotify import inotifyTracker
                        TrackerClass = inotifyTracker
                    except ImportError:
                        from trackma.tracker.polling import PollingTracker
                        TrackerClass = PollingTracker

            self.tracker = TrackerClass(
                self.msg,
                self._get_tracker_list(),
                self.config['tracker_process'],
                self.config['searchdir'],
                int(self.config['tracker_interval']),
                int(self.config['tracker_update_wait_s']),
                self.config['tracker_update_close'],
                self.config['tracker_not_found_prompt'],
            )
            self.tracker.connect_signal('detected', self._tracker_detected)
            self.tracker.connect_signal('removed', self._tracker_removed)
            self.tracker.connect_signal('playing', self._tracker_playing)
            self.tracker.connect_signal('update', self._tracker_update)
            self.tracker.connect_signal('unrecognised',
                                        self._tracker_unrecognised)
            self.tracker.connect_signal('state', self._tracker_state)

        self.loaded = True
        return True
Example #6
0
    def start(self):
        """
        Starts the engine.
        This function should be called before doing anything with the engine,
        as it initializes the data handler.
        """
        if self.loaded:
            raise utils.TrackmaError("Already loaded.")

        # Start the data handler
        try:
            (self.api_info, self.mediainfo) = self.data_handler.start()
        except utils.DataError as e:
            raise utils.DataFatal(str(e))
        except utils.APIError as e:
            raise utils.APIFatal(str(e))

        # Rescan library if necessary
        if self.config['library_autoscan']:
            try:
                self.scan_library()
            except utils.TrackmaError as e:
                self.msg.warn(self.name,
                              "Can't auto-scan library: {}".format(e))

        # Load hook files
        if self.config['use_hooks']:
            hooks_dir = utils.to_config_path('hooks')
            if os.path.isdir(hooks_dir):
                import sys
                import pkgutil

                self.msg.info(self.name, "Importing user hooks...")
                for loader, name, ispkg in pkgutil.iter_modules([hooks_dir]):
                    # List all the hook files in the hooks folder, import them
                    # and call the init() function if they have them
                    # We build the list "hooks available" with the loaded modules
                    # for later calls.
                    try:
                        self.msg.debug(self.name,
                                       "Importing hook {}...".format(name))
                        module = loader.find_module(name).load_module(name)
                        if hasattr(module, 'init'):
                            module.init(self)
                        self.hooks_available.append(module)
                    except ImportError:
                        self.msg.warn(self.name,
                                      "Error importing hook {}.".format(name))

        # Start tracker
        if self.mediainfo.get('can_play') and self.config['tracker_enabled']:
            self.msg.debug(self.name, "Initializing tracker...")
            try:
                TrackerClass = self._get_tracker_class(
                    self.config['tracker_type'])

                self.tracker = TrackerClass(
                    self.msg,
                    self._get_tracker_list(),
                    self.config['tracker_process'],
                    self.searchdirs,
                    int(self.config['tracker_interval']),
                    int(self.config['tracker_update_wait_s']),
                    self.config['tracker_update_close'],
                    self.config['tracker_not_found_prompt'],
                )
                self.tracker.connect_signal('detected', self._tracker_detected)
                self.tracker.connect_signal('removed', self._tracker_removed)
                self.tracker.connect_signal('playing', self._tracker_playing)
                self.tracker.connect_signal('update', self._tracker_update)
                self.tracker.connect_signal('unrecognised',
                                            self._tracker_unrecognised)
                self.tracker.connect_signal('state', self._tracker_state)
            except ImportError:
                self.msg.warn(
                    self.name, "Couldn't import specified tracker: {}".format(
                        self.config['tracker_type']))

        self.loaded = True
        return True