Esempio n. 1
0
    def set_task(self, task):
        """ Propagate a change in local tasks into server """
        if self._parameters["state"] != "online":
            return

        sync_tags = self._xmpp.get_synchronized_tags()
        tags = task.get_tags_name()
        tag_overlap = set(sync_tags) & set(tags)
        if not tag_overlap:
            return

        if task.get_id() in self._changed_remotely:
            self._changed_remotely.remove(task.get_id())
            return

        Log.info("GTG --set--> PubSub: [%s] '%s'" %
                 (task.get_id(), task.get_title()))

        doc = xml.dom.minidom.parseString("<task></task>")
        task_id = task.get_id()
        task_xml = task_to_xml(doc, task).toxml()
        tags = task.get_tags_name()

        self._xmpp.set_task(task_id, tags, task_xml)
        self._sync_tasks.add(task_id)
        self._changed_locally.add(task_id)
Esempio n. 2
0
    def on_remote_set_task(self, task_id, raw_xml):
        """ Task was set on server """
        if self._parameters["state"] != "online":
            return

        if task_id in self._changed_locally:
            self._changed_locally.remove(task_id)
            return

        Log.info("PubSub --set--> GTG: [%s]" % task_id)

        # Parse XML string into <task> node
        xmldoc = xml.dom.minidom.parseString(raw_xml)
        task_xml = xmldoc.getElementsByTagName("task")[0]

        self._changed_remotely.add(task_id)
        task = self.datastore.get_task(task_id)
        if task:
            # Already exists
            task = task_from_xml(task, task_xml)
        else:
            # New task
            task = self.datastore.task_factory(task_id)
            task = task_from_xml(task, task_xml)
            self.datastore.push_task(task)
Esempio n. 3
0
    def on_connected(self):
        """ Get the initial set of the tasks from the XMPP """
        if self._parameters["state"] != "onine":
            self._parameters["state"] = "online"

        # Ensure all teams
        tag_tree = self.datastore.get_tagstore().get_main_view()
        for tag_id in tag_tree.get_all_nodes():
            tag = self.datastore.get_tag(tag_id)
            team = tag.get_people_shared_with()
            if len(team) > 0:
                self._xmpp.ensure_team(tag_id, team)

        # Fetch initial tasks
        for task_id, tag, raw_xml in self._xmpp.get_tasks():
            # Parse the raw_xml by DOM
            doc = xml.dom.minidom.parseString(raw_xml)
            task_xml = doc.getElementsByTagName("task")[0]

            # Create a new task or return the existing one with the same id
            task = self.datastore.task_factory(task_id)
            task = task_from_xml(task, task_xml)
            task.add_tag(tag)
            self.datastore.push_task(task)

            self._sync_tasks.add(task_id)
            Log.info("(init) PubSub --set--> GTG: [%s] '%s'" %
                     (task_id, task.get_title()))
Esempio n. 4
0
    def save_state(self):
        """ The last function before shutting this backend down.

        Disconnect XMPP and store picked_file """
        Log.info("Quitting backend")
        self._xmpp.disconnect()
        Log.info("Backend is shut down")
Esempio n. 5
0
    def set_task(self, task):
        """ Propagate a change in local tasks into server """
        if self._parameters["state"] != "online":
            return

        sync_tags = self._xmpp.get_synchronized_tags()
        tags = task.get_tags_name()
        tag_overlap = set(sync_tags) & set(tags)
        if not tag_overlap:
            return

        if task.get_id() in self._changed_remotely:
            self._changed_remotely.remove(task.get_id())
            return

        Log.info("GTG --set--> PubSub: [%s] '%s'" % (task.get_id(),
                task.get_title()))

        doc = xml.dom.minidom.parseString("<task></task>")
        task_id = task.get_id()
        task_xml = task_to_xml(doc, task).toxml()
        tags = task.get_tags_name()

        self._xmpp.set_task(task_id, tags, task_xml)
        self._sync_tasks.add(task_id)
        self._changed_locally.add(task_id)
Esempio n. 6
0
    def save_state(self):
        """ The last function before shutting this backend down.

        Disconnect XMPP and store picked_file """
        Log.info("Quitting backend")
        self._xmpp.disconnect()
        Log.info("Backend is shut down")
