Example #1
0
 def del_contact(self, account_jid, jid):
     """
     Remove jid from account_jid roster
     """
     try:
         account_jid_id = self.get_jid_id(account_jid)
         jid_id = self.get_jid_id(jid)
     except exceptions.PysqliteOperationalError as e:
         raise exceptions.PysqliteOperationalError(str(e))
     self.cur.execute(
         'DELETE FROM roster_group WHERE account_jid_id=? AND jid_id=?',
         (account_jid_id, jid_id))
     self.cur.execute(
         'DELETE FROM roster_entry WHERE account_jid_id=? AND jid_id=?',
         (account_jid_id, jid_id))
     self._timeout_commit()
Example #2
0
    def add_or_update_contact(self,
                              account_jid,
                              jid,
                              name,
                              sub,
                              ask,
                              groups,
                              commit=True):
        """
        Add or update a contact from account_jid roster
        """
        if sub == 'remove':
            self.del_contact(account_jid, jid)
            return

        try:
            account_jid_id = self.get_jid_id(account_jid)
            jid_id = self.get_jid_id(jid)
        except exceptions.PysqliteOperationalError as e:
            raise exceptions.PysqliteOperationalError(str(e))

        # Update groups information
        # First we delete all previous groups information
        self.cur.execute(
            'DELETE FROM roster_group WHERE account_jid_id=? AND jid_id=?',
            (account_jid_id, jid_id))
        # Then we add all new groups information
        for group in groups:
            self.cur.execute('INSERT INTO roster_group VALUES(?, ?, ?)',
                             (account_jid_id, jid_id, group))

        if name is None:
            name = ''

        self.cur.execute(
            'REPLACE INTO roster_entry VALUES(?, ?, ?, ?, ?)',
            (account_jid_id, jid_id, name,
             self.convert_human_subscription_values_to_db_api_values(sub),
             bool(ask)))
        if commit:
            self._timeout_commit()
Example #3
0
 def commit_to_db(self, values, write_unread=False):
     sql = '''INSERT INTO logs (jid_id, contact_name, time, kind, show,
             message, subject, additional_data) VALUES (?, ?, ?, ?, ?, ?, ?, ?)'''
     try:
         self.cur.execute(sql, values)
     except sqlite.OperationalError as e:
         raise exceptions.PysqliteOperationalError(str(e))
     except sqlite.DatabaseError:
         raise exceptions.DatabaseMalformed
     message_id = None
     if write_unread:
         try:
             self.con.commit()
             message_id = self.cur.lastrowid
         except sqlite.OperationalError as e:
             print(str(e), file=sys.stderr)
     else:
         self._timeout_commit()
     if message_id:
         self.insert_unread_events(message_id, values[0])
     return message_id
Example #4
0
 def get_jid_id(self, jid, typestr=None):
     """
     jids table has jid and jid_id logs table has log_id, jid_id,
     contact_name, time, kind, show, message so to ask logs we need jid_id
     that matches our jid in jids table this method wants jid and returns the
     jid_id for later sql-ing on logs typestr can be 'ROOM' or anything else
     depending on the type of JID and is only needed to be specified when the
     JID is new in DB
     """
     if jid.find('/') != -1:  # if it has a /
         jid_is_from_pm = self.jid_is_from_pm(jid)
         if not jid_is_from_pm:  # it's normal jid with resource
             jid = jid.split('/', 1)[0]  # remove the resource
     if jid in self.jids_already_in:  # we already have jids in DB
         self.cur.execute('SELECT jid_id FROM jids WHERE jid=?', [jid])
         row = self.cur.fetchone()
         if row:
             return row[0]
     # oh! a new jid :), we add it now
     if typestr == 'ROOM':
         typ = constants.JID_ROOM_TYPE
     else:
         typ = constants.JID_NORMAL_TYPE
     try:
         self.cur.execute('INSERT INTO jids (jid, type) VALUES (?, ?)',
                          (jid, typ))
         self.con.commit()
     except sqlite.IntegrityError:
         # Jid already in DB, maybe added by another instance. re-read DB
         self.get_jids_already_in_db()
         return self.get_jid_id(jid, typestr)
     except sqlite.OperationalError as e:
         raise exceptions.PysqliteOperationalError(str(e))
     jid_id = self.cur.lastrowid
     self.jids_already_in.append(jid)
     return jid_id
Example #5
0
    def write(self,
              kind,
              jid,
              message=None,
              show=None,
              tim=None,
              subject=None,
              additional_data={}):
        """
        Write a row (status, gcstatus, message etc) to logs database

        kind can be status, gcstatus, gc_msg, (we only recv for those 3),
        single_msg_recv, chat_msg_recv, chat_msg_sent, single_msg_sent we cannot
        know if it is pm or normal chat message, we try to guess see
        jid_is_from_pm()

        We analyze jid and store it as follows:
                jids.jid text column will hold JID if TC-related, room_jid if GC-related,
                ROOM_JID/nick if pm-related.
        """

        if self.jids_already_in == []:  # only happens if we just created the db
            self.open_db()

        contact_name_col = None  # holds nickname for kinds gcstatus, gc_msg
        # message holds the message unless kind is status or gcstatus,
        # then it holds status message
        message_col = message
        subject_col = subject
        additional_data_col = json.dumps(additional_data)
        if tim:
            time_col = float(tim)
        else:
            time_col = float(time.time())

        kind_col, show_col = self.convert_human_values_to_db_api_values(
            kind, show)

        write_unread = False

        # now we may have need to do extra care for some values in columns
        if kind == 'status':  # we store (not None) time, jid, show, msg
            # status for roster items
            try:
                jid_id = self.get_jid_id(jid)
            except exceptions.PysqliteOperationalError as e:
                raise exceptions.PysqliteOperationalError(str(e))
            if show is None:  # show is None (xmpp), but we say that 'online'
                show_col = constants.SHOW_ONLINE

        elif kind == 'gcstatus':
            # status in ROOM (for pm status see status)
            if show is None:  # show is None (xmpp), but we say that 'online'
                show_col = constants.SHOW_ONLINE
            jid, nick = jid.split('/', 1)
            try:
                # re-get jid_id for the new jid
                jid_id = self.get_jid_id(jid, 'ROOM')
            except exceptions.PysqliteOperationalError as e:
                raise exceptions.PysqliteOperationalError(str(e))
            contact_name_col = nick

        elif kind == 'gc_msg':
            if jid.find('/') != -1:  # if it has a /
                jid, nick = jid.split('/', 1)
            else:
                # it's server message f.e. error message
                # when user tries to ban someone but he's not allowed to
                nick = None
            try:
                # re-get jid_id for the new jid
                jid_id = self.get_jid_id(jid, 'ROOM')
            except exceptions.PysqliteOperationalError as e:
                raise exceptions.PysqliteOperationalError(str(e))
            contact_name_col = nick
        else:
            try:
                jid_id = self.get_jid_id(jid)
            except exceptions.PysqliteOperationalError as e:
                raise exceptions.PysqliteOperationalError(str(e))
            if kind == 'chat_msg_recv':
                if not self.jid_is_from_pm(jid):
                    # Save in unread table only if it's not a pm
                    write_unread = True

        if show_col == 'UNKNOWN':  # unknown show, do not log
            return

        values = (jid_id, contact_name_col, time_col, kind_col, show_col,
                  message_col, subject_col, additional_data_col)
        return self.commit_to_db(values, write_unread)