Commits

Anonymous committed 4c64356

mezzanine with rosetta for translation

  • Participants

Comments (0)

Files changed (87)

File myproject/.gitignore

+*.pyc
+*.pyo
+*.db
+.DS_Store
+.coverage
+local_settings.py
+/static

File myproject/.hgignore

+syntax: glob
+*.pyc
+*.pyo
+*.db
+.DS_Store
+.coverage
+local_settings.py
+
+syntax: regexp
+^static/

File myproject/__init__.py

Empty file added.

File myproject/deploy/crontab

+*/5 * * * * %(user)s %(manage)s poll_twitter

File myproject/deploy/gunicorn.conf.py

+import os
+
+bind = "127.0.0.1:%(gunicorn_port)s"
+workers = (os.sysconf("SC_NPROCESSORS_ONLN") * 2) + 1
+loglevel = "error"
+proc_name = "%(proj_name)s"

File myproject/deploy/live_settings.py

+
+DATABASES = {
+    "default": {
+        # Ends with "postgresql_psycopg2", "mysql", "sqlite3" or "oracle".
+        "ENGINE": "django.db.backends.postgresql_psycopg2",
+        # DB name or path to database file if using sqlite3.
+        "NAME": "%(proj_name)s",
+        # Not used with sqlite3.
+        "USER": "%(proj_name)s",
+        # Not used with sqlite3.
+        "PASSWORD": "%(db_pass)s",
+        # Set to empty string for localhost. Not used with sqlite3.
+        "HOST": "127.0.0.1",
+        # Set to empty string for default. Not used with sqlite3.
+        "PORT": "",
+    }
+}
+
+SECURE_PROXY_SSL_HEADER = ("HTTP_X_FORWARDED_PROTOCOL", "https")
+
+CACHE_MIDDLEWARE_SECONDS = 60
+
+CACHE_MIDDLEWARE_KEY_PREFIX = "%(proj_name)s"
+
+CACHES = {
+    "default": {
+        "BACKEND": "django.core.cache.backends.memcached.MemcachedCache",
+        "LOCATION": "127.0.0.1:11211",
+    }
+}
+
+SESSION_ENGINE = "django.contrib.sessions.backends.cache"

File myproject/deploy/nginx.conf

+
+upstream %(proj_name)s {
+    server 127.0.0.1:%(gunicorn_port)s;
+}
+
+server {
+
+    listen 80;
+    listen 443;
+    server_name %(live_host)s;
+    client_max_body_size 10M;
+    keepalive_timeout    15;
+
+    ssl                  on;
+    ssl_certificate      conf/%(proj_name)s.crt;
+    ssl_certificate_key  conf/%(proj_name)s.key;
+    ssl_session_cache    shared:SSL:10m;
+    ssl_session_timeout  10m;
+
+    location / {
+        proxy_redirect      off;
+        proxy_set_header    Host                    $host;
+        proxy_set_header    X-Real-IP               $remote_addr;
+        proxy_set_header    X-Forwarded-For         $proxy_add_x_forwarded_for;
+        proxy_set_header    X-Forwarded-Protocol    $scheme;
+        proxy_pass          http://%(proj_name)s;
+    }
+
+    location /static/ {
+        root            %(proj_path)s;
+        access_log      off;
+        log_not_found   off;
+    }
+
+    location /robots.txt {
+        root            %(proj_path)s/static;
+        access_log      off;
+        log_not_found   off;
+    }
+
+    location /favicon.ico {
+        root            %(proj_path)s/static/img;
+        access_log      off;
+        log_not_found   off;
+    }
+
+}

File myproject/deploy/supervisor.conf

+[group:%(proj_name)s]
+programs=gunicorn_%(proj_name)s
+
+[program:gunicorn_%(proj_name)s]
+command=%(venv_path)s/bin/gunicorn_django -c gunicorn.conf.py -p gunicorn.pid
+directory=%(proj_path)s
+user=%(user)s
+autostart=true
+autorestart=true
+redirect_stderr=true
+environment=LANG="%(locale)s",LC_ALL="%(locale)s",LC_LANG="%(locale)s"

File myproject/fabfile.py