Esempio n. 7
0
    def on_connected(self):
        """ Get the initial set of the tasks from the XMPP """
        if self._parameters["state"] != "onine":
            self._parameters["state"] = "online"

        # Ensure all teams
        tag_tree = self.datastore.get_tagstore().get_main_view()
        for tag_id in tag_tree.get_all_nodes():
            tag = self.datastore.get_tag(tag_id)
            team = tag.get_people_shared_with()
            if len(team) > 0:
                self._xmpp.ensure_team(tag_id, team)

        # Fetch initial tasks
        for task_id, tag, raw_xml in self._xmpp.get_tasks():
            # Parse the raw_xml by DOM
            doc = xml.dom.minidom.parseString(raw_xml)
            task_xml = doc.getElementsByTagName("task")[0]

            # Create a new task or return the existing one with the same id
            task = self.datastore.task_factory(task_id)
            task = task_from_xml(task, task_xml)
            task.add_tag(tag)
            self.datastore.push_task(task)

            self._sync_tasks.add(task_id)
            Log.info("(init) PubSub --set--> GTG: [%s] '%s'" %
                (task_id, task.get_title()))
Esempio n. 8
0
    def _get_avatar(self, jid):
        """ Return avatar for jid if it is possible.

        The avatar is cached for the future runs.
        """
        if not os.path.exists(self.AVATARS_DIR):
            os.makedirs(self.AVATARS_DIR)

        # If avatar was cached, return it
        avatars = glob.glob(os.path.join(self.AVATARS_DIR, jid + ".*"))
        if len(avatars) > 0:
            return avatars[0]

        # Download vCard and avatar in it
        vcard = self['xep_0054'].get_vcard(jid)
        img_type = vcard['vcard_temp']['PHOTO']['TYPE']
        photo = vcard['vcard_temp']['PHOTO']['BINVAL']

        # Determine a name for the file
        if not img_type.startswith("image/") or " " in img_type:
            return None
        suffix = img_type[len("image/"):]
        name = os.path.join(self.AVATARS_DIR, "%s.%s" % (jid, suffix))

        Log.info("Saving avatar for '%s'" % jid)
        with open(name, 'wb') as avatar_file:
            avatar_file.write(photo)

        return name
Esempio n. 9
0
    def on_remote_set_task(self, task_id, raw_xml):
        """ Task was set on server """
        if self._parameters["state"] != "online":
            return

        if task_id in self._changed_locally:
            self._changed_locally.remove(task_id)
            return

        Log.info("PubSub --set--> GTG: [%s]" % task_id)

        # Parse XML string into <task> node
        xmldoc = xml.dom.minidom.parseString(raw_xml)
        task_xml = xmldoc.getElementsByTagName("task")[0]

        self._changed_remotely.add(task_id)
        task = self.datastore.get_task(task_id)
        if task:
            # Already exists
            task = task_from_xml(task, task_xml)
        else:
            # New task
            task = self.datastore.task_factory(task_id)
            task = task_from_xml(task, task_xml)
            self.datastore.push_task(task)
Esempio n. 10
0
    def _get_avatar(self, jid):
        """ Return avatar for jid if it is possible.

        The avatar is cached for the future runs.
        """
        if not os.path.exists(self.AVATARS_DIR):
            os.makedirs(self.AVATARS_DIR)

        # If avatar was cached, return it
        avatars = glob.glob(os.path.join(self.AVATARS_DIR, jid + ".*"))
        if len(avatars) > 0:
            return avatars[0]

        # Download vCard and avatar in it
        vcard = self['xep_0054'].get_vcard(jid)
        img_type = vcard['vcard_temp']['PHOTO']['TYPE']
        photo = vcard['vcard_temp']['PHOTO']['BINVAL']

        # Determine a name for the file
        if not img_type.startswith("image/") or " " in img_type:
            return None
        suffix = img_type[len("image/"):]
        name = os.path.join(self.AVATARS_DIR, "%s.%s" % (jid, suffix))

        Log.info("Saving avatar for '%s'" % jid)
        with open(name, 'wb') as avatar_file:
            avatar_file.write(photo)

        return name
