Exemple #1
0
 def write_timeline_to_db(self, msglist):
     logger.debug("acquiring lock")
     self.dblock.acquire()
     try:
         conn = sqlite3.connect(self.sqlitefile)
         cursor = conn.cursor()
         what_to_write = []
         for msg in msglist:
             try:
                 pickled_msg = obj2str(msg)
                 sig = unicode(msg.digest())
                 cursor.execute(
                     "SELECT * FROM home_timeline WHERE digest = ?",
                     (sig, ))
                 if not cursor.fetchone():
                     what_to_write.append(
                         (unicode(pickled_msg), sig, msg.parsed.text,
                          msg.parsed.username, msg.parsed.userid,
                          msg.parsed.time))
             except Exception, e:
                 logger.warning("Error while checking message: %s" %
                                (str(e)))
         try:
             logger.info("Writing %d messages" % (len(what_to_write)))
             cursor.executemany(
                 "INSERT INTO home_timeline (pickled_object, digest, text, username, userid, time) VALUES(?, ?, ?, ?, ?, ?)",
                 what_to_write)
         except Exception, e:
             logger.warning("Error %s" % (str(e)))
Exemple #2
0
    def like(self, message, channel=None):
        """
        like a message

        """

        if isinstance(message, snstype.Message):
            mID = message.ID
        elif isinstance(message, snstype.MessageID):
            mID = message
        else:
            logger.warning("unknown type: %s", type(message))
            return {}

        if channel:
            if channel in self:
                # If the platforms are not identical, like method will surly fail
                if self[channel].platform != mID.platform:
                    logger.warning("Inter-platform like method is not supported.")                   
                elif self[channel].is_expired():
                    logger.warning("channel '%s' is expired. Do nothing.", channel)
                else:
                    re = self[channel].like(message)
            else:
                logger.warning("channel '%s' is not in pocket. Do nothing.", channel)
        else:
            for c in self.itervalues():
                if self.__check_method(c, 'like') and not c.is_expired():
                    re = c.like(message)
                    break

        logger.info("Like status '%s'. Result: %s",\
                message.digest(), re)
        return re
    def unlike(self, message, channel=None):
        """
        unlike a message

        """
        if channel:
            if channel in self:
                # If the platforms are not identical, unlike method will surly fail
                if self[channel].platform != mID.platform:
                    logger.warning("Inter-platform unlike method is not supported.")                   
                elif self[channel].is_expired():
                    logger.warning("channel '%s' is expired. Do nothing.", channel)
                else:
                    re = self[channel].unlike(message)
            else:
                logger.warning("channel '%s' is not in pocket. Do nothing.", channel)
        else:
            for c in self.itervalues():
                if self.__check_method(c, 'unlike') and not c.is_expired():
                    re = c.unlike(message)
                    break

        logger.info("UnLike status '%s'. Result: %s",\
                message.digest(), re)
        return re
Exemple #4
0
    def load_config(self,
            fn_channel = DIR_DEFAULT_CONF_CHANNEL,
            fn_pocket = DIR_DEFAULT_CONF_POCKET):
        """
        Read configs:
        * channel.conf
        * pocket.conf
        """

        count_add_channel = 0
        try:
            with open(path.abspath(fn_channel), "r") as fp:
                allinfo = json.load(fp)
                for site in allinfo:
                    if self.add_channel(utils.JsonDict(site)):
                        count_add_channel += 1
        except IOError:
            #raise snserror.config.nofile(fn_channel)
            logger.warning("'%s' does not exist. Use default", fn_channel)
        except ValueError as e:
            raise snserror.config.load("file: %s; message: %s" % (fn_channel, e))

        try:
            with open(path.abspath(fn_pocket), "r") as fp:
                allinfo = json.load(fp)
                self.jsonconf = allinfo
        except IOError:
            #raise snserror.config.nofile(fn_pocket)
            logger.warning("'%s' does not exist. Use default", fn_pocket)
        except ValueError as e:
            raise snserror.config.load("file: %s; message:%s" % (fn_channel, e))

        logger.info("Read configs done. Add %d channels" % count_add_channel)
Exemple #5
0
    def save_config(self,
            fn_channel = DIR_DEFAULT_CONF_CHANNEL,
            fn_pocket = DIR_DEFAULT_CONF_POCKET):
        """
        Save configs: reverse of load_config

        Configs can be modified during execution. snsapi components
        communicate with upper layer using Python objects. Pocket
        will be the unified place to handle file transactions.

        """

        conf_channel = []
        for c in self.itervalues():
            conf_channel.append(c.jsonconf)

        conf_pocket = self.jsonconf

        try:
            json.dump(conf_channel, open(fn_channel, "w"), indent = 2)
            json.dump(conf_pocket, open(fn_pocket, "w"), indent = 2)
        except:
            raise snserror.config.save

        logger.info("save configs done")
