Exemplo n.º 1
0
    def _parse(self, dct):
        if 'deleted' in dct and dct['deleted']:
            logger.debug("This is a deleted message %s of SinaWeiboStatusMessage", dct["id"])
            self.parsed.time = "unknown"
            self.parsed.username = "******"
            self.parsed.userid = "unknown"
            self.parsed.text = "unknown"
            self.deleted = True
            return 

        self.ID.id = dct["id"]

        self.parsed.time = utils.str2utc(dct["created_at"])
        self.parsed.username = dct['user']['name']
        self.parsed.userid = dct['user']['id']
        self.parsed.reposts_count = dct['reposts_count']
        self.parsed.comments_count = dct['comments_count']
        
        if 'retweeted_status' in dct:
            self.parsed.username_orig = "unknown"
            try:
                self.parsed.username_orig = dct['retweeted_status']['user']['name']
            except KeyError:
                logger.warning('KeyError when parsing SinaWeiboStatus. May be deleted original message')
            self.parsed.text_orig = dct['retweeted_status']['text']
            self.parsed.text_trace = dct['text']
            self.parsed.text = self.parsed.text_trace \
                    + " || " + "@" + self.parsed.username_orig \
                    + " : " + self.parsed.text_orig
        else:
            self.parsed.text_orig = dct['text'] 
            self.parsed.text_trace = None
            self.parsed.text = self.parsed.text_orig