Esempio n. 11
0
    def _discover_nodes(self):
        """ Discover all nodes user can access """
        subscriptions = self._get_subscribed_nodes()
        self._nodes = {}

        affiliations = self['xep_0060'].get_affiliations(self._pubsub)
        affiliations = affiliations['pubsub']['affiliations']
        if 'substanzas' not in affiliations.values:
            # No nodes available
            return
        for affiliation in affiliations.values['substanzas']:
            affiliation, node = affiliation['affiliation'], affiliation['node']
            if affiliation == 'owner' and node.startswith('GTG_'):
                # Check node config
                config = self['xep_0060'].get_node_config(self._pubsub, node)
                values = config['pubsub_owner']['configure']['form']['values']

                form = xep_0004.Form()
                form.add_field(
                    var='FORM_TYPE',
                    type='hidden',
                    value='http://jabber.org/protocol/pubsub#node_config')

                if int(values['pubsub#max_items']) < self.MAX_ITEMS:
                    Log.info("Max items is set only to %s" %
                             values['pubsub#max_items'])
                    form.add_field(var='pubsub#max_items',
                                   value=str(self.MAX_ITEMS))

                if values['pubsub#access_model'] != 'whitelist':
                    form.add_field(var='pubsub#access_model',
                                   value='whitelist')

                if not values['pubsub#notify_delete']:
                    form.add_field(var='pubsub#notify_delete', value='1')

                if not values['pubsub#notify_config']:
                    form.add_field(var='pubsub#notify_config', value='1')

                m = re.match('Project (@\w+)', values['pubsub#title'])
                if not m:
                    Log.warning("Malformed node name '%s'" %
                                values['pubsub#title'])
                    continue

                project_name = m.group(1)
                self._nodes[node] = project_name
                Log.info("Discovered project '%s'" % project_name)

                if len(form.field) > 1:
                    form['type'] = 'submit'
                    self['xep_0060'].set_node_config(self._pubsub, node, form)

                if node not in subscriptions:
                    self['xep_0060'].subscribe(self._pubsub, node)

                # Find teammates for cache
                self._teams[node] = self._get_teammates(node)
Esempio n. 12
0
def openxmlfile(zefile, root):
    """ Open an XML file in a robust way

    If file could not be opened, try:
        - file__
        - file.bak.0
        - file.bak.1
        - .... until BACKUP_NBR

    If file doesn't exist, create a new file """

    tmpfile = zefile + '__'
    try:
        if os.path.exists(zefile):
            return _try_openxmlfile(zefile, root)
        elif os.path.exists(tmpfile):
            Log.warning("Something happened to %s. Using backup" % zefile)
            os.rename(tmpfile, zefile)
            return _try_openxmlfile(zefile, root)
        else:
            # Creating empty file
            doc, xmlproject = emptydoc(root)
            newfile = savexml(zefile, doc)
            if not newfile:
                Log.error("Could not create a new file %s" % zefile)
                sys.exit(1)
            return _try_openxmlfile(zefile, root)

    except IOError as msg:
        print(msg)
        sys.exit(1)

    except xml.parsers.expat.ExpatError as msg:
        errormsg = "Error parsing XML file %s: %s" % (zefile, msg)
        Log.error(errormsg)
        if os.path.exists(tmpfile):
            Log.warning("Something happened to %s. Using backup" % zefile)
            os.rename(tmpfile, zefile)
            # Ok, try one more time now
            try:
                return _try_openxmlfile(zefile, root)
            except Exception as msg:
                Log.warning('Failed with reason: %s' % msg)

        # Try to revert to backup
        backup_name = _get_backup_name(zefile)
        for i in range(BACKUP_NBR):
            backup_file = "%s.bak.%d" % (backup_name, i)
            if os.path.exists(backup_file):
                Log.info("Trying to restore backup file %s" % backup_file)
                try:
                    return _try_openxmlfile(backup_file, root)
                except Exception as msg:
                    Log.warning('Failed with reason: %s' % msg)

        Log.info("No suitable backup was found")
        sys.exit(1)