Exemple #6
0
    def update(self, text, title=None):
        '''
        Post a blog

        :param text: Blog post body.
        :param title: Blog post title. (optional)
        :return: success or not
        '''

        if title is None:
            title = self._cat(20, [(text, 1)])

        api_params = {'method': 'blog.addBlog',
                      'content': text,
                      'title': title}

        try:
            ret = self.renren_request(api_params)
            logger.debug("response: %s", ret)
            #TODO:
            #    Preserve the id for further use?
            #    Return it as multi-return-value?
            if 'id' in ret:
                logger.info("Update status '%s' on '%s' succeed", text, self.jsonconf.channel_name)
                return True
        except Exception, e:
            logger.warning("Catch Exception %s", e)
Exemple #7
0
 def report_time_wrapper(*al, **ad):
     start = time.time()
     ret = func(*al, **ad)
     end = time.time()
     logger.info("Function '%s' execution time: %.2f", func.__name__,
                 end - start)
     return ret
Exemple #8
0
    def get_saved_token(self):
        try:
            fname = self.auth_info.save_token_file
            if fname == "(default)" :
                fname = self.jsonconf.channel_name+".token.save"
            if fname != "(null)" :
                with open(fname, "r") as fp:
                    token = utils.JsonObject(json.load(fp))
                    # check expire time
                    if self.is_expired(token):
                        logger.debug("Saved Access token is expired, try to get one through sns.auth() :D")
                        return False
                    #TODO: decrypt token
                    self.token = token
            else:
                logger.debug("This channel is configured not to save token to file")
                return False
                    
        except IOError:
            logger.debug("No access token saved, try to get one through sns.auth() :D")
            return False

        logger.info("Read saved token for '%s' successfully", self.jsonconf.channel_name)
        print self.token
        return True
Exemple #9
0
    def home_timeline(self, count=20):
        '''Get home timeline
        get statuses of yours and your friends'
        @param count: number of statuses
        '''

        api_params = dict(method = "feed.get", type = 10, page = 1, count = count)
        try:
            jsonlist = self.renren_request(api_params)
        except Exception as e:
            logger.warning("catch expection: %s", e)
            jsonlist = []

        statuslist = snstype.MessageList()
        for j in jsonlist:
            try:
                statuslist.append(self.Message(j,\
                        platform = self.jsonconf['platform'],\
                        channel = self.jsonconf['channel_name']\
                        ))
            except Exception as e:
                logger.warning("catch expection '%s' in parsing '%s'", e, j)

        logger.info("Read %d statuses from '%s'", len(statuslist), self.jsonconf.channel_name)
        return statuslist
Exemple #10
0
    def reply(self, mID, text):
        '''
        Reply a renren blog

        :param mID: MessageID object
        :param text: string, the reply message
        :return: success or not
        '''

        if mID.user_type == 'user':
            owner_key = 'uid'
            owner_value = mID.source_user_id
        else:  # 'page'
            owner_key = 'page_id'
            owner_value = mID.source_page_id

        api_params = {'method': 'blog.addComment',
                      'content': text,
                      'id': mID.blog_id,
                      owner_key: owner_value}

        logger.debug('request parameters: %s', api_params)

        try:
            ret = self.renren_request(api_params)
            if 'result' in ret and ret['result'] == 1:
                logger.info("Reply '%s' to status '%s' succeed", text, mID)
                return True
        except Exception, e:
            logger.warning("Catch Exception %s", e)
Exemple #11
0
    def save_config(self,
                    fn_channel=DIR_DEFAULT_CONF_CHANNEL,
                    fn_pocket=DIR_DEFAULT_CONF_POCKET):
        """
        Save configs: reverse of load_config

        Configs can be modified during execution. snsapi components
        communicate with upper layer using Python objects. Pocket
        will be the unified place to handle file transactions.

        """

        conf_channel = []
        for c in self.itervalues():
            conf_channel.append(c.jsonconf)

        conf_pocket = self.jsonconf

        try:
            json.dump(conf_channel, open(fn_channel, "w"), indent=2)
            json.dump(conf_pocket, open(fn_pocket, "w"), indent=2)
        except:
            raise snserror.config.save

        logger.info("save configs done")
Exemple #12
0
    def update(self, text, pic=None):
        '''update a status

           * parameter text: the update message
           * return: success or not
        '''

        text = self._cat(self.jsonconf['text_length_limit'], [(text, 1)])

        if not pic:
            method = "t/add"
        else:
            method = "t/add_pic"

        try:
            if pic:
                ret = self.tencent_request(method,
                                           "POST",
                                           content=text,
                                           files={'pic': ('pic.jpg', pic)})
            else:
                ret = self.tencent_request(method, "POST", content=text)
            if (ret['msg'] == "ok"):
                logger.info("Update status '%s' on '%s' succeed", text,
                            self.jsonconf.channel_name)
                return True
            else:
                return ret
        except Exception, e:
            logger.warning("Catch Exception: %s", e)
            return False
Exemple #13
0
    def home_timeline(self, count=None, channel=None):
        """
        Route to home_timeline method of snsapi.

        :param channel:
            The channel name. Use None to read all channels
        """

        status_list = snstype.MessageList()
        if channel:
            if channel in self:
                if self[channel].is_expired():
                    logger.warning("channel '%s' is expired. Do nothing.",
                                   channel)
                else:
                    status_list.extend(
                        self._home_timeline(count, self[channel]))
            else:
                logger.warning("channel '%s' is not in pocket. Do nothing.",
                               channel)
        else:
            for c in self.itervalues():
                if self.__check_method(c,
                                       'home_timeline') and not c.is_expired():
                    status_list.extend(self._home_timeline(count, c))

        logger.info("Read %d statuses", len(status_list))
        return status_list
