'''
Created on Jun 2, 2010

@author: jnaous
'''
from django.utils.importlib import import_module
from django.db.models import signals
from django.conf import settings
import logging

logger = logging.getLogger("permissions.management")

def _import_module(name, app_name):    
    # Below is copied and modified from django's syncdb command.
    # Import the module within each installed app, to register
    # permissions
    try:
        import_module('.%s' % name, app_name)
    except ImportError, exc:
        # This is slightly hackish. We want to ignore ImportErrors
        # if the "management" module itself is missing -- but we don't
        # want to ignore the exception if the management module exists
        # but raises an ImportError for some reason. The only way we
        # can do this is to check the text of the exception. Note that
        # we're a bit broad in how we check the text, because different
        # Python implementations may not use the same text.
        # CPython uses the text "No module named management"
        # PyPy uses "No module named myproject.myapp.management"
        msg = exc.args[0]
        if not msg.startswith('No module named') or name not in msg:
            raise

# XXX: Hack!
def post_syncdb_run(sender, **kwargs):
    """Look for permissions.run in each app and call it.
    
    This function will wait till the last installed app, and then
    search for all permissions modules, and try to call a C{run} function
    in them if found.
    """
    post_syncdb_run.processed = getattr(post_syncdb_run, "processed", 0)
    num_apps = len(settings.INSTALLED_APPS)
    
    # if this is the last app then install permissions for all apps
    if post_syncdb_run.processed == num_apps - 1:
        for app in settings.INSTALLED_APPS:
            try:
                mod = import_module("%s.permissions" % app)
            except ImportError as exc:
                msg = exc.args[0]
                if not msg.startswith('No module named') or\
                "permissions" not in msg:
                    raise
                else:
                    continue
            try:
                mod.run()
            except AttributeError as exc:
                msg = "%s" % exc
                if msg == "'module' object has no attribute 'run'":
                    logger.warn(
                        "Function called 'run' missing from %s.permissions."\
                        " Skipping." % app
                    )
                else:
                    raise
        del post_syncdb_run.processed
    else:
        post_syncdb_run.processed += 1

post_syncdb_run.waiting_for_permissions = []
post_syncdb_run.installed_permissions = False

signals.post_syncdb.connect(post_syncdb_run)

@@ -234,999 +234,8 @@
 %22)%0A%0A
-def _import_module(name, app_name):    %0A    # Below is copied and modified from django's syncdb command.%0A    # Import the module within each installed app, to register%0A    # permissions%0A    try:%0A        import_module('.%25s' %25 name, app_name)%0A    except ImportError, exc:%0A        # This is slightly hackish. We want to ignore ImportErrors%0A        # if the %22management%22 module itself is missing -- but we don't%0A        # want to ignore the exception if the management module exists%0A        # but raises an ImportError for some reason. The only way we%0A        # can do this is to check the text of the exception. Note that%0A        # we're a bit broad in how we check the text, because different%0A        # Python implementations may not use the same text.%0A        # CPython uses the text %22No module named management%22%0A        # PyPy uses %22No module named myproject.myapp.management%22%0A        msg = exc.args%5B0%5D%0A        if not msg.startswith('No module named') or name not in msg:%0A            raise%0A%0A
 # XX
@@ -530,31 +530,28 @@
 _syncdb_run.
-process
+queu
 ed = getattr
@@ -585,102 +585,369 @@
 d%22, 
-0
+%5B%5D
 )%0A    
-num_apps = len(settings.INSTALLED_APPS)%0A    %0A    # if this is the last app then install
+post_syncdb_run.perms_installed = getattr(%0A        post_syncdb_run, %22perms_installed%22, False)%0A%0A    app = sender.__name__.split(%22.models%22)%5B0%5D%0A    print app%0A%0A    # installed!%0A    if app == %22expedient.common.permissions%22:%0A        post_syncdb_run.perms_installed = True%0A        %0A    post_syncdb_run.queued.append(app)%0A%0A    # need to wait until we syncdb the
  per
@@ -959,20 +959,11 @@
 ons 
-for all 
 app
-s
 %0A   
@@ -987,77 +987,132 @@
 un.p
-rocessed == num_apps - 1:%0A        for app in settings.INSTALLED_APPS:
+erms_installed:%0A        for app in post_syncdb_run.queued:%0A            logger.debug(%22Checking app %25s for permissions%22 %25 app)
 %0A   
@@ -1481,16 +1481,83 @@
 d.run()%0A
+                logger.debug(%22Ran permissions.run() for %25s%22 %25 app)%0A
         
@@ -1927,12 +1927,8 @@
     
-del 
 post
@@ -1943,158 +1943,19 @@
 run.
-processed%0A    else:%0A        post_syncdb_run.processed += 1%0A%0Apost_syncdb_run.waiting_for_permissions = %5B%5D%0Apost_syncdb_run.installed_permissions = False
+queued = %5B%5D
 %0A%0Asi

Robustify the postsyncdb call for permissions