Exemplo n.º 2
0
    def unlike(self, message, channel=None):
        """
        unlike 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, 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
Exemplo n.º 3
0
    def home_timeline(self, count=20):
        '''Get home timeline

            * function : get statuses of yours and your friends'
            * parameter count: number of statuses
        '''
        url = "https://api.weibo.com/2/statuses/home_timeline.json"
        params = {}
        params['count'] = count
        params['access_token'] = self.token.access_token
        
        jsonobj = self._http_get(url, params)
        
        statuslist = snstype.MessageList()
        try:
            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']\
                        ))
        except Exception, e:
            logger.warning("Catch exception: %s", e)
Exemplo n.º 4
0
 def unlike(self, message):
     '''
     Unlike method
        * Weibo doesn't provide an API for "unlike"
        * So "unfavourite" function supersedes "unlike"
        * Here "unlike" means "remove from my favourites"
        * Receive a message
     '''
     mID = message.ID
     try:
         ret = self.weibo_request('favorites/destroy',
                 'POST',
                 {'id': mID.id})
         # error_code 20705 means this status had never been collected.
         # For the purpose of backward compatibility, we also view
         # it as a successful unlike
         if 'favorited_time' in ret or ret["error_code"] == 20705:
             return True
         else:
             logger.warning("'%s' unlikes status '%s' fail. ret: %s",
                     self.jsonconf.channel_name, mID, ret)
             return False
     except Exception, e:
         logger.warning("'%s' unlike status '%s' fail. ret: %s",
                     self.jsonconf.channel_name, mID, ret)
         return False
Exemplo n.º 5
0
 def update(self, text):
     try:
         self.client.miniblog.new(text)
         return True
     except Exception, e:
         logger.warning("DoubanAPIError: %s", e)
         return False
Exemplo n.º 6
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")
Exemplo n.º 7
0
    def _fetch_code_local_username_password(self):
        try:
            login_username = self.auth_info.login_username
            login_password = self.auth_info.login_password
            app_key = self.jsonconf.app_key
            app_secret = self.jsonconf.app_secret
            callback_url = self.auth_info.callback_url

            referer_url = self._last_requested_url

            postdata = {"client_id": app_key,
                        "redirect_uri": callback_url,
                        "userId": login_username,
                        "passwd": login_password,
                        "isLoginSina": "0",
                        "action": "submit",
                        "response_type": "code",
            }

            headers = {"User-Agent": "Mozilla/5.0 (Windows NT 6.1; rv:11.0) Gecko/20100101 Firefox/11.0",
                       "Host": "api.weibo.com",
                       "Referer": referer_url
            }

            auth_url = "https://api.weibo.com/oauth2/authorize"
            # auth_url = self.auth_info.auth_url
            resp_url = self._http_post(auth_url, data=postdata, headers=headers, json_parse=False).url
            logger.debug("response URL from local post: %s", resp_url)
            return resp_url
        except Exception, e:
            logger.warning("Catch exception: %s", e)
Exemplo n.º 8
0
    def _parse(self, dct):
        if "deleted" in dct and dct["deleted"]:
            logger.debug("This is a deleted message %s of SinaWeiboStatusMessage", dct["id"])
            self.parsed.time = "unknown"
            self.parsed.username = "******"
            self.parsed.userid = "unknown"
            self.parsed.text = "unknown"
            self.deleted = True
            return

        self.ID.id = dct["id"]

        self.parsed.time = utils.str2utc(dct["created_at"])
        self.parsed.username = dct["user"]["name"]
        self.parsed.userid = dct["user"]["id"]
        self.parsed.reposts_count = dct["reposts_count"]
        self.parsed.comments_count = dct["comments_count"]

        if "retweeted_status" in dct:
            self.parsed.username_orig = "unknown"
            try:
                self.parsed.username_orig = dct["retweeted_status"]["user"]["name"]
            except KeyError:
                logger.warning("KeyError when parsing SinaWeiboStatus. May be deleted original message")
            self.parsed.text_orig = dct["retweeted_status"]["text"]
            self.parsed.text_trace = dct["text"]
            self.parsed.text = (
                self.parsed.text_trace + " || " + "@" + self.parsed.username_orig + " : " + self.parsed.text_orig
            )
        else:
            self.parsed.text_orig = dct["text"]
            self.parsed.text_trace = None
            self.parsed.text = self.parsed.text_orig
Exemplo n.º 9
0
 def reply(self, statusId, text):
     res = None
     flag = False
     try:
         # The order in the bracket is important since there
         # exists "SHARE_XXXX" type. In order to figure out
         # the actual type, SHARE must be put in the first position.
         for msg_type in [
                 "SHARE", "BLOG", "PHOTO", "ALBUM", "STATUS", "VIDEO"
         ]:
             if msg_type in statusId.feed_type:
                 flag = True
                 break
         if flag:
             res = self.renren_request(method="comment/put",
                                       content=text,
                                       commentType=msg_type,
                                       entryOwnerId=statusId.source_user_id,
                                       entryId=statusId.resource_id)
         else:
             return BooleanWrappedData(False, {
                 'errors': ['SNSAPI_NOT_SUPPORTED'],
             })
     except Exception, e:
         logger.warning('Catch exception: %s', e)
         return BooleanWrappedData(False, {
             'errors': ['PLATFORM_'],
         })
Exemplo n.º 10
0
 def unlike(self, message):
     try:
         self.client.miniblog.unlike(message.ID.id)
         return True
     except Exception, e:
         logger.warning("DoubanAPIError, %s", e)
         return False
Exemplo n.º 11
0
 def forward(self, message, text):
     try:
         self.client.miniblog.reshare(message.ID.id)
         return True
     except Exception, e:
         logger.warning("DoubanAPIError: %s", e)
         return False
Exemplo n.º 12
0
 def update(self, text):
     try:
         self.client.miniblog.new(text)
         return True
     except Exception, e:
         logger.warning("DoubanAPIError: %s", e)
         return False
Exemplo n.º 13
0
 def reply(self, statusID, text):
     try:
         self.client.miniblog.comment.new(statusID.id, text)
         return True
     except Exception, e:
         logger.warning('DoubanAPIError: %s', str(e))
         return False
Exemplo n.º 14
0
 def forward(self, message, text):
     try:
         self.client.miniblog.reshare(message.ID.id)
         return True
     except Exception, e:
         logger.warning("DoubanAPIError: %s", e)
         return False
Exemplo n.º 15
0
 def unlike(self, message):
     try:
         self.client.miniblog.unlike(message.ID.id)
         return True
     except Exception, e:
         logger.warning("DoubanAPIError, %s", e)
         return False
Exemplo n.º 16
0
 def reply(self, statusID, text):
     try:
         self.client.miniblog.comment.new(statusID.id, text)
         return True
     except Exception, e:
         logger.warning('DoubanAPIError: %s', str(e))
         return False
Exemplo n.º 17
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
Exemplo n.º 18
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")
Exemplo n.º 19
0
 def reply(self, statusId, text):
     res = None
     flag = False
     try:
         # The order in the bracket is important since there
         # exists "SHARE_XXXX" type. In order to figure out
         # the actual type, SHARE must be put in the first position.
         for msg_type in ["SHARE", "BLOG", "PHOTO", "ALBUM", "STATUS", "VIDEO"]:
             if msg_type in statusId.feed_type:
                 flag = True
                 break
         if flag:
             res = self.renren_request(
                 method="comment/put",
                 content=text,
                 commentType=msg_type,
                 entryOwnerId=statusId.source_user_id,
                 entryId=statusId.resource_id
             )
         else:
             return BooleanWrappedData(False, {
                 'errors': ['SNSAPI_NOT_SUPPORTED'],
             })
     except Exception, e:
         logger.warning('Catch exception: %s', e)
         return BooleanWrappedData(False, {
             'errors': ['PLATFORM_'],
         })
Exemplo n.º 20
0
 def update_func(self):
     logger.debug("acquiring lock")
     self.dblock.acquire()
     try:
         conn = sqlite3.connect(self.sqlitefile)
         conn.row_factory = sqlite3.Row
         cursor = conn.cursor()
         cursor.execute("SELECT * FROM pending_update")
         i = cursor.fetchone()
         if i:
             cursor.execute("DELETE FROM pending_update WHERE id = ?",
                            (i['id'], ))
             j = {
                 'id': str(i['id']),
                 'args': str2obj(str(i['args'])),
                 'kwargs': str2obj(str(i['kwargs'])),
                 'type': str(i['type']),
                 'callback': str2obj(str(i['callback']))
             }
             res = getattr(self.sp, j['type'])(*j['args'], **j['kwargs'])
             if j['callback']:
                 j['callback'](self, res)
         conn.commit()
         cursor.close()
     except Exception, e:
         logger.warning("Error while updating: %s" % (str(e)))
Exemplo n.º 21
0
    def _forward(self, mID, text):
        """
        Raw forward method

           * Only support Sina message
           * Use 'text' as exact comment sequence
        """
        try:
            ret = self.weibo_request("statuses/repost", "POST", {"id": mID.id, "status": text})
            if "id" in ret:
                return True
            else:
                logger.warning(
                    "'%s' forward status '%s' with comment '%s' fail. ret: %s",
                    self.jsonconf.channel_name,
                    mID,
                    text,
                    ret,
                )
                return False
        except Exception as e:
            logger.warning(
                "'%s' forward status '%s' with comment '%s' fail: %s", self.jsonconf.channel_name, mID, text, e
            )
            return False
Exemplo n.º 22
0
 def request_url(self, url):
     if self.auth_info.cmd_request_url == "(webbrowser)":
         self.open_brower(url)
     elif self.auth_info.cmd_request_url == "(console_output)":
         utils.console_output(url)
     elif self.auth_info.cmd_request_url == "(local_webserver)+(webbrowser)":
         host = self.auth_info.host
         port = self.auth_info.port
         from third.server import ClientRedirectServer
         from third.server import ClientRedirectHandler
         import socket
         try:
             self.httpd = ClientRedirectServer((host, port),
                                               ClientRedirectHandler)
             self.open_brower(url)
         except socket.error:
             raise snserror.auth
     else:
         self.__last_request_time = self.time()
         cmd = "%s '%s'" % (self.auth_info.cmd_request_url, url)
         logger.debug("request_url command is: %s", cmd)
         res = subprocess.Popen(cmd, stdout=subprocess.PIPE,
                                shell=True).stdout.read().rstrip()
         logger.debug("request_url result is: %s", res)
         return
Exemplo n.º 23
0
 def unlike(self, message):
     res = None
     flag = False
     try:
         # The order in the bracket is important since there
         # exists "SHARE_XXXX" type. In order to figure out
         # the actual type, SHARE must be put in the first position.
         for msg_type in [
                 "SHARE", "BLOG", "PHOTO", "ALBUM", "STATUS", "VIDEO"
         ]:
             if msg_type in message.ID.feed_type:
                 flag = True
                 break
         if flag:
             res = self.renren_request(method="like/ugc/remove",
                                       ugcOwnerId=message.ID.source_user_id,
                                       likeUGCType="TYPE_" + msg_type,
                                       ugcId=message.ID.resource_id)
         else:
             return False
     except Exception as e:
         logger.warning('Catch exception: %s', type(e))
         return False
     if res:
         return True
     else:
         return False
Exemplo n.º 24
0
 def unlike(self, message):
     '''
     Unlike method
        * Weibo doesn't provide an API for "unlike"
        * So "unfavourite" function supersedes "unlike"
        * Here "unlike" means "remove from my favourites"
        * Receive a message
     '''
     mID = message.ID
     try:
         ret = self.weibo_request('favorites/destroy', 'POST',
                                  {'id': mID.id})
         # error_code 20705 means this status had never been collected.
         # For the purpose of backward compatibility, we also view
         # it as a successful unlike
         if 'favorited_time' in ret or ret["error_code"] == 20705:
             return True
         else:
             logger.warning("'%s' unlikes status '%s' fail. ret: %s",
                            self.jsonconf.channel_name, mID, ret)
             return False
     except Exception, e:
         logger.warning("'%s' unlike status '%s' fail. ret: %s",
                        self.jsonconf.channel_name, mID, ret)
         return False
Exemplo n.º 25
0
 def update_func(self):
     logger.debug("acquiring lock")
     self.dblock.acquire()
     try:
         conn = sqlite3.connect(self.sqlitefile)
         conn.row_factory = sqlite3.Row
         cursor = conn.cursor()
         cursor.execute("SELECT * FROM pending_update")
         i = cursor.fetchone()
         if i:
             cursor.execute("DELETE FROM pending_update WHERE id = ?", (i['id'], ))
             j = {
                 'id': str(i['id']),
                 'args': str2obj(str(i['args'])),
                 'kwargs': str2obj(str(i['kwargs'])),
                 'type': str(i['type']),
                 'callback': str2obj(str(i['callback']))
             }
             res = getattr(self.sp, j['type'])(*j['args'], **j['kwargs'])
             if j['callback']:
                 j['callback'](self, res)
         conn.commit()
         cursor.close()
     except Exception, e:
         logger.warning("Error while updating: %s" % (str(e)))
Exemplo n.º 26
0
 def forward(self, message, text):
     res = None
     try:
         if message.ID.feed_type == 'STATUS':
             res = self.renren_request(
                 method='status.forward',
                 status=text,
                 forward_id=message.ID.status_id,
                 forward_owner=message.ID.source_user_id,
             )
         elif message.ID.feed_type != 'OTHER':
             res = self.renren_request(method='share.share',
                                       type=str({
                                           'BLOG': 1,
                                           'PHOTO': 2,
                                           'SHARE': 20
                                       }[message.parsed.feed_type]),
                                       ugc_id=message.ID.status_id,
                                       user_id=message.ID.source_user_id,
                                       comment=text)
         else:
             return BooleanWrappedData(False, {
                 'errors': ['SNSAPI_NOT_SUPPORTED'],
             })
     except Exception as e:
         logger.warning('Catch exception: %s', e)
         return BooleanWrappedData(False, {
             'errors': ['PLATFORM_'],
         })
     if res:
         return BooleanWrappedData(True)
     else:
         return BooleanWrappedData(False, {
             'errors': ['PLATFORM_'],
         })
Exemplo n.º 27
0
 def like(self, message):
     '''
     Like method
        * Weibo doesn't provide an API for "like"
        * So "favourite" function supersedes "like"
        * Here "like" means "add to my favourites"
        * Receive a message
     '''
     mID = message.ID
     try:
         ret = self.weibo_request('favorites/create',
                 'POST',
                 {'id': mID.id})
         # error_code 20704 means this status had been collected.
         # For the purpose of backward compatibility, we also view
         # it as a successful like
         if 'favorited_time' in ret or ret["error_code"] == 20704:
             message.parsed.liked = True
             return True
         else:
             logger.warning("'%s' likes status '%s' fail. ret: %s",
                     self.jsonconf.channel_name, mID, ret)
             return False
     except Exception, e:
         logger.warning("Exception: %s. '%s' like status '%s' fail. ret: %s",
                     e, self.jsonconf.channel_name, mID, ret)
         return False
Exemplo n.º 28
0
    def _forward(self, mID, text):
        '''
        Raw forward method

           * Only support Renren message
           * Use 'text' as exact comment sequence
        '''
        try:
            api_params = {
                'method': 'status.forward',
                'status': text,
                'forward_owner': mID.source_user_id,
                'place_id': 'RRAF04D95FA37892FFA88',
                'forward_id': mID.status_id
            }
            ret = self.renren_request(api_params)
            if 'id' in ret:
                # ret['id'] is the ID of new status
                # X, their doc says the field name is 'result'...
                return True
            else:
                logger.warning(
                    "'%s' forward status '%s' with comment '%s' fail. ret: %s",
                    self.jsonconf.channel_name, mID, text, ret)
                return False
        except Exception as e:
            logger.warning(
                "'%s' forward status '%s' with comment '%s' fail: %s",
                self.jsonconf.channel_name, mID, text, e)
            return False
Exemplo n.º 29
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
Exemplo n.º 30
0
    def get(self, attr, default_value = "(null)"):
        '''
        dict entry reading with fault tolerance. 

        :attr:
            A str or a list of str. 

        If attr is a list, we will try all the candidates until 
        one 'get' is successful. If none of the candidates succeed,
        we will return a "(null)"

        e.g. RSS format is very diverse. 
        To my current knowledge, some formats have 'author' fields, 
        but others do not:
           * rss : no
           * rss2 : yes
           * atom : yes
           * rdf : yes
        This function will return a string "(null)" by default if the 
        field does not exist. The purpose is to expose unified interface
        to upper layers. seeing "(null)" is better than catching an error. 

        '''
        if isinstance(attr, str):
            return dict.get(self, attr, default_value)
        elif isinstance(attr, list):
            for a in attr:
                val = dict.get(self, a, None)
                if val:
                    return val
            return default_value
        else:
            logger.warning("Unkown type: %s", type(attr))
            return default_value
Exemplo n.º 31
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
Exemplo n.º 32
0
 def unlike(self, message):
     res = None
     flag = False
     try:
         # The order in the bracket is important since there
         # exists "SHARE_XXXX" type. In order to figure out
         # the actual type, SHARE must be put in the first position.
         for msg_type in ["SHARE", "BLOG", "PHOTO", "ALBUM", "STATUS", "VIDEO"]:
             if msg_type in message.ID.feed_type:
                 flag = True
                 break
         if flag:
             res = self.renren_request(
                 method="like/ugc/remove",
                 ugcOwnerId=message.ID.source_user_id,
                 likeUGCType="TYPE_" + msg_type,
                 ugcId=message.ID.resource_id
             )
         else:
             return False
     except Exception as e:
         logger.warning('Catch exception: %s', type(e))
         return False
     if res:
         return True
     else:
         return False
Exemplo n.º 33
0
    def _forward(self, mID, text):
        '''
        Raw forward method

           * Only support Renren message
           * Use 'text' as exact comment sequence
        '''
        try:
            api_params = {'method': 'status.forward',
                    'status': text,
                    'forward_owner': mID.source_user_id,
                    'place_id': 'RRAF04D95FA37892FFA88',
                    'forward_id': mID.status_id
                    }
            ret = self.renren_request(api_params)
            if 'id' in ret:
                # ret['id'] is the ID of new status
                # X, their doc says the field name is 'result'...
                return True
            else:
                logger.warning("'%s' forward status '%s' with comment '%s' fail. ret: %s",
                        self.jsonconf.channel_name, mID, text, ret)
                return False
        except Exception as e:
            logger.warning("'%s' forward status '%s' with comment '%s' fail: %s",
                    self.jsonconf.channel_name, mID, text, e)
            return False
Exemplo n.º 34
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
Exemplo n.º 35
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
Exemplo n.º 36
0
 def append(self, e):
     if isinstance(e, Message):
         if hasattr(e, 'deleted') and e.deleted:
             logger.debug("Trying to append Deleted Message type element. Ignored")
         else:
             super(MessageList, self).append(e)
     else:
         logger.debug("Trying to append non- Message type element. Ignored")
Exemplo n.º 37
0
    def _parse(self, dct):
        if 'deleted' in dct and dct['deleted']:
            logger.debug(
                "This is a deleted message %s of SinaWeiboStatusMessage",
                dct["id"])
            self.parsed.time = "unknown"
            self.parsed.username = "******"
            self.parsed.userid = "unknown"
            self.parsed.text = "unknown"
            self.deleted = True
            return

        self.ID.id = dct["id"]

        self.parsed.time = utils.str2utc(dct["created_at"])
        self.parsed.username = dct['user']['name']
        self.parsed.userid = dct['user']['id']
        self.parsed.reposts_count = dct['reposts_count']
        self.parsed.comments_count = dct['comments_count']
        if 'pic_urls' in dct:
            for pic in dct['pic_urls']:
                self.parsed.attachments.append({
                    'type':
                    'picture',
                    'format': ['link'],
                    'data':
                    pic['thumbnail_pic'].replace('/thumbnail/', '/woriginal/')
                })

        if 'retweeted_status' in dct:
            self.parsed.username_orig = "unknown"
            if 'pic_urls' in dct['retweeted_status']:
                for pic in dct['retweeted_status']['pic_urls']:
                    self.parsed.attachments.append({
                        'type':
                        'picture',
                        'format': ['link'],
                        'data':
                        pic['thumbnail_pic'].replace('/thumbnail/',
                                                     '/woriginal/')
                    })

            try:
                self.parsed.username_orig = dct['retweeted_status']['user'][
                    'name']
            except KeyError:
                logger.warning(
                    'KeyError when parsing SinaWeiboStatus. May be deleted original message'
                )
            self.parsed.text_orig = dct['retweeted_status']['text']
            self.parsed.text_trace = dct['text']
            self.parsed.text = self.parsed.text_trace \
                    + "//@" + self.parsed.username_orig \
                    + ": " + self.parsed.text_orig
        else:
            self.parsed.text_orig = dct['text']
            self.parsed.text_trace = None
            self.parsed.text = self.parsed.text_orig
Exemplo n.º 38
0
    def _parse(self, dct):
        if 'deleted' in dct and dct['deleted']:
            logger.debug(
                "This is a deleted message %s of SinaWeiboStatusMessage",
                dct["id"])
            self.parsed.time = "unknown"
            self.parsed.username = "******"
            self.parsed.userid = "unknown"
            self.parsed.text = "unknown"
            self.deleted = True
            return

        self.ID.id = dct["id"]

        self.parsed.time = utils.str2utc(dct["created_at"])
        self.parsed.username = dct['user']['name']
        self.parsed.userid = dct['user']['id']
        self.parsed.reposts_count = dct['reposts_count']
        self.parsed.comments_count = dct['comments_count']
        if 'pic_urls' in dct:
            for pic in dct['pic_urls']:
                self.parsed.attachments.append({
                    'type':
                    'picture',
                    'format': ['link'],
                    'data':
                    pic['thumbnail_pic'].replace('/thumbnail/', '/woriginal/')
                })

        if 'retweeted_status' in dct:
            self.parsed.username_orig = "unknown"
            if 'pic_urls' in dct['retweeted_status']:
                for pic in dct['retweeted_status']['pic_urls']:
                    self.parsed.attachments.append({
                        'type':
                        'picture',
                        'format': ['link'],
                        'data':
                        pic['thumbnail_pic'].replace('/thumbnail/',
                                                     '/woriginal/')
                    })

            try:
                self.parsed.username_orig = dct['retweeted_status']['user'][
                    'name']
            except KeyError:
                logger.warning(
                    'KeyError when parsing SinaWeiboStatus. May be deleted original message'
                )
            self.parsed.text_orig = dct['retweeted_status']['text']
            self.parsed.text_trace = dct['text']
            self.parsed.text = self.parsed.text_trace \
                    + " || " + "@" + self.parsed.username_orig \
                    + " : " + self.parsed.text_orig
        else:
            self.parsed.text_orig = dct['text']
            self.parsed.text_trace = None
            self.parsed.text = self.parsed.text_orig
Exemplo n.º 39
0
 def new_channel(self, pl=None, **kwarg):
     if pl:
         try:
             return getattr(platform, pl).new_channel(**kwarg)
         except AttributeError:
             logger.warning("can not find platform '%s'", pl)
             return utils.JsonDict()
     else:
         return utils.JsonDict(json.load(open(abspath("conf/init-channel.json.example"), "r")))
Exemplo n.º 40
0
    def home_timeline(self, count=20):

        try:
            jsonlist = self.instagram_request(resource="users/self/feed",
                                              method="get",
                                              count=count)
        except Exception, e:
            logger.warning("InstagramAPIError, %s", e)
            return snstype.MessageList()
Exemplo n.º 41
0
 def __init_oauth2_client(self):
     if self.auth_client == None:
         try:
             self.auth_client = oauth.APIClient(self.jsonconf.app_key, \
                     self.jsonconf.app_secret, self.auth_info.callback_url, \
                     auth_url = self.auth_info.auth_url)
         except:
             logger.critical("auth_client init error")
             raise snserror.auth
Exemplo n.º 42
0
 def __init_oauth2_client(self):
     if self.auth_client == None:
         try:
             self.auth_client = oauth.APIClient(self.jsonconf.app_key, \
                     self.jsonconf.app_secret, self.auth_info.callback_url, \
                     auth_url = self.auth_info.auth_url)
         except:
             logger.critical("auth_client init error")
             raise snserror.auth
Exemplo n.º 43
0
 def unlike(self, message):
     try:
         jsonlist = self.instagram_request(resource="media/" +
                                           message.ID.id + "/likes",
                                           method="delete")
         return True
     except Exception, e:
         logger.warning("InstagramAPIError, %s", e)
         return False
Exemplo n.º 44
0
 def auth(self):
     if self.get_saved_token():
         return self.is_authed()
     if self.jsonconf['auth_by'] == 'gsid':
         self.token['gsid'] = self.jsonconf['gsid']
     elif self.jsonconf['auth_by'] == 'userpass':
         show_verification = False
         verification_code = ''
         req = urllib2.Request('http://login.weibo.cn/login/?vt=4&revalid=2&ns=1&pt=1')
         req = self._process_req(req)
         response = urllib2.urlopen(req, timeout = 10)
         p = response.read()
         while True:
             req = urllib2.Request('http://login.weibo.cn/login/?rand=' + (re.search("rand=([0-9]*)", p).group(1) )+ '&backURL=http%3A%2F%2Fweibo.cn&backTitle=%E6%89%8B%E6%9C%BA%E6%96%B0%E6%B5%AA%E7%BD%91&vt=4&revalid=2&ns=1')
             data = {'mobile': self.auth_info['login_username'],
                     'password_%s' % (re.search('name="password_([0-9]*)"', p).group(1)): self.auth_info['login_password'],
                     'backURL': 'http%3A%2F%2Fweibo.cn',
                     'backTitle': '手机新浪网',
                     'tryCount': '',
                     'vk': re.search('name="vk" value="([^"]*)"', p).group(1),
                     'submit' : '登录'}
             if show_verification:
                 data['code'] = verification_code
                 data['capId'] = re.search('name="capId" value="([^"]*)"', p).group(1)
                 show_verification = False
             req = self._process_req(req)
             data = urllib.urlencode(data)
             response = urllib2.urlopen(req, data, timeout = 10)
             p = response.read()
             final_url = response.geturl()
             if 'newlogin' in final_url:
                 final_gsid = re.search('g=([^&]*)', final_url).group(1)
                 self.token = {'gsid' :  final_gsid}
                 break
             elif '验证码' in p:
                 err_msg = re.search('class="me">([^>]*)<', p).group(1)
                 if '请输入图片中的字符' in p:
                     captcha_url = re.search(r'"([^"]*captcha[^"]*)', p).group(1)
                     show_verification = True
                     import Image
                     import StringIO
                     ss = urllib2.urlopen(captcha_url, timeout=10).read()
                     sss = StringIO.StringIO(ss)
                     img = Image.open(sss)
                     img.show()
                     verification_code = raw_input(err_msg)
             else:
                 err_msg = re.search('class="me">([^>]*)<', p).group(1)
                 logger.warning(err_msg)
                 break
     else:
         return False
     res = self.is_authed()
     if res:
         self.save_token()
     return res
Exemplo n.º 45
0
 def _get_weibo(self, page = 1):
     #FIXME: 获取转发和评论数应该修改为分析DOM而不是正则表达式(以免与内容重复)
     #FIXME: 对于转发的微博,原微博信息不足
     req = urllib2.Request('http://weibo.cn/?gsid=' + self.token['gsid'] + '&page=%d' % (page))
     req = self._process_req(req)
     m = urllib2.urlopen(req, timeout = 10).read()
     h = lxml.html.fromstring(m)
     weibos = []
     for i in h.find_class('c'):
         try:
             if i.get('id') and i.get('id')[0:2] == 'M_':
                 weibo = None
                 if i.find_class('cmt'): # 转发微博
                     weibo = {
                             'uid' : self._get_uid_by_pageurl(i.find_class('nk')[0].attrib['href'], self.jsonconf['uidtype']),
                             'author' : i.find_class('nk')[0].text,
                             'id': i.get('id')[2:],
                             'time': i.find_class('ct')[0].text.encode('utf-8').strip(' ').split(' ')[0].decode('utf-8'),
                             'text' : None,
                             'orig' : {
                                 'text': unicode(i.find_class('ctt')[0].text_content()),
                                 'author': re.search(u'转发了\xa0(.*)\xa0的微博', i.find_class('cmt')[0].text_content()).group(1),
                                 'comments_count' : 0,
                                 'reposts_count' : 0
                                 },
                             'comments_count' : 0,
                             'reposts_count' : 0
                             }
                     parent = i.find_class('cmt')[-1].getparent()
                     retweet_reason = re.sub(r'转发理由:(.*)赞\[[0-9]*\] 转发\[[0-9]*\] 评论\[[0-9]*\] 收藏.*$', r'\1', parent.text_content().encode('utf-8'))
                     weibo['text'] = retweet_reason.decode('utf-8')
                     zf = re.search(r'赞\[([0-9]*)\] 转发\[([0-9]*)\] 评论\[([0-9]*)\]', parent.text_content().encode('utf-8'))
                     if zf:
                         weibo['comments_count'] = int(zf.group(3))
                         weibo['reposts_count'] = int(zf.group(2))
                     zf = re.search(r'赞\[([0-9]*)\] 原文转发\[([0-9]*)\] 原文评论\[([0-9]*)\]', i.text_content().encode('utf-8'))
                     if zf:
                         weibo['orig']['comments_count'] = int(zf.group(3))
                         weibo['orig']['reposts_count'] = int(zf.group(2))
                 else:
                     weibo = {'author' : i.find_class('nk')[0].text,
                             'uid' : self._get_uid_by_pageurl(i.find_class('nk')[0].attrib['href'], self.jsonconf['uidtype']),
                             'text': i.find_class('ctt')[0].text_content()[1:],
                             'id': i.get('id')[2:],
                             'time': i.find_class('ct')[0].text.encode('utf-8').strip(' ').split(' ')[0].decode('utf-8')
                             }
                     zf = re.search(r'赞\[([0-9]*)\] 转发\[([0-9]*)\] 评论\[([0-9]*)\]', i.text_content().encode('utf-8'))
                     if zf:
                         weibo['comments_count'] = int(zf.group(3))
                         weibo['reposts_count'] = int(zf.group(2))
                 if i.find_class('ib'):
                     #FIXME: Still not able to process a collections of pictures
                     weibo['attachment_img'] = i.find_class('ib')[0].get('src').replace('wap128', 'woriginal')
                 weibos.append(weibo)
         except Exception, e:
             logger.warning("Catch exception: %s" % (str(e)))
Exemplo n.º 46
0
 def auth(self):
     if self.get_saved_token():
         return self.is_authed()
     if self.jsonconf['auth_by'] == 'gsid':
         self.token['gsid'] = self.jsonconf['gsid']
     elif self.jsonconf['auth_by'] == 'userpass':
         show_verification = False
         verification_code = ''
         req = urllib2.Request('http://login.weibo.cn/login/?vt=4&revalid=2&ns=1&pt=1')
         req = self._process_req(req)
         response = urllib2.urlopen(req, timeout = 10)
         p = response.read()
         while True:
             req = urllib2.Request('http://login.weibo.cn/login/?rand=' + (re.search("rand=([0-9]*)", p).group(1) )+ '&backURL=http%3A%2F%2Fweibo.cn&backTitle=%E6%89%8B%E6%9C%BA%E6%96%B0%E6%B5%AA%E7%BD%91&vt=4&revalid=2&ns=1')
             data = {'mobile': self.auth_info['login_username'],
                     'password_%s' % (re.search('name="password_([0-9]*)"', p).group(1)): self.auth_info['login_password'],
                     'backURL': 'http%3A%2F%2Fweibo.cn',
                     'backTitle': '手机新浪网',
                     'tryCount': '',
                     'vk': re.search('name="vk" value="([^"]*)"', p).group(1),
                     'submit' : '登录'}
             if show_verification:
                 data['code'] = verification_code
                 data['capId'] = re.search('name="capId" value="([^"]*)"', p).group(1)
                 show_verification = False
             req = self._process_req(req)
             data = urllib.urlencode(data)
             response = urllib2.urlopen(req, data, timeout = 10)
             p = response.read()
             final_url = response.geturl()
             if 'newlogin' in final_url:
                 final_gsid = re.search('g=([^&]*)', final_url).group(1)
                 self.token = {'gsid' :  final_gsid}
                 break
             elif '验证码' in p:
                 err_msg = re.search('class="me">([^>]*)<', p).group(1)
                 if '请输入图片中的字符' in p:
                     captcha_url = re.search(r'"([^"]*captcha[^"]*)', p).group(1)
                     show_verification = True
                     import Image
                     import StringIO
                     ss = urllib2.urlopen(captcha_url, timeout=10).read()
                     sss = StringIO.StringIO(ss)
                     img = Image.open(sss)
                     img.show()
                     verification_code = raw_input(err_msg)
             else:
                 err_msg = re.search('class="me">([^>]*)<', p).group(1)
                 logger.warning(err_msg)
                 break
     else:
         return False
     res = self.is_authed()
     if res:
         self.save_token()
     return res
Exemplo n.º 47
0
 def new_channel(self, pl = None, **kwarg):
     if pl:
         try:
             return getattr(platform, pl).new_channel(**kwarg)
         except AttributeError:
             logger.warning("can not find platform '%s'", pl)
             return utils.JsonDict()
     else:
         _fn_conf = path.join(SNSConf._SNSAPI_DIR_STATIC_DATA, 'init-channel.json.example')
         return utils.JsonDict(json.load(open(_fn_conf)))
Exemplo n.º 48
0
 def unlike(self, message):
     try:
         jsonlist = self.instagram_request(
             resource="media/" + message.ID.id + "/likes",
             method="delete"
         )
         return True
     except Exception, e:
         logger.warning("InstagramAPIError, %s", e)
         return False
Exemplo n.º 49
0
    def _parse(self, dct):
        if 'deleted' in dct and dct['deleted']:
            logger.debug("This is a deleted message %s of SinaWeiboStatusMessage", dct["id"])
            self.parsed.time = "unknown"
            self.parsed.username = "******"
            self.parsed.userid = "unknown"
            self.parsed.text = "unknown"
            self.deleted = True
            return

        self.ID.id = dct["id"]

        self.parsed.time = utils.str2utc(dct["created_at"])
        self.parsed.username = dct['user']['name']
        self.parsed.userid = dct['user']['id']
        self.parsed.reposts_count = dct['reposts_count']
        self.parsed.comments_count = dct['comments_count']
        # accordian to http://open.weibo.com/qa/index.php?qa=448&qa_1=v2-%E5%B7%B2%E6%94%B6%E8%97%8F%E5%BE%AE%E5%8D%9A-%E6%8E%A5%E5%8F%A3statuses-friends-timeline%E8%BF%94%E5%9B%9E%E5%AD%97%E6%AE%B5-favorited-%E4%B8%BAfalse
        # Currently we have no way to tell whether 
        # a weibo message is favorited Although there's a 
        # specious property
        self.parsed.liked = False
        if 'pic_urls' in dct:
            for pic in dct['pic_urls']:
                self.parsed.attachments.append(
                {
                    'type': 'picture',
                    'format': ['link'],
                    'data': pic['thumbnail_pic'].replace('/thumbnail/', '/woriginal/')
                })

        if 'retweeted_status' in dct:
            self.parsed.username_orig = "unknown"
            if 'pic_urls' in dct['retweeted_status']:
                for pic in dct['retweeted_status']['pic_urls']:
                    self.parsed.attachments.append(
                        {
                            'type': 'picture',
                            'format': ['link'],
                            'data': pic['thumbnail_pic'].replace('/thumbnail/', '/woriginal/')
                        })

            try:
                self.parsed.username_orig = dct['retweeted_status']['user']['name']
            except KeyError:
                logger.warning('KeyError when parsing SinaWeiboStatus. May be deleted original message')
            self.parsed.text_orig = dct['retweeted_status']['text']
            self.parsed.text_trace = dct['text']
            self.parsed.text = self.parsed.text_trace \
                    + "//@" + self.parsed.username_orig \
                    + ": " + self.parsed.text_orig
        else:
            self.parsed.text_orig = dct['text']
            self.parsed.text_trace = None
            self.parsed.text = self.parsed.text_orig
Exemplo n.º 50
0
 def new_channel(self, pl=None, **kwarg):
     if pl:
         try:
             return getattr(platform, pl).new_channel(**kwarg)
         except AttributeError:
             logger.warning("can not find platform '%s'", pl)
             return utils.JsonDict()
     else:
         _fn_conf = path.join(SNSConf._SNSAPI_DIR_STATIC_DATA,
                              'init-channel.json.example')
         return utils.JsonDict(json.load(open(_fn_conf)))
Exemplo n.º 51
0
 def _http_post(self, baseurl, params):
     try:
         for p in params:
             params[p] = self._unicode_encode(params[p])
         data = urllib.urlencode(params)
         resp = urllib.urlopen(baseurl,data)
         json_objs = json.loads(resp.read())
         return json_objs
     except Exception, e:
         logger.warning("_http_post fail: %s", e)
         return {}
Exemplo n.º 52
0
    def home_timeline(self, count=20):

        try:
            jsonlist = self.instagram_request(
                resource="users/self/feed",
                method="get",
                count=count
            )
        except Exception, e:
            logger.warning("InstagramAPIError, %s", e)
            return snstype.MessageList()
Exemplo n.º 53
0
 def _get_user_status_list(self, count, userid, username):
     try:
         jsonlist = self.renren_request(
             method="status.gets",
             page=1,
             count=count,
             uid = userid,
         )
     except RenrenAPIError, e:
         logger.warning("RenrenAPIError, %s", e)
         return snstype.MessageList()
Exemplo n.º 54
0
 def new_channel(self, pl=None, **argd):
     if pl:
         try:
             return getattr(platform, pl).new_channel(**argd)
         except AttributeError:
             logger.warning("can not find platform '%s'", pl)
             return utils.JsonDict()
     else:
         return utils.JsonDict(
             json.load(open(abspath('conf/init-channel.json.example'),
                            'r')))
Exemplo n.º 55
0
 def _get_user_status_list(self, count, userid, username):
     try:
         jsonlist = self.renren_request(
             method="status/list",
             pageNumberint=1,
             pageSize=count,
             ownerId=userid,
         )
     except RenrenAPIError, e:
         logger.warning("RenrenAPIError, %s", e)
         return snstype.MessageList()
Exemplo n.º 56
0
 def extend(self, l):
     if isinstance(l, MessageList):
         super(MessageList, self).extend(l)
     elif isinstance(l, list):
         # We still extend the list if the user asks to.
         # However, a warning will be placed. Doing this
         # may violate some properties of MessageList, e.g.
         # there is no Deleted Message in the list.
         super(MessageList, self).extend(l)
         logger.warning("Extend MessageList with non MessageList list.")
     else:
         logger.warning("Extend MessageList with unknown type.")
Exemplo n.º 57
0
 def reply(self, statusID, text):
     try:
         result = self.instagram_request(resource="media/" + statusID.id +
                                         "/comments",
                                         method="post",
                                         text=text)
         # TODO:
         #     Find better indicator for status update success
         return True
     except Exception, e:
         logger.warning('update Instagram failed: %s', str(e))
         return False
Exemplo n.º 58
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()
Exemplo n.º 59
0
 def callback_and_sleep(self, value):
     if self.callback:
         try:
             self.callback(value)
         except Exception as e:
             logger.warning("Error while executing callback %s" % (str(e)))
     if self.started:
         for i in range(self.sleepsec):
             time.sleep(1)
             if not self.started:
                 break
         if self.started:
             self._start()