<s> from __future__ import with_statement <EOL> import base64 <EOL> import datetime <EOL> import httplib <EOL> import logging <EOL> import os <EOL> import random <EOL> import struct <EOL> import time <EOL> import urllib , urllib2 <EOL> import uuid <EOL> from google . appengine . api import app_identity <EOL> from google . appengine . ext import webapp <EOL> from google . appengine . ext . webapp import util <EOL> from google . appengine . runtime import DeadlineExceededError <EOL> from apns import APNs , Payload , PayloadAlert <EOL> import apnsAuthToken <EOL> import c2dm <EOL> import c2dmAuthToken <EOL> import cloudstorage as gcs <EOL> import filestorage <EOL> import gcmAuthToken <EOL> import registration <EOL> class PostMessage ( webapp . RequestHandler ) : <EOL> def post ( self ) : <EOL> minlen = <NUM_LIT:4> + <NUM_LIT:4> + <NUM_LIT:20> + <NUM_LIT:4> + <NUM_LIT:1> + <NUM_LIT:4> + <NUM_LIT:1> <EOL> STR_VERSERVER = '<STR_LIT>' <EOL> INT_VERCLIENT = <NUM_LIT> <EOL> STR_VERCLIENT = '<STR_LIT>' <EOL> if not os . environ . has_key ( '<STR_LIT>' ) : <EOL> self . resp_simple ( <NUM_LIT:0> , '<STR_LIT>' ) <EOL> return <EOL> if not os . environ . has_key ( '<STR_LIT>' ) : <EOL> self . resp_simple ( <NUM_LIT:0> , '<STR_LIT>' ) <EOL> return <EOL> HTTPS = os . environ . get ( '<STR_LIT>' , '<STR_LIT>' ) <EOL> CURRENT_VERSION_ID = os . environ . get ( '<STR_LIT>' , STR_VERSERVER ) <EOL> if HTTPS . __str__ ( ) != '<STR_LIT>' : <EOL> self . resp_simple ( <NUM_LIT:0> , '<STR_LIT>' ) <EOL> return <EOL> self . response . headers [ '<STR_LIT:Content-Type>' ] = '<STR_LIT>' <EOL> data = self . request . body <EOL> size = str . __len__ ( data ) <EOL> if size < minlen : <EOL> logging . debug ( "<STR_LIT>" % data ) <EOL> logging . debug ( "<STR_LIT>" % size ) <EOL> self . resp_simple ( <NUM_LIT:0> , '<STR_LIT>' ) <EOL> return <EOL> client = ( struct . unpack ( "<STR_LIT>" , data [ <NUM_LIT:0> : <NUM_LIT:4> ] ) ) [ <NUM_LIT:0> ] <EOL> data = data [ <NUM_LIT:4> : ] <EOL> if client < INT_VERCLIENT : <EOL> self . resp_simple ( <NUM_LIT:0> , ( '<STR_LIT>' % STR_VERCLIENT ) ) <EOL> return <EOL> server = int ( CURRENT_VERSION_ID [ <NUM_LIT:0> : <NUM_LIT:8> ] , <NUM_LIT:16> ) <EOL> isProd = CURRENT_VERSION_ID [ <NUM_LIT:8> : <NUM_LIT:9> ] == '<STR_LIT:p>' <EOL> pos = <NUM_LIT:0> <EOL> lenrid = ( struct . unpack ( "<STR_LIT>" , data [ pos : ( pos + <NUM_LIT:4> ) ] ) ) [ <NUM_LIT:0> ] <EOL> pos = pos + <NUM_LIT:4> <EOL> retrievalId = base64 . encodestring ( data [ pos : ( pos + lenrid ) ] ) <EOL> pos = pos + lenrid <EOL> lenrtok = ( struct . unpack ( "<STR_LIT>" , data [ pos : ( pos + <NUM_LIT:4> ) ] ) ) [ <NUM_LIT:0> ] <EOL> pos = pos + <NUM_LIT:4> <EOL> recipientToken = str ( data [ pos : ( pos + lenrtok ) ] ) <EOL> pos = pos + lenrtok <EOL> lenmd = ( struct . unpack ( "<STR_LIT>" , data [ pos : ( pos + <NUM_LIT:4> ) ] ) ) [ <NUM_LIT:0> ] <EOL> pos = pos + <NUM_LIT:4> <EOL> msgData = data [ pos : ( pos + lenmd ) ] <EOL> pos = pos + lenmd <EOL> lenfd = ( struct . unpack ( "<STR_LIT>" , data [ pos : ( pos + <NUM_LIT:4> ) ] ) ) [ <NUM_LIT:0> ] <EOL> pos = pos + <NUM_LIT:4> <EOL> fileData = data [ pos : ( pos + lenfd ) ] <EOL> pos = pos + lenfd <EOL> if len ( data ) >= ( pos + <NUM_LIT:4> ) : <EOL> devtype = ( struct . unpack ( "<STR_LIT>" , data [ pos : ( pos + <NUM_LIT:4> ) ] ) ) [ <NUM_LIT:0> ] <EOL> else : <EOL> if lenrtok <= <NUM_LIT:64> : <EOL> devtype = <NUM_LIT:2> <EOL> else : <EOL> devtype = <NUM_LIT:1> <EOL> canonicalId = None <EOL> active_reg = True <EOL> reg_new = None <EOL> query = registration . Registration . all ( ) . order ( '<STR_LIT>' ) <EOL> query . filter ( '<STR_LIT>' , recipientToken ) <EOL> reg_old = query . get ( ) <EOL> if reg_old is not None : <EOL> query2 = registration . Registration . all ( ) . order ( '<STR_LIT>' ) <EOL> query2 . filter ( '<STR_LIT>' , reg_old . key_id ) <EOL> reg_new = query2 . get ( ) <EOL> if reg_new is not None : <EOL> logging . info ( '<STR_LIT>' % ( reg_new . notify_type , reg_new . registration_id [ <NUM_LIT:0> : <NUM_LIT:10> ] , devtype , recipientToken [ <NUM_LIT:0> : <NUM_LIT:10> ] ) ) <EOL> recipientToken = reg_new . registration_id <EOL> devtype = reg_new . notify_type <EOL> canonicalId = reg_new . canonical_id <EOL> active_reg = reg_new . active <EOL> logging . debug ( "<STR_LIT>" + retrievalId ) <EOL> logging . debug ( "<STR_LIT>" + recipientToken ) <EOL> if devtype <= <NUM_LIT:0> : <EOL> self . resp_simple ( <NUM_LIT:0> , '<STR_LIT>' ) <EOL> return <EOL> elif devtype >= <NUM_LIT:4> : <EOL> self . resp_simple ( <NUM_LIT:0> , ( '<STR_LIT>' % devtype ) ) <EOL> return <EOL> if lenfd > <NUM_LIT:0> : <EOL> DATASTORE_LIMIT = <NUM_LIT> <EOL> if lenfd <= DATASTORE_LIMIT : <EOL> filestore = filestorage . FileStorage ( id = retrievalId , data = fileData , msg = msgData , client_ver = client , sender_token = str ( recipientToken ) , notify_type = devtype ) <EOL> else : <EOL> bucket_name = app_identity . get_default_gcs_bucket_name ( ) <EOL> object_name = str ( uuid . uuid4 ( ) ) <EOL> filename = '<STR_LIT:/>' + bucket_name + '<STR_LIT:/>' + object_name <EOL> with gcs . open ( filename , '<STR_LIT:w>' ) as f : <EOL> pos = <NUM_LIT:0> <EOL> bdata = str ( fileData [ pos : ( pos + <NUM_LIT> ) ] ) <EOL> pos = pos + <NUM_LIT> <EOL> while bdata : <EOL> f . write ( bdata ) <EOL> bdata = str ( fileData [ pos : ( pos + <NUM_LIT> ) ] ) <EOL> pos = pos + <NUM_LIT> <EOL> f . close ( ) <EOL> filestore = filestorage . FileStorage ( id = retrievalId , blobkey = filename , msg = msgData , client_ver = client , sender_token = str ( recipientToken ) , notify_type = devtype ) <EOL> else : <EOL> filestore = filestorage . FileStorage ( id = retrievalId , msg = msgData , client_ver = client , sender_token = str ( recipientToken ) , notify_type = devtype ) <EOL> filestore . put ( ) <EOL> key = filestore . key ( ) <EOL> if not key . has_id_or_name ( ) : <EOL> self . resp_simple ( <NUM_LIT:0> , '<STR_LIT>' ) <EOL> return <EOL> msgdata_sec = <NUM_LIT> <EOL> msgdata_tot = <NUM_LIT:0> <EOL> data_retry = True <EOL> while data_retry and msgdata_tot < <NUM_LIT:32> : <EOL> query = filestorage . FileStorage . all ( ) <EOL> query . filter ( '<STR_LIT>' , retrievalId ) <EOL> num = query . count ( ) <EOL> if num >= <NUM_LIT:1> : <EOL> data_retry = False <EOL> elif num == <NUM_LIT:0> : <EOL> msgdata_tot += msgdata_sec <EOL> logging . info ( "<STR_LIT>" + str ( msgdata_sec ) ) <EOL> time . sleep ( msgdata_sec ) <EOL> msgdata_sec *= <NUM_LIT:2> <EOL> if data_retry : <EOL> logging . error ( "<STR_LIT>" + str ( msgdata_sec ) ) <EOL> if devtype == <NUM_LIT:1> : <EOL> sender = c2dm . C2DM ( ) <EOL> sender . registrationId = recipientToken <EOL> sender . collapseKey = retrievalId <EOL> sender . fileid = retrievalId <EOL> query = c2dmAuthToken . C2dmAuthToken . all ( ) . order ( '<STR_LIT>' ) <EOL> items = query . fetch ( <NUM_LIT:1> ) <EOL> num = <NUM_LIT:0> <EOL> for token in items : <EOL> sender . clientAuth = token . token <EOL> num = num + <NUM_LIT:1> <EOL> if num != <NUM_LIT:1> : <EOL> logging . error ( '<STR_LIT>' % num ) <EOL> self . resp_simple ( <NUM_LIT:0> , '<STR_LIT>' ) <EOL> return <EOL> respMessage = sender . sendMessage ( ) <EOL> if respMessage . find ( '<STR_LIT>' ) != - <NUM_LIT:1> : <EOL> if reg_new is not None : <EOL> reg_new . active = False <EOL> reg_new . put ( ) <EOL> if respMessage . find ( '<STR_LIT>' ) != - <NUM_LIT:1> : <EOL> self . resp_simple ( <NUM_LIT:0> , ( '<STR_LIT>' ) % respMessage ) <EOL> return <EOL> elif devtype == <NUM_LIT:2> : <EOL> query = apnsAuthToken . APNSAuthToken . all ( ) <EOL> if isProd : <EOL> query . filter ( '<STR_LIT>' , '<STR_LIT>' ) <EOL> else : <EOL> query . filter ( '<STR_LIT>' , '<STR_LIT:test>' ) <EOL> items = query . fetch ( <NUM_LIT:1> ) <EOL> num = <NUM_LIT:0> <EOL> for credential in items : <EOL> APNS_KEY = credential . apnsKey <EOL> APNS_CERT = credential . apnsCert <EOL> num = num + <NUM_LIT:1> <EOL> apns = None <EOL> if isProd : <EOL> apns = APNs ( use_sandbox = False , cert_file = APNS_CERT , key_file = APNS_KEY , enhanced = True ) <EOL> else : <EOL> apns = APNs ( use_sandbox = True , cert_file = APNS_CERT , key_file = APNS_KEY , enhanced = True ) <EOL> query = filestorage . FileStorage . all ( ) <EOL> undownloaded = False <EOL> query . filter ( '<STR_LIT>' , recipientToken ) . filter ( '<STR_LIT>' , undownloaded ) <EOL> badge = query . count ( ) <EOL> apnsmessage = { } <EOL> apnsmessage [ '<STR_LIT:data>' ] = { } <EOL> apnsmessage [ '<STR_LIT>' ] = '<STR_LIT:default>' <EOL> apnsmessage [ '<STR_LIT>' ] = badge <EOL> apnsmessage [ '<STR_LIT>' ] = PayloadAlert ( "<STR_LIT>" , loc_key = "<STR_LIT>" ) <EOL> apnsmessage [ '<STR_LIT>' ] = { '<STR_LIT>' : retrievalId } <EOL> payload = Payload ( alert = apnsmessage [ '<STR_LIT>' ] , sound = apnsmessage [ '<STR_LIT>' ] , custom = apnsmessage [ '<STR_LIT>' ] , badge = apnsmessage [ '<STR_LIT>' ] ) <EOL> status = <NUM_LIT:0> <EOL> try : <EOL> identifier = random . getrandbits ( <NUM_LIT:32> ) <EOL> status = apns . gateway_server . send_notification ( recipientToken , payload , identifier = identifier ) <EOL> except DeadlineExceededError : <EOL> logging . info ( "<STR_LIT>" ) <EOL> self . resp_simple ( <NUM_LIT:0> , '<STR_LIT>' ) <EOL> return <EOL> if status == <NUM_LIT:8> : <EOL> if reg_new is not None : <EOL> reg_new . active = False <EOL> reg_new . put ( ) <EOL> if status == <NUM_LIT:0> : <EOL> logging . info ( "<STR_LIT>" + str ( status ) ) <EOL> elif status == <NUM_LIT:1> or status == <NUM_LIT:10> : <EOL> logging . error ( "<STR_LIT>" ) <EOL> self . resp_simple ( <NUM_LIT:0> , '<STR_LIT>' ) <EOL> return <EOL> elif status == <NUM_LIT:2> or status == <NUM_LIT:5> or status == <NUM_LIT:8> : <EOL> self . resp_simple ( <NUM_LIT:0> , '<STR_LIT>' ) <EOL> return <EOL> else : <EOL> logging . error ( "<STR_LIT>" % status ) <EOL> self . resp_simple ( <NUM_LIT:0> , '<STR_LIT>' ) <EOL> return <EOL> respMessage = struct . pack ( '<STR_LIT>' , status ) <EOL> elif devtype == <NUM_LIT:3> : <EOL> query = gcmAuthToken . GcmAuthToken . all ( ) . order ( '<STR_LIT>' ) <EOL> items = query . fetch ( <NUM_LIT:1> ) <EOL> num = <NUM_LIT:0> <EOL> for token in items : <EOL> GCM_KEY = token . gcmkey <EOL> num = num + <NUM_LIT:1> <EOL> if canonicalId is not None : <EOL> proper_registration_id = canonicalId <EOL> logging . info ( '<STR_LIT>' % ( canonicalId [ <NUM_LIT:0> : <NUM_LIT:10> ] , recipientToken [ <NUM_LIT:0> : <NUM_LIT:10> ] ) ) <EOL> else : <EOL> proper_registration_id = recipientToken <EOL> values = { '<STR_LIT>' : proper_registration_id , <EOL> '<STR_LIT>' : retrievalId , <EOL> } <EOL> headers = { '<STR_LIT>' : '<STR_LIT>' + GCM_KEY } <EOL> data = urllib . urlencode ( values ) <EOL> request = urllib2 . Request ( '<STR_LIT>' , data , headers ) <EOL> timeout_sec = <NUM_LIT:2> <EOL> timeout_tot = <NUM_LIT:0> <EOL> url_retry = True <EOL> while url_retry and timeout_tot < <NUM_LIT:32> : <EOL> try : <EOL> timeout_tot += timeout_sec <EOL> response = urllib2 . urlopen ( request , timeout = timeout_sec ) <EOL> url_retry = False <EOL> respMessage = response . read ( ) <EOL> logging . info ( '<STR_LIT:%s>' % respMessage ) <EOL> lines = respMessage . splitlines ( ) <EOL> if lines . __len__ ( ) == <NUM_LIT:2> : <EOL> kv = lines [ <NUM_LIT:1> ] . split ( '<STR_LIT:=>' ) <EOL> if kv [ <NUM_LIT:0> ] == '<STR_LIT>' : <EOL> if canonicalId != kv [ <NUM_LIT:1> ] : <EOL> if reg_new is not None : <EOL> reg_new . canonical_id = kv [ <NUM_LIT:1> ] <EOL> reg_new . canonical_updated = datetime . datetime . now ( ) <EOL> reg_new . put ( ) <EOL> except httplib . HTTPException , e : <EOL> logging . info ( "<STR_LIT>" + str ( e ) + "<STR_LIT>" + str ( timeout_sec ) ) <EOL> timeout_sec *= <NUM_LIT:2> <EOL> except urllib2 . HTTPError , e : <EOL> logging . error ( "<STR_LIT>" + str ( e ) ) <EOL> if e . code == <NUM_LIT> : <EOL> self . resp_simple ( <NUM_LIT:0> , '<STR_LIT>' ) <EOL> return <EOL> else : <EOL> self . resp_simple ( <NUM_LIT:0> , '<STR_LIT>' ) <EOL> return <EOL> if url_retry : <EOL> self . resp_simple ( <NUM_LIT:0> , '<STR_LIT>' ) <EOL> return <EOL> if respMessage . find ( '<STR_LIT>' ) != - <NUM_LIT:1> : <EOL> if reg_new is not None : <EOL> reg_new . active = False <EOL> reg_new . put ( ) <EOL> if respMessage . find ( '<STR_LIT>' ) != - <NUM_LIT:1> : <EOL> self . resp_simple ( <NUM_LIT:0> , ( '<STR_LIT>' ) % respMessage ) <EOL> return <EOL> filestore . push_accepted = True <EOL> filestore . put ( ) <EOL> self . response . out . write ( '<STR_LIT:%s>' % struct . pack ( '<STR_LIT>' , server ) ) <EOL> self . response . out . write ( '<STR_LIT>' % ( struct . pack ( '<STR_LIT>' , <NUM_LIT:1> ) , respMessage ) ) <EOL> def resp_simple ( self , code , msg ) : <EOL> self . response . out . write ( '<STR_LIT>' % ( struct . pack ( '<STR_LIT>' , code ) , msg ) ) <EOL> if code == <NUM_LIT:0> : <EOL> logging . error ( msg ) <EOL> def main ( ) : <EOL> STR_VERSERVER = '<STR_LIT>' <EOL> CURRENT_VERSION_ID = os . environ . get ( '<STR_LIT>' , STR_VERSERVER ) <EOL> isProd = CURRENT_VERSION_ID [ <NUM_LIT:8> : <NUM_LIT:9> ] == '<STR_LIT:p>' <EOL> if isProd : <EOL> logging . getLogger ( ) . setLevel ( logging . INFO ) <EOL> else : <EOL> logging . getLogger ( ) . setLevel ( logging . DEBUG ) <EOL> application = webapp . WSGIApplication ( [ ( '<STR_LIT>' , PostMessage ) , <EOL> ( '<STR_LIT>' , PostMessage ) , <EOL> ( '<STR_LIT>' , PostMessage ) ] , <EOL> debug = True ) <EOL> util . run_wsgi_app ( application ) <EOL> if __name__ == '<STR_LIT:__main__>' : <EOL> main ( ) </s>
