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 get_message_to_share(db, payment_message): # status means if we approved or not the message. Default True messages = list(Messages.find(db, {'account_id': ObjectId(payment_message.get('account_id')), 'status': True, 'active': True})) total_messages = len(messages) if total_messages == 0: log('cron2', 'WARNING: No active or validated messages available', payment_message.get('subscription_id')) return return messages[randint(0, total_messages-1)]
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 store_payment(db, twitter_json, payment_message, message, raw_message): subscription = Subscriptions.findOne(db, {'account_id': ObjectId(payment_message.get('account_id')),'parrot_id': ObjectId(payment_message.get('parrot_id'))}) payment_data = { 'twitter_response': twitter_json, # action date means when this payment has to be tweeted 'action_date': datetime.now(), 'account_id': ObjectId(payment_message.get('account_id')), 'subscription_id': ObjectId(subscription.id), 'parrot_id': ObjectId(payment_message.get('parrot_id')), 'message_id': ObjectId(message.get('id')), 'message_id_sqs': raw_message.id, 'callback_url': message.get('url', ''), 'success': True } if twitter_json.get('error'): payment_data['success'] = False log('cron2', 'ERROR: Payment coulndt be processed because of twitter error %s' % json.dumps(twitter_json), payment_message.get('subscription_id')) else: log('cron2', 'Payment executed successfully', payment_message.get('subscription_id')) payment = Payments(db, payment_data) payment.insert() return payment
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')
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 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'))
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')) else: log('cron3', "Failed. No notification found in db with id %s" % notification_message.get('notification_id'), notification_message.get('subscription_id')) if __name__ == '__main__': main()