Esempio n. 13
0
    def _discover_nodes(self):
        """ Discover all nodes user can access """
        subscriptions = self._get_subscribed_nodes()
        self._nodes = {}

        affiliations = self['xep_0060'].get_affiliations(self._pubsub)
        affiliations = affiliations['pubsub']['affiliations']
        if 'substanzas' not in affiliations.values:
            # No nodes available
            return
        for affiliation in affiliations.values['substanzas']:
            affiliation, node = affiliation['affiliation'], affiliation['node']
            if affiliation == 'owner' and node.startswith('GTG_'):
                # Check node config
                config = self['xep_0060'].get_node_config(self._pubsub, node)
                values = config['pubsub_owner']['configure']['form']['values']

                form = xep_0004.Form()
                form.add_field(var='FORM_TYPE', type='hidden',
                    value='http://jabber.org/protocol/pubsub#node_config')

                if int(values['pubsub#max_items']) < self.MAX_ITEMS:
                    Log.info("Max items is set only to %s" %
                        values['pubsub#max_items'])
                    form.add_field(var='pubsub#max_items',
                        value=str(self.MAX_ITEMS))

                if values['pubsub#access_model'] != 'whitelist':
                    form.add_field(var='pubsub#access_model',
                        value='whitelist')

                if not values['pubsub#notify_delete']:
                    form.add_field(var='pubsub#notify_delete', value='1')

                if not values['pubsub#notify_config']:
                    form.add_field(var='pubsub#notify_config', value='1')

                m = re.match('Project (@\w+)', values['pubsub#title'])
                if not m:
                    Log.warning("Malformed node name '%s'" %
                        values['pubsub#title'])
                    continue

                project_name = m.group(1)
                self._nodes[node] = project_name
                Log.info("Discovered project '%s'" % project_name)

                if len(form.field) > 1:
                    form['type'] = 'submit'
                    self['xep_0060'].set_node_config(self._pubsub, node, form)

                if node not in subscriptions:
                    self['xep_0060'].subscribe(self._pubsub, node)

                # Find teammates for cache
                self._teams[node] = self._get_teammates(node)
Esempio n. 14
0
 def get_tasks(self):
     """ Return list of all available tasks """
     Log.info("Looking for available tasks")
     for node in self._nodes:
         project_tag = self._nodes[node]
         result_items = self['xep_0060'].get_items(self._pubsub, node,
                 max_items=self.MAX_ITEMS, block=True)
         items = result_items['pubsub']['items']['substanzas']
         for item in items:
             yield item['id'], project_tag, tostring(item['payload'])
Esempio n. 15
0
 def remove_task(self, task_id):
     """ After removing local task remove tasks from the server """
     if self._parameters["state"] != "online":
         return
     if task_id in self._sync_tasks:
         Log.info("GTG --del--> PubSub: [%s]" % task_id)
         self._xmpp.delete_task(task_id)
         self._sync_tasks.remove(task_id)
         if task_id in self._changed_locally:
             self._changed_locally.remove(task_id)
         if task_id in self._changed_remotely:
             self._changed_remotely.remove(task_id)
Esempio n. 16
0
 def get_tasks(self):
     """ Return list of all available tasks """
     Log.info("Looking for available tasks")
     for node in self._nodes:
         project_tag = self._nodes[node]
         result_items = self['xep_0060'].get_items(self._pubsub,
                                                   node,
                                                   max_items=self.MAX_ITEMS,
                                                   block=True)
         items = result_items['pubsub']['items']['substanzas']
         for item in items:
             yield item['id'], project_tag, tostring(item['payload'])
Esempio n. 17
0
    def on_new_remote_project(self, tag_id, team_jids):
        """ New project was added on server """
        if self._parameters["state"] != "online":
            return
        team = [unicode(member) for member in team_jids]
        Log.info("Pubsub --new project--> GTG: %s, teammates: %s" % (tag_id,
                team))

        tag = self.datastore.get_tag(tag_id)
        if tag is None:
            tag = self.datastore.new_tag(tag_id)
        tag.set_people_shared_with(team)
Esempio n. 18
0
 def remove_task(self, task_id):
     """ After removing local task remove tasks from the server """
     if self._parameters["state"] != "online":
         return
     if task_id in self._sync_tasks:
         Log.info("GTG --del--> PubSub: [%s]" % task_id)
         self._xmpp.delete_task(task_id)
         self._sync_tasks.remove(task_id)
         if task_id in self._changed_locally:
             self._changed_locally.remove(task_id)
         if task_id in self._changed_remotely:
             self._changed_remotely.remove(task_id)
Esempio n. 19
0
    def on_new_remote_project(self, tag_id, team_jids):
        """ New project was added on server """
        if self._parameters["state"] != "online":
            return
        team = [unicode(member) for member in team_jids]
        Log.info("Pubsub --new project--> GTG: %s, teammates: %s" %
                 (tag_id, team))

        tag = self.datastore.get_tag(tag_id)
        if tag is None:
            tag = self.datastore.new_tag(tag_id)
        tag.set_people_shared_with(team)