+
+import os
+import re
+import sys
+from functools import wraps
+from getpass import getpass, getuser
+from glob import glob
+from contextlib import contextmanager
+
+from fabric.api import env, cd, prefix, sudo as _sudo, run as _run, hide, task
+from fabric.contrib.files import exists, upload_template
+from fabric.colors import yellow, green, blue, red
+
+
+################
+# Config setup #
+################
+
+conf = {}
+if sys.argv[0].split(os.sep)[-1] == "fab":
+    # Ensure we import settings from the current dir
+    try:
+        conf = __import__("settings", globals(), locals(), [], 0).FABRIC
+        try:
+            conf["HOSTS"][0]
+        except (KeyError, ValueError):
+            raise ImportError
+    except (ImportError, AttributeError):
+        print "Aborting, no hosts defined."
+        exit()
+
+env.db_pass = conf.get("DB_PASS", None)
+env.admin_pass = conf.get("ADMIN_PASS", None)
+env.user = conf.get("SSH_USER", getuser())
+env.password = conf.get("SSH_PASS", None)
+env.key_filename = conf.get("SSH_KEY_PATH", None)
+env.hosts = conf.get("HOSTS", [])
+
+env.proj_name = conf.get("PROJECT_NAME", os.getcwd().split(os.sep)[-1])
+env.venv_home = conf.get("VIRTUALENV_HOME", "/home/%s" % env.user)
+env.venv_path = "%s/%s" % (env.venv_home, env.proj_name)
+env.proj_dirname = "project"
+env.proj_path = "%s/%s" % (env.venv_path, env.proj_dirname)
+env.manage = "%s/bin/python %s/project/manage.py" % (env.venv_path,
+                                                     env.venv_path)
+env.live_host = conf.get("LIVE_HOSTNAME", env.hosts[0] if env.hosts else None)
+env.repo_url = conf.get("REPO_URL", None)
+env.reqs_path = conf.get("REQUIREMENTS_PATH", None)
+env.gunicorn_port = conf.get("GUNICORN_PORT", 8000)
+env.locale = conf.get("LOCALE", "en_US.UTF-8")
+
+
+##################
+# Template setup #
+##################
+
+# Each template gets uploaded at deploy time, only if their
+# contents has changed, in which case, the reload command is
+# also run.
+
+templates = {
+    "nginx": {
+        "local_path": "deploy/nginx.conf",
+        "remote_path": "/etc/nginx/sites-enabled/%(proj_name)s.conf",
+        "reload_command": "service nginx restart",
+    },
+    "supervisor": {
+        "local_path": "deploy/supervisor.conf",
+        "remote_path": "/etc/supervisor/conf.d/%(proj_name)s.conf",
+        "reload_command": "supervisorctl reload",
+    },
+    "cron": {
+        "local_path": "deploy/crontab",
+        "remote_path": "/etc/cron.d/%(proj_name)s",
+        "owner": "root",
+        "mode": "600",
+    },
+    "gunicorn": {
+        "local_path": "deploy/gunicorn.conf.py",
+        "remote_path": "%(proj_path)s/gunicorn.conf.py",
+    },
+    "settings": {
+        "local_path": "deploy/live_settings.py",
+        "remote_path": "%(proj_path)s/local_settings.py",
+    },
+}
+
+
+######################################
+# Context for virtualenv and project #
+######################################
+
+@contextmanager
+def virtualenv():
+    """
+    Runs commands within the project's virtualenv.
+    """
+    with cd(env.venv_path):
+        with prefix("source %s/bin/activate" % env.venv_path):
+            yield
+
+
+@contextmanager
+def project():
+    """
+    Runs commands within the project's directory.
+    """
+    with virtualenv():
+        with cd(env.proj_dirname):
+            yield
+
+
+@contextmanager
+def update_changed_requirements():
+    """
+    Checks for changes in the requirements file across an update,
+    and gets new requirements if changes have occurred.
+    """
+    reqs_path = os.path.join(env.proj_path, env.reqs_path)
+    get_reqs = lambda: run("cat %s" % reqs_path, show=False)
+    old_reqs = get_reqs() if env.reqs_path else ""
+    yield
+    if old_reqs:
+        new_reqs = get_reqs()
+        if old_reqs == new_reqs:
+            # Unpinned requirements should always be checked.
+            for req in new_reqs.split("\n"):
+                if req.startswith("-e"):
+                    if "@" not in req:
+                        # Editable requirement without pinned commit.
+                        break
+                elif req.strip() and not req.startswith("#"):
+                    if not set(">=<") & set(req):
+                        # PyPI requirement without version.
+                        break
+            else:
+                # All requirements are pinned.
+                return
+        pip("-r %s/%s" % (env.proj_path, env.reqs_path))
+
+
+###########################################
+# Utils and wrappers for various commands #
+###########################################
+
+def _print(output):
+    print
+    print output
+    print
+
+
+def print_command(command):
+    _print(blue("$ ", bold=True) +
+           yellow(command, bold=True) +
+           red(" ->", bold=True))
+
+
+@task
+def run(command, show=True):
+    """
+    Runs a shell comand on the remote server.
+    """
+    if show:
+        print_command(command)
+    with hide("running"):
+        return _run(command)
+
+
+@task
+def sudo(command, show=True):
+    """
+    Runs a command as sudo.
+    """
+    if show:
+        print_command(command)
+    with hide("running"):
+        return _sudo(command)
+
+
+def log_call(func):
+    @wraps(func)
+    def logged(*args, **kawrgs):
+        header = "-" * len(func.__name__)
+        _print(green("\n".join([header, func.__name__, header]), bold=True))
+        return func(*args, **kawrgs)
+    return logged
+
+
+def get_templates():
+    """
+    Returns each of the templates with env vars injected.
+    """
+    injected = {}
+    for name, data in templates.items():
+        injected[name] = dict([(k, v % env) for k, v in data.items()])
+    return injected
+
+
+def upload_template_and_reload(name):
+    """
+    Uploads a template only if it has changed, and if so, reload a
+    related service.
+    """
+    template = get_templates()[name]
+    local_path = template["local_path"]
+    remote_path = template["remote_path"]
+    reload_command = template.get("reload_command")
+    owner = template.get("owner")
+    mode = template.get("mode")
+    remote_data = ""
+    if exists(remote_path):
+        with hide("stdout"):
+            remote_data = sudo("cat %s" % remote_path, show=False)
+    with open(local_path, "r") as f:
+        local_data = f.read()
+        # Escape all non-string-formatting-placeholder occurrences of '%':
+        local_data = re.sub(r"%(?!\(\w+\)s)", "%%", local_data)
+        if "%(db_pass)s" in local_data:
+            env.db_pass = db_pass()
+        local_data %= env
+    clean = lambda s: s.replace("\n", "").replace("\r", "").strip()
+    if clean(remote_data) == clean(local_data):
+        return
+    upload_template(local_path, remote_path, env, use_sudo=True, backup=False)
+    if owner:
+        sudo("chown %s %s" % (owner, remote_path))
+    if mode:
+        sudo("chmod %s %s" % (mode, remote_path))
+    if reload_command:
+        sudo(reload_command)
+
+
+def db_pass():
+    """
+    Prompts for the database password if unknown.
+    """
+    if not env.db_pass:
+        env.db_pass = getpass("Enter the database password: ")
+    return env.db_pass
+
+
+@task
+def apt(packages):
+    """
+    Installs one or more system packages via apt.
+    """
+    return sudo("apt-get install -y -q " + packages)
+
+
+@task
+def pip(packages):
+    """
+    Installs one or more Python packages within the virtual environment.
+    """
+    with virtualenv():
+        return sudo("pip install %s" % packages)
+
+
+def postgres(command):
+    """
+    Runs the given command as the postgres user.
+    """
+    show = not command.startswith("psql")
+    return run("sudo -u root sudo -u postgres %s" % command, show=show)
+
+
+@task
+def psql(sql, show=True):
+    """
+    Runs SQL against the project's database.
+    """
+    out = postgres('psql -c "%s"' % sql)
+    if show:
+        print_command(sql)
+    return out
+
+
+@task
+def backup(filename):
+    """
+    Backs up the database.
+    """
+    return postgres("pg_dump -Fc %s > %s" % (env.proj_name, filename))
+
+
+@task
+def restore(filename):
+    """
+    Restores the database.
+    """
+    return postgres("pg_restore -c -d %s %s" % (env.proj_name, filename))
+
+
+@task
+def python(code, show=True):
+    """
+    Runs Python code in the project's virtual environment, with Django loaded.
+    """
+    setup = "import os; os.environ[\'DJANGO_SETTINGS_MODULE\']=\'settings\';"
+    full_code = 'python -c "%s%s"' % (setup, code.replace("`", "\\\`"))
+    with project():
+        result = run(full_code, show=False)
+        if show:
+            print_command(code)
+    return result
+
+
+def static():
+    """
+    Returns the live STATIC_ROOT directory.
+    """
+    return python("from django.conf import settings;"
+                  "print settings.STATIC_ROOT").split("\n")[-1]
+
+
+@task
+def manage(command):
+    """
+    Runs a Django management command.
+    """
+    return run("%s %s" % (env.manage, command))
+
+
+#########################
+# Install and configure #
+#########################
+
+@task
+@log_call
+def install():
+    """
+    Installs the base system and Python requirements for the entire server.
+    """
+    locale = "LC_ALL=%s" % env.locale
+    with hide("stdout"):
+        if locale not in sudo("cat /etc/default/locale"):
+            sudo("update-locale %s" % locale)
+            run("exit")
+    sudo("apt-get update -y -q")
+    apt("nginx libjpeg-dev python-dev python-setuptools git-core "
+        "postgresql libpq-dev memcached supervisor")
+    sudo("easy_install pip")
+    sudo("pip install virtualenv mercurial")
+
+
+@task
+@log_call
+def create():
+    """
+    Create a new virtual environment for a project.
+    Pulls the project's repo from version control, adds system-level
+    configs for the project, and initialises the database with the
+    live host.
+    """
+
+    # Create virtualenv
+    with cd(env.venv_home):
+        if exists(env.proj_name):
+            prompt = raw_input("\nVirtualenv exists: %s\nWould you like "
+                               "to replace it? (yes/no) " % env.proj_name)
+            if prompt.lower() != "yes":
+                print "\nAborting!"
+                return False
+            remove()
+        run("virtualenv %s --distribute" % env.proj_name)
+        vcs = "git" if env.repo_url.startswith("git") else "hg"
+        run("%s clone %s %s" % (vcs, env.repo_url, env.proj_path))
+
+    # Create DB and DB user.
+    pw = db_pass()
+    user_sql_args = (env.proj_name, pw.replace("'", "\'"))
+    user_sql = "CREATE USER %s WITH ENCRYPTED PASSWORD '%s';" % user_sql_args
+    psql(user_sql, show=False)
+    shadowed = "*" * len(pw)
+    print_command(user_sql.replace("'%s'" % pw, "'%s'" % shadowed))
+    psql("CREATE DATABASE %s WITH OWNER %s ENCODING = 'UTF8' "
+         "LC_CTYPE = '%s' LC_COLLATE = '%s' TEMPLATE template0;" %
+         (env.proj_name, env.proj_name, env.locale, env.locale))
+
+    # Set up SSL certificate.
+    conf_path = "/etc/nginx/conf"
+    if not exists(conf_path):
+        sudo("mkdir %s" % conf_path)
+    with cd(conf_path):
+        crt_file = env.proj_name + ".crt"
+        key_file = env.proj_name + ".key"
+        if not exists(crt_file) and not exists(key_file):
+            try:
+                crt_local, = glob(os.path.join("deploy", "*.crt"))
+                key_local, = glob(os.path.join("deploy", "*.key"))
+            except ValueError:
+                parts = (crt_file, key_file, env.live_host)
+                sudo("openssl req -new -x509 -nodes -out %s -keyout %s "
+                     "-subj '/CN=%s' -days 3650" % parts)
+            else:
+                upload_template(crt_local, crt_file, use_sudo=True)
+                upload_template(key_local, key_file, use_sudo=True)
+
+    # Set up project.
+    upload_template_and_reload("settings")
+    with project():
+        if env.reqs_path:
+            pip("-r %s/%s" % (env.proj_path, env.reqs_path))
+        pip("gunicorn setproctitle south psycopg2 "
+            "django-compressor python-memcached")
+        manage("createdb --noinput --nodata")
+        python("from django.conf import settings;"
+               "from django.contrib.sites.models import Site;"
+               "site, _ = Site.objects.get_or_create(id=settings.SITE_ID);"
+               "site.domain = '" + env.live_host + "';"
+               "site.save();")
+        if env.admin_pass:
+            pw = env.admin_pass
+            user_py = ("from django.contrib.auth.models import User;"
+                       "u, _ = User.objects.get_or_create(username='admin');"
+                       "u.is_staff = u.is_superuser = True;"
+                       "u.set_password('%s');"
+                       "u.save();" % pw)
+            python(user_py, show=False)
+            shadowed = "*" * len(pw)
+            print_command(user_py.replace("'%s'" % pw, "'%s'" % shadowed))
+
+    return True
+
+
+@task
+@log_call
+def remove():
+    """
+    Blow away the current project.
+    """
+    if exists(env.venv_path):
+        sudo("rm -rf %s" % env.venv_path)
+    for template in get_templates().values():
+        remote_path = template["remote_path"]
+        if exists(remote_path):
+            sudo("rm %s" % remote_path)
+    psql("DROP DATABASE %s;" % env.proj_name)
+    psql("DROP USER %s;" % env.proj_name)
+
+
+##############
+# Deployment #
+##############
+
+@task
+@log_call
+def restart():
+    """
+    Restart gunicorn worker processes for the project.
+    """
+    pid_path = "%s/gunicorn.pid" % env.proj_path
+    if exists(pid_path):
+        sudo("kill -HUP `cat %s`" % pid_path)
+    else:
+        start_args = (env.proj_name, env.proj_name)
+        sudo("supervisorctl start %s:gunicorn_%s" % start_args)
+
+
+@task
+@log_call
+def deploy():
+    """
+    Deploy latest version of the project.
+    Check out the latest version of the project from version
+    control, install new requirements, sync and migrate the database,
+    collect any new static assets, and restart gunicorn's work
+    processes for the project.
+    """
+    if not exists(env.venv_path):
+        prompt = raw_input("\nVirtualenv doesn't exist: %s\nWould you like "
+                           "to create it? (yes/no) " % env.proj_name)
+        if prompt.lower() != "yes":
+            print "\nAborting!"
+            return False
+        create()
+    for name in get_templates():
+        upload_template_and_reload(name)
+    with project():
+        backup("last.db")
+        run("tar -cf last.tar %s" % static())
+        git = env.repo_url.startswith("git")
+        run("%s > last.commit" % "git rev-parse HEAD" if git else "hg id -i")
+        with update_changed_requirements():
+            run("git pull origin master -f" if git else "hg pull && hg up -C")
+        manage("collectstatic -v 0 --noinput")
+        manage("syncdb --noinput")
+        manage("migrate --noinput")
+    restart()
+    return True
+
+
+@task
+@log_call
+def rollback():
+    """
+    Reverts project state to the last deploy.
+    When a deploy is performed, the current state of the project is
+    backed up. This includes the last commit checked out, the database,
+    and all static files. Calling rollback will revert all of these to
+    their state prior to the last deploy.
+    """
+    with project():
+        with update_changed_requirements():
+            git = env.repo_url.startswith("git")
+            update = "git checkout" if git else "hg up -C"
+            run("%s `cat last.commit`" % update)
+        with cd(os.path.join(static(), "..")):
+            run("tar -xf %s" % os.path.join(env.proj_path, "last.tar"))
+        restore("last.db")
+    restart()
+
+
+@task
+@log_call
+def all():
+    """
+    Installs everything required on a new system and deploy.
+    From the base software, up to the deployed project.
+    """
+    install()
+    if create():
+        deploy()

