PageRenderTime 45ms CodeModel.GetById 16ms RepoModel.GetById 0ms app.codeStats 0ms

/demisauce/demisauce/model/actions.py

https://github.com/araddon/demisauce
Python | 161 lines | 150 code | 5 blank | 6 comment | 3 complexity | 6db01dd3808c9f305a2ae2ec936a8913 MD5 | raw file
  1. import time, json, datetime, logging, sys, traceback, urllib
  2. from datetime import datetime, date
  3. import random, hashlib, string, re, urllib2
  4. from tornado import escape
  5. from tornado.options import define, options
  6. import tornado.httpclient
  7. from sqlalchemy import engine, orm
  8. from sqlalchemy.sql import and_, or_, not_, func, select, text
  9. from sqlalchemy.orm import mapper, relation, class_mapper, synonym, dynamic_loader
  10. from sqlalchemy.orm import scoped_session, sessionmaker, join, eagerload
  11. try:
  12. from gearman import GearmanClient
  13. from gearman.task import Task
  14. except:
  15. from gearman import libgearman
  16. #import twitter
  17. #from demisauce.lib import bitly, publish
  18. from demisauce import model
  19. from demisauce.model import mapping
  20. from demisauce.model import user, site
  21. from demisaucepy.cache import DummyCache, MemcacheCache
  22. log = logging.getLogger("demisauce")
  23. db = None
  24. actions = {} # global list of actions
  25. gearman_client = GearmanClient(options.gearman_servers)
  26. def send_email(name,user,data):
  27. jsondict = {
  28. 'template_name':name,
  29. 'emails':[user.email],
  30. 'template_data':data,
  31. 'apikey':options.demisauce_api_key
  32. }
  33. data = json.dumps(jsondict)
  34. url = "%s/api/email/%s/send.json?apikey=%s" % (options.demisauce_url,name,options.demisauce_api_key)
  35. gearman_client = GearmanClient(options.gearman_servers)
  36. gearman_client.do_task(Task("email_send",data, background=True))
  37. def add_action(action,func=None,bg=False):
  38. """This adds a func to be called when action is called from do_action.
  39. If func is none, then it is assumed that there is a subscriber configured
  40. through site.settings that will be listening::
  41. add_action('webhook_testing',bg=True) # check for subscriber
  42. """
  43. global actions
  44. if action in actions:
  45. actorlist = actions[action]
  46. actorlist.append((bg,func))
  47. actions[action] = actorlist
  48. else:
  49. actions[action] = [(bg,func)]
  50. def do_action(action,**kwargs):
  51. """triggers an action, checks if there are any listeners previously defined
  52. in add_action and runs those first. If the action called here is defined as
  53. run in background (defined in add_action) it will send to Gearman.
  54. Requires site_id if is a plugin::
  55. do_action("new_user",{'site_id':1,'name':'bob'})
  56. """
  57. global actions
  58. if action in actions:
  59. actorlist = actions[action]
  60. for bg,func in actorlist:
  61. if bg:
  62. jsond = {'action':str(func.__name__) if func else action}
  63. for k in kwargs.keys():
  64. if isinstance(kwargs[k],(str,unicode,int,long,list)):
  65. jsond.update({k:kwargs[k]})
  66. else:
  67. log.debug('not adding %s type=%s' % (k,type(kwargs[k])))
  68. do_bg(jsond)
  69. else:
  70. func(**kwargs)
  71. def do_action_bg(job_object):
  72. "deserializes info from gearman, finds action and processes"
  73. try:
  74. global db
  75. if not db:
  76. # Have one global connection to the DB across app
  77. log.debug("in actions db get bg")
  78. memcache_cache = MemcacheCache(options.memcached_servers)
  79. db = model.get_database(cache=memcache_cache)
  80. db.session()
  81. g = globals()
  82. args = json.loads(job_object.arg)
  83. log.debug('in do_action_bg %s' % args)
  84. if 'action' in args and g.has_key(args['action']):
  85. log.debug('calling action = %s for args=%s' % (args['action'],args))
  86. g[args['action']](args)
  87. elif 'action' in args:
  88. log.debug('calling action 2 = %s for args=%s' % (args['action'],args))
  89. check_subscribers(args)
  90. else:
  91. log.error('whoops, that didnt work %s' % (args))
  92. db.session.close()
  93. except:
  94. logging.error("Error in gearman task do_action_bg: %s" % traceback.print_exc())
  95. return -1
  96. def do_bg(kwargs):
  97. log.debug('sending to bg %s' % kwargs)
  98. global gearman_client
  99. gearman_client.do_task(Task("demisauce_do_action_bg",json.dumps(kwargs), background=True))
  100. def func_template(jsond):
  101. try:
  102. u = user.Person.saget(jsond['user_id'])
  103. if u:
  104. log.debug("found user %s" % (u))
  105. except:
  106. logging.error("Error in gearman task activity_update_bg: %s" % traceback.print_exc())
  107. return -1
  108. def check_subscribers(args):
  109. """Checks if any subscribers, requires site_id in args"""
  110. try:
  111. log.debug('in check_subscribers %s' % (args))
  112. if 'site_id' in args and 'action' in args:
  113. if args['action'].find('_user') > 0 and 'user_id' in args:
  114. o = user.Person.saget(args['user_id'])
  115. args.update({'user':o.to_dict_api()})
  116. s = site.Site.get_cache(args['site_id'],reload=False)
  117. hook = s.get_attribute(args['action'])
  118. if hook and hook.category == 'event' and hook.event_type == 'gearman':
  119. global gearman_client
  120. log.debug('found a gearman pub/sub hook = %s requires=%s' % (hook.value,hook.requires))
  121. if hook.requires and isinstance(hook.requires,(str,unicode)):
  122. requires = json.loads(hook.requires)
  123. for req in requires:
  124. r = s.get_attribute(req)
  125. if r:
  126. args.update({r.name:r.value})
  127. log.debug('calling task args=%s' % args)
  128. gearman_client.do_task(Task(hook.value,json.dumps(args), background=True))
  129. elif hook and hook.category == 'event' and hook.event_type == 'webhook':
  130. http = tornado.httpclient.HTTPClient()
  131. log.debug("webhook calling url = %s" % (hook.value))
  132. res = http.fetch(hook.value,method="POST",body=json.dumps(args))
  133. log.debug("webhook resut = %s" % res.body)
  134. else:
  135. log.error("wtf, no site_id? %s" % (args))
  136. except:
  137. logging.error("Error in gearman task activity_update_bg: %s" % traceback.print_exc())
  138. return -1
  139. add_action('new_user',check_subscribers,bg=True)
  140. def register_workers(worker):
  141. log.debug('registering demisauce_do_action_bg')
  142. worker.register_function("demisauce_do_action_bg", do_action_bg)