def _handlers(module_name): """ Return a list of handlers (subclasses of app.handlers.HandlerBase) defined in the ``handlers`` directory of ``module_name``. Each Python file is expected to contain a single new-style class, which can be named arbitrarily. (But probably shouldn't be.) Return an empty list if no handlers are defined, or the directory can't be opened. All exceptions raised while importing handlers are allowed to propagate, to avoid masking errors. """ handlers_module = try_import("%s.handlers" % module_name) if handlers_module is None: return [] if not hasattr(handlers_module, "__path__"): raise Exception("Module %s must be a directory." % (handlers_module.__name__)) files = find_python_files(handlers_module.__path__[0]) module_names = [ "%s.%s" % (handlers_module.__name__, file) for file in files ] modules = [try_import(mod_name) for mod_name in module_names] return [get_class(mod, BaseHandler) for mod in filter(None, modules)]
def _handlers(module_name): """ Return a list of handlers (subclasses of app.handlers.HandlerBase) defined in the ``handlers`` directory of ``module_name``. Each Python file is expected to contain a single new-style class, which can be named arbitrarily. (But probably shouldn't be.) Return an empty list if no handlers are defined, or the directory can't be opened. All exceptions raised while importing handlers are allowed to propagate, to avoid masking errors. """ handlers_module = try_import( "%s.handlers" % module_name) if handlers_module is None: return [] if not hasattr(handlers_module, "__path__"): return [] files = find_python_files( handlers_module.__path__[0]) module_names = [ "%s.%s" % (handlers_module.__name__, file) for file in files] modules = [ try_import(mod_name) for mod_name in module_names] return [ get_class(mod, BaseHandler) for mod in filter(None, modules)]
def form_for_model(model): """ Return the Form which should be used to add/edit ``model`` in the WebUI, by importing the class named ``"%sForm" % model.__name__`` from the sibling ``forms`` module. For example:: app1.models.Alpha -> myapp.forms.SchoolForm app2.models.beta.Beta -> app2.forms.beta.BetaForm If no such form is defined, an appropriately-patched copy of the rapidsms.contrib.locations.forms.LocationForm form is returned. """ parts = model.__module__.split(".") parts[parts.index("models")] = "forms" module_name = ".".join(parts) form_name = model.__name__ + "Form" module = try_import(module_name) if module is not None: form = getattr(module, form_name, None) if form is not None: return form meta_dict = LocationForm.Meta.__dict__ meta_dict["model"] = model return type( form_name, (LocationForm,), { "Meta": type("Meta", (), meta_dict) } )
def form_for_model(model): """ Return the Form which should be used to add/edit ``model`` in the WebUI, by importing the class named ``"%sForm" % model.__name__`` from the sibling ``forms`` module. For example:: app1.models.Alpha -> myapp.forms.SchoolForm app2.models.beta.Beta -> app2.forms.beta.BetaForm If no such form is defined, an appropriately-patched copy of the rapidsms.contrib.locations.forms.LocationForm form is returned. """ parts = model.__module__.split(".") parts[parts.index("models")] = "forms" module_name = ".".join(parts) form_name = model.__name__ + "Form" module = try_import(module_name) if module is not None: form = getattr(module, form_name, None) if form is not None: return form meta_dict = LocationForm.Meta.__dict__ meta_dict["model"] = model return type(form_name, (LocationForm, ), {"Meta": type("Meta", (), meta_dict)})
def get_contact_generator_functions(): """ This is similar to the method used by alerts, but adapted for a dict. """ if not hasattr(settings, "CONTACT_GROUP_GENERATORS"): groups = [ "groupmessaging.views.all_contacts", "groupmessaging.views.all_contacts_with_all_roles", "groupmessaging.views.all_contacts_with_all_backends", ] else: groups = settings.CONTACT_GROUP_GENERATORS fns = [] for group in groups: mod = group[0 : group.rindex(".")] contact_module = try_import(mod) if contact_module is None: raise Exception("Contact generator module %s is not defined." % mod) func = group[group.rindex(".") + 1 :] if not hasattr(contact_module, func): raise Exception("No function %s in module %s." % (mod, func)) fns.append(getattr(contact_module, func)) return fns
def app_section (self, name): # fetch the current config for this app # from raw_data (or default to an empty dict), # then copy it, so we don't alter the original data = self.raw_data.get(name, {}).copy() # "type" is ONLY VALID FOR BACKENDS now. it's not [easily] possible # to run multple django apps of the same type side-by-side, so i'm # warning here to avoid confusion (and allow apps to be lazy loaded) if "type" in data: raise DeprecationWarning( 'The "type" option is not supported for apps. It does ' +\ 'nothing, since running multple apps of the same type ' +\ 'is not currently possible.') # ...that said, the terms _type_ and _name_ are still mixed up # in various places, so we must support both. another naming # upheaval is probably needed to clear this up (or perhaps we # should just scrap the shitty INI format, like we should have # done in the first place to avoid this entire mess) data["type"] = name # attempt to import the module, to locate it (it might be in ./apps, # contrib, or rapidsms/apps) and verify that it imports cleanly module = try_import(data["type"]) # load the config.py for this app, if possible config = try_import("%s.config" % module.__name__) if config is not None: # copy all of the names not starting with underscore (those are # private or __magic__) into this component's default config, # unless they're already present (ini overrides config.py) for var_name in dir(config): if not var_name.startswith("_"): if not var_name in data: data[var_name] = getattr(config, var_name) # the module was imported! add it's full path to the # config, since it might not be in rapidsms/apps/%s data["path"] = module.__path__[0] # return the component with the additional # app-specific data included. return data
def handle_label(self, project_name, **options): if try_import(project_name) is not None: raise CommandError( "%r conflicts with the name of an existing Python module and cannot be used as a project name. Please try another name." % project_name) src_dir = os.path.join(rapidsms.__path__[0], "skeleton", "project") shutil.copytree(src_dir, project_name)
def handle_label(self, project_name, **options): if try_import(project_name) is not None: raise CommandError( "%r conflicts with the name of an existing Python module and cannot be used as a project name. Please try another name." % project_name) src_dir = os.path.join(rapidsms.__path__[0], "skeleton", "project") shutil.copytree(src_dir, project_name, ignore=shutil.ignore_patterns('*.pyc'))
def form_for_model(model): """ """ parts = model.__module__.split(".") parts[parts.index("models")] = "forms" module = try_import(".".join(parts)) form_name = model.__name__ + "Form" form = getattr(module, form_name) return form
def incoming(backend_name, identity, text): backend = settings.INSTALLED_BACKENDS.get(backend_name, {}) if "HANDLER" in backend: module = try_import(backend["HANDLER"]) if module: module.incoming(backend_name, identity, text) else: backend, _ = Backend.objects.get_or_create(name=backend_name) connection, _ = backend.connection_set.get_or_create(identity=identity) message = IncomingMessage(connection, text, datetime.datetime.now()) router = Router() response = router.incoming(message)
def incoming(backend_name, identity, text): backend = settings.INSTALLED_BACKENDS.get(backend_name, {}) if "HANDLER" in backend: module = try_import(backend['HANDLER']) if module: module.incoming(backend_name, identity, text) else: backend, _ = Backend.objects.get_or_create(name=backend_name) connection, _ = backend.connection_set.get_or_create(identity=identity) message = IncomingMessage(connection, text, datetime.datetime.now()) router = Router() response = router.incoming(message)
def dynamic_import(import_name): import_split = import_name.split('.') module_name = '.'.join(import_split[:-1]) method_name = import_split[-1] module = try_import(module_name) if module is None: raise Exception("Module %s could not be imported." % (module_name)) try: return getattr(module, method_name) except AttributeError: raise Exception("No member %s in module %s." % (method_name, module_name))
def handle_label(self, project_name, **options): if try_import(project_name) is not None: raise CommandError( "%r conflicts with the name of an existing Python module and cannot be used as a project name. Please try another name." % project_name) src_dir = os.path.join(rapidsms.__path__[0], 'skeleton', 'project') shutil.copytree(src_dir, project_name) #pythonic kludge to clean out *.pyc files for dirpath, dirnames, filenames in os.walk(project_name): for name in filenames: if name.endswith('.pyc'): os.remove(os.path.join(dirpath, name))
def _find_handlers(self, module_name): """ Returns a list of handlers (subclasses of app.handlers.HandlerBase) defined in the "handlers" directory of *module_name*. Each Python file (*.py) is expected to contain a single new-style class, which can be named arbitrarily. (but probably shouldn't be.) Returns an empty list if no handlers are defined, or the directory can't be opened. All exceptions raised while importing handlers are allowed to propagate. """ handlers_module = try_import( "%s.handlers" % module_name) if handlers_module is None: return [] if not hasattr(handlers_module, "__path__"): raise Exception( "Module %s must be a directory." % (handlers_module.__name__)) files = find_python_files( handlers_module.__path__[0]) module_names = [ "%s.%s" % (handlers_module.__name__, file) for file in files] modules = [ try_import(mod_name) for mod_name in module_names] return [ get_class(mod, BaseHandler) for mod in filter(None, modules)]
def _find_extensions(app_label, model_name): ext = [] suffix = "extensions.%s.%s" % ( app_label, model_name.lower()) modules = filter(None, [ try_import("%s.%s" % (app_name, suffix)) for app_name in settings.INSTALLED_APPS ]) for module in modules: for cls in get_classes(module, models.Model): #check for duplicate base classes if cls not in ext: ext.append(cls) return ext
def __path(module_name): module = try_import(module_name) return "%s/templates/regions/%s.html" %\ (module.__path__[0], name)
import os from django.conf.urls.defaults import * from rapidsms.utils.modules import try_import from ..conf import settings urlpatterns = [] for module_name in settings.INSTALLED_APPS: if not settings.MEDIA_URL.startswith("http://"): media_prefix = settings.MEDIA_URL.strip("/") module_suffix = module_name.split(".")[-1] # does the app have a child "static" dir? (media is always # served from "static", regardless of what MEDIA_URL says) module = try_import(module_name) if not module: continue module_path = os.path.dirname(module.__file__) static_dir = "%s/static" % (module_path) if os.path.exists(static_dir): # map to {{ MEDIA_URL }}/appname urlpatterns += patterns("", url( "^%s/%s/(?P<path>.*)$" % ( media_prefix, module_suffix), "django.views.static.serve", {"document_root": static_dir} ))
4) Afterwards go to https://dev.twitter.com/apps to setup an 'application' and get the required credentials. 5) Finally, you have to put these into the field 'oauth' when editing the connection for your contact details in the format: consumer_key:consumer_secret:access_token:access_secret Add as many twitter contacts as you like! """ from rapidsms.backends.base import BackendBase from rapidsms.utils.modules import try_import tweepy = try_import('tweepy') class TwitterError (Exception): def __init__(self, value): self.value = value def __str__(self): return repr(self.value) class TwitterBackend(BackendBase): len_max = 140 trail = ' ...' # trailing chars for oversized messages def configure(self, consumer_key=False, consumer_secret=False, access_token=False, access_secret=False):
def render_to_response(req, template_name, dictionary=None, **kwargs): """Proxies calls to django.shortcuts.render_to_response, to avoid having to include the global variables in every request. This is a giant hack, and there's probably a much better solution.""" rs_dict = { "apps": settings.RAPIDSMS_APPS, "debug": settings.DEBUG, "javascripts": [] } def __js_dir(fs_path, web_prefix): """Adds all of the .js files in a given directory to the javascripts array, to be included in the <head>. Also checks for a single file js with the same name as the directory. (dir_name/*.js and dir_name.js)""" if os.path.exists(fs_path): rs_dict["javascripts"].extend([ "%s/%s" % (web_prefix, fn) for fn in os.listdir(fs_path) if fn[-3:] == ".js"]) if os.path.exists("%s.js" % (fs_path)): rs_dict["javascripts"].append( "%s.js" % (web_prefix)) # add all of the global javascript files for all running # apps. this is super handy for packaging functionality # which affects the whole webui without hard-coding it for module_name in settings.RAPIDSMS_APPS.keys(): __js_dir( "%s/static/javascripts/global" % get_module_path(module_name), "/static/%s/javascripts/global" % module_name) # A NEW KIND OF LUNACY: inspect the stack to find out # which rapidsms app this function is being called from # -- # TODO: we're assuming that this function was called # directly from the view, and looking for it at -2 in # the stack. this could be wrong, if something else is # further abstracting the call (which sounds fun). tb = traceback.extract_stack(limit=2) m = re.match(r'^.+/(.+?)/views\.py$', tb[-2][0]) if m is not None: app_name = m.group(1) path = get_module_path(app_name) # since we're fetching the app conf, add it to the # template dict. it wouldn't be a very good idea to # use it, but sometimes, when time is short... rs_dict["app_conf"] = settings.RAPIDSMS_APPS[app_name] # note which app this func was called from, so the tmpl # can mark the tab (or some other type of nav) as active rs_dict["active_app"] = app_name # also note which "view" (function) this func was called # from, for a little introspection later in the rendering # process (the view name is added to the css class # of <body> to make per-view styling free) rs_dict["active_view"] = tb[-2][2] # find all of the javascript assets for # this app, and add them to the <head> __js_dir( "%s/static/javascripts/app" % path, "/static/%s/javascripts/app" % app_name) # check for a view-specific javascript, # to add LAST, after the dependencies __js_dir( "%s/static/javascripts/page/%s" % (path, rs_dict["active_view"]), "/static/%s/javascripts/page/%s.js" % (app_name, rs_dict["active_view"])) # attempt to import the "__global" function from # the views.py that this method was called from module = try_import("%s.views" % app_name) # if the views have a __global function, call it with the # request object, and add the output (a dictionary) to the # rs_dict. note that the 'dictionary' argument to _this_ # method is merged AFTER this, overriding the global data. # also note that we do this here, rather than in the try # block above, to avoid masking exceptions raised within if module and hasattr(module, "__global"): global_data = module.__global(req) rs_dict.update(global_data) # allow the dict argument to # be omitted without blowing up if dictionary is not None: rs_dict.update(dictionary) # unless a context instance has been provided, # default to RequestContext, to get all of # the TEMPLATE_CONTEXT_PROCESSORS working if "context_instance" not in kwargs: kwargs["context_instance"] = RequestContext(req) # pass on the combined dicts to the original function return django_r_to_r(template_name, rs_dict, **kwargs)
# this list will be populated with the urls from the urls.urlpatterns of # each installed app, then found by django as if we'd listed them here. urlpatterns = [] for module_name in settings.INSTALLED_APPS: # leave django contrib apps alone. (many of them include urlpatterns # which shouldn't be auto-mapped.) this is a hack, but i like the # automatic per-app mapping enough to keep it. (for now.) if module_name.startswith("django."): continue # attempt to import this app's urls module = try_import("%s.urls" % (module_name)) if not hasattr(module, "urlpatterns"): continue # add the explicitly defined urlpatterns urlpatterns += module.urlpatterns # if the MEDIA_URL does not contain a hostname (ie, it's just an # http path), and we are running in DEBUG mode, we will also serve # the media for this app via this development server. in production, # these files should be served directly if settings.DEBUG: if not settings.MEDIA_URL.startswith("http://"): media_prefix = settings.MEDIA_URL.strip("/") module_suffix = module_name.split(".")[-1]
def find(cls, module_name): module = try_import(module_name) if module is None: return None return get_class(module, cls)
4) Afterwards go to https://dev.twitter.com/apps to setup an 'application' and get the required credentials. 5) Finally, you have to put these into the field 'oauth' when editing the connection for your contact details in the format: consumer_key:consumer_secret:access_token:access_secret Add as many twitter contacts as you like! """ from rapidsms.backends.base import BackendBase from rapidsms.utils.modules import try_import tweepy = try_import('tweepy') class TwitterError(Exception): def __init__(self, value): self.value = value def __str__(self): return repr(self.value) class TwitterBackend(BackendBase): len_max = 140 trail = ' ...' # trailing chars for oversized messages def configure(self,
from ..conf import settings # this list will be populated with the urls from the urls.urlpatterns of # each installed app, then found by django as if we'd listed them here. urlpatterns = [] for module_name in settings.INSTALLED_APPS: # leave django contrib apps alone. (many of them include urlpatterns # which shouldn't be auto-mapped.) this is a hack, but i like the # automatic per-app mapping enough to keep it. (for now.) if module_name.startswith("django."): continue # attempt to import this app's urls module = try_import("%s.urls" % (module_name)) if not hasattr(module, "urlpatterns"): continue # add the explicitly defined urlpatterns urlpatterns += module.urlpatterns # if the MEDIA_URL does not contain a hostname (ie, it's just an # http path), and we are running in DEBUG mode, we will also serve # the media for this app via this development server. in production, # these files should be served directly if settings.DEBUG: if not settings.MEDIA_URL.startswith("http://"): media_prefix = settings.MEDIA_URL.strip("/") module_suffix = module_name.split(".")[-1]
#!/usr/bin/env python # vim: ai ts=4 sts=4 et sw=4 import os from django.conf.urls.defaults import * from rapidsms.utils.modules import try_import from ..conf import settings urlpatterns = [] for module_name in settings.INSTALLED_APPS: if not settings.MEDIA_URL.startswith("http://"): media_prefix = settings.MEDIA_URL.strip("/") module_suffix = module_name.split(".")[-1] # does the app have a child "static" dir? (media is always # served from "static", regardless of what MEDIA_URL says) module = try_import(module_name) if not module: continue module_path = os.path.dirname(module.__file__) static_dir = "%s/static" % (module_path) if os.path.exists(static_dir): # map to {{ MEDIA_URL }}/appname urlpatterns += patterns( "", url("^%s/%s/(?P<path>.*)$" % (media_prefix, module_suffix), "django.views.static.serve", {"document_root": static_dir}))