File myproject/locale/ar/LC_MESSAGES/django.mo

Binary file added.

File myproject/locale/ar/LC_MESSAGES/django.po

+# SOME DESCRIPTIVE TITLE.
+# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the PACKAGE package.
+# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
+#
+#, fuzzy
+msgid ""
+msgstr ""
+"Project-Id-Version: PACKAGE VERSION\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2013-01-13 14:14+0200\n"
+"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
+"Language-Team: LANGUAGE <LL@li.org>\n"
+"Language: \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=6; plural=n==0 ? 0 : n==1 ? 1 : n==2 ? 2 : n%100>=3 "
+"&& n%100<=10 ? 3 : n%100>=11 && n%100<=99 ? 4 : 5\n"
+
+#: templates/base.html:121 templates/mobile/base.html:43
+msgid "Powered by"
+msgstr ""
+
+#: templates/base.html:124
+msgid "and"
+msgstr ""
+
+#: templates/base.html:127
+msgid "Theme by"
+msgstr ""
+
+#: templates/base.html:130
+msgid "View Mobile Site"
+msgstr ""
+
+#: templates/index.html:4 templates/index.html.py:5 templates/index.html:8
+#: templates/search_results.html:10 templates/mobile/base.html:31
+#: templates/mobile/index.html:6 templates/pages/menus/breadcrumb.html:4
+#: templates/pages/menus/breadcrumb.html:10
+#: templates/pages/menus/dropdown.html:10
+#: templates/pages/menus/footer_tree.html:10
+#: templates/pages/menus/mobile.html:9 templates/pages/menus/primary.html:9
+#: templates/pages/menus/tree.html:9
+msgid "Home"
+msgstr ""
+
+#: templates/index.html:12
+msgid "This is the homepage."
+msgstr ""
+
+#: templates/search_results.html:5 templates/search_results.html.py:6
+#: templates/search_results.html:13 templates/mobile/search_results.html:5
+#: templates/mobile/search_results.html:6
+msgid "Search Results"
+msgstr ""
+
+#: templates/search_results.html:20
+#, python-format
+msgid ""
+"\n"
+"No results were found in %(search_type)s matching your query: %(query)s\n"
+msgstr ""
+
+#: templates/search_results.html:24
+#, python-format
+msgid ""
+"\n"
+"Showing %(start)s to %(end)s of %(total)s results in %(search_type)s "
+"matching your query: %(query)s\n"
+msgstr ""
+
+#: templates/search_results.html:35 templates/blog/blog_post_list.html:121
+#: templates/mobile/search_results.html:23
+msgid "read more"
+msgstr ""
+
+#: templates/accounts/account_login.html:7
+msgid "You're already logged in."
+msgstr ""
+
+#: templates/accounts/account_login.html:11
+#, python-format
+msgid ""
+"If you don't have an account you can <a href=\"%(signup_url)s?next=%(next)s"
+"\">sign up</a> for one now."
+msgstr ""
+
+#: templates/accounts/account_login.html:14
+#, python-format
+msgid ""
+"<p>You can also <a href=\"%(password_reset_url)s?next=%(profile_update_url)s"
+"\">reset your password</a> if you've forgotten it.</p>"
+msgstr ""
+
+#: templates/accounts/account_password_reset.html:6
+msgid ""
+"Enter your username or email address and you'll receive an email with a link "
+"you need to click, in order to log in and change your password."
+msgstr ""
+
+#: templates/accounts/account_profile.html:17
+#: templates/accounts/includes/user_panel.html:9
+msgid "Update profile"
+msgstr ""
+
+#: templates/accounts/account_signup.html:7
+msgid ""
+"You're already logged in. If you'd like to create a new account, you'll need "
+"to log out first."
+msgstr ""
+
+#: templates/accounts/account_signup.html:11
+msgid ""
+"After signing up, you'll receive an email with a link you need to click, in "
+"order to activate your account."
+msgstr ""
+
+#: templates/accounts/includes/user_panel.html:4
+msgid "Logged in as: "
+msgstr ""
+
+#: templates/accounts/includes/user_panel.html:14
+#: templates/includes/editable_toolbar.html:11
+msgid "Log out"
+msgstr ""
+
+#: templates/accounts/includes/user_panel.html:17
+msgid "Log in"
+msgstr ""
+
+#: templates/accounts/includes/user_panel.html:18
+#: templates/mobile/blog/blog_post_detail.html:54
+msgid "or"
+msgstr ""
+
+#: templates/accounts/includes/user_panel.html:20
+msgid "Sign up"
+msgstr ""
+
+#: templates/blog/blog_post_detail.html:29
+#: templates/blog/blog_post_list.html:83
+#: templates/mobile/blog/blog_post_detail.html:23
+msgid "Posted by"
+msgstr ""
+
+#: templates/blog/blog_post_detail.html:33
+#: templates/blog/blog_post_list.html:93
+#, python-format
+msgid "%(sometime)s ago"
+msgstr ""
+
+#: templates/blog/blog_post_detail.html:43
+#: templates/blog/blog_post_list.html:126
+#: templates/generic/includes/comments.html:3
+msgid "Comments"
+msgstr ""
+
+#: templates/blog/blog_post_detail.html:46
+#: templates/blog/blog_post_list.html:130
+#, python-format
+msgid "1 comment"
+msgid_plural "%(comments_count)s comments"
+msgstr[0] ""
+msgstr[1] ""
+
+#: templates/blog/blog_post_detail.html:74
+#: templates/blog/blog_post_list.html:113
+#: templates/blog/includes/filter_panel.html:48
+#: templates/mobile/blog/blog_post_detail.html:41
+msgid "Tags"
+msgstr ""
+
+#: templates/blog/blog_post_detail.html:87
+msgid "Share on Twitter"
+msgstr ""
+
+#: templates/blog/blog_post_detail.html:88
+msgid "Share on Facebook"
+msgstr ""
+
+#: templates/blog/blog_post_detail.html:113
+msgid "Related posts"
+msgstr ""
+
+#: templates/blog/blog_post_list.html:4 templates/blog/blog_post_list.html:22
+#: templates/mobile/blog/blog_post_list.html:4
+#: templates/mobile/blog/blog_post_list.html:19
+msgid "Blog"
+msgstr ""
+
+#: templates/blog/blog_post_list.html:31
+msgid "Tag:"
+msgstr ""
+
+#: templates/blog/blog_post_list.html:33
+msgid "Category:"
+msgstr ""
+
+#: templates/blog/blog_post_list.html:37
+msgid "Author:"
+msgstr ""
+
+#: templates/blog/blog_post_list.html:50
+msgid "Viewing posts tagged"
+msgstr ""
+
+#: templates/blog/blog_post_list.html:52
+msgid "Viewing posts for the category"
+msgstr ""
+
+#: templates/blog/blog_post_list.html:54
+msgid "Viewing posts from"
+msgstr ""
+
+#: templates/blog/blog_post_list.html:57
+msgid "Viewing posts by"
+msgstr ""
+
+#: templates/blog/blog_post_list.html:88
+msgid "in"
+msgstr ""
+
+#: templates/blog/includes/filter_panel.html:6
+msgid "Recent Posts"
+msgstr ""
+
+#: templates/blog/includes/filter_panel.html:19
+msgid "Archive"
+msgstr ""
+
+#: templates/blog/includes/filter_panel.html:35
+msgid "Categories"
+msgstr ""
+
+#: templates/blog/includes/filter_panel.html:64
+msgid "Authors"
+msgstr ""
+
+#: templates/blog/includes/filter_panel.html:76
+msgid "Feeds"
+msgstr ""
+
+#: templates/blog/includes/filter_panel.html:78
+#: templates/blog/includes/filter_panel.html:82
+#: templates/blog/includes/filter_panel.html:86
+#: templates/blog/includes/filter_panel.html:90
+msgid "RSS"
+msgstr ""
+
+#: templates/blog/includes/filter_panel.html:79
+#: templates/blog/includes/filter_panel.html:83
+#: templates/blog/includes/filter_panel.html:87
+#: templates/blog/includes/filter_panel.html:91
+msgid "Atom"
+msgstr ""
+
+#: templates/email/comment_notification.html:6
+msgid "A new comment has been posted on"
+msgstr ""
+
+#: templates/email/comment_notification.html:10
+#, python-format
+msgid ""
+"\n"
+"    At %(submit_date)s %(user_name)s wrote:\n"
+"    "
+msgstr ""
+
+#: templates/email/comment_notification.txt:7
+#, python-format
+msgid ""
+"\n"
+"At %(submit_date)s %(user_name)s wrote:\n"
+msgstr ""
+
+#: templates/email/password_reset_verify.html:3
+#: templates/email/password_reset_verify.txt:3
+msgid "Hey there, the password reset form was used for your account."
+msgstr ""
+
+#: templates/email/password_reset_verify.html:4
+#: templates/email/password_reset_verify.txt:4
+msgid "Please use the link below to log in and update your password."
+msgstr ""
+
+#: templates/email/password_reset_verify.html:6
+#: templates/email/password_reset_verify.txt:6
+msgid ""
+"If you didn't request for your password to be reset, please ignore this "
+"email."
+msgstr ""
+
+#: templates/email/password_reset_verify_subject.txt:2
+msgid "Reset your password"
+msgstr ""
+
+#: templates/email/signup_verify.html:3 templates/email/signup_verify.txt:3
+msgid "Hey there, thanks for creating your account."
+msgstr ""
+
+#: templates/email/signup_verify.html:4 templates/email/signup_verify.txt:4
+msgid "Please use the link below to activate it."
+msgstr ""
+
+#: templates/email/signup_verify_subject.txt:2
+msgid "Activate your account"
+msgstr ""
+
+#: templates/errors/404.html:6 templates/mobile/404.html:6
+msgid "Page not found"
+msgstr ""
+
+#: templates/errors/404.html:10 templates/mobile/404.html:10
+msgid "The page you requested does not exist."
+msgstr ""
+
+#: templates/errors/500.html:6 templates/mobile/500.html:6
+msgid "Error"
+msgstr ""
+
+#: templates/errors/500.html:10 templates/mobile/500.html:10
+msgid "Sorry, an error occurred."
+msgstr ""
+
+#: templates/generic/includes/comment.html:22
+#: templates/generic/includes/comment.html:53
+#: templates/generic/includes/comment.html:63
+#: templates/mobile/blog/blog_post_detail.html:30
+#: templates/mobile/blog/blog_post_list.html:28
+#: templates/twitter/tweets.html:20
+msgid "ago"
+msgstr ""
+
+#: templates/generic/includes/comment.html:25
+msgid "Link"
+msgstr ""
+
+#: templates/generic/includes/comment.html:26
+#: templates/generic/includes/comment.html:36
+msgid "Reply"
+msgstr ""
+
+#: templates/generic/includes/comment.html:59
+msgid "Comment deleted"
+msgstr ""
+
+#: templates/generic/includes/comment.html:61
+msgid "Comment awaiting approval"
+msgstr ""
+
+#: templates/generic/includes/comment.html:72
+msgid "There are currently no comments"
+msgstr ""
+
+#: templates/generic/includes/comments.html:16
+msgid "New Comment"
+msgstr ""
+
+#: templates/generic/includes/comments.html:24
+msgid "Send"
+msgstr ""
+
+#: templates/generic/includes/rating.html:7
+msgid "Current rating"
+msgstr ""
+
+#: templates/generic/includes/rating.html:9
+msgid "Currently unrated"
+msgstr ""
+
+#: templates/generic/includes/rating.html:18
+msgid "Rate"
+msgstr ""
+
+#: templates/includes/editable_form.html:16
+msgid "Save"
+msgstr ""
+
+#: templates/includes/editable_form.html:17
+msgid "Cancel"
+msgstr ""
+
+#: templates/includes/editable_form.html:25
+msgid "Edit"
+msgstr ""
+
+#: templates/includes/editable_toolbar.html:7
+#: templates/includes/editable_toolbar.html:9
+msgid "Admin"
+msgstr ""
+
+#: templates/includes/pagination.html:8
+msgid "Page"
+msgstr ""
+
+#: templates/includes/pagination.html:8
+#: templates/mobile/search_results.html:14
+msgid "of"
+msgstr ""
+
+#: templates/includes/search_form.html:4
+#: templates/mobile/includes/search.html:4
+msgid "Search"
+msgstr ""
+
+#: templates/includes/search_form.html:11
+msgid "Everything"
+msgstr ""
+
+#: templates/includes/search_form.html:18
+msgid "Go"
+msgstr ""
+
+#: templates/mobile/base.html:44
+msgid "View Full Site"
+msgstr ""
+
+#: templates/mobile/index.html:10
+msgid "This is the mobile homepage."
+msgstr ""
+
+#: templates/mobile/search_results.html:12
+msgid "No results were found matching your query: "
+msgstr ""
+
+#: templates/mobile/search_results.html:14
+msgid "Showing"
+msgstr ""
+
+#: templates/mobile/search_results.html:14
+msgid "to"
+msgstr ""
+
+#: templates/mobile/search_results.html:15
+msgid "results matching your query:"
+msgstr ""
+
+#: templates/mobile/blog/blog_post_detail.html:52
+msgid "Share this on:"
+msgstr ""
+
+#: templates/mobile/includes/pagination.html:6
+msgid "Previous"
+msgstr ""
+
+#: templates/mobile/includes/pagination.html:9
+msgid "Next"
+msgstr ""
+
+#: templates/mobile/includes/search.html:5
+msgid "Use "
+msgstr ""
+
+#: templates/mobile/includes/search.html:5
+msgid "quotes"
+msgstr ""
+
+#: templates/mobile/includes/search.html:5
+msgid ""
+" for exact phrases, + to make a word or phrase required, and - to exclude a "
+"word or phrase."
+msgstr ""
+
+#: templates/pages/menus/admin.html:31
+msgid "Add"
+msgstr ""
+
+#: templates/twitter/tweets.html:7
+msgid "Recent Tweets"
+msgstr ""

