Used in management commands or at the module level of a fabfile to
    integrate woven project django.conf settings into fabric, and set the local current
    working directory to the distribution root (where setup.py lives).
    
    ``settings`` is your django settings module to pass in
    if you want to call this from a fabric script.
    
    ``setup_dir`` is an optional path to the directory containing setup.py
    This would be used in instances where setup.py was not above the cwd
    
    This function is used to set the environment for all hosts

def set_env(settings=None, setup_dir=''):
    """
    Used in management commands or at the module level of a fabfile to
    integrate woven project django.conf settings into fabric, and set the local current
    working directory to the distribution root (where setup.py lives).
    
    ``settings`` is your django settings module to pass in
    if you want to call this from a fabric script.
    
    ``setup_dir`` is an optional path to the directory containing setup.py
    This would be used in instances where setup.py was not above the cwd
    
    This function is used to set the environment for all hosts
   
    """

    #switch the working directory to the distribution root where setup.py is
    if hasattr(env, 'setup_path') and env.setup_path:
        setup_path = env.setup_path
    else:
        with fab_settings(fabfile='setup.py'):
            if setup_dir:
                setup_path = os.path.join(setup_dir,'setup.py')
            else:
                setup_path = find_fabfile()
            if not setup_path:
                print 'Error: You must have a setup.py file in the current or a parent folder'
                sys.exit(1)
        
    local_working_dir = os.path.split(setup_path)[0]
    os.chdir(local_working_dir)
    
    setup = run_setup('setup.py',stop_after="init")

    if setup.get_name() == 'UNKNOWN' or setup.get_version()=='0.0.0' or not setup.packages:
        print "ERROR: You must define a minimum of name, version and packages in your setup.py"
        sys.exit(1)
    
    #project env variables for deployment
    env.project_name = setup.get_name() #project_name()
    env.project_full_version = setup.get_version()#local('python setup.py --version').rstrip()
    env.project_version = _parse_project_version(env.project_full_version)
    env.project_fullname = '-'.join([env.project_name,env.project_version])
    env.project_package_name = setup.packages[0]
    env.patch = False

    #django settings are passed in by the command
    #We'll assume that if the settings aren't passed in we're running from a fabfile
    if not settings:
        sys.path.insert(0,local_working_dir)
        
        #import global settings
        project_settings = import_module(env.project_name+'.settings')
    else:

        project_settings = settings
    #If sqlite is used we can manage the database on first deployment
    env.DEFAULT_DATABASE_ENGINE = project_settings.DATABASES['default']['ENGINE']
    env.DEFAULT_DATABASE_NAME = project_settings.DATABASES['default']['NAME']
    
    #overwrite with main sitesettings module
    #just for MEDIA_URL, ADMIN_MEDIA_PREFIX, and STATIC_URL
    #if this settings file exists
    try:
        site_settings = import_module('.'.join([env.project_name,'sitesettings.settings']))
        project_settings.MEDIA_URL = site_settings.MEDIA_URL
        project_settings.ADMIN_MEDIA_PREFIX = site_settings.ADMIN_MEDIA_PREFIX
        project_settings.DATABASES = site_settings.DATABASES 
        if hasattr(site_settings,'STATIC_URL'):
            project_settings.STATIC_URL = site_settings.STATIC_URL
        else:
            project_settings.STATIC_URL = project_settings.ADMIN_MEDIA_PREFIX
    except ImportError:
        pass

    #update woven_env from project_settings    
    local_settings = dir(project_settings)
    #only get settings that woven uses
    for setting in local_settings:
        if setting.isupper() and hasattr(woven_env,setting):
            s = getattr(project_settings,setting,'')
            woven_env[setting] = s
    
    #upate the fabric env with all the woven settings
    env.update(woven_env)
    
    #set any user/password defaults if they are not supplied
    #Fabric would get the user from the options by default as the system user
    #We will overwrite that
    if woven_env.HOST_USER:
        env.user = woven_env.HOST_USER
    env.password = woven_env.HOST_PASSWORD
    
    #set the hosts if they aren't already
    if not env.hosts: env.hosts = woven_env.HOSTS
    if not env.roledefs: env.roledefs = woven_env.ROLEDEFS
    
    #reverse_lookup hosts to roles
    role_lookup  = {}
    for role in env.roles:
        r_hosts = env.roledefs[role]
        for host in r_hosts:
            #since port is not handled by fabric.main.normalize we'll do it ourselves
            role_lookup['%s:%s'% (host,str(woven_env.HOST_SSH_PORT))]=role
    #now add any hosts that aren't already defined in roles
    for host in env.hosts:
        host_string = '%s:%s'% (host,str(woven_env.HOST_SSH_PORT))
        if host_string not in role_lookup.keys():
            role_lookup[host_string] = ''
    env.role_lookup = role_lookup
    env.hosts = role_lookup.keys()
    
    #remove any unneeded db adaptors - except sqlite
    remove_backends = ['postgresql_psycopg2', 'mysql']
    for db in project_settings.DATABASES:
        engine = project_settings.DATABASES[db]['ENGINE'].split('.')[-1]
        if engine in remove_backends: remove_backends.remove(engine)
    for backend in remove_backends:
        if backend == 'postgresql_psycopg2': rm = 'python-psycopg2'
        elif backend == 'mysql': rm = 'python-mysqldb'
        env.HOST_BASE_PACKAGES.remove(rm)

    #packages can be just the base + extra packages
    #or role dependent we need to just map out the packages to hosts and roles here
    packages = {}
    all_packages = set([])
    for role in env.roles:
        packages[role]=env.ROLE_PACKAGES.get(role,[])
        if not packages[role]:
            packages[role] = env.HOST_BASE_PACKAGES + env.HOST_EXTRA_PACKAGES
        all_packages = set(packages[role]) | all_packages

    #no role
    packages[''] = env.HOST_BASE_PACKAGES + env.HOST_EXTRA_PACKAGES
    all_packages = set(packages['']) | all_packages

    #conveniently add gunicorn ppa
    if 'gunicorn' in all_packages:
        if 'ppa:bchesneau/gunicorn' not in env.LINUX_PACKAGE_REPOSITORIES:
            env.LINUX_PACKAGE_REPOSITORIES.append('ppa:bchesneau/gunicorn')    

    env.packages = packages
    
    #sanity check for unwanted combinations in the empty role
    u = set(packages[''])
    wsgi = u & set(['gunicorn','uwsgi'])
    if wsgi and 'apache2' in u:
        u = u - set(['apache2','libapache2-mod-wsgi'])

    #Used to detect certain apps eg South, static_builder
    env.INSTALLED_APPS = project_settings.INSTALLED_APPS

    env.packages[''] = list(u)
   
    #per host
    env.installed_packages = {} 
    env.uninstalled_packages = {}
    
    #UFW firewall rules
    firewall_rules = {}
    for role in env.roles:
        firewall_rules[role]= env.ROLE_UFW_RULES.get(role,[])
    firewall_rules['']=env.UFW_RULES
    env.firewall_rules = firewall_rules
    
    #Now update the env with any settings that are not defined by woven but may
    #be used by woven or fabric
    env.MEDIA_ROOT = project_settings.MEDIA_ROOT
    env.MEDIA_URL = project_settings.MEDIA_URL
    try:
        env.ADMIN_MEDIA_PREFIX = project_settings.ADMIN_MEDIA_PREFIX
    except AttributeError:
        env.ADMIN_MEDIA_PREFIX = ''
    if not env.STATIC_URL:
        env.STATIC_URL = project_settings.ADMIN_MEDIA_PREFIX
    env.TEMPLATE_DIRS = project_settings.TEMPLATE_DIRS
    
    #Set the server /etc/timezone
    env.TIME_ZONE = project_settings.TIME_ZONE
    #Used to detect certain apps eg South, static_builder
    env.INSTALLED_APPS = project_settings.INSTALLED_APPS
    
    #SSH key
    if not hasattr(env,'key_filename') and not env.key_filename and env.SSH_KEY_FILENAME:
        env.key_filename = env.SSH_KEY_FILENAME
    elif not hasattr(env,'key_filename'):
        env.key_filename = None
        
    #noinput
    if not hasattr(env,'INTERACTIVE'):
        env.INTERACTIVE = True
    if not hasattr(env,'verbosity'):
        env.verbosity = 1
    
    #overwrite existing settings
    if not hasattr(env,'overwrite'):
        env.overwrite=False
    
    #South integration defaults
    env.nomigration = False
    env.manualmigration = False
    env.migration = ''
    
    env.root_disabled = False
    
    #Sites
    env.sites = {}
    env.shell = '/bin/bash --noprofile -l -c'