def process_payment(db, raw_message, payment_message): parrot = Parrots.findOne(db, {'_id': ObjectId(payment_message.get('parrot_id'))}) if parrot: message = get_message_to_share(db, payment_message) twitter_json = tweet_message(parrot, message, raw_message.id) payment = store_payment(db, twitter_json, payment_message, message, raw_message) if payment.success: if Queue.delete_message('payments', raw_message): log('cron2', 'Payments succeded', payment_message.get('subscription_id')) send_notification(db, payment, 'payment_success') log('cron2', 'Notification sent', payment_message.get('subscription_id')) create_next_payment(db, payment) log('cron2', 'Next payment created', payment_message.get('subscription_id')) add_payment_to_parrot(db, parrot, payment_message, twitter_json) else: log('cron2', 'ERROR: Couldnt delete message', payment_message.get('subscription_id')) else: total_payments_attempts = Payments.find(db, {'message_id_sqs': raw_message.id}).count() subscription = Subscriptions.findOne(db, {'account_id': payment.account_id, 'parrot_id': payment.parrot_id}) if subscription: if total_payments_attempts > 3: log('cron2', 'Too many payments attempts', payment_message.get('subscription_id')) subscription.update({'active': False}) if Queue.delete_message('payments', raw_message): send_notification(db, payment,'subscription_deactivated') else: log('cron2', 'ERROR: Couldnt delete message', payment_message.get('subscription_id')) else: log('cron2', 'Attempt %s' % total_payments_attempts, payment_message.get('subscription_id'))
def notify(db, notification_raw, notification_message): notification = Notifications.findOne(db, notification_message.get('notification_id')) account = Accounts.findOne(db, notification.account_id) if notification: log('cron3', 'Notifying remote customer', notification_message.get('subscription_id')) if not notification_message.get('type') in VALID_NOTIFICATIONS: log('cron3', 'ERROR: Unknown notification', notification_message.get('subscription_id')) # TODO: Check what to do in this case return if notification.request_url: query_data = { 'subscription_id': str(notification.subscription_id), 'account_id': str(notification.account_id), 'parrot_id': str(notification.parrot_id), 'type': notification_message.get('type'), 'external_id': str(notification.external_id), 'notification_id': str(notification.id), } log('cron3', 'Notification URL: %s' % notification.request_url, notification_message.get('subscription_id')) utf8_query_data = dict([(key,val.encode('utf-8')) for key, val in query_data.items() if isinstance(val, basestring)]) delete_message = False try: if account.notification_active: http_client = Http() headers, body = http_client.request(uri = notification.request_url, body = urlencode(utf8_query_data), method = 'POST') if int(headers.status) >= 200 and int(headers.status) < 300: notification.update({ 'response_status': headers.status, 'response_headers': headers, 'response_body': body, 'status': 'sent' }) log('cron3', 'Remote notification succeded', notification_message.get('subscription_id')) else: log('cron3', "Failed. Notification response not 2XX (received %s) from url %s" % ( headers.status, notification.request_url ), notification_message.get('subscription_id')) else: delete_message = True notification.update({ 'status': 'off' }) if delete_message: Queue.delete_message('notifications', notification_raw) except Exception, e: log('cron3', "Failed. Exception %specified" % e) else: log('cron3', 'ERROR: No remote url specified', notification_message.get('subscription_id'))
def main(): log('cron2', 'Starting') connection = None try: connection, db = connect() message = Queue.get_message('payments') while message: payment_message = json.loads(message.get_body()) log('cron2', 'Got payment %s' % message.id, payment_message.get('subscription_id')) process_payment(db, message, payment_message) message = Queue.get_message('payments') finally: log('cron2', 'Finishing') if connection: connection.close()
def test_crons(self): from payparrot_scripts.crons.cron1 import main as cron1 cron1() from payparrot_scripts.crons.cron2 import main as cron2 cron2() sleep(2) parrot = Parrots.findOne(self.db, {}) twitter = Twitter() twitter.create_client(parrot.oauth_token, parrot.oauth_token_secret) headers, body = twitter.get("http://api.twitter.com/1/statuses/user_timeline.json?user_id=%s&include_rts=false&count=1" % parrot.twitter_info.get('screen_name')) json_twitter_status = json.loads(body) message_start = self.message.text received_message = json_twitter_status[0].get('text') self.assertEqual(self.message.text, received_message[0:len(message_start)]) queue = Queue.get_queue('payments') self.assertEqual(0, queue.count()) from payparrot_scripts.crons.cron3 import main as cron3 cron3() raw_input("Check? ")
def main(): connection = None log('cron4', 'Starting') try: connection, db = connect() next_payments = NextPayments.find( db, {'action_date': {'$lte': datetime.now()}}, {'parrot_id':1,'account_id':1,'_id':1} ).sort([('_id', -1)]) for next_payment in next_payments: subscription = Subscriptions.findOne(db, {'account_id': next_payment.get('account_id'), 'parrot_id': next_payment.get('parrot_id')}) if subscription and subscription.active: created_message = Queue.insert( 'payments', { 'subscription_id': str(subscription.id), 'account_id': str(subscription.account_id), 'parrot_id': str(subscription.parrot_id) } ) if created_message: db.next_payments.remove({'_id': next_payment.get('_id')}) else: db.next_payments.remove({'_id': next_payment.get('_id')}) finally: if connection: connection.close() log('cron4', 'Finishing')
def main(): connection = None # TODO: change i i = 0 log('cron3', 'Starting') try: connection, db = connect() message = Queue.get_message('notifications') while message is not None and i<20: notification_message = json.loads(message.get_body()) notify(db, message, notification_message) message = Queue.get_message('notifications') i+=1 finally: if connection: connection.close() log('cron3', 'Finishing')
def tear_down(db, app=None, queue = False): db.accounts.drop() db.messages.drop() db.accounts_sessions.drop() db.subscriptions.drop() db.sessions.drop() db.parrots.drop() db.notifications.drop() db.payments.drop() if app: app.get('/logout') if queue: sleep(1) for queue_name in ['notifications', 'payments']: queue = Queue.get_queue(queue_name) while queue.count(): for message in queue.get_messages(num_messages=10, visibility_timeout=60): Queue.delete_message(queue_name, message)
def insert(self, safe = True): super(Notifications, self).insert(safe) created_message = Queue.insert( 'notifications', { 'subscription_id': str(self.subscription_id), 'account_id': str(self.account_id), 'parrot_id': str(self.parrot_id), 'type': self.type, 'notification_id': str(self.id) } ) self.update({'queue_message_id': created_message.id})
def test_cron4_no_subscription(self): account = Accounts(self.db, { 'email': '*****@*****.**', 'password': '******', 'name': 'Daniel', 'startup': 'Payparrot', 'url': 'http://payparrot.com/', 'callback_url': 'http://www.epistemonikos.org', 'notification_url': 'http://www.epistemonikos.org', }) account.insert() parrot = Parrots(self.db, { 'twitter_id': '123123123', 'oauth_token': 'asd', 'oauth_token_secret': 'asdf', 'twitter_info': {}, 'payments': [], 'twitter_info': { 'screen_name': 'danielgua' } }) parrot.insert() subscription = Subscriptions(self.db, {'account_id': account.id, 'active': False, 'parrot_id': parrot.id, 'twitter_screen_name': parrot.twitter_info.get("screen_name")}) subscription.insert() last_date = datetime.now(); next_action_date = last_date; next_payment = NextPayments(self.db, { 'account_id': account.id, 'parrot_id': parrot.id, 'action_date': next_action_date }); next_payment.insert() from payparrot_scripts.crons.cron4 import main as cron4 cron4() message = Queue.get_message('payments') self.assertFalse(message) self.assertEqual(0, self.db.next_payments.find({'_id': next_payment.id}).count())
def main(): connection = None try: log('cron1', 'Starting') connection, db = connect() subscriptions = Subscriptions.find(db, {'active': True, 'first_tweet': False}) for subscription_raw in subscriptions: created_message = Queue.insert( 'payments', { 'subscription_id': str(subscription_raw['_id']), 'account_id': str(subscription_raw['account_id']), 'parrot_id': str(subscription_raw['parrot_id']) } ) log('cron1', 'Payment queued %s' % created_message.id, subscription_raw['_id']) db.subscriptions.update({'_id': subscription_raw['_id']}, {'$set': {'first_tweet': True}}) log('cron1', 'Subscription updated', subscription_raw['_id']) finally: if connection: connection.close() log('cron1', 'Finishing')