File myproject/locale/en/LC_MESSAGES/django.mo

Binary file added.

File myproject/locale/en/LC_MESSAGES/django.po

+# SOME DESCRIPTIVE TITLE.
+# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the PACKAGE package.
+# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
+#
+#, fuzzy
+msgid ""
+msgstr ""
+"Project-Id-Version: PACKAGE VERSION\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2013-01-13 14:14+0200\n"
+"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
+"Language-Team: LANGUAGE <LL@li.org>\n"
+"Language: \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+#: templates/base.html:121 templates/mobile/base.html:43
+msgid "Powered by"
+msgstr ""
+
+#: templates/base.html:124
+msgid "and"
+msgstr ""
+
+#: templates/base.html:127
+msgid "Theme by"
+msgstr ""
+
+#: templates/base.html:130
+msgid "View Mobile Site"
+msgstr ""
+
+#: templates/index.html:4 templates/index.html.py:5 templates/index.html:8
+#: templates/search_results.html:10 templates/mobile/base.html:31
+#: templates/mobile/index.html:6 templates/pages/menus/breadcrumb.html:4
+#: templates/pages/menus/breadcrumb.html:10
+#: templates/pages/menus/dropdown.html:10
+#: templates/pages/menus/footer_tree.html:10
+#: templates/pages/menus/mobile.html:9 templates/pages/menus/primary.html:9
+#: templates/pages/menus/tree.html:9
+msgid "Home"
+msgstr ""
+
+#: templates/index.html:12
+msgid "This is the homepage."
+msgstr ""
+
+#: templates/search_results.html:5 templates/search_results.html.py:6
+#: templates/search_results.html:13 templates/mobile/search_results.html:5
+#: templates/mobile/search_results.html:6
+msgid "Search Results"
+msgstr ""
+
+#: templates/search_results.html:20
+#, python-format
+msgid ""
+"\n"
+"No results were found in %(search_type)s matching your query: %(query)s\n"
+msgstr ""
+
+#: templates/search_results.html:24
+#, python-format
+msgid ""
+"\n"
+"Showing %(start)s to %(end)s of %(total)s results in %(search_type)s "
+"matching your query: %(query)s\n"
+msgstr ""
+
+#: templates/search_results.html:35 templates/blog/blog_post_list.html:121
+#: templates/mobile/search_results.html:23
+msgid "read more"
+msgstr ""
+
+#: templates/accounts/account_login.html:7
+msgid "You're already logged in."
+msgstr ""
+
+#: templates/accounts/account_login.html:11
+#, python-format
+msgid ""
+"If you don't have an account you can <a href=\"%(signup_url)s?next=%(next)s"
+"\">sign up</a> for one now."
+msgstr ""
+
+#: templates/accounts/account_login.html:14
+#, python-format
+msgid ""
+"<p>You can also <a href=\"%(password_reset_url)s?next=%(profile_update_url)s"
+"\">reset your password</a> if you've forgotten it.</p>"
+msgstr ""
+
+#: templates/accounts/account_password_reset.html:6
+msgid ""
+"Enter your username or email address and you'll receive an email with a link "
+"you need to click, in order to log in and change your password."
+msgstr ""
+
+#: templates/accounts/account_profile.html:17
+#: templates/accounts/includes/user_panel.html:9
+msgid "Update profile"
+msgstr ""
+
+#: templates/accounts/account_signup.html:7
+msgid ""
+"You're already logged in. If you'd like to create a new account, you'll need "
+"to log out first."
+msgstr ""
+
+#: templates/accounts/account_signup.html:11
+msgid ""
+"After signing up, you'll receive an email with a link you need to click, in "
+"order to activate your account."
+msgstr ""
+
+#: templates/accounts/includes/user_panel.html:4
+msgid "Logged in as: "
+msgstr ""
+
+#: templates/accounts/includes/user_panel.html:14
+#: templates/includes/editable_toolbar.html:11
+msgid "Log out"
+msgstr ""
+
+#: templates/accounts/includes/user_panel.html:17
+msgid "Log in"
+msgstr ""
+
+#: templates/accounts/includes/user_panel.html:18
+#: templates/mobile/blog/blog_post_detail.html:54
+msgid "or"
+msgstr ""
+
+#: templates/accounts/includes/user_panel.html:20
+msgid "Sign up"
+msgstr ""
+
+#: templates/blog/blog_post_detail.html:29
+#: templates/blog/blog_post_list.html:83
+#: templates/mobile/blog/blog_post_detail.html:23
+msgid "Posted by"
+msgstr ""
+
+#: templates/blog/blog_post_detail.html:33
+#: templates/blog/blog_post_list.html:93
+#, python-format
+msgid "%(sometime)s ago"
+msgstr ""
+
+#: templates/blog/blog_post_detail.html:43
+#: templates/blog/blog_post_list.html:126
+#: templates/generic/includes/comments.html:3
+msgid "Comments"
+msgstr ""
+
+#: templates/blog/blog_post_detail.html:46
+#: templates/blog/blog_post_list.html:130
+#, python-format
+msgid "1 comment"
+msgid_plural "%(comments_count)s comments"
+msgstr[0] ""
+msgstr[1] ""
+
+#: templates/blog/blog_post_detail.html:74
+#: templates/blog/blog_post_list.html:113
+#: templates/blog/includes/filter_panel.html:48
+#: templates/mobile/blog/blog_post_detail.html:41
+msgid "Tags"
+msgstr ""
+
+#: templates/blog/blog_post_detail.html:87
+msgid "Share on Twitter"
+msgstr ""
+
+#: templates/blog/blog_post_detail.html:88
+msgid "Share on Facebook"
+msgstr ""
+
+#: templates/blog/blog_post_detail.html:113
+msgid "Related posts"
+msgstr ""
+
+#: templates/blog/blog_post_list.html:4 templates/blog/blog_post_list.html:22
+#: templates/mobile/blog/blog_post_list.html:4
+#: templates/mobile/blog/blog_post_list.html:19
+msgid "Blog"
+msgstr ""
+
+#: templates/blog/blog_post_list.html:31
+msgid "Tag:"
+msgstr ""
+
+#: templates/blog/blog_post_list.html:33
+msgid "Category:"
+msgstr ""
+
+#: templates/blog/blog_post_list.html:37
+msgid "Author:"
+msgstr ""
+
+#: templates/blog/blog_post_list.html:50
+msgid "Viewing posts tagged"
+msgstr ""
+
+#: templates/blog/blog_post_list.html:52
+msgid "Viewing posts for the category"
+msgstr ""
+
+#: templates/blog/blog_post_list.html:54
+msgid "Viewing posts from"
+msgstr ""
+
+#: templates/blog/blog_post_list.html:57
+msgid "Viewing posts by"
+msgstr ""
+
+#: templates/blog/blog_post_list.html:88
+msgid "in"
+msgstr ""
+
+#: templates/blog/includes/filter_panel.html:6
+msgid "Recent Posts"
+msgstr ""
+
+#: templates/blog/includes/filter_panel.html:19
+msgid "Archive"
+msgstr ""
+
+#: templates/blog/includes/filter_panel.html:35
+msgid "Categories"
+msgstr ""
+
+#: templates/blog/includes/filter_panel.html:64
+msgid "Authors"
+msgstr ""
+
+#: templates/blog/includes/filter_panel.html:76
+msgid "Feeds"
+msgstr ""
+
+#: templates/blog/includes/filter_panel.html:78
+#: templates/blog/includes/filter_panel.html:82
+#: templates/blog/includes/filter_panel.html:86
+#: templates/blog/includes/filter_panel.html:90
+msgid "RSS"
+msgstr ""
+
+#: templates/blog/includes/filter_panel.html:79
+#: templates/blog/includes/filter_panel.html:83
+#: templates/blog/includes/filter_panel.html:87
+#: templates/blog/includes/filter_panel.html:91
+msgid "Atom"
+msgstr ""
+
+#: templates/email/comment_notification.html:6
+msgid "A new comment has been posted on"
+msgstr ""
+
+#: templates/email/comment_notification.html:10
+#, python-format
+msgid ""
+"\n"
+"    At %(submit_date)s %(user_name)s wrote:\n"
+"    "
+msgstr ""
+
+#: templates/email/comment_notification.txt:7
+#, python-format
+msgid ""
+"\n"
+"At %(submit_date)s %(user_name)s wrote:\n"
+msgstr ""
+
+#: templates/email/password_reset_verify.html:3
+#: templates/email/password_reset_verify.txt:3
+msgid "Hey there, the password reset form was used for your account."
+msgstr ""
+
+#: templates/email/password_reset_verify.html:4
+#: templates/email/password_reset_verify.txt:4
+msgid "Please use the link below to log in and update your password."
+msgstr ""
+
+#: templates/email/password_reset_verify.html:6
+#: templates/email/password_reset_verify.txt:6
+msgid ""
+"If you didn't request for your password to be reset, please ignore this "
+"email."
+msgstr ""
+
+#: templates/email/password_reset_verify_subject.txt:2
+msgid "Reset your password"
+msgstr ""
+
+#: templates/email/signup_verify.html:3 templates/email/signup_verify.txt:3
+msgid "Hey there, thanks for creating your account."
+msgstr ""
+
+#: templates/email/signup_verify.html:4 templates/email/signup_verify.txt:4
+msgid "Please use the link below to activate it."
+msgstr ""
+
+#: templates/email/signup_verify_subject.txt:2
+msgid "Activate your account"
+msgstr ""
+
+#: templates/errors/404.html:6 templates/mobile/404.html:6
+msgid "Page not found"
+msgstr ""
+
+#: templates/errors/404.html:10 templates/mobile/404.html:10
+msgid "The page you requested does not exist."
+msgstr ""
+
+#: templates/errors/500.html:6 templates/mobile/500.html:6
+msgid "Error"
+msgstr ""
+
+#: templates/errors/500.html:10 templates/mobile/500.html:10
+msgid "Sorry, an error occurred."
+msgstr ""
+
+#: templates/generic/includes/comment.html:22
+#: templates/generic/includes/comment.html:53
+#: templates/generic/includes/comment.html:63
+#: templates/mobile/blog/blog_post_detail.html:30
+#: templates/mobile/blog/blog_post_list.html:28
+#: templates/twitter/tweets.html:20
+msgid "ago"
+msgstr ""
+
+#: templates/generic/includes/comment.html:25
+msgid "Link"
+msgstr ""
+
+#: templates/generic/includes/comment.html:26
+#: templates/generic/includes/comment.html:36
+msgid "Reply"
+msgstr ""
+
+#: templates/generic/includes/comment.html:59
+msgid "Comment deleted"
+msgstr ""
+
+#: templates/generic/includes/comment.html:61
+msgid "Comment awaiting approval"
+msgstr ""
+
+#: templates/generic/includes/comment.html:72
+msgid "There are currently no comments"
+msgstr ""
+
+#: templates/generic/includes/comments.html:16
+msgid "New Comment"
+msgstr ""
+
+#: templates/generic/includes/comments.html:24
+msgid "Send"
+msgstr ""
+
+#: templates/generic/includes/rating.html:7
+msgid "Current rating"
+msgstr ""
+
+#: templates/generic/includes/rating.html:9
+msgid "Currently unrated"
+msgstr ""
+
+#: templates/generic/includes/rating.html:18
+msgid "Rate"
+msgstr ""
+
+#: templates/includes/editable_form.html:16
+msgid "Save"
+msgstr ""
+
+#: templates/includes/editable_form.html:17
+msgid "Cancel"
+msgstr ""
+
+#: templates/includes/editable_form.html:25
+msgid "Edit"
+msgstr ""
+
+#: templates/includes/editable_toolbar.html:7
+#: templates/includes/editable_toolbar.html:9
+msgid "Admin"
+msgstr ""
+
+#: templates/includes/pagination.html:8
+msgid "Page"
+msgstr ""
+
+#: templates/includes/pagination.html:8
+#: templates/mobile/search_results.html:14
+msgid "of"
+msgstr ""
+
+#: templates/includes/search_form.html:4
+#: templates/mobile/includes/search.html:4
+msgid "Search"
+msgstr ""
+
+#: templates/includes/search_form.html:11
+msgid "Everything"
+msgstr ""
+
+#: templates/includes/search_form.html:18
+msgid "Go"
+msgstr ""
+
+#: templates/mobile/base.html:44
+msgid "View Full Site"
+msgstr ""
+
+#: templates/mobile/index.html:10
+msgid "This is the mobile homepage."
+msgstr ""
+
+#: templates/mobile/search_results.html:12
+msgid "No results were found matching your query: "
+msgstr ""
+
+#: templates/mobile/search_results.html:14
+msgid "Showing"
+msgstr ""
+
+#: templates/mobile/search_results.html:14
+msgid "to"
+msgstr ""
+
+#: templates/mobile/search_results.html:15
+msgid "results matching your query:"
+msgstr ""
+
+#: templates/mobile/blog/blog_post_detail.html:52
+msgid "Share this on:"
+msgstr ""
+
+#: templates/mobile/includes/pagination.html:6
+msgid "Previous"
+msgstr ""
+
+#: templates/mobile/includes/pagination.html:9
+msgid "Next"
+msgstr ""
+
+#: templates/mobile/includes/search.html:5
+msgid "Use "
+msgstr ""
+
+#: templates/mobile/includes/search.html:5
+msgid "quotes"
+msgstr ""
+
+#: templates/mobile/includes/search.html:5
+msgid ""
+" for exact phrases, + to make a word or phrase required, and - to exclude a "
+"word or phrase."
+msgstr ""
+
+#: templates/pages/menus/admin.html:31
+msgid "Add"
+msgstr ""
+
+#: templates/twitter/tweets.html:7
+msgid "Recent Tweets"
+msgstr ""