Esempio n. 20
0
    def on_remote_rm_task(self, task_id):
        """ Task was removed on server """
        if task_id not in self._sync_tasks:
            # This task is not synchronized via this synchronization service
            return

        if task_id in self._changed_locally:
            self._changed_locally.remove(task_id)
        if task_id in self._changed_remotely:
            self._changed_remotely.remove(task_id)

        Log.info("PubSub --del--> GTG: [%s]" % task_id)
        self.datastore.request_task_deletion(task_id)
        if task_id in self._sync_tasks:
            self._sync_tasks.remove(task_id)
Esempio n. 21
0
    def ensure_team(self, tag, team):
        """ Set the team members of the tag

        If a node for the tag doesn't exists, create it. """
        Log.info("Set team for tag '%s' to '%s'" % (tag, team))
        team_node = None
        for node, associated_tag in self._nodes.items():
            if associated_tag == tag:
                team_node = node
                break

        if team_node is None:
            team_node = self._create_node(tag)

        self._set_teammates(team_node, team)
Esempio n. 22
0
    def on_remote_rm_task(self, task_id):
        """ Task was removed on server """
        if task_id not in self._sync_tasks:
            # This task is not synchronized via this synchronization service
            return

        if task_id in self._changed_locally:
            self._changed_locally.remove(task_id)
        if task_id in self._changed_remotely:
            self._changed_remotely.remove(task_id)

        Log.info("PubSub --del--> GTG: [%s]" % task_id)
        self.datastore.request_task_deletion(task_id)
        if task_id in self._sync_tasks:
            self._sync_tasks.remove(task_id)
Esempio n. 23
0
    def ensure_team(self, tag, team):
        """ Set the team members of the tag

        If a node for the tag doesn't exists, create it. """
        Log.info("Set team for tag '%s' to '%s'" % (tag, team))
        team_node = None
        for node, associated_tag in self._nodes.items():
            if associated_tag == tag:
                team_node = node
                break

        if team_node is None:
            team_node = self._create_node(tag)

        self._set_teammates(team_node, team)
Esempio n. 24
0
    def _create_node(self, tag):
        """ Create a new node for tag """
        name = 'GTG_%s' % uuid.uuid4()
        form = xep_0004.Form()
        form.add_field(var='pubsub#max_items', value=str(self.MAX_ITEMS))
        form.add_field(var='pubsub#access_model', value='whitelist')
        form.add_field(var='pubsub#notify_delete', value='1')
        form.add_field(var='pubsub#notify_config', value='1')
        title = "Project %s" % tag
        form.add_field(var='pubsub#title', value=title)

        Log.info("Creating node '%s' for tag %s" % (name, tag))
        self['xep_0060'].create_node(self._pubsub, name, config=form)
        self['xep_0060'].subscribe(self._pubsub, name)
        self._nodes[name] = tag
        return name
Esempio n. 25
0
    def _create_node(self, tag):
        """ Create a new node for tag """
        name = 'GTG_%s' % uuid.uuid4()
        form = xep_0004.Form()
        form.add_field(var='pubsub#max_items', value=str(self.MAX_ITEMS))
        form.add_field(var='pubsub#access_model', value='whitelist')
        form.add_field(var='pubsub#notify_delete', value='1')
        form.add_field(var='pubsub#notify_config', value='1')
        title = "Project %s" % tag
        form.add_field(var='pubsub#title', value=title)

        Log.info("Creating node '%s' for tag %s" % (name, tag))
        self['xep_0060'].create_node(self._pubsub, name, config=form)
        self['xep_0060'].subscribe(self._pubsub, name)
        self._nodes[name] = tag
        return name
Esempio n. 26
0
    def _on_start(self, event):
        """ Do stuff after connection

        Fetch a list of assigned nodes, create a home node if needed. Get
        avatars if there are not available. """

        Log.info("Connected to PubSub")

        # Get roster notifications
        self.get_roster()
        self.send_presence()

        # Discover nodes and notify GTG about project nodes
        self._discover_nodes()
        for node, name in self._nodes.items():
            self._callback("project_tag", name, self._get_teammates(node))

        self._callback("connected")