Exemple #14
0
    def update(self, text, title=None):
        '''
        Post a blog

        :param text: Blog post body.
        :param title: Blog post title. (optional)
        :return: success or not
        '''

        if title is None:
            title = self._cat(20, [(text, 1)])

        api_params = {
            'method': 'blog.addBlog',
            'content': text,
            'title': title
        }

        try:
            ret = self.renren_request(api_params)
            logger.debug("response: %s", ret)
            #TODO:
            #    Preserve the id for further use?
            #    Return it as multi-return-value?
            if 'id' in ret:
                logger.info("Update status '%s' on '%s' succeed", text,
                            self.jsonconf.channel_name)
                return True
        except Exception, e:
            logger.warning("Catch Exception %s", e)
Exemple #15
0
    def reply(self, statusID, text):
        '''
        docstring placeholder
        '''

        #"""reply status
        #@param status: StatusID object
        #@param text: string, the reply message
        #@return: success or not
        #"""

        api_params = dict(method = "share.addComment", content = text, \
            share_id = statusID.status_id, user_id = statusID.source_user_id)

        try:
            ret = self.renren_request(api_params)
            logger.debug("Reply to status '%s' return: %s", statusID, ret)
            if 'result' in ret and ret['result'] == 1:
                logger.info("Reply '%s' to status '%s' succeed", text,
                            statusID)
                return True
            else:
                return False
        except Exception, e:
            logger.warning("Reply failed: %s", e)
Exemple #16
0
    def home_timeline(self, count=20):
        '''Get home timeline
        get statuses of yours and your friends'
        @param count: number of statuses
        '''

        api_params = dict(method="feed.get", type=10, page=1, count=count)
        try:
            jsonlist = self.renren_request(api_params)
        except Exception as e:
            logger.warning("catch expection: %s", e)
            jsonlist = []

        statuslist = snstype.MessageList()
        for j in jsonlist:
            try:
                statuslist.append(self.Message(j,\
                        platform = self.jsonconf['platform'],\
                        channel = self.jsonconf['channel_name']\
                        ))
            except Exception as e:
                logger.warning("catch expection '%s' in parsing '%s'", e, j)

        logger.info("Read %d statuses from '%s'", len(statuslist),
                    self.jsonconf.channel_name)
        return statuslist
Exemple #17
0
    def reply(self, statusID, text):
        '''
        docstring placeholder
        '''

        """reply status

           * parameter status: StatusID object
           * paramter text: string, the reply message
           * return: success or not
        """

        api_params = dict(method = "share.addComment", content = text, \
            share_id = statusID.status_id, user_id = statusID.source_user_id)

        try:
            ret = self.renren_request(api_params)
            logger.debug("Reply to status '%s' return: %s", statusID, ret)
            if 'result' in ret and ret['result'] == 1:
                logger.info("Reply '%s' to status '%s' succeed", text, statusID)
                return True
            else:
                return False
        except Exception, e:
            logger.warning("Reply failed: %s", e)
Exemple #18
0
    def update(self, text, channel=None, **kwargs):
        """
        Route to update method of snsapi.

        :param channel:
            The channel name. Use None to update all channels
        """
        re = {}
        if channel:
            if channel in self:
                if self[channel].is_expired():
                    logger.warning("channel '%s' is expired. Do nothing.",
                                   channel)
                else:
                    re[channel] = self[channel].update(text)
            else:
                logger.warning("channel '%s' is not in pocket. Do nothing.",
                               channel)
        else:
            for c in self.itervalues():
                if self.__check_method(c, 'update') and not c.is_expired():
                    re[c.jsonconf['channel_name']] = c.update(text, **kwargs)

        logger.info("Update status '%s'. Result:%s", text, re)
        return re
Exemple #19
0
    def get_saved_token(self):
        try:
            fname = self.auth_info.save_token_file
            if fname == "(default)":
                fname = self.jsonconf.channel_name + ".token.save"
            if fname != "(null)":
                with open(fname, "r") as fp:
                    token = utils.JsonObject(json.load(fp))
                    #check expire time
                    if self.is_expired(token):
                        logger.debug(
                            "Saved Access token is expired, try to get one through sns.auth() :D"
                        )
                        return False
                    #TODO: decrypt token
                    self.token = token
            else:
                logger.debug(
                    "This channel is configured not to save token to file")
                return False

        except IOError:
            logger.debug(
                "No access token saved, try to get one through sns.auth() :D")
            return False

        logger.info("Read saved token for '%s' successfully",
                    self.jsonconf.channel_name)
        return True