File myproject/manage.py

+#!/usr/bin/env python
+
+import os
+import sys
+
+
+# Corrects some pathing issues in various contexts, such as cron jobs,
+# and the project layout still being in Django 1.3 format.
+from settings import PROJECT_ROOT, PROJECT_DIRNAME
+os.chdir(PROJECT_ROOT)
+sys.path.insert(0, os.path.abspath(os.path.join(PROJECT_ROOT, "..")))
+
+
+# Add the site ID CLI arg to the environment, which allows for the site
+# used in any site related queries to be manually set for management
+# commands.
+for i, arg in enumerate(sys.argv):
+    if arg.startswith("--site"):
+        os.environ["MEZZANINE_SITE_ID"] = arg.split("=")[1]
+        sys.argv.pop(i)
+
+
+# Run Django.
+if __name__ == "__main__":
+    settings_module = "%s.settings" % PROJECT_DIRNAME
+    os.environ.setdefault("DJANGO_SETTINGS_MODULE", settings_module)
+    from django.core.management import execute_from_command_line
+    execute_from_command_line(sys.argv)

File myproject/requirements/project.txt

+Mezzanine==1.3.0
+django-rosetta==0.6.8
+django-rosetta-grappelli==1.0.1 

File myproject/settings.py

+
+######################
+# MEZZANINE SETTINGS #
+######################
+
+# The following settings are already defined with default values in
+# the ``defaults.py`` module within each of Mezzanine's apps, but are
+# common enough to be put here, commented out, for convenient
+# overriding. Please consult the settings documentation for a full list
+# of settings Mezzanine implements:
+# http://mezzanine.jupo.org/docs/configuration.html#default-settings
+
+# Controls the ordering and grouping of the admin menu.
+#
+# ADMIN_MENU_ORDER = (
+#     ("Content", ("pages.Page", "blog.BlogPost",
+#        "generic.ThreadedComment", ("Media Library", "fb_browse"),)),
+#     ("Site", ("sites.Site", "redirects.Redirect", "conf.Setting")),
+#     ("Users", ("auth.User", "auth.Group",)),
+# )
+
+# A three item sequence, each containing a sequence of template tags
+# used to render the admin dashboard.
+#
+# DASHBOARD_TAGS = (
+#     ("blog_tags.quick_blog", "mezzanine_tags.app_list"),
+#     ("comment_tags.recent_comments",),
+#     ("mezzanine_tags.recent_actions",),
+# )
+
+# A sequence of templates used by the ``page_menu`` template tag. Each
+# item in the sequence is a three item sequence, containing a unique ID
+# for the template, a label for the template, and the template path.
+# These templates are then available for selection when editing which
+# menus a page should appear in. Note that if a menu template is used
+# that doesn't appear in this setting, all pages will appear in it.
+
+# PAGE_MENU_TEMPLATES = (
+#     (1, "Top navigation bar", "pages/menus/dropdown.html"),
+#     (2, "Left-hand tree", "pages/menus/tree.html"),
+#     (3, "Footer", "pages/menus/footer.html"),
+# )
+
+# A sequence of fields that will be injected into Mezzanine's (or any
+# library's) models. Each item in the sequence is a four item sequence.
+# The first two items are the dotted path to the model and its field
+# name to be added, and the dotted path to the field class to use for
+# the field. The third and fourth items are a sequence of positional
+# args and a dictionary of keyword args, to use when creating the
+# field instance. When specifying the field class, the path
+# ``django.models.db.`` can be omitted for regular Django model fields.
+#
+# EXTRA_MODEL_FIELDS = (
+#     (
+#         # Dotted path to field.
+#         "mezzanine.blog.models.BlogPost.image",
+#         # Dotted path to field class.
+#         "somelib.fields.ImageField",
+#         # Positional args for field class.
+#         ("Image",),
+#         # Keyword args for field class.
+#         {"blank": True, "upload_to": "blog"},
+#     ),
+#     # Example of adding a field to *all* of Mezzanine's content types:
+#     (
+#         "mezzanine.pages.models.Page.another_field",
+#         "IntegerField", # 'django.db.models.' is implied if path is omitted.
+#         ("Another name",),
+#         {"blank": True, "default": 1},
+#     ),
+# )
+
+# Setting to turn on featured images for blog posts. Defaults to False.
+#
+# BLOG_USE_FEATURED_IMAGE = True
+
+# If True, the south application will be automatically added to the
+# INSTALLED_APPS setting.
+USE_SOUTH = True
+
+
+########################
+# MAIN DJANGO SETTINGS #
+########################
+
+# People who get code error notifications.
+# In the format (('Full Name', 'email@example.com'),
+#                ('Full Name', 'anotheremail@example.com'))
+ADMINS = (
+    # ('Your Name', 'your_email@domain.com'),
+)
+MANAGERS = ADMINS
+
+# Local time zone for this installation. Choices can be found here:
+# http://en.wikipedia.org/wiki/List_of_tz_zones_by_name
+# although not all choices may be available on all operating systems.
+# On Unix systems, a value of None will cause Django to use the same
+# timezone as the operating system.
+# If running in a Windows environment this must be set to the same as your
+# system time zone.
+TIME_ZONE = None
+
+# If you set this to True, Django will use timezone-aware datetimes.
+USE_TZ = True
+
+# Language code for this installation. All choices can be found here:
+# http://www.i18nguy.com/unicode/language-identifiers.html
+LANGUAGE_CODE = "en"
+
+# A boolean that turns on/off debug mode. When set to ``True``, stack traces
+# are displayed for error pages. Should always be set to ``False`` in
+# production. Best set to ``True`` in local_settings.py
+DEBUG = False
+
+# Whether a user's session cookie expires when the Web browser is closed.
+SESSION_EXPIRE_AT_BROWSER_CLOSE = True
+
+SITE_ID = 1
+
+# If you set this to False, Django will make some optimizations so as not
+# to load the internationalization machinery.
+USE_I18N = False
+
+# Make this unique, and don't share it with anybody.
+SECRET_KEY = "9ea15346-ce7a-45c1-a7a3-16c5abc5337c61f5926d-a941-44fc-a3f1-590c0366369a6fd25c56-4165-4a3a-8061-fe734fc3f203"
+
+# Tuple of IP addresses, as strings, that:
+#   * See debug comments, when DEBUG is true
+#   * Receive x-headers
+INTERNAL_IPS = ("127.0.0.1",)
+
+# List of callables that know how to import templates from various sources.
+TEMPLATE_LOADERS = (
+    "django.template.loaders.filesystem.Loader",
+    "django.template.loaders.app_directories.Loader",
+)
+
+AUTHENTICATION_BACKENDS = ("mezzanine.core.auth_backends.MezzanineBackend",)
+
+# List of finder classes that know how to find static files in
+# various locations.
+STATICFILES_FINDERS = (
+    "django.contrib.staticfiles.finders.FileSystemFinder",
+    "django.contrib.staticfiles.finders.AppDirectoriesFinder",
+#    'django.contrib.staticfiles.finders.DefaultStorageFinder',
+)
+
+
+#############
+# DATABASES #
+#############
+
+DATABASES = {
+    "default": {
+        # Add "postgresql_psycopg2", "mysql", "sqlite3" or "oracle".
+        "ENGINE": "django.db.backends.",
+        # DB name or path to database file if using sqlite3.
+        "NAME": "",
+        # Not used with sqlite3.
+        "USER": "",
+        # Not used with sqlite3.
+        "PASSWORD": "",
+        # Set to empty string for localhost. Not used with sqlite3.
+        "HOST": "",
+        # Set to empty string for default. Not used with sqlite3.
+        "PORT": "",
+    }
+}
+
+
+#########
+# PATHS #
+#########
+
+import os
+
+# Full filesystem path to the project.
+PROJECT_ROOT = os.path.dirname(os.path.abspath(__file__))
+
+# Name of the directory for the project.
+PROJECT_DIRNAME = PROJECT_ROOT.split(os.sep)[-1]
+
+# Every cache key will get prefixed with this value - here we set it to
+# the name of the directory the project is in to try and use something
+# project specific.
+CACHE_MIDDLEWARE_KEY_PREFIX = PROJECT_DIRNAME
+
+# URL prefix for static files.
+# Example: "http://media.lawrence.com/static/"
+STATIC_URL = "/static/"
+
+# Absolute path to the directory static files should be collected to.
+# Don't put anything in this directory yourself; store your static files
+# in apps' "static/" subdirectories and in STATICFILES_DIRS.
+# Example: "/home/media/media.lawrence.com/static/"
+STATIC_ROOT = os.path.join(PROJECT_ROOT, STATIC_URL.strip("/"))
+
+# URL that handles the media served from MEDIA_ROOT. Make sure to use a
+# trailing slash.
+# Examples: "http://media.lawrence.com/media/", "http://example.com/media/"
+MEDIA_URL = STATIC_URL + "media/"
+
+# Absolute filesystem path to the directory that will hold user-uploaded files.
+# Example: "/home/media/media.lawrence.com/media/"
+MEDIA_ROOT = os.path.join(PROJECT_ROOT, *MEDIA_URL.strip("/").split("/"))
+
+# URL prefix for admin media -- CSS, JavaScript and images. Make sure to use a
+# trailing slash.
+# Examples: "http://foo.com/media/", "/media/".
+ADMIN_MEDIA_PREFIX = STATIC_URL + "grappelli/"
+
+# Package/module name to import the root urlpatterns from for the project.
+ROOT_URLCONF = "%s.urls" % PROJECT_DIRNAME
+
+# Put strings here, like "/home/html/django_templates"
+# or "C:/www/django/templates".
+# Always use forward slashes, even on Windows.
+# Don't forget to use absolute paths, not relative paths.
+TEMPLATE_DIRS = (os.path.join(PROJECT_ROOT, "templates"),)
+
+
+################
+# APPLICATIONS #
+################
+
+INSTALLED_APPS = (
+    "django.contrib.admin",
+    "django.contrib.auth",
+    "django.contrib.contenttypes",
+    "django.contrib.redirects",
+    "django.contrib.sessions",
+    "django.contrib.sites",
+    "django.contrib.sitemaps",
+    "django.contrib.staticfiles",
+
+    'grappelli_safe',
+    
+    'rosetta',
+    'rosetta-grappelli',
+
+
+    "mezzanine.boot",
+    "mezzanine.conf",
+    "mezzanine.core",
+    "mezzanine.generic",
+    "mezzanine.blog",
+    "mezzanine.forms",
+    "mezzanine.pages",
+    "mezzanine.galleries",
+    "mezzanine.twitter",
+    "mezzanine.accounts",
+    "mezzanine.mobile",
+)
+
+# List of processors used by RequestContext to populate the context.
+# Each one should be a callable that takes the request object as its
+# only parameter and returns a dictionary to add to the context.
+TEMPLATE_CONTEXT_PROCESSORS = (
+    "django.contrib.auth.context_processors.auth",
+    "django.contrib.messages.context_processors.messages",
+    "django.core.context_processors.debug",
+    "django.core.context_processors.i18n",
+    "django.core.context_processors.static",
+    "django.core.context_processors.media",
+    "django.core.context_processors.request",
+    "django.core.context_processors.tz",
+    "mezzanine.conf.context_processors.settings",
+)
+
+# List of middleware classes to use. Order is important; in the request phase,
+# these middleware classes will be applied in the order given, and in the
+# response phase the middleware will be applied in reverse order.
+MIDDLEWARE_CLASSES = (
+    "mezzanine.core.middleware.UpdateCacheMiddleware",
+    "django.contrib.sessions.middleware.SessionMiddleware",
+    "django.contrib.auth.middleware.AuthenticationMiddleware",
+    "django.contrib.redirects.middleware.RedirectFallbackMiddleware",
+    "django.middleware.common.CommonMiddleware",
+    "django.middleware.csrf.CsrfViewMiddleware",
+    "django.contrib.messages.middleware.MessageMiddleware",
+    "mezzanine.core.request.CurrentRequestMiddleware",
+    "mezzanine.core.middleware.TemplateForDeviceMiddleware",
+    "mezzanine.core.middleware.TemplateForHostMiddleware",
+    "mezzanine.core.middleware.AdminLoginInterfaceSelectorMiddleware",
+    "mezzanine.core.middleware.SitePermissionMiddleware",
+    # Uncomment the following if using any of the SSL settings:
+    # "mezzanine.core.middleware.SSLRedirectMiddleware",
+    "mezzanine.pages.middleware.PageMiddleware",
+    "mezzanine.core.middleware.FetchFromCacheMiddleware",
+)
+
+# Store these package names here as they may change in the future since
+# at the moment we are using custom forks of them.
+PACKAGE_NAME_FILEBROWSER = "filebrowser_safe"
+PACKAGE_NAME_GRAPPELLI = "grappelli_safe"
+
+#########################
+# OPTIONAL APPLICATIONS #