Esempio n. 27
0
    def _on_start(self, event):
        """ Do stuff after connection

        Fetch a list of assigned nodes, create a home node if needed. Get
        avatars if there are not available. """

        Log.info("Connected to PubSub")

        # Get roster notifications
        self.get_roster()
        self.send_presence()

        # Discover nodes and notify GTG about project nodes
        self._discover_nodes()
        for node, name in self._nodes.items():
            self._callback("project_tag", name, self._get_teammates(node))

        self._callback("connected")
Esempio n. 28
0
    def _load_pickled_file(self, path, default_value=None):
        '''
        A helper function to load some object from a file.

        @param path: the relative path of the file
        @param default_value: the value to return if the file is missing or
        corrupt
        @returns object: the needed object, or default_value
        '''
        path = os.path.join(CoreConfig().get_data_dir(), path)
        if not os.path.exists(path):
            return default_value

        with open(path, 'r') as file:
            try:
                return pickle.load(file)
            except Exception:
                Log.error("Pickle file for backend '%s' is damaged" %
                          self.get_name())

        # Loading file failed, trying backups
        for i in range(1, PICKLE_BACKUP_NBR + 1):
            backup_file = "%s.bak.%d" % (path, i)
            if os.path.exists(backup_file):
                with open(backup_file, 'r') as file:
                    try:
                        data = pickle.load(file)
                        Log.info("Succesfully restored backup #%d for '%s'" %
                                 (i, self.get_name()))
                        return data
                    except Exception:
                        Log.error("Backup #%d for '%s' is damaged as well" %
                                  (i, self.get_name()))

        # Data could not be loaded, degrade to default data
        Log.error("There is no suitable backup for '%s', "
                  "loading default data" % self.get_name())
        return default_value
Esempio n. 29
0
    def _load_pickled_file(self, path, default_value=None):
        '''
        A helper function to load some object from a file.

        @param path: the relative path of the file
        @param default_value: the value to return if the file is missing or
        corrupt
        @returns object: the needed object, or default_value
        '''
        path = os.path.join(CoreConfig().get_data_dir(), path)
        if not os.path.exists(path):
            return default_value

        with open(path, 'r') as file:
            try:
                return pickle.load(file)
            except Exception:
                Log.error("Pickle file for backend '%s' is damaged" %
                          self.get_name())

        # Loading file failed, trying backups
        for i in range(1, PICKLE_BACKUP_NBR + 1):
            backup_file = "%s.bak.%d" % (path, i)
            if os.path.exists(backup_file):
                with open(backup_file, 'r') as file:
                    try:
                        data = pickle.load(file)
                        Log.info("Succesfully restored backup #%d for '%s'" %
                                (i, self.get_name()))
                        return data
                    except Exception:
                        Log.error("Backup #%d for '%s' is damaged as well" %
                                 (i, self.get_name()))

        # Data could not be loaded, degrade to default data
        Log.error("There is no suitable backup for '%s', "
                  "loading default data" % self.get_name())
        return default_value