Exemple #20
0
    def update(self, text, pic=None):
        '''update a status

           * parameter text: the update message
           * return: success or not
        '''

        text = self._cat(self.jsonconf['text_length_limit'], [(text, 1)])

        if not pic:
            method = "t/add"
        else:
            method = "t/add_pic"

        try:
            if pic:
                ret = self.tencent_request(method, "POST", content=text, files={'pic': ('pic.jpg', pic)})
            else:
                ret = self.tencent_request(method, "POST", content=text)
            if(ret['msg'] == "ok"):
                logger.info("Update status '%s' on '%s' succeed", text, self.jsonconf.channel_name)
                return True
            else:
                return ret
        except Exception, e:
            logger.warning("Catch Exception: %s", e)
            return False
Exemple #21
0
    def reply(self, mID, text):
        '''
        Reply a renren blog

        :param mID: MessageID object
        :param text: string, the reply message
        :return: success or not
        '''

        if mID.user_type == 'user':
            owner_key = 'uid'
            owner_value = mID.source_user_id
        else:  # 'page'
            owner_key = 'page_id'
            owner_value = mID.source_page_id

        api_params = {
            'method': 'blog.addComment',
            'content': text,
            'id': mID.blog_id,
            owner_key: owner_value
        }

        logger.debug('request parameters: %s', api_params)

        try:
            ret = self.renren_request(api_params)
            if 'result' in ret and ret['result'] == 1:
                logger.info("Reply '%s' to status '%s' succeed", text, mID)
                return True
        except Exception, e:
            logger.warning("Catch Exception %s", e)
Exemple #22
0
    def update(self, text, pic=None):
        '''update a status

           * parameter text: the update message
           * return: success or not
        '''
        # NOTE:
        #     * With this pre-shortening, we can post potentially longer messages.
        #     * It consumes one more API quota.
        text = self._replace_with_short_url(text)
        text = self._cat(self.jsonconf['text_length_limit'], [(text, 1)],
                         delim='//')

        try:
            if not pic:
                ret = self.weibo_request('statuses/update', 'POST',
                                         {'status': text})
            else:
                ret = self.weibo_request('statuses/upload',
                                         'POST', {'status': text},
                                         files={'pic': ('pic.jpg', pic)})
            self.Message(ret)
            logger.info("Update status '%s' on '%s' succeed", text,
                        self.jsonconf.channel_name)
            return True
        except Exception as e:
            logger.warning("Update status fail. Message: %s", e)
            return False
Exemple #23
0
    def load_config(self,
                    fn_channel=DIR_DEFAULT_CONF_CHANNEL,
                    fn_pocket=DIR_DEFAULT_CONF_POCKET):
        """
        Read configs:
        * channel.conf
        * pocket.conf
        """

        count_add_channel = 0
        try:
            with open(path.abspath(fn_channel), "r") as fp:
                allinfo = json.load(fp)
                for site in allinfo:
                    if self.add_channel(utils.JsonDict(site)):
                        count_add_channel += 1
        except IOError:
            #raise snserror.config.nofile(fn_channel)
            logger.warning("'%s' does not exist. Use default", fn_channel)
        except ValueError as e:
            raise snserror.config.load("file: %s; message: %s" %
                                       (fn_channel, e))

        try:
            with open(path.abspath(fn_pocket), "r") as fp:
                allinfo = json.load(fp)
                self.jsonconf = allinfo
        except IOError:
            #raise snserror.config.nofile(fn_pocket)
            logger.warning("'%s' does not exist. Use default", fn_pocket)
        except ValueError as e:
            raise snserror.config.load("file: %s; message:%s" %
                                       (fn_channel, e))

        logger.info("Read configs done. Add %d channels" % count_add_channel)
Exemple #24
0
    def update(self, text, pic=None):
        '''update a status

           * parameter text: the update message
           * return: success or not
        '''
        # NOTE:
        #     * With this pre-shortening, we can post potentially longer messages.
        #     * It consumes one more API quota.
        text = self._replace_with_short_url(text)
        text = self._cat(self.jsonconf['text_length_limit'], [(text, 1)], delim='//')

        try:
            if not pic:
                ret = self.weibo_request('statuses/update',
                        'POST',
                        {'status': text})
            else:
                ret = self.weibo_request(
                    'statuses/upload',
                    'POST',
                    {'status': text},
                    files={'pic': ('pic.jpg', pic)}
                )
            self.Message(ret)
            logger.info("Update status '%s' on '%s' succeed", text, self.jsonconf.channel_name)
            return True
        except Exception as e:
            logger.warning("Update status fail. Message: %s", e)
            return False
Exemple #25
0
    def auth(self):
        if self.get_saved_token():
            return

        logger.info("Try to authenticate '%s' using OAuth2", self.jsonconf.channel_name)
        self.auth_first()
        self.auth_second()
        self.save_token()
        logger.debug("Authorized! access token is " + str(self.token))
        logger.info("Channel '%s' is authorized", self.jsonconf.channel_name)
Exemple #26
0
    def reply(self, statusID, text):
        '''reply to a status

           * parameter text: the comment text
           * return: success or not
        '''
        ret = self.tencent_request("t/reply", "POST", content=text, reid=statusID.reid)
        if(ret['msg'] == "ok"):
            return True
        logger.info("Reply '%s' to status '%s' fail: %s", text, self.jsonconf.channel_name, ret)
        return ret
