Beispiel #1
0
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)]
Beispiel #2
0
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)]
Beispiel #3
0
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)
        }
    )
Beispiel #4
0
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
Beispiel #6
0
    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)
Beispiel #8
0
    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)
Beispiel #11
0
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)
Beispiel #12
0
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))
Beispiel #14
0
    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)]
Beispiel #15
0
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
Beispiel #16
0
 def __path(module_name):
     module = try_import(module_name)
     return "%s/templates/regions/%s.html" %\
         (module.__path__[0], name)
Beispiel #17
0
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}
            ))
Beispiel #18
0
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):
Beispiel #19
0
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)
Beispiel #20
0
# 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]
Beispiel #21
0
 def find(cls, module_name):
     module = try_import(module_name)
     if module is None:
         return None
     return get_class(module, cls)
Beispiel #22
0
 def find(cls, module_name):
     module = try_import(module_name)
     if module is None:
         return None
     return get_class(module, cls)
Beispiel #23
0
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,
Beispiel #24
0
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]
Beispiel #25
0
#!/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}))