Esempio n. 30
0
def openxmlfile(zefile, root):
    """ Open an XML file in a robust way

    If file could not be opened, try:
        - file__
        - file.bak.0
        - file.bak.1
        - .... until BACKUP_NBR

    If file doesn't exist, create a new file """

    # reset _USED_BACKUP and _BACKUP_FILE_INFO
    global _USED_BACKUP
    global _BACKUP_FILE_INFO
    _USED_BACKUP = False
    _BACKUP_FILE_INFO = ""
    tmpfile = zefile + '__'
    try:
        if os.path.exists(zefile):
            return _try_openxmlfile(zefile, root)
        elif os.path.exists(tmpfile):
            Log.warning("Something happened to %s. Using backup" % zefile)
            os.rename(tmpfile, zefile)
            _USED_BACKUP = True
            _BACKUP_FILE_INFO = "Recovered from backup made on: " + \
                datetime.datetime.fromtimestamp(
                    os.path.getmtime(tmpfile)).strftime('%Y-%m-%d')
            return _try_openxmlfile(zefile, root)

    except IOError as msg:
        print(msg)
        sys.exit(1)

    except xml.parsers.expat.ExpatError as msg:
        errormsg = "Error parsing XML file %s: %s" % (zefile, msg)
        Log.error(errormsg)
        if os.path.exists(tmpfile):
            Log.warning("Something happened to %s. Using backup" % zefile)
            os.rename(tmpfile, zefile)
            _USED_BACKUP = True
            _BACKUP_FILE_INFO = "Recovered from backup made on: " + \
                datetime.datetime.fromtimestamp(
                    os.path.getmtime(tmpfile)).strftime('%Y-%m-%d')
            # Ok, try one more time now
            try:
                return _try_openxmlfile(zefile, root)
            except Exception as msg:
                Log.warning('Failed with reason: %s' % msg)

    # Try to revert to backup
    backup_name = _get_backup_name(zefile)
    for i in range(BACKUP_NBR):
        backup_file = "%s.bak.%d" % (backup_name, i)
        if os.path.exists(backup_file):
            Log.info("Trying to restore backup file %s" % backup_file)
            _USED_BACKUP = True
            _BACKUP_FILE_INFO = "Recovered from backup made on: " + \
                datetime.datetime.fromtimestamp(
                    os.path.getmtime(backup_file)).strftime('%Y-%m-%d')
            try:
                return _try_openxmlfile(backup_file, root)
            except Exception as msg:
                Log.warning('Failed with reason: %s' % msg)

    Log.info("No suitable backup was found")

    # Creating empty file
    doc, xmlproject = emptydoc(root)
    newfile = savexml(zefile, doc)
    if not newfile:
        Log.error("Could not create a new file %s" % zefile)
        sys.exit(1)
    # set _USED_BACKUP even if there's a failure to notify about the same
    _USED_BACKUP = True
    _BACKUP_FILE_INFO = "No backups found. Created a new file"
    return _try_openxmlfile(zefile, root)

    # exit if execution reached this statement
    sys.exit(1)
Esempio n. 31
0
        Log.error(errormsg)
        if os.path.exists(tmpfile):
            Log.warning("Something happened to %s. Using backup" % zefile)
            os.rename(tmpfile, zefile)
            # Ok, try one more time now
            try:
                return _try_openxmlfile(zefile, root)
            except Exception, msg:
                Log.warning('Failed with reason: %s' % msg)

        # Try to revert to backup
        backup_name = _get_backup_name(zefile)
        for i in range(BACKUP_NBR):
            backup_file = "%s.bak.%d" % (backup_name, i)
            if os.path.exists(backup_file):
                Log.info("Trying to restore backup file %s" % backup_file)
                try:
                    return _try_openxmlfile(backup_file, root)
                except Exception, msg:
                    Log.warning('Failed with reason: %s' % msg)

        Log.info("No suitable backup was found")
        sys.exit(1)


# Return a doc element with only one root element of the name "root"


def emptydoc(root):
    doc = xml.dom.minidom.Document()
    rootproject = doc.createElement(root)
Esempio n. 32
0

class FallbackKeyring(Borg):

    def __init__(self):
        super(Keyring, self).__init__()
        if not hasattr(self, "keyring"):
            self.keyring = {}
            self.max_key = 1

    def set_password(self, name, password, userid=""):
        """ This implementation does nto need name and userid.
        It is there because of GNOMEKeyring """

        # Find unused key
        while self.max_key in self.keyring:
            self.max_key += 1

        self.keyring[self.max_key] = password
        return self.max_key

    def get_password(self, key):
        return self.keyring.get(key, "")

if gnomekeyring is not None:
    Keyring = GNOMEKeyring
else:
    Log.info("GNOME keyring was not found, passwords will be not stored after\
                                                              restart of GTG")
    Keyring = FallbackKeyring
Esempio n. 33
0
        Log.error(errormsg)
        if os.path.exists(tmpfile):
            Log.warning("Something happened to %s. Using backup" % zefile)
            os.rename(tmpfile, zefile)
            # Ok, try one more time now
            try:
                return _try_openxmlfile(zefile, root)
            except Exception, msg:
                Log.warning('Failed with reason: %s' % msg)

        # Try to revert to backup
        backup_name = _get_backup_name(zefile)
        for i in range(BACKUP_NBR):
            backup_file = "%s.bak.%d" % (backup_name, i)
            if os.path.exists(backup_file):
                Log.info("Trying to restore backup file %s" % backup_file)
                try:
                    return _try_openxmlfile(backup_file, root)
                except Exception, msg:
                    Log.warning('Failed with reason: %s' % msg)

        Log.info("No suitable backup was found")
        sys.exit(1)


# Return a doc element with only one root element of the name "root"