Exemple #27
0
    def oauth2(self):
        '''
        Authorizing using synchronized invocation of OAuth2.

        Users need to collect the code in the browser's address bar to this client.
        callback_url MUST be the same one you set when you apply for an app in openSNS platform.
        '''
        
        logger.info("Try to authenticate '%s' using OAuth2", self.jsonconf.channel_name)
        self._oauth2_first()
        self._oauth2_second()
Exemple #28
0
    def oauth2(self):
        '''
        Authorizing using synchronized invocation of OAuth2.


        Users need to collect the code in the browser's address bar to this client.
        callback_url MUST be the same one you set when you apply for an app in openSNS platform.
        '''

        logger.info("Try to authenticate '%s' using OAuth2",
                    self.jsonconf.channel_name)
        self._oauth2_first()
        self._oauth2_second()
Exemple #29
0
    def reply(self, statusID, text):
        """reply to a status

           * parameter text: the comment text
           * return: success or not
        """
        try:
            ret = self.weibo_request("comments/create", "POST", {"id": statusID.id, "comment": text})
            ret["id"]
            return True
        except Exception as e:
            logger.info("Reply '%s' to status '%s' fail: %s", text, self.jsonconf.channel_name, e)
            return False
Exemple #30
0
    def home_timeline(self, count=20):
        '''
        Return count ``Message`` for each uid configured.

        Configure 'friend_list' in your ``channel.json`` first.
        Or, it returns your own status list by default.
        '''
        statuslist = snstype.MessageList()
        for user in self.jsonconf['friend_list']:
            userid = user['userid']
            username = user['username']
            statuslist.extend(self._get_user_status_list(count, userid, username))
        logger.info("Read %d statuses from '%s'", len(statuslist), self.jsonconf['channel_name'])
        return statuslist
Exemple #31
0
    def home_timeline(self, count=20):
        '''
        Return count ``Message`` for each uid configured.

        Configure 'friend_list' in your ``channel.json`` first.
        Or, it returns your own status list by default.
        '''
        statuslist = snstype.MessageList()
        for user in self.jsonconf['friend_list']:
            userid = user['userid']
            username = user['username']
            statuslist.extend(self._get_user_status_list(count, userid, username))
        logger.info("Read %d statuses from '%s'", len(statuslist), self.jsonconf['channel_name'])
        return statuslist
Exemple #32
0
    def _oauth2_second(self):
        '''
        The second stage of oauth. 
        Fetch authenticated code. 
        '''
        self.__init_oauth2_client() 

        url = self.fetch_code() 
        if url == "(null)" :
            raise snserror.auth
        self.token = self.parseCode(url)
        self.token.update(self.auth_client.request_access_token(self.token.code))
        logger.debug("Authorized! access token is " + str(self.token))
        logger.info("Channel '%s' is authorized", self.jsonconf.channel_name)
Exemple #33
0
 def home_timeline(self, count=20):
     ret = snstype.MessageList()
     logger.debug("acquiring lock")
     self.dblock.acquire()
     try:
         conn = sqlite3.connect(self.sqlitefile)
         c = conn.cursor()
         c.execute("SELECT pickled_object FROM home_timeline ORDER BY time DESC LIMIT 0, %d" % (count,))
         p = c.fetchall()
         logger.info("%d messages read from database" % (len(p)))
         for i in p:
             ret.append(str2obj(str(i[0])))
     except Exception, e:
         logger.warning("Error while reading database: %s" % (str(e)))
Exemple #34
0
    def like(self, message):
        '''like a status

           * parameter message: the message to be liked
           * return: success or not
        '''
        ret = self.tencent_request("t/like", "POST", id=message.ID.reid, format="json")
        # errcode 6 means this status had been collected.
        # For the purpose of backward compatibility, we also view
        # it as a successful like
        if ret['msg'] == "ok" or ret["errcode"] == 6:
            return True
        logger.info("Like status '%s' fail: %s", self.jsonconf.channel_name, ret)
        return ret
Exemple #35
0
    def _oauth2_second(self):
        '''
        The second stage of oauth. 
        Fetch authenticated code. 
        '''
        self.__init_oauth2_client()

        url = self.fetch_code()
        if url == "(null)":
            raise snserror.auth
        self.token = self.parseCode(url)
        self.token.update(
            self.auth_client.request_access_token(self.token.code))
        logger.debug("Authorized! access token is " + str(self.token))
        logger.info("Channel '%s' is authorized", self.jsonconf.channel_name)
Exemple #36
0
    def unlike(self, message):
        '''unlike a status

           * parameter message: the message to be unliked
           * return: success or not
        '''
        # errcode 6 means this status had never been collected.
        # For the purpose of backward compatibility, we also view
        # it as a successful like
        ret = self.tencent_request("t/unlike", "POST", id=message.ID.reid, format="json", favoriteId=random.randint(10, 20))
        # Accordion to the API document, favoriteId can be a random number other than 0
        if ret['msg'] == "ok" or ret["errcode"] == 6:
            return True
        logger.info("Unlike status '%s' fail: %s", self.jsonconf.channel_name, ret)
        return ret
