def update_twitter(self, post, found=False): try: client = TwitterClient(secret.CONSUMER_KEY, secret.CONSUMER_SECRET, "/") info_url = "http://www.neperczagtu.lv/info/%s" % post.key().id() params = {} if found: params['status'] = "Tikko atrasts velosipēds: %s :)" % info_url else: params['status'] = "Tikko pievienots nozagts velosipēds: %s :(" % info_url response = client.make_request("http://api.twitter.com/1/statuses/update.json", secret.TOKEN, secret.TOKEN_SECRET, params, True, urlfetch.POST) data = json.loads(response.content) logging.info('Twitter status update response: %s' % data) except Exception, e: self.error(500) logging.exception(e) return False
def api(self): path_list=self.request.path.rstrip('/').split('/') try: passwd=path_list.pop(1) [self.SCREEN_NAME,self.ACCESS_TOKEN,self.ACCESS_TOKEN_SECRET]=dec_info(passwd,ACCOUNTS[md5sum(passwd)]) except: # show 'Not Found' on any error about authentication self.response.headers['Content-Type']='text/html' self.response.set_status(404) self.response.write(dummy_msg.format(self.request.path_qs)) return else: if path_list==['']: self.response.headers['Content-Type']='text/html' self.response.write(work_msg.format(self.SCREEN_NAME,self.request.host)) return elif path_list[-2:]==['oauth','access_token']: self.response.headers['Content-Type']='text/plain' self.response.write(urlencode([('oauth_token',self.ACCESS_TOKEN), ('oauth_token_secret',self.ACCESS_TOKEN_SECRET), ('user_id',self.ACCESS_TOKEN.split('-')[0]), ('screen_name',self.SCREEN_NAME), ('x_auth_expires',0)])) return else: editable=(path_list[-2:] in editable_api) if 'get_original_rest=1' in self.request.query_string:editable=False if GAPLESS and editable and 'since_id' in parse_qs(self.request.query_string): qsdict={k:v for k,v in parse_qsl(self.request.query_string)} offset=10000 qsdict.update(count=200) qsdict.update(since_id=int(qsdict['since_id'])-offset) self.request.query_string=urlencode(qsdict) tcqdict=dict(path_list=path_list, qsdict=qsdict, token=self.ACCESS_TOKEN, secret=self.ACCESS_TOKEN_SECRET, body=self.request.body, offset=offset) else: tcqdict=None client=TwitterClient(CONSUMER_KEY,CONSUMER_SECRET,None) try: data=client.make_request(url=urlunparse(('https','api.twitter.com','/'.join(path_list),None,self.request.query_string,None)), token=self.ACCESS_TOKEN, secret=self.ACCESS_TOKEN_SECRET, method=self.request.method, protected=True, additional_params={k:v for k,v in parse_qsl(self.request.body)}) except Exception as error_message: debug(error_message) self.response.set_status(503) self.response.headers['Content-Type']='application/json' self.response.write(dumps(dict(error=str(error_message)),separators=(',', ':'))) return else: try: self.response.set_status(data.status_code) except KeyError: # GAE does not support special HTTP Status Codes, so it will be logged here and set the status to 403 # probably 429 info('Invalid HTTP status code: {0}'.format(data.status_code)) self.response.set_status(403) self.response.headers['Content-Type']=data.headers['Content-Type'] if data.status_code>399: info(data.status_code) self.response.write(data.content) return else: if self.request.path.endswith('.json') and self.request.method=='GET' and editable: self.response.write(ppatp(data.content,tcqdict=tcqdict)) else: self.response.write(data.content) return
def gaplesslize(status_list, tcqdict): if status_list and tcqdict: sc, st = clock(), time() client = TwitterClient(CONSUMER_KEY, CONSUMER_SECRET, None) qsdict = tcqdict["qsdict"] real_since_id = int(qsdict["since_id"]) + tcqdict["offset"] if int(status_list[-1]["id_str"]) <= real_since_id: del status_list[-1] debug("already gaplessed.") return elif int(status_list[-1]["id_str"]) - real_since_id < tcqdict["offset"] / 2: # buggy client requested debug("already gaplessed (buggy).".format(len(status_list))) return retry = 2 while True: if retry == 0: info("abort") break qsdict.update(max_id=int(status_list[-1]["id_str"])) try: data = client.make_request( url=urlunparse( ("https", "api.twitter.com", "/".join(tcqdict["path_list"]), None, urlencode(qsdict), None) ), token=tcqdict["token"], secret=tcqdict["secret"], method="GET", protected=True, additional_params=dict([(k, v) for k, v in parse_qsl(tcqdict["body"])]), ) except Exception as error_message: info(error_message) retry -= 1 else: if data.status_code > 399: # twitter refuse to response request, or twitter servers is down, abort. info("Error HTTP Status Code in gaplesslize: {0}".format(data.status_code)) break else: # it must be a json of list # successful request, reset retry counter debug("requested for gapless") new_status_list, retry = loads(data.content), 2 if new_status_list: if new_status_list[0]["id_str"] == status_list[-1]["id_str"]: # delete duplicate tweet del new_status_list[0] if not new_status_list: # empty list after delete duplicate tweet info("empty list after delete duplicate tweet") debug("Gaplessly, totally {0} tweet.".format(len(status_list))) break status_list.extend(new_status_list) if int(status_list[-1]["id_str"]) <= real_since_id: # OK, gapless, so delete the oldest del status_list[-1] debug("Gaplessly, totally {0} tweet.".format(len(status_list))) break elif int(status_list[-1]["id_str"]) - real_since_id < tcqdict["offset"] / 2: # buggy client requested debug("Gaplessly, totally {0} tweet (buggy).".format(len(status_list))) break else: debug("twitter return an empty list, should be gapless.") # empty list, should be gapless break ec, et = clock(), time() debug("gaplesslize use {0:.2f} processor time in {1:.4f} second".format(ec - sc, et - st)) return else: # no need to gaplesslize return