def emptydoc(root):
    doc = xml.dom.minidom.Document()
    rootproject = doc.createElement(root)
    doc.appendChild(rootproject)
Esempio n. 34
0
 def on_task_deleted(self, task_id, path):
     """ Stop tracking a deleted task if it is being tracked """
     Log.info('Hamster: task deleted %s', task_id)
     self.stop_task(task_id)
Esempio n. 35
0

class FallbackKeyring(Borg):
    def __init__(self):
        super(Keyring, self).__init__()
        if not hasattr(self, "keyring"):
            self.keyring = {}
            self.max_key = 1

    def set_password(self, name, password, userid=""):
        """ This implementation does nto need name and userid.
        It is there because of GNOMEKeyring """

        # Find unused key
        while self.max_key in self.keyring:
            self.max_key += 1

        self.keyring[self.max_key] = password
        return self.max_key

    def get_password(self, key):
        return self.keyring.get(key, "")


if GnomeKeyring is not None:
    Keyring = GNOMEKeyring
else:
    Log.info("GNOME keyring was not found, passwords will be not stored after\
                                                              restart of GTG")
    Keyring = FallbackKeyring
Esempio n. 36
0
 def on_task_deleted(self, task_id, path):
     """ Stop tracking a deleted task if it is being tracked """
     Log.info('Hamster: task deleted %s', task_id)
     self.stop_task(task_id)
Esempio n. 37
0
def openxmlfile(zefile, root):
    """ Open an XML file in a robust way

    If file could not be opened, try:
        - file__
        - file.bak.0
        - file.bak.1
        - .... until BACKUP_NBR

    If file doesn't exist, create a new file """

    # reset _USED_BACKUP and _BACKUP_FILE_INFO
    global _USED_BACKUP
    global _BACKUP_FILE_INFO
    _USED_BACKUP = False
    _BACKUP_FILE_INFO = ""
    tmpfile = zefile + '__'
    try:
        if os.path.exists(zefile):
            return _try_openxmlfile(zefile, root)
        elif os.path.exists(tmpfile):
            Log.warning("Something happened to %s. Using backup" % zefile)
            os.rename(tmpfile, zefile)
            _USED_BACKUP = True
            _BACKUP_FILE_INFO = "Recovered from backup made on: " + \
                datetime.datetime.fromtimestamp(
                    os.path.getmtime(tmpfile)).strftime('%Y-%m-%d')
            return _try_openxmlfile(zefile, root)

    except IOError as msg:
        print(msg)
        sys.exit(1)

    except xml.parsers.expat.ExpatError as msg:
        errormsg = "Error parsing XML file %s: %s" % (zefile, msg)
        Log.error(errormsg)
        if os.path.exists(tmpfile):
            Log.warning("Something happened to %s. Using backup" % zefile)
            os.rename(tmpfile, zefile)
            _USED_BACKUP = True
            _BACKUP_FILE_INFO = "Recovered from backup made on: " + \
                datetime.datetime.fromtimestamp(
                    os.path.getmtime(tmpfile)).strftime('%Y-%m-%d')
            # Ok, try one more time now
            try:
                return _try_openxmlfile(zefile, root)
            except Exception as msg:
                Log.warning('Failed with reason: %s' % msg)

    # Try to revert to backup
    backup_name = _get_backup_name(zefile)
    for i in range(BACKUP_NBR):
        backup_file = "%s.bak.%d" % (backup_name, i)
        if os.path.exists(backup_file):
            Log.info("Trying to restore backup file %s" % backup_file)
            _USED_BACKUP = True
            _BACKUP_FILE_INFO = "Recovered from backup made on: " + \
                datetime.datetime.fromtimestamp(
                    os.path.getmtime(backup_file)).strftime('%Y-%m-%d')
            try:
                return _try_openxmlfile(backup_file, root)
            except Exception as msg:
                Log.warning('Failed with reason: %s' % msg)

    Log.info("No suitable backup was found")

    # Creating empty file
    doc, xmlproject = emptydoc(root)
    newfile = savexml(zefile, doc)
    if not newfile:
        Log.error("Could not create a new file %s" % zefile)
        sys.exit(1)
    # set _USED_BACKUP even if there's a failure to notify about the same
    _USED_BACKUP = True
    _BACKUP_FILE_INFO = "No backups found. Created a new file"
    return _try_openxmlfile(zefile, root)

    # exit if execution reached this statement
    sys.exit(1)