Exemple #37
0
    def reply(self, statusID, text):
        '''reply to a status

           * parameter text: the comment text
           * return: success or not
        '''
        try:
            ret = self.weibo_request('comments/create',
                    'POST',
                    {'id': statusID.id, 'comment': text })
            ret['id']
            return True
        except Exception as e:
            logger.info("Reply '%s' to status '%s' fail: %s", text, self.jsonconf.channel_name, e)
            return False
Exemple #38
0
    def forward(self, message, text, channel=None):
        """
        forward a message

        """
        re = {}
        if channel and not self[channel].is_expired():
            re = self[channel].forward(message, text)
        else:
            for c in self.itervalues():
                if self.__check_method(c, "forward") and not c.is_expired():
                    re[c.jsonconf["channel_name"]] = c.forward(message, text)

        logger.info("Forward status '%s' with text '%s'. Result: %s", message.digest(), text, re)
        return re
Exemple #39
0
    def reply(self, statusID, text):
        '''reply to a status

           * parameter text: the comment text
           * return: success or not
        '''
        ret = self.tencent_request("t/reply",
                                   "POST",
                                   content=text,
                                   reid=statusID.reid)
        if (ret['msg'] == "ok"):
            return True
        logger.info("Reply '%s' to status '%s' fail: %s", text,
                    self.jsonconf.channel_name, ret)
        return ret
Exemple #40
0
    def reply(self, statusID, text):
        '''reply to a status

           * parameter text: the comment text
           * return: success or not
        '''
        try:
            ret = self.weibo_request('comments/create',
                    'POST',
                    {'id': statusID.id, 'comment': text})
            ret['id']
            return True
        except Exception as e:
            logger.info("Reply '%s' to status '%s' fail: %s", text, self.jsonconf.channel_name, e)
            return False
Exemple #41
0
    def reply(self, message, text, channel=None):
        """
        Route to reply method of snsapi.

        :param channel:
            The channel name. Use None to automatically select
            one compatible channel.

        :param status:
            Message or MessageID object.

        :text:
            Reply text.
        """

        if isinstance(message, snstype.Message):
            mID = message.ID
        elif isinstance(message, snstype.MessageID):
            mID = message
        else:
            logger.warning("unknown type: %s", type(message))
            return {}

        re = {}
        if channel:
            if channel in self:
                # If the platforms are not identical, reply method will surly fail
                if self[channel].platform != mID.platform:
                    logger.warning(
                        "Inter-platform reply method is not supported.")
                elif self[channel].is_expired():
                    logger.warning("channel '%s' is expired. Do nothing.",
                                   channel)
                else:
                    re = self[channel].reply(mID, text)
            else:
                logger.warning("channel '%s' is not in pocket. Do nothing.",
                               channel)
        else:
            for c in self.itervalues():
                if self.__check_method(c, 'reply') and not c.is_expired():
                    if c.jsonconf['platform'] == mID.platform:
                        re = c.reply(mID, text)
                        break

        logger.info("Reply to status '%s' with text '%s'. Result: %s",\
                mID, text, re)
        return re
Exemple #42
0
 def home_timeline(self, count=20):
     ret = snstype.MessageList()
     logger.debug("acquiring lock")
     self.dblock.acquire()
     try:
         conn = sqlite3.connect(self.sqlitefile)
         c = conn.cursor()
         c.execute(
             "SELECT pickled_object FROM home_timeline ORDER BY time DESC LIMIT 0, %d"
             % (count, ))
         p = c.fetchall()
         logger.info("%d messages read from database" % (len(p)))
         for i in p:
             ret.append(str2obj(str(i[0])))
     except Exception, e:
         logger.warning("Error while reading database: %s" % (str(e)))
Exemple #43
0
    def auth(self):
        '''
        docstring placeholder
        '''

        if self.get_saved_token():
            return

        logger.info("Try to authenticate '%s' using OAuth2", self.jsonconf.channel_name)
        self.auth_first()
        self.auth_second()
        if not self.token:
            return False
        self.save_token()
        logger.debug("Authorized! access token is " + str(self.token))
        logger.info("Channel '%s' is authorized", self.jsonconf.channel_name)
Exemple #44
0
    def forward(self, message, text, channel=None):
        """
        forward a message

        """
        re = {}
        if channel:
            re = self[channel].forward(message, text)
        else:
            for c in self.itervalues():
                if self.__check_method(c, 'forward'):
                    re[c.jsonconf['channel_name']] = c.forward(message, text)

        logger.info("Forward status '%s' with text '%s'. Result: %s",\
                message.digest(), text, re)
        return re
Exemple #45
0
    def forward(self, message, text, channel = None):
        """
        forward a message

        """
        re = {}
        if channel:
            re = self[channel].forward(message, text)
        else:
            for c in self.itervalues():
                if self.__check_method(c, 'forward'):
                    re[c.jsonconf['channel_name']] = c.forward(message, text)

        logger.info("Forward status '%s' with text '%s'. Result: %s",\
                message.digest(), text, re)
        return re
Exemple #46
0
    def update(self, text, channel=None):
        """
        Route to update method of snsapi. 
        
        :param channel:
            The channel name. Use None to update all channels
        """
        re = {}
        if channel and not self[channel].is_expired():
            re[channel] = self[channel].update(text)
        else:
            for c in self.itervalues():
                if self.__check_method(c, "update") and not c.is_expired():
                    re[c.jsonconf["channel_name"]] = c.update(text)

        logger.info("Update status '%s'. Result:%s", text, re)
        return re
Exemple #47
0
    def home_timeline(self, count=20, channel=None):
        """
        Route to home_timeline method of snsapi. 
        
        :param channel:
            The channel name. Use None to read all channels
        """
        status_list = snstype.MessageList()
        if channel:
            status_list.extend(self[channel].home_timeline(count))
        else:
            for c in self.itervalues():
                if self.__check_method(c, 'home_timeline'):
                    status_list.extend(c.home_timeline(count))

        logger.info("Read %d statuses", len(status_list))
        return status_list
Exemple #48
0
    def update(self, text, channel=None):
        """
        Route to update method of snsapi. 
        
        :param channel:
            The channel name. Use None to update all channels
        """
        re = {}
        if channel:
            re[channel] = self[channel].update(text)
        else:
            for c in self.itervalues():
                if self.__check_method(c, 'update'):
                    re[c.jsonconf['channel_name']] = c.update(text)

        logger.info("Update status '%s'. Result:%s", text, re)
        return re
Exemple #49
0
    def home_timeline(self, count = 20, channel = None):
        """
        Route to home_timeline method of snsapi. 
        
        :param channel:
            The channel name. Use None to read all channels
        """
        status_list = snstype.MessageList()
        if channel and not self[channel].is_expired():
            status_list.extend(self[channel].home_timeline(count))
        else:
            for c in self.itervalues():
                if self.__check_method(c, 'home_timeline') and not c.is_expired():
                    status_list.extend(c.home_timeline(count))

        logger.info("Read %d statuses", len(status_list))
        return status_list
Exemple #50
0
    def update(self, text):
        '''update a status
        @param text: the update message
        @return: success or not
        '''

        text = self._cat(self.jsonconf['text_length_limit'], [(text,1)])

        api_params = dict(method = "status.set", status = text)
        
        try:
            ret = self.renren_request(api_params)
            if 'result' in ret and ret['result'] == 1:
                logger.info("Update status '%s' on '%s' succeed", text, self.jsonconf.channel_name)
                return True
        except Exception, e:
            logger.warning("Catch Exception %s", e)
Exemple #51
0
    def reply(self, message, text, channel = None):
        """
        Route to reply method of snsapi.

        :param channel:
            The channel name. Use None to automatically select
            one compatible channel.

        :param status:
            Message or MessageID object.

        :text:
            Reply text.
        """

        if isinstance(message, snstype.Message):
            mID = message.ID
        elif isinstance(message, snstype.MessageID):
            mID = message
        else:
            logger.warning("unknown type: %s", type(message))
            return {}

        re = {}
        if channel:
            if channel in self:
                if self[channel].is_expired():
                    logger.warning("channel '%s' is expired. Do nothing.", channel)
                else:
                    re = self[channel].reply(mID, text)
            else:
                logger.warning("channel '%s' is not in pocket. Do nothing.", channel)
        else:
            for c in self.itervalues():
                if self.__check_method(c, 'reply') and not c.is_expired():
                    #TODO:
                    #    First try to match "channel_name".
                    #    If there is no match, try to match "platform".
                    if c.jsonconf['platform'] == mID.platform:
                        re = c.reply(mID, text)
                        break

        logger.info("Reply to status '%s' with text '%s'. Result: %s",\
                mID, text, re)
        return re
Exemple #52
0
    def like(self, message):
        '''like a status

           * parameter message: the message to be liked
           * return: success or not
        '''
        ret = self.tencent_request("t/like",
                                   "POST",
                                   id=message.ID.reid,
                                   format="json")
        # errcode 6 means this status had been collected.
        # For the purpose of backward compatibility, we also view
        # it as a successful like
        if ret['msg'] == "ok" or ret["errcode"] == 6:
            return True
        logger.info("Like status '%s' fail: %s", self.jsonconf.channel_name,
                    ret)
        return ret
Exemple #53
0
 def reply(self, statusID, text):
     '''reply to a status
     @param text: the comment text
     @return: success or not
     '''
     url = "https://api.weibo.com/2/comments/create.json"
     params = {}
     params['id'] = statusID.id
     params['comment'] = text
     params['access_token'] = self.token.access_token
     
     ret = self._http_post(url, params)
     try:
         ret['id']
         return True
     except Exception as e:
         logger.info("Reply '%s' to status '%s' fail: %s", text, self.jsonconf.channel_name, ret)
         return False
Exemple #54
0
 def _oauth2_second(self):
     '''
     The second stage of oauth. 
     Fetch authenticated code. 
     '''
     try:
         self.__init_oauth2_client() 
         url = self.fetch_code() 
         logger.debug("get url: %s", url)
         if url == "(null)" :
             raise snserror.auth
         self.token = self.parseCode(url)
         self.token.update(self.auth_client.request_access_token(self.token.code))
         logger.debug("Authorized! access token is " + str(self.token))
         logger.info("Channel '%s' is authorized", self.jsonconf.channel_name)
     except Exception, e:
         logger.warning("Auth second fail. Catch exception: %s", e)
         self.token = None
Exemple #55
0
    def auth(self):
        '''
        docstring placeholder
        '''
        try:
            if self.get_saved_token():
                return

            logger.info("Try to authenticate '%s' using OAuth2", self.jsonconf.channel_name)
            self.auth_first()
            self.auth_second()
            if not self.token:
                return False
            self.save_token()
            logger.debug("Authorized! access token is " + str(self.token))
            logger.info("Channel '%s' is authorized", self.jsonconf.channel_name)
        except Exception, e:
            logger.warning("Auth second fail. Catch exception: %s", e)
Exemple #56
0
 def fetch_code(self):
     if self.auth_info.cmd_fetch_code == "(console_input)":
         utils.console_output(
             "Please input the whole url from Broswer's address bar:")
         return self.console_input().strip()
     elif self.auth_info.cmd_fetch_code == "(local_webserver)":
         try:
             self.httpd.handle_request()
             if 'code' in self.httpd.query_params:
                 code = self.httpd.query_params['code']
                 logger.info("Get code from local server: %s", code)
                 return "http://localhost/?%s" % urllib.urlencode(
                     self.httpd.query_params)
             else:
                 #TODO:
                 #    There is a non repeatable bug here.
                 #    When we have multiple platforms to authorize,
                 #    successive platforms may fail in this branch.
                 #    That means there is other HTTP request to the local HTTP server
                 #    before the call_back URL.
                 #
                 #    Solution:
                 #        * Configure different port for different channels.
                 #          This is solved at upper layer.
                 #        * Support random port by default.
                 raise snserror.auth.fetchcode
         finally:
             del self.httpd
     else:
         cmd = "%s %s" % (self.auth_info.cmd_fetch_code,
                          self.__last_request_time)
         logger.debug("fetch_code command is: %s", cmd)
         ret = subprocess.Popen(cmd, stdout=subprocess.PIPE,
                                shell=True).stdout.readline().rstrip()
         tries = 1
         while ret == "(null)":
             tries += 1
             if tries > self.__fetch_code_max_try:
                 break
             time.sleep(self.__fetch_code_timeout)
             ret = subprocess.Popen(cmd, stdout=subprocess.PIPE,
                                    shell=True).stdout.read().rstrip()
         return ret
Exemple #57
0
    def unlike(self, message):
        '''unlike a status

           * parameter message: the message to be unliked
           * return: success or not
        '''
        # errcode 6 means this status had never been collected.
        # For the purpose of backward compatibility, we also view
        # it as a successful like
        ret = self.tencent_request("t/unlike",
                                   "POST",
                                   id=message.ID.reid,
                                   format="json",
                                   favoriteId=random.randint(10, 20))
        # Accordion to the API document, favoriteId can be a random number other than 0
        if ret['msg'] == "ok" or ret["errcode"] == 6:
            return True
        logger.info("Unlike status '%s' fail: %s", self.jsonconf.channel_name,
                    ret)
        return ret
Exemple #58
0
    def auth(self):
        '''
        docstring placeholder
        '''
        try:
            if self.get_saved_token():
                self.client.auth_with_token(self.token["access_token"])
                return

            logger.info("Try to authenticate '%s' using OAuth2",
                        self.jsonconf.channel_name)
            self.auth_first()
            self.auth_second()
            if not self.token:
                return False
            self.save_token()
            logger.debug("Authorized! access token is " + str(self.token))
            logger.info("Channel '%s' is authorized",
                        self.jsonconf.channel_name)
        except Exception, e:
            logger.warning("Auth second fail. Catch exception: %s", e)
Exemple #59
0
    def update(self, text):
        '''update a status
        @param text: the update message
        @return: success or not
        '''

        text = self._cat(self.jsonconf['text_length_limit'], [(text, 1)])

        api_params = dict(method="status.set",
                          status=text,
                          place_id='RRAF04D95FA37892FFA88')

        try:
            ret = self.renren_request(api_params)
            if 'result' in ret and ret['result'] == 1:
                logger.info("Update status '%s' on '%s' succeed", text,
                            self.jsonconf.channel_name)
                return True
        except Exception, e:
            logger.warning("Catch Exception %s", e)
            return False
Exemple #60
0
    def home_timeline(self, count=20):
        '''Get home timeline

        :param count: number of statuses
        '''

        statuslist = snstype.MessageList()
        try:
            jsonobj = self.weibo_request('statuses/home_timeline', 'GET',
                                         {'count': count})
            if ("error" in jsonobj):
                logger.warning("error json object returned: %s", jsonobj)
                return []
            for j in jsonobj['statuses']:
                statuslist.append(self.Message(j,\
                        platform = self.jsonconf['platform'],\
                        channel = self.jsonconf['channel_name']\
                        ))
            logger.info("Read %d statuses from '%s'", len(statuslist),
                        self.jsonconf['channel_name'])
        except Exception, e:
            logger.warning("Catch exception: %s", e)