<commit_before>"""
The code that should be run on Travis
"""

import os
import shlex
import shutil
import subprocess
import sys
import glob

from cryptography.fernet import Fernet

def decrypt_file(file, key):
    """
    Decrypts the file ``file``.

    The encrypted file is assumed to end with the ``.enc`` extension. The
    decrypted file is saved to the same location without the ``.enc``
    extension.

    The permissions on the decrypted file are automatically set to 0o600.

    See also :func:`doctr.local.encrypt_file`.

    """
    if not file.endswith('.enc'):
        raise ValueError("%s does not end with .enc" % file)

    fer = Fernet(key)

    with open(file, 'rb') as f:
        decrypted_file = fer.decrypt(f.read())

    with open(file[:-4], 'wb') as f:
        f.write(decrypted_file)

    os.chmod(file[:-4], 0o600)

def setup_deploy_key(keypath='github_deploy_key', key_ext='.enc'):
    """
    Decrypts the deploy key and configures it with ssh

    The key is assumed to be encrypted as keypath + key_ext, and the
    encryption key is assumed to be set in the environment variable
    DOCTR_DEPLOY_ENCRYPTION_KEY.

    """
    key = os.environ.get("DOCTR_DEPLOY_ENCRYPTION_KEY", None)
    if not key:
        raise RuntimeError("DOCTR_DEPLOY_ENCRYPTION_KEY environment variable is not set")

    key_filename = os.path.basename(keypath)
    key = key.encode('utf-8')
    decrypt_file(keypath + key_ext, key)

    key_path = os.path.expanduser("~/.ssh/" + key_filename)
    os.makedirs(os.path.expanduser("~/.ssh"), exist_ok=True)
    os.rename(keypath, key_path)

    with open(os.path.expanduser("~/.ssh/config"), 'a') as f:
        f.write("Host github.com"
                '  IdentityFile "%s"'
                "  LogLevel ERROR\n" % key_path)

    # start ssh-agent and add key to it
    # info from SSH agent has to be put into the environment
    agent_info = subprocess.check_output(['ssh-agent', '-s'])
    agent_info = agent_info.decode('utf-8')
    agent_info = agent_info.split()

    AUTH_SOCK = agent_info[0].split('=')[1][:-1]
    AGENT_PID = agent_info[3].split('=')[1][:-1]

    os.putenv('SSH_AUTH_SOCK', AUTH_SOCK)
    os.putenv('SSH_AGENT_PID', AGENT_PID)

    run(['ssh-add', os.path.expanduser('~/.ssh/' + key_filename)])

# XXX: Do this in a way that is streaming
def run_command_hiding_token(args, token):
    command = ' '.join(map(shlex.quote, args))
    command = command.replace(token.decode('utf-8'), '~'*len(token))
    print(command)
    p = subprocess.run(args, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
    out, err = p.stdout, p.stderr
    out = out.replace(token, b"~"*len(token))
    err = err.replace(token, b"~"*len(token))
    return (out, err, p.returncode)

def get_token():
    """
    Get the encrypted GitHub token in Travis.

    Make sure the contents this variable do not leak. The ``run()`` function
    will remove this from the output, so always use it.
    """
    token = os.environ.get("GH_TOKEN", None)
    if not token:
        raise RuntimeError("GH_TOKEN environment variable not set")
    token = token.encode('utf-8')
    return token

def run(args):
    """
    Run the command ``args``.

    Automatically hides the secret GitHub token from the output.
    """
    if "DOCTR_DEPLOY_ENCRYPTION_KEY" in os.environ:
        token = b''
    else:
        token = get_token()
    out, err, returncode = run_command_hiding_token(args, token)
    if out:
        print(out.decode('utf-8'))
    if err:
        print(err.decode('utf-8'), file=sys.stderr)
    if returncode != 0:
        sys.exit(returncode)

def get_current_repo():
    """
    Get the GitHub repo name for the current directory.

    Assumes that the repo is in the ``origin`` remote.
    """
    remote_url = subprocess.check_output(['git', 'config', '--get',
        'remote.origin.url']).decode('utf-8')

    # Travis uses the https clone url
    _, org, git_repo = remote_url.rsplit('.git', 1)[0].rsplit('/', 2)
    return (org + '/' + git_repo)

def setup_GitHub_push(deploy_repo, auth_type='deploy_key', full_key_path='github_deploy_key.enc', require_master=True, deploy_branch='gh-pages'):
    """
    Setup the remote to push to GitHub (to be run on Travis).

    ``auth_type`` should be either ``'deploy_key'`` or ``'token'``.

    For ``auth_type='token'``, this sets up the remote with the token and
    checks out the gh-pages branch. The token to push to GitHub is assumed to be in the ``GH_TOKEN`` environment
    variable.

    For ``auth_type='deploy_key'``, this sets up the remote with ssh access.
    """
    if auth_type not in ['deploy_key', 'token']:
        raise ValueError("auth_type must be 'deploy_key' or 'token'")

    TRAVIS_BRANCH = os.environ.get("TRAVIS_BRANCH", "")
    TRAVIS_PULL_REQUEST = os.environ.get("TRAVIS_PULL_REQUEST", "")

    if TRAVIS_BRANCH != "master" and require_master:
        print("The docs are only pushed to {} from master. To allow pushing from "
        "a non-master branch, use the --no-require-master flag".format(deploy_branch), file=sys.stderr)
        print("This is the {TRAVIS_BRANCH} branch".format(TRAVIS_BRANCH=TRAVIS_BRANCH), file=sys.stderr)
        return False

    if TRAVIS_PULL_REQUEST != "false":
        print("The website and docs are not pushed to {} on pull requests".format(deploy_branch),
              file=sys.stderr)
        return False

    print("Setting git attributes")
    # Should we add some user.email?
    run(['git', 'config', '--global', 'user.name', "Doctr (Travis CI)"])

    remotes = subprocess.check_output(['git', 'remote']).decode('utf-8').split('\n')
    if 'doctr_remote' in remotes:
        print("doctr_remote already exists, removing")
        run(['git', 'remote', 'remove', 'doctr_remote'])
    print("Adding doctr remote")
    if auth_type == 'token':
        token = get_token()
        run(['git', 'remote', 'add', 'doctr_remote',
            'https://{token}@github.com/{deploy_repo}.git'.format(token=token.decode('utf-8'),
                deploy_repo=deploy_repo)])
    else:
        keypath, key_ext = full_key_path.rsplit('.', 1)
        key_ext = '.' + key_ext
        setup_deploy_key(keypath=keypath, key_ext=key_ext)
        run(['git', 'remote', 'add', 'doctr_remote',
            'git@github.com:{deploy_repo}.git'.format(deploy_repo=deploy_repo)])

    print("Fetching doctr remote")
    run(['git', 'fetch', 'doctr_remote'])

    #create empty branch with .nojekyll if it doesn't already exist
    new_deploy_branch = create_deploy_branch(deploy_branch)
    print("Checking out {}".format(deploy_branch))
    local_deploy_branch_exists = deploy_branch in subprocess.check_output(['git', 'branch']).decode('utf-8').split()
    if new_deploy_branch or local_deploy_branch_exists:
        run(['git', 'checkout', deploy_branch])
    else:
        run(['git', 'checkout', '-b', deploy_branch, '--track',
             'doctr_remote/{}'.format(deploy_branch)])
    print("Done")

    return True

def deploy_branch_exists(deploy_branch='gh-pages'):
    """Check if the remote deploy branch exists

    This isn't completely robust. If there are multiple remotes and the branch
    is created on the non-default remote, this won't see it.
    """
    remote_name = 'doctr_remote'
    branch_names = subprocess.check_output(['git', 'branch', '-r']).decode('utf-8').split()

    return '{remote}/{branch}'.format(remote=remote_name,
                                      branch=deploy_branch) in branch_names

def create_deploy_branch(deploy_branch):
    """
    If there is no remote deploy branch, create one.
    Return True if branch was created, False if not.
    Default value for deploy_branch is ``gh-pages``
    """
    if not deploy_branch_exists():
        print("Creating {} branch".format(deploy_branch))
        run(['git', 'checkout', '--orphan', deploy_branch])
        # delete everything in the new ref.  this is non-destructive to existing
        # refs/branches, etc...
        run(['git', 'rm', '-rf', '.'])
        print("Adding .nojekyll file to {}".format(deploy_branch))
        run(['touch', '.nojekyll'])
        run(['git', 'add', '.nojekyll'])
        run(['git', 'commit', '-m', 'Create new branch {} with .nojekyll'.format(deploy_branch)])
        print("Pushing branch {} to remote".format(deploy_branch))
        run(['git', 'push', '-u', 'doctr_remote', deploy_branch])
        # return to master branch
        run(['git', 'checkout', '-'])

        return True
    return False

def find_sphinx_build_dir():
    """
    Find build subfolder within sphinx docs directory.

    This is called by :func:`commit_docs` if keyword arg ``built_docs`` is not
    specified on the command line.
    """
    build = glob.glob('**/*build/html', recursive=True)
    if not build:
        raise RuntimeError("Could not find Sphinx build directory automatically")
    build_folder = build[0]

    return build_folder

# Here is the logic to get the Travis job number, to only run commit_docs in
# the right build.
#
# TRAVIS_JOB_NUMBER = os.environ.get("TRAVIS_JOB_NUMBER", '')
# ACTUAL_TRAVIS_JOB_NUMBER = TRAVIS_JOB_NUMBER.split('.')[1]

def sync_from_log(src, dst, log_file):
    """
    Sync the files in ``src`` to ``dst``.

    The files that are synced are logged to ``log_file``. If ``log_file``
    exists, the files in ``log_file`` are removed first.

    Returns ``(added, removed)``, where added is a list of all files synced from
    ``src`` (even if it already existed in ``dst``), and ``removed`` is every
    file from ``log_file`` that was removed from ``dst`` because it wasn't in
    ``src``. ``added`` also includes the log file.
    """
    from os.path import join, exists, isdir
    if not src.endswith(os.sep):
        src += os.sep

    added, removed = [], []

    if not exists(log_file):
        # Assume this is the first run
        print("%s doesn't exist. Not removing any files." % log_file)
    else:
        with open(log_file) as f:
            files = f.read().strip().split('\n')

        for new_f in files:
            new_f = new_f.strip()
            if exists(new_f):
                os.remove(new_f)
                removed.append(new_f)
            else:
                print("Warning: File %s doesn't exist." % new_f, file=sys.stderr)

    files = glob.iglob(join(src, '**'), recursive=True)
    # sorted makes this easier to test
    for f in sorted(files):
        new_f = join(dst, f[len(src):])
        if isdir(f):
            os.makedirs(new_f, exist_ok=True)
        else:
            shutil.copy2(f, new_f)
            added.append(new_f)
            if new_f in removed:
                removed.remove(new_f)

    with open(log_file, 'w') as f:
        f.write('\n'.join(added))

    added.append(log_file)

    return added, removed

def commit_docs(*, added, removed):
    """
    Commit the docs to ``gh-pages`` or a specified deploy branch.

    Assumes that :func:`setup_GitHub_push`, which sets up the ``doctr_remote``
    remote, has been run and returned True.

    Returns True if changes were committed and False if no changes were
    committed.
    """
    TRAVIS_BUILD_NUMBER = os.environ.get("TRAVIS_BUILD_NUMBER", "<unknown>")

    for f in added:
        run(['git', 'add', f])
    for f in removed:
        run(['git', 'rm', f])

    # Only commit if there were changes
    if subprocess.run(['git', 'diff-index', '--quiet', 'HEAD', '--'],
        stdout=subprocess.PIPE, stderr=subprocess.PIPE).returncode != 0:
        print("Committing")
        run(['git', 'commit', '-am', "Update docs after building Travis build " + TRAVIS_BUILD_NUMBER])
        return True

    return False

def push_docs(deploy_branch='gh-pages'):
    """
    Push the changes to the ``gh-pages`` branch or specified deploy branch.

    Assumes that :func:`setup_GitHub_push` has been run and returned True, and
    that :func:`commit_docs` has been run. Does not push anything if no changes
    were made.

    """

    print("Pulling")
    run(["git", "pull"])
    print("Pushing commit")
    run(['git', 'push', '-q', 'doctr_remote', deploy_branch])
<commit_msg>fix for `create_deploy_branch`<commit_after>"""
The code that should be run on Travis
"""

import os
import shlex
import shutil
import subprocess
import sys
import glob

from cryptography.fernet import Fernet

def decrypt_file(file, key):
    """
    Decrypts the file ``file``.

    The encrypted file is assumed to end with the ``.enc`` extension. The
    decrypted file is saved to the same location without the ``.enc``
    extension.

    The permissions on the decrypted file are automatically set to 0o600.

    See also :func:`doctr.local.encrypt_file`.

    """
    if not file.endswith('.enc'):
        raise ValueError("%s does not end with .enc" % file)

    fer = Fernet(key)

    with open(file, 'rb') as f:
        decrypted_file = fer.decrypt(f.read())

    with open(file[:-4], 'wb') as f:
        f.write(decrypted_file)

    os.chmod(file[:-4], 0o600)

def setup_deploy_key(keypath='github_deploy_key', key_ext='.enc'):
    """
    Decrypts the deploy key and configures it with ssh

    The key is assumed to be encrypted as keypath + key_ext, and the
    encryption key is assumed to be set in the environment variable
    DOCTR_DEPLOY_ENCRYPTION_KEY.

    """
    key = os.environ.get("DOCTR_DEPLOY_ENCRYPTION_KEY", None)
    if not key:
        raise RuntimeError("DOCTR_DEPLOY_ENCRYPTION_KEY environment variable is not set")

    key_filename = os.path.basename(keypath)
    key = key.encode('utf-8')
    decrypt_file(keypath + key_ext, key)

    key_path = os.path.expanduser("~/.ssh/" + key_filename)
    os.makedirs(os.path.expanduser("~/.ssh"), exist_ok=True)
    os.rename(keypath, key_path)

    with open(os.path.expanduser("~/.ssh/config"), 'a') as f:
        f.write("Host github.com"
                '  IdentityFile "%s"'
                "  LogLevel ERROR\n" % key_path)

    # start ssh-agent and add key to it
    # info from SSH agent has to be put into the environment
    agent_info = subprocess.check_output(['ssh-agent', '-s'])
    agent_info = agent_info.decode('utf-8')
    agent_info = agent_info.split()

    AUTH_SOCK = agent_info[0].split('=')[1][:-1]
    AGENT_PID = agent_info[3].split('=')[1][:-1]

    os.putenv('SSH_AUTH_SOCK', AUTH_SOCK)
    os.putenv('SSH_AGENT_PID', AGENT_PID)

    run(['ssh-add', os.path.expanduser('~/.ssh/' + key_filename)])

# XXX: Do this in a way that is streaming
def run_command_hiding_token(args, token):
    command = ' '.join(map(shlex.quote, args))
    command = command.replace(token.decode('utf-8'), '~'*len(token))
    print(command)
    p = subprocess.run(args, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
    out, err = p.stdout, p.stderr
    out = out.replace(token, b"~"*len(token))
    err = err.replace(token, b"~"*len(token))
    return (out, err, p.returncode)

def get_token():
    """
    Get the encrypted GitHub token in Travis.

    Make sure the contents this variable do not leak. The ``run()`` function
    will remove this from the output, so always use it.
    """
    token = os.environ.get("GH_TOKEN", None)
    if not token:
        raise RuntimeError("GH_TOKEN environment variable not set")
    token = token.encode('utf-8')
    return token

def run(args):
    """
    Run the command ``args``.

    Automatically hides the secret GitHub token from the output.
    """
    if "DOCTR_DEPLOY_ENCRYPTION_KEY" in os.environ:
        token = b''
    else:
        token = get_token()
    out, err, returncode = run_command_hiding_token(args, token)
    if out:
        print(out.decode('utf-8'))
    if err:
        print(err.decode('utf-8'), file=sys.stderr)
    if returncode != 0:
        sys.exit(returncode)

def get_current_repo():
    """
    Get the GitHub repo name for the current directory.

    Assumes that the repo is in the ``origin`` remote.
    """
    remote_url = subprocess.check_output(['git', 'config', '--get',
        'remote.origin.url']).decode('utf-8')

    # Travis uses the https clone url
    _, org, git_repo = remote_url.rsplit('.git', 1)[0].rsplit('/', 2)
    return (org + '/' + git_repo)

def setup_GitHub_push(deploy_repo, auth_type='deploy_key', full_key_path='github_deploy_key.enc', require_master=True, deploy_branch='gh-pages'):
    """
    Setup the remote to push to GitHub (to be run on Travis).

    ``auth_type`` should be either ``'deploy_key'`` or ``'token'``.

    For ``auth_type='token'``, this sets up the remote with the token and
    checks out the gh-pages branch. The token to push to GitHub is assumed to be in the ``GH_TOKEN`` environment
    variable.

    For ``auth_type='deploy_key'``, this sets up the remote with ssh access.
    """
    if auth_type not in ['deploy_key', 'token']:
        raise ValueError("auth_type must be 'deploy_key' or 'token'")

    TRAVIS_BRANCH = os.environ.get("TRAVIS_BRANCH", "")
    TRAVIS_PULL_REQUEST = os.environ.get("TRAVIS_PULL_REQUEST", "")

    if TRAVIS_BRANCH != "master" and require_master:
        print("The docs are only pushed to {} from master. To allow pushing from "
        "a non-master branch, use the --no-require-master flag".format(deploy_branch), file=sys.stderr)
        print("This is the {TRAVIS_BRANCH} branch".format(TRAVIS_BRANCH=TRAVIS_BRANCH), file=sys.stderr)
        return False

    if TRAVIS_PULL_REQUEST != "false":
        print("The website and docs are not pushed to {} on pull requests".format(deploy_branch),
              file=sys.stderr)
        return False

    print("Setting git attributes")
    # Should we add some user.email?
    run(['git', 'config', '--global', 'user.name', "Doctr (Travis CI)"])

    remotes = subprocess.check_output(['git', 'remote']).decode('utf-8').split('\n')
    if 'doctr_remote' in remotes:
        print("doctr_remote already exists, removing")
        run(['git', 'remote', 'remove', 'doctr_remote'])
    print("Adding doctr remote")
    if auth_type == 'token':
        token = get_token()
        run(['git', 'remote', 'add', 'doctr_remote',
            'https://{token}@github.com/{deploy_repo}.git'.format(token=token.decode('utf-8'),
                deploy_repo=deploy_repo)])
    else:
        keypath, key_ext = full_key_path.rsplit('.', 1)
        key_ext = '.' + key_ext
        setup_deploy_key(keypath=keypath, key_ext=key_ext)
        run(['git', 'remote', 'add', 'doctr_remote',
            'git@github.com:{deploy_repo}.git'.format(deploy_repo=deploy_repo)])

    print("Fetching doctr remote")
    run(['git', 'fetch', 'doctr_remote'])

    #create empty branch with .nojekyll if it doesn't already exist
    new_deploy_branch = create_deploy_branch(deploy_branch)
    print("Checking out {}".format(deploy_branch))
    local_deploy_branch_exists = deploy_branch in subprocess.check_output(['git', 'branch']).decode('utf-8').split()
    if new_deploy_branch or local_deploy_branch_exists:
        run(['git', 'checkout', deploy_branch])
    else:
        run(['git', 'checkout', '-b', deploy_branch, '--track',
             'doctr_remote/{}'.format(deploy_branch)])
    print("Done")

    return True

def deploy_branch_exists(deploy_branch='gh-pages'):
    """Check if the remote deploy branch exists

    This isn't completely robust. If there are multiple remotes and the branch
    is created on the non-default remote, this won't see it.
    """
    remote_name = 'doctr_remote'
    branch_names = subprocess.check_output(['git', 'branch', '-r']).decode('utf-8').split()

    return '{remote}/{branch}'.format(remote=remote_name,
                                      branch=deploy_branch) in branch_names

def create_deploy_branch(deploy_branch):
    """
    If there is no remote deploy branch, create one.
    Return True if branch was created, False if not.
    Default value for deploy_branch is ``gh-pages``
    """
    if not deploy_branch_exists(deploy_branch):
        print("Creating {} branch".format(deploy_branch))
        run(['git', 'checkout', '--orphan', deploy_branch])
        # delete everything in the new ref.  this is non-destructive to existing
        # refs/branches, etc...
        run(['git', 'rm', '-rf', '.'])
        print("Adding .nojekyll file to {}".format(deploy_branch))
        run(['touch', '.nojekyll'])
        run(['git', 'add', '.nojekyll'])
        run(['git', 'commit', '-m', 'Create new branch {} with .nojekyll'.format(deploy_branch)])
        print("Pushing branch {} to remote".format(deploy_branch))
        run(['git', 'push', '-u', 'doctr_remote', deploy_branch])
        # return to master branch
        run(['git', 'checkout', '-'])

        return True
    return False

def find_sphinx_build_dir():
    """
    Find build subfolder within sphinx docs directory.

    This is called by :func:`commit_docs` if keyword arg ``built_docs`` is not
    specified on the command line.
    """
    build = glob.glob('**/*build/html', recursive=True)
    if not build:
        raise RuntimeError("Could not find Sphinx build directory automatically")
    build_folder = build[0]

    return build_folder

# Here is the logic to get the Travis job number, to only run commit_docs in
# the right build.
#
# TRAVIS_JOB_NUMBER = os.environ.get("TRAVIS_JOB_NUMBER", '')
# ACTUAL_TRAVIS_JOB_NUMBER = TRAVIS_JOB_NUMBER.split('.')[1]

def sync_from_log(src, dst, log_file):
    """
    Sync the files in ``src`` to ``dst``.

    The files that are synced are logged to ``log_file``. If ``log_file``
    exists, the files in ``log_file`` are removed first.

    Returns ``(added, removed)``, where added is a list of all files synced from
    ``src`` (even if it already existed in ``dst``), and ``removed`` is every
    file from ``log_file`` that was removed from ``dst`` because it wasn't in
    ``src``. ``added`` also includes the log file.
    """
    from os.path import join, exists, isdir
    if not src.endswith(os.sep):
        src += os.sep

    added, removed = [], []

    if not exists(log_file):
        # Assume this is the first run
        print("%s doesn't exist. Not removing any files." % log_file)
    else:
        with open(log_file) as f:
            files = f.read().strip().split('\n')

        for new_f in files:
            new_f = new_f.strip()
            if exists(new_f):
                os.remove(new_f)
                removed.append(new_f)
            else:
                print("Warning: File %s doesn't exist." % new_f, file=sys.stderr)

    files = glob.iglob(join(src, '**'), recursive=True)
    # sorted makes this easier to test
    for f in sorted(files):
        new_f = join(dst, f[len(src):])
        if isdir(f):
            os.makedirs(new_f, exist_ok=True)
        else:
            shutil.copy2(f, new_f)
            added.append(new_f)
            if new_f in removed:
                removed.remove(new_f)

    with open(log_file, 'w') as f:
        f.write('\n'.join(added))

    added.append(log_file)

    return added, removed

def commit_docs(*, added, removed):
    """
    Commit the docs to ``gh-pages`` or a specified deploy branch.

    Assumes that :func:`setup_GitHub_push`, which sets up the ``doctr_remote``
    remote, has been run and returned True.

    Returns True if changes were committed and False if no changes were
    committed.
    """
    TRAVIS_BUILD_NUMBER = os.environ.get("TRAVIS_BUILD_NUMBER", "<unknown>")

    for f in added:
        run(['git', 'add', f])
    for f in removed:
        run(['git', 'rm', f])

    # Only commit if there were changes
    if subprocess.run(['git', 'diff-index', '--quiet', 'HEAD', '--'],
        stdout=subprocess.PIPE, stderr=subprocess.PIPE).returncode != 0:
        print("Committing")
        run(['git', 'commit', '-am', "Update docs after building Travis build " + TRAVIS_BUILD_NUMBER])
        return True

    return False

def push_docs(deploy_branch='gh-pages'):
    """
    Push the changes to the ``gh-pages`` branch or specified deploy branch.

    Assumes that :func:`setup_GitHub_push` has been run and returned True, and
    that :func:`commit_docs` has been run. Does not push anything if no changes
    were made.

    """

    print("Pulling")
    run(["git", "pull"])
    print("Pushing commit")
    run(['git', 'push', '-q', 'doctr_remote', deploy_branch])
<|endoftext|>


<commit_before>"""
The code that should be run on Travis
"""

import os
import shlex
import shutil
import subprocess
import sys
import glob

from cryptography.fernet import Fernet

def decrypt_file(file, key):
    """
    Decrypts the file ``file``.

    The encrypted file is assumed to end with the ``.enc`` extension. The
    decrypted file is saved to the same location without the ``.enc``
    extension.

    The permissions on the decrypted file are automatically set to 0o600.

    See also :func:`doctr.local.encrypt_file`.

    """
    if not file.endswith('.enc'):
        raise ValueError("%s does not end with .enc" % file)

    fer = Fernet(key)

    with open(file, 'rb') as f:
        decrypted_file = fer.decrypt(f.read())

    with open(file[:-4], 'wb') as f:
        f.write(decrypted_file)

    os.chmod(file[:-4], 0o600)

def setup_deploy_key(keypath='github_deploy_key', key_ext='.enc'):
    """
    Decrypts the deploy key and configures it with ssh

    The key is assumed to be encrypted as keypath + key_ext, and the
    encryption key is assumed to be set in the environment variable
    DOCTR_DEPLOY_ENCRYPTION_KEY.

    """
    key = os.environ.get("DOCTR_DEPLOY_ENCRYPTION_KEY", None)
    if not key:
        raise RuntimeError("DOCTR_DEPLOY_ENCRYPTION_KEY environment variable is not set")

    key_filename = os.path.basename(keypath)
    key = key.encode('utf-8')
    decrypt_file(keypath + key_ext, key)

    key_path = os.path.expanduser("~/.ssh/" + key_filename)
    os.makedirs(os.path.expanduser("~/.ssh"), exist_ok=True)
    os.rename(keypath, key_path)

    with open(os.path.expanduser("~/.ssh/config"), 'a') as f:
        f.write("Host github.com"
                '  IdentityFile "%s"'
                "  LogLevel ERROR\n" % key_path)

    # start ssh-agent and add key to it
    # info from SSH agent has to be put into the environment
    agent_info = subprocess.check_output(['ssh-agent', '-s'])
    agent_info = agent_info.decode('utf-8')
    agent_info = agent_info.split()

    AUTH_SOCK = agent_info[0].split('=')[1][:-1]
    AGENT_PID = agent_info[3].split('=')[1][:-1]

    os.putenv('SSH_AUTH_SOCK', AUTH_SOCK)
    os.putenv('SSH_AGENT_PID', AGENT_PID)

    run(['ssh-add', os.path.expanduser('~/.ssh/' + key_filename)])

# XXX: Do this in a way that is streaming
def run_command_hiding_token(args, token):
    command = ' '.join(map(shlex.quote, args))
    command = command.replace(token.decode('utf-8'), '~'*len(token))
    print(command)
    p = subprocess.run(args, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
    out, err = p.stdout, p.stderr
    out = out.replace(token, b"~"*len(token))
    err = err.replace(token, b"~"*len(token))
    return (out, err, p.returncode)

def get_token():
    """
    Get the encrypted GitHub token in Travis.

    Make sure the contents this variable do not leak. The ``run()`` function
    will remove this from the output, so always use it.
    """
    token = os.environ.get("GH_TOKEN", None)
    if not token:
        raise RuntimeError("GH_TOKEN environment variable not set")
    token = token.encode('utf-8')
    return token

def run(args):
    """
    Run the command ``args``.

    Automatically hides the secret GitHub token from the output.
    """
    if "DOCTR_DEPLOY_ENCRYPTION_KEY" in os.environ:
        token = b''
    else:
        token = get_token()
    out, err, returncode = run_command_hiding_token(args, token)
    if out:
        print(out.decode('utf-8'))
    if err:
        print(err.decode('utf-8'), file=sys.stderr)
    if returncode != 0:
        sys.exit(returncode)

def get_current_repo():
    """
    Get the GitHub repo name for the current directory.

    Assumes that the repo is in the ``origin`` remote.
    """
    remote_url = subprocess.check_output(['git', 'config', '--get',
        'remote.origin.url']).decode('utf-8')

    # Travis uses the https clone url
    _, org, git_repo = remote_url.rsplit('.git', 1)[0].rsplit('/', 2)
    return (org + '/' + git_repo)

def setup_GitHub_push(deploy_repo, auth_type='deploy_key', full_key_path='github_deploy_key.enc', require_master=True, deploy_branch='gh-pages'):
    """
    Setup the remote to push to GitHub (to be run on Travis).

    ``auth_type`` should be either ``'deploy_key'`` or ``'token'``.

    For ``auth_type='token'``, this sets up the remote with the token and
    checks out the gh-pages branch. The token to push to GitHub is assumed to be in the ``GH_TOKEN`` environment
    variable.

    For ``auth_type='deploy_key'``, this sets up the remote with ssh access.
    """
    if auth_type not in ['deploy_key', 'token']:
        raise ValueError("auth_type must be 'deploy_key' or 'token'")

    TRAVIS_BRANCH = os.environ.get("TRAVIS_BRANCH", "")
    TRAVIS_PULL_REQUEST = os.environ.get("TRAVIS_PULL_REQUEST", "")

    if TRAVIS_BRANCH != "master" and require_master:
        print("The docs are only pushed to {} from master. To allow pushing from "
        "a non-master branch, use the --no-require-master flag".format(deploy_branch), file=sys.stderr)
        print("This is the {TRAVIS_BRANCH} branch".format(TRAVIS_BRANCH=TRAVIS_BRANCH), file=sys.stderr)
        return False

    if TRAVIS_PULL_REQUEST != "false":
        print("The website and docs are not pushed to {} on pull requests".format(deploy_branch),
              file=sys.stderr)
        return False

    print("Setting git attributes")
    # Should we add some user.email?
    run(['git', 'config', '--global', 'user.name', "Doctr (Travis CI)"])

    remotes = subprocess.check_output(['git', 'remote']).decode('utf-8').split('\n')
    if 'doctr_remote' in remotes:
        print("doctr_remote already exists, removing")
        run(['git', 'remote', 'remove', 'doctr_remote'])
    print("Adding doctr remote")
    if auth_type == 'token':
        token = get_token()
        run(['git', 'remote', 'add', 'doctr_remote',
            'https://{token}@github.com/{deploy_repo}.git'.format(token=token.decode('utf-8'),
                deploy_repo=deploy_repo)])
    else:
        keypath, key_ext = full_key_path.rsplit('.', 1)
        key_ext = '.' + key_ext
        setup_deploy_key(keypath=keypath, key_ext=key_ext)
        run(['git', 'remote', 'add', 'doctr_remote',
            'git@github.com:{deploy_repo}.git'.format(deploy_repo=deploy_repo)])

    print("Fetching doctr remote")
    run(['git', 'fetch', 'doctr_remote'])

    #create empty branch with .nojekyll if it doesn't already exist
    new_deploy_branch = create_deploy_branch(deploy_branch)
    print("Checking out {}".format(deploy_branch))
    local_deploy_branch_exists = deploy_branch in subprocess.check_output(['git', 'branch']).decode('utf-8').split()
    if new_deploy_branch or local_deploy_branch_exists:
        run(['git', 'checkout', deploy_branch])
    else:
        run(['git', 'checkout', '-b', deploy_branch, '--track',
             'doctr_remote/{}'.format(deploy_branch)])
    print("Done")

    return True

def deploy_branch_exists(deploy_branch='gh-pages'):
    """Check if the remote deploy branch exists

    This isn't completely robust. If there are multiple remotes and the branch
    is created on the non-default remote, this won't see it.
    """
    remote_name = 'doctr_remote'
    branch_names = subprocess.check_output(['git', 'branch', '-r']).decode('utf-8').split()

    return '{remote}/{branch}'.format(remote=remote_name,
                                      branch=deploy_branch) in branch_names

def create_deploy_branch(deploy_branch):
    """
    If there is no remote deploy branch, create one.
    Return True if branch was created, False if not.
    Default value for deploy_branch is ``gh-pages``
    """
    if not deploy_branch_exists(deploy_branch):
        print("Creating {} branch".format(deploy_branch))
        run(['git', 'checkout', '--orphan', deploy_branch])
        # delete everything in the new ref.  this is non-destructive to existing
        # refs/branches, etc...
        run(['git', 'rm', '-rf', '.'])
        print("Adding .nojekyll file to {}".format(deploy_branch))
        run(['touch', '.nojekyll'])
        run(['git', 'add', '.nojekyll'])
        run(['git', 'commit', '-m', 'Create new branch {} with .nojekyll'.format(deploy_branch)])
        print("Pushing branch {} to remote".format(deploy_branch))
        run(['git', 'push', '-u', 'doctr_remote', deploy_branch])
        # return to master branch
        run(['git', 'checkout', '-'])

        return True
    return False

def find_sphinx_build_dir():
    """
    Find build subfolder within sphinx docs directory.

    This is called by :func:`commit_docs` if keyword arg ``built_docs`` is not
    specified on the command line.
    """
    build = glob.glob('**/*build/html', recursive=True)
    if not build:
        raise RuntimeError("Could not find Sphinx build directory automatically")
    build_folder = build[0]

    return build_folder

# Here is the logic to get the Travis job number, to only run commit_docs in
# the right build.
#
# TRAVIS_JOB_NUMBER = os.environ.get("TRAVIS_JOB_NUMBER", '')
# ACTUAL_TRAVIS_JOB_NUMBER = TRAVIS_JOB_NUMBER.split('.')[1]

def sync_from_log(src, dst, log_file):
    """
    Sync the files in ``src`` to ``dst``.

    The files that are synced are logged to ``log_file``. If ``log_file``
    exists, the files in ``log_file`` are removed first.

    Returns ``(added, removed)``, where added is a list of all files synced from
    ``src`` (even if it already existed in ``dst``), and ``removed`` is every
    file from ``log_file`` that was removed from ``dst`` because it wasn't in
    ``src``. ``added`` also includes the log file.
    """
    from os.path import join, exists, isdir
    if not src.endswith(os.sep):
        src += os.sep

    added, removed = [], []

    if not exists(log_file):
        # Assume this is the first run
        print("%s doesn't exist. Not removing any files." % log_file)
    else:
        with open(log_file) as f:
            files = f.read().strip().split('\n')

        for new_f in files:
            new_f = new_f.strip()
            if exists(new_f):
                os.remove(new_f)
                removed.append(new_f)
            else:
                print("Warning: File %s doesn't exist." % new_f, file=sys.stderr)

    files = glob.iglob(join(src, '**'), recursive=True)
    # sorted makes this easier to test
    for f in sorted(files):
        new_f = join(dst, f[len(src):])
        if isdir(f):
            os.makedirs(new_f, exist_ok=True)
        else:
            shutil.copy2(f, new_f)
            added.append(new_f)
            if new_f in removed:
                removed.remove(new_f)

    with open(log_file, 'w') as f:
        f.write('\n'.join(added))

    added.append(log_file)

    return added, removed

def commit_docs(*, added, removed):
    """
    Commit the docs to ``gh-pages`` or a specified deploy branch.

    Assumes that :func:`setup_GitHub_push`, which sets up the ``doctr_remote``
    remote, has been run and returned True.

    Returns True if changes were committed and False if no changes were
    committed.
    """
    TRAVIS_BUILD_NUMBER = os.environ.get("TRAVIS_BUILD_NUMBER", "<unknown>")

    for f in added:
        run(['git', 'add', f])
    for f in removed:
        run(['git', 'rm', f])

    # Only commit if there were changes
    if subprocess.run(['git', 'diff-index', '--quiet', 'HEAD', '--'],
        stdout=subprocess.PIPE, stderr=subprocess.PIPE).returncode != 0:
        print("Committing")
        run(['git', 'commit', '-am', "Update docs after building Travis build " + TRAVIS_BUILD_NUMBER])
        return True

    return False

def push_docs(deploy_branch='gh-pages'):
    """
    Push the changes to the ``gh-pages`` branch or specified deploy branch.

    Assumes that :func:`setup_GitHub_push` has been run and returned True, and
    that :func:`commit_docs` has been run. Does not push anything if no changes
    were made.

    """

    print("Pulling")
    run(["git", "pull"])
    print("Pushing commit")
    run(['git', 'push', '-q', 'doctr_remote', deploy_branch])
<commit_msg>debug<commit_after>"""
The code that should be run on Travis
"""

import os
import shlex
import shutil
import subprocess
import sys
import glob

from cryptography.fernet import Fernet

def decrypt_file(file, key):
    """
    Decrypts the file ``file``.

    The encrypted file is assumed to end with the ``.enc`` extension. The
    decrypted file is saved to the same location without the ``.enc``
    extension.

    The permissions on the decrypted file are automatically set to 0o600.

    See also :func:`doctr.local.encrypt_file`.

    """
    if not file.endswith('.enc'):
        raise ValueError("%s does not end with .enc" % file)

    fer = Fernet(key)

    with open(file, 'rb') as f:
        decrypted_file = fer.decrypt(f.read())

    with open(file[:-4], 'wb') as f:
        f.write(decrypted_file)

    os.chmod(file[:-4], 0o600)

def setup_deploy_key(keypath='github_deploy_key', key_ext='.enc'):
    """
    Decrypts the deploy key and configures it with ssh

    The key is assumed to be encrypted as keypath + key_ext, and the
    encryption key is assumed to be set in the environment variable
    DOCTR_DEPLOY_ENCRYPTION_KEY.

    """
    key = os.environ.get("DOCTR_DEPLOY_ENCRYPTION_KEY", None)
    if not key:
        raise RuntimeError("DOCTR_DEPLOY_ENCRYPTION_KEY environment variable is not set")

    key_filename = os.path.basename(keypath)
    key = key.encode('utf-8')
    decrypt_file(keypath + key_ext, key)

    key_path = os.path.expanduser("~/.ssh/" + key_filename)
    os.makedirs(os.path.expanduser("~/.ssh"), exist_ok=True)
    os.rename(keypath, key_path)

    with open(os.path.expanduser("~/.ssh/config"), 'a') as f:
        f.write("Host github.com"
                '  IdentityFile "%s"'
                "  LogLevel ERROR\n" % key_path)

    # start ssh-agent and add key to it
    # info from SSH agent has to be put into the environment
    agent_info = subprocess.check_output(['ssh-agent', '-s'])
    agent_info = agent_info.decode('utf-8')
    agent_info = agent_info.split()

    AUTH_SOCK = agent_info[0].split('=')[1][:-1]
    AGENT_PID = agent_info[3].split('=')[1][:-1]

    os.putenv('SSH_AUTH_SOCK', AUTH_SOCK)
    os.putenv('SSH_AGENT_PID', AGENT_PID)

    run(['ssh-add', os.path.expanduser('~/.ssh/' + key_filename)])

# XXX: Do this in a way that is streaming
def run_command_hiding_token(args, token):
    command = ' '.join(map(shlex.quote, args))
    command = command.replace(token.decode('utf-8'), '~'*len(token))
    print(command)
    p = subprocess.run(args, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
    out, err = p.stdout, p.stderr
    out = out.replace(token, b"~"*len(token))
    err = err.replace(token, b"~"*len(token))
    return (out, err, p.returncode)

def get_token():
    """
    Get the encrypted GitHub token in Travis.

    Make sure the contents this variable do not leak. The ``run()`` function
    will remove this from the output, so always use it.
    """
    token = os.environ.get("GH_TOKEN", None)
    if not token:
        raise RuntimeError("GH_TOKEN environment variable not set")
    token = token.encode('utf-8')
    return token

def run(args):
    """
    Run the command ``args``.

    Automatically hides the secret GitHub token from the output.
    """
    if "DOCTR_DEPLOY_ENCRYPTION_KEY" in os.environ:
        token = b''
    else:
        token = get_token()
    out, err, returncode = run_command_hiding_token(args, token)
    if out:
        print(out.decode('utf-8'))
    if err:
        print(err.decode('utf-8'), file=sys.stderr)
    if returncode != 0:
        sys.exit(returncode)

def get_current_repo():
    """
    Get the GitHub repo name for the current directory.

    Assumes that the repo is in the ``origin`` remote.
    """
    remote_url = subprocess.check_output(['git', 'config', '--get',
        'remote.origin.url']).decode('utf-8')

    # Travis uses the https clone url
    _, org, git_repo = remote_url.rsplit('.git', 1)[0].rsplit('/', 2)
    return (org + '/' + git_repo)

def setup_GitHub_push(deploy_repo, auth_type='deploy_key', full_key_path='github_deploy_key.enc', require_master=True, deploy_branch='gh-pages'):
    """
    Setup the remote to push to GitHub (to be run on Travis).

    ``auth_type`` should be either ``'deploy_key'`` or ``'token'``.

    For ``auth_type='token'``, this sets up the remote with the token and
    checks out the gh-pages branch. The token to push to GitHub is assumed to be in the ``GH_TOKEN`` environment
    variable.

    For ``auth_type='deploy_key'``, this sets up the remote with ssh access.
    """
    if auth_type not in ['deploy_key', 'token']:
        raise ValueError("auth_type must be 'deploy_key' or 'token'")

    TRAVIS_BRANCH = os.environ.get("TRAVIS_BRANCH", "")
    TRAVIS_PULL_REQUEST = os.environ.get("TRAVIS_PULL_REQUEST", "")

    if TRAVIS_BRANCH != "master" and require_master:
        print("The docs are only pushed to {} from master. To allow pushing from "
        "a non-master branch, use the --no-require-master flag".format(deploy_branch), file=sys.stderr)
        print("This is the {TRAVIS_BRANCH} branch".format(TRAVIS_BRANCH=TRAVIS_BRANCH), file=sys.stderr)
        return False

    if TRAVIS_PULL_REQUEST != "false":
        print("The website and docs are not pushed to {} on pull requests".format(deploy_branch),
              file=sys.stderr)
        return False

    print("Setting git attributes")
    # Should we add some user.email?
    run(['git', 'config', '--global', 'user.name', "Doctr (Travis CI)"])

    remotes = subprocess.check_output(['git', 'remote']).decode('utf-8').split('\n')
    if 'doctr_remote' in remotes:
        print("doctr_remote already exists, removing")
        run(['git', 'remote', 'remove', 'doctr_remote'])
    print("Adding doctr remote")
    if auth_type == 'token':
        token = get_token()
        run(['git', 'remote', 'add', 'doctr_remote',
            'https://{token}@github.com/{deploy_repo}.git'.format(token=token.decode('utf-8'),
                deploy_repo=deploy_repo)])
    else:
        keypath, key_ext = full_key_path.rsplit('.', 1)
        key_ext = '.' + key_ext
        setup_deploy_key(keypath=keypath, key_ext=key_ext)
        run(['git', 'remote', 'add', 'doctr_remote',
            'git@github.com:{deploy_repo}.git'.format(deploy_repo=deploy_repo)])

    print("Fetching doctr remote")
    run(['git', 'fetch', 'doctr_remote'])

    #create empty branch with .nojekyll if it doesn't already exist
    new_deploy_branch = create_deploy_branch(deploy_branch)
    print("Checking out {}".format(deploy_branch))
    local_deploy_branch_exists = deploy_branch in subprocess.check_output(['git', 'branch']).decode('utf-8').split()
    if new_deploy_branch or local_deploy_branch_exists:
        run(['git', 'checkout', deploy_branch])
    else:
        run(['git', 'checkout', '-b', deploy_branch, '--track',
             'doctr_remote/{}'.format(deploy_branch)])
    print("Done")

    return True

def deploy_branch_exists(deploy_branch='gh-pages'):
    """Check if the remote deploy branch exists

    This isn't completely robust. If there are multiple remotes and the branch
    is created on the non-default remote, this won't see it.
    """
    remote_name = 'doctr_remote'
    branch_names = subprocess.check_output(['git', 'branch', '-r']).decode('utf-8').split()
    print(branch_names)

    return '{remote}/{branch}'.format(remote=remote_name,
                                      branch=deploy_branch) in branch_names

def create_deploy_branch(deploy_branch):
    """
    If there is no remote deploy branch, create one.
    Return True if branch was created, False if not.
    Default value for deploy_branch is ``gh-pages``
    """
    if not deploy_branch_exists(deploy_branch):
        print("Creating {} branch".format(deploy_branch))
        run(['git', 'checkout', '--orphan', deploy_branch])
        # delete everything in the new ref.  this is non-destructive to existing
        # refs/branches, etc...
        run(['git', 'rm', '-rf', '.'])
        print("Adding .nojekyll file to {}".format(deploy_branch))
        run(['touch', '.nojekyll'])
        run(['git', 'add', '.nojekyll'])
        run(['git', 'commit', '-m', 'Create new branch {} with .nojekyll'.format(deploy_branch)])
        print("Pushing branch {} to remote".format(deploy_branch))
        run(['git', 'push', '-u', 'doctr_remote', deploy_branch])
        # return to master branch
        run(['git', 'checkout', '-'])

        return True
    return False

def find_sphinx_build_dir():
    """
    Find build subfolder within sphinx docs directory.

    This is called by :func:`commit_docs` if keyword arg ``built_docs`` is not
    specified on the command line.
    """
    build = glob.glob('**/*build/html', recursive=True)
    if not build:
        raise RuntimeError("Could not find Sphinx build directory automatically")
    build_folder = build[0]

    return build_folder

# Here is the logic to get the Travis job number, to only run commit_docs in
# the right build.
#
# TRAVIS_JOB_NUMBER = os.environ.get("TRAVIS_JOB_NUMBER", '')
# ACTUAL_TRAVIS_JOB_NUMBER = TRAVIS_JOB_NUMBER.split('.')[1]

def sync_from_log(src, dst, log_file):
    """
    Sync the files in ``src`` to ``dst``.

    The files that are synced are logged to ``log_file``. If ``log_file``
    exists, the files in ``log_file`` are removed first.

    Returns ``(added, removed)``, where added is a list of all files synced from
    ``src`` (even if it already existed in ``dst``), and ``removed`` is every
    file from ``log_file`` that was removed from ``dst`` because it wasn't in
    ``src``. ``added`` also includes the log file.
    """
    from os.path import join, exists, isdir
    if not src.endswith(os.sep):
        src += os.sep

    added, removed = [], []

    if not exists(log_file):
        # Assume this is the first run
        print("%s doesn't exist. Not removing any files." % log_file)
    else:
        with open(log_file) as f:
            files = f.read().strip().split('\n')

        for new_f in files:
            new_f = new_f.strip()
            if exists(new_f):
                os.remove(new_f)
                removed.append(new_f)
            else:
                print("Warning: File %s doesn't exist." % new_f, file=sys.stderr)

    files = glob.iglob(join(src, '**'), recursive=True)
    # sorted makes this easier to test
    for f in sorted(files):
        new_f = join(dst, f[len(src):])
        if isdir(f):
            os.makedirs(new_f, exist_ok=True)
        else:
            shutil.copy2(f, new_f)
            added.append(new_f)
            if new_f in removed:
                removed.remove(new_f)

    with open(log_file, 'w') as f:
        f.write('\n'.join(added))

    added.append(log_file)

    return added, removed

def commit_docs(*, added, removed):
    """
    Commit the docs to ``gh-pages`` or a specified deploy branch.

    Assumes that :func:`setup_GitHub_push`, which sets up the ``doctr_remote``
    remote, has been run and returned True.

    Returns True if changes were committed and False if no changes were
    committed.
    """
    TRAVIS_BUILD_NUMBER = os.environ.get("TRAVIS_BUILD_NUMBER", "<unknown>")

    for f in added:
        run(['git', 'add', f])
    for f in removed:
        run(['git', 'rm', f])

    # Only commit if there were changes
    if subprocess.run(['git', 'diff-index', '--quiet', 'HEAD', '--'],
        stdout=subprocess.PIPE, stderr=subprocess.PIPE).returncode != 0:
        print("Committing")
        run(['git', 'commit', '-am', "Update docs after building Travis build " + TRAVIS_BUILD_NUMBER])
        return True

    return False

def push_docs(deploy_branch='gh-pages'):
    """
    Push the changes to the ``gh-pages`` branch or specified deploy branch.

    Assumes that :func:`setup_GitHub_push` has been run and returned True, and
    that :func:`commit_docs` has been run. Does not push anything if no changes
    were made.

    """

    print("Pulling")
    run(["git", "pull"])
    print("Pushing commit")
    run(['git', 'push', '-q', 'doctr_remote', deploy_branch])
<|endoftext|>


<commit_before>"""
Django settings for dpb project.

For more information on this file, see
https://docs.djangoproject.com/en/1.7/topics/settings/

For the full list of settings and their values, see
https://docs.djangoproject.com/en/1.7/ref/settings/
"""

# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
import os
BASE_DIR = os.path.dirname(os.path.dirname(__file__))

# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/1.7/howto/deployment/checklist/

# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = 'fy5#xmxaf&@-30c_nm)0te&@=-g9y+45i6r03+%2(1q@vfztr_'

# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True

TEMPLATE_DEBUG = True

ALLOWED_HOSTS = ['christian-meter.de', 'localhost', 'deutscher-pfadfinderbund.de']

SITE_ID = 1

# Application definition

INSTALLED_APPS = (
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'django.contrib.sites',
    #'django.contrib.pages',

    # 3rd party
    'pipeline',
    'filer',
    'mptt',
    'easy_thumbnails',
    'tinymce',

    # Own apps
    'polls',
    'pages',
    'login',
    'archive',
)

MIDDLEWARE_CLASSES = (
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.auth.middleware.SessionAuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
    'pipeline.middleware.MinifyHTMLMiddleware',
)

ROOT_URLCONF = 'dpb.urls'

WSGI_APPLICATION = 'dpb.wsgi.application'

# Database
# https://docs.djangoproject.com/en/1.7/ref/settings/#databases

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
    }
}

# Internationalization
# https://docs.djangoproject.com/en/1.7/topics/i18n/

LANGUAGE_CODE = 'de-de'

TIME_ZONE = 'Europe/Berlin'

USE_I18N = True

USE_L10N = True

USE_TZ = True

# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/1.7/howto/static-files/

STATIC_URL = '/static/'

# STATIC_ROOT = os.path.join(BASE_DIR, 'static')
# STATIC_ROOT = "/var/www/dpbstatic/"
STATIC_ROOT = "static/"

# Define Paths for Pipeline
STATICFILES_STORAGE = 'pipeline.storage.PipelineCachedStorage'

STATICFILES_FINDERS = (
    'django.contrib.staticfiles.finders.FileSystemFinder',
    'django.contrib.staticfiles.finders.AppDirectoriesFinder',
    'pipeline.finders.PipelineFinder',
)

STATICFILES_DIRS = (
#    os.path.join(BASE_DIR, 'media'),
    os.path.join(BASE_DIR, 'templates/dpb'),
)

MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
MEDIA_URL = '/media/'

### Pipeline ###

# Set Pipeline Compilers
PIPELINE_COMPILERS = (
  'pipeline.compilers.sass.SASSCompiler',
)

PIPELINE_CSS_COMPRESSOR = 'pipeline.compressors.yuglify.YuglifyCompressor'

PIPELINE_JS_COMPRESSOR = 'pipeline.compressors.yuglify.YuglifyCompressor'

#PIPELINE_ENABLED = True

PIPELINE_CSS = {
  'master': {
    'source_filenames': (
      'css/*.sass',
    ),
    'output_filename': 'compressed/master.css',
    'extra_context': {
      'media': 'screen, projection',
    },
  },
  'vendor': {
    'source_filenames': (
      'assets/bootstrap/css/bootstrap.min.css',
      'assets/bootstrap/css/bootstrap-theme.min.css',
      'assets/bootswatch/bootswatch.min.css',
      #'assets/fontawesome/css/font-awesome.min.css',

    ),
    'output_filename': 'compressed/vendor.css'
  }
}

PIPELINE_JS = {
  'master': {
    'source_filenames': (
      'js/*.js',
    ),
    'output_filename': 'compressed/master.js'
  },
  'vendor': {
    'source_filenames': (
      'assets/jquery/jquery.min.js',
      'assets/bootstrap/js/bootstrap.min.js',
    ),
    'output_filename': 'compressed/vendor.js'
  }
}

### END Pipeline ###

# Configure TinyMCE
# Find the TinyMCE configuration in /templates/admin/base_site.html

TINYMCE_JS_URL = STATIC_URL + 'assets/tinymce/tinymce.min.js'
TINYMCE_DEFAULT_CONFIG = {
    'plugins': "code,directionality,paste,searchreplace,bootstrap",
    'theme': "modern",
    'cleanup_on_startup': True,
    'custom_undo_redo_levels': 10,
    'language': "de",
    'directionality': "de",
    'spellchecker_languages': "de",
    'spellchecker_rpc_url': STATIC_URL + 'assets/tinymce/langs/de.js',
    'bootstrapConfig': {
        'imagesPath': MEDIA_URL + 'img/filer_public',
    },
    'toolbar': "bootstrap",
    'fullpage_default_encoding': "UTF-8",
    'entity_encoding': "raw",
}
TINYMCE_SPELLCHECKER = False
TINYMCE_COMPRESSOR = False

# Configure Templates
TEMPLATES = [{
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [os.path.join(BASE_DIR, 'templates')],
        'APP_DIRS': True,
        'OPTIONS': {
            'context_processors': [
                'django.template.context_processors.debug',
                'django.template.context_processors.request',
                'django.contrib.auth.context_processors.auth',
                'django.contrib.messages.context_processors.messages',
                'django.core.context_processors.media',
                'django.core.context_processors.static',
            ],
        },
    },
]

# Needed for login
import django.contrib.auth
django.contrib.auth.LOGIN_URL = '/'
<commit_msg>Update language code<commit_after>"""
Django settings for dpb project.

For more information on this file, see
https://docs.djangoproject.com/en/1.7/topics/settings/

For the full list of settings and their values, see
https://docs.djangoproject.com/en/1.7/ref/settings/
"""

# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
import os
BASE_DIR = os.path.dirname(os.path.dirname(__file__))

# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/1.7/howto/deployment/checklist/

# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = 'fy5#xmxaf&@-30c_nm)0te&@=-g9y+45i6r03+%2(1q@vfztr_'

# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True

TEMPLATE_DEBUG = True

ALLOWED_HOSTS = ['christian-meter.de', 'localhost', 'deutscher-pfadfinderbund.de']

SITE_ID = 1

# Application definition

INSTALLED_APPS = (
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'django.contrib.sites',
    #'django.contrib.pages',

    # 3rd party
    'pipeline',
    'filer',
    'mptt',
    'easy_thumbnails',
    'tinymce',

    # Own apps
    'polls',
    'pages',
    'login',
    'archive',
)

MIDDLEWARE_CLASSES = (
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.auth.middleware.SessionAuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
    'pipeline.middleware.MinifyHTMLMiddleware',
)

ROOT_URLCONF = 'dpb.urls'

WSGI_APPLICATION = 'dpb.wsgi.application'

# Database
# https://docs.djangoproject.com/en/1.7/ref/settings/#databases

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
    }
}

# Internationalization
# https://docs.djangoproject.com/en/1.7/topics/i18n/

LANGUAGE_CODE = 'de'

TIME_ZONE = 'Europe/Berlin'

USE_I18N = True

USE_L10N = True

USE_TZ = True

# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/1.7/howto/static-files/

STATIC_URL = '/static/'

# STATIC_ROOT = os.path.join(BASE_DIR, 'static')
# STATIC_ROOT = "/var/www/dpbstatic/"
STATIC_ROOT = "static/"

# Define Paths for Pipeline
STATICFILES_STORAGE = 'pipeline.storage.PipelineCachedStorage'

STATICFILES_FINDERS = (
    'django.contrib.staticfiles.finders.FileSystemFinder',
    'django.contrib.staticfiles.finders.AppDirectoriesFinder',
    'pipeline.finders.PipelineFinder',
)

STATICFILES_DIRS = (
#    os.path.join(BASE_DIR, 'media'),
    os.path.join(BASE_DIR, 'templates/dpb'),
)

MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
MEDIA_URL = '/media/'

### Pipeline ###

# Set Pipeline Compilers
PIPELINE_COMPILERS = (
  'pipeline.compilers.sass.SASSCompiler',
)

PIPELINE_CSS_COMPRESSOR = 'pipeline.compressors.yuglify.YuglifyCompressor'

PIPELINE_JS_COMPRESSOR = 'pipeline.compressors.yuglify.YuglifyCompressor'

#PIPELINE_ENABLED = True

PIPELINE_CSS = {
  'master': {
    'source_filenames': (
      'css/*.sass',
    ),
    'output_filename': 'compressed/master.css',
    'extra_context': {
      'media': 'screen, projection',
    },
  },
  'vendor': {
    'source_filenames': (
      'assets/bootstrap/css/bootstrap.min.css',
      'assets/bootstrap/css/bootstrap-theme.min.css',
      'assets/bootswatch/bootswatch.min.css',
      #'assets/fontawesome/css/font-awesome.min.css',

    ),
    'output_filename': 'compressed/vendor.css'
  }
}

PIPELINE_JS = {
  'master': {
    'source_filenames': (
      'js/*.js',
    ),
    'output_filename': 'compressed/master.js'
  },
  'vendor': {
    'source_filenames': (
      'assets/jquery/jquery.min.js',
      'assets/bootstrap/js/bootstrap.min.js',
    ),
    'output_filename': 'compressed/vendor.js'
  }
}

### END Pipeline ###

# Configure TinyMCE
# Find the TinyMCE configuration in /templates/admin/base_site.html

TINYMCE_JS_URL = STATIC_URL + 'assets/tinymce/tinymce.min.js'
TINYMCE_DEFAULT_CONFIG = {
    'plugins': "code,directionality,paste,searchreplace,bootstrap",
    'theme': "modern",
    'cleanup_on_startup': True,
    'custom_undo_redo_levels': 10,
    'language': "de",
    'directionality': "de",
    'spellchecker_languages': "de",
    'spellchecker_rpc_url': STATIC_URL + 'assets/tinymce/langs/de.js',
    'bootstrapConfig': {
        'imagesPath': MEDIA_URL + 'img/filer_public',
    },
    'toolbar': "bootstrap",
    'fullpage_default_encoding': "UTF-8",
    'entity_encoding': "raw",
}
TINYMCE_SPELLCHECKER = False
TINYMCE_COMPRESSOR = False

# Configure Templates
TEMPLATES = [{
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [os.path.join(BASE_DIR, 'templates')],
        'APP_DIRS': True,
        'OPTIONS': {
            'context_processors': [
                'django.template.context_processors.debug',
                'django.template.context_processors.request',
                'django.contrib.auth.context_processors.auth',
                'django.contrib.messages.context_processors.messages',
                'django.core.context_processors.media',
                'django.core.context_processors.static',
            ],
        },
    },
]

# Needed for login
import django.contrib.auth
django.contrib.auth.LOGIN_URL = '/'
<|endoftext|>


<commit_before>from AppKit import *

import sys

# errors
class DrawBotError(TypeError): pass

# default tools

def getDefault(key, defaultValue=None):
    """
    Get a value from the user default for a key.
    """
    defaultsFromFile = NSUserDefaults.standardUserDefaults()
    return defaultsFromFile.get(key, defaultValue)

def setDefault(key, value):
    """
    Set a value to the user defaults for a given key.
    """
    defaultsFromFile = NSUserDefaults.standardUserDefaults()
    defaultsFromFile.setObject_forKey_(value, key)

def _getNSDefault(key, defaultValue=None):
    data = getDefault(key, defaultValue)
    if isinstance(data, NSData):
        return NSUnarchiver.unarchiveObjectWithData_(data)
    return data

def _setNSDefault(key, value):
    data = NSArchiver.archivedDataWithRootObject_(value)
    setDefault(key, data)

def getFontDefault(key, defaultValue=None):
    return _getNSDefault(key, defaultValue)

def setFontDefault(key, font):
    _setNSDefault(key, font)

def getColorDefault(key, defaultValue=None):
    return _getNSDefault(key, defaultValue)

def setColorDefault(key, color):
    _setNSDefault(key, color)

# color tools

def cmyk2rgb(c, m, y, k):
    """
    Convert cmyk color to rbg color.
    """
    r = 1.0 - min(1.0, c + k)
    g = 1.0 - min(1.0, m + k)
    b = 1.0 - min(1.0, y + k)
    return r, g, b

def rgb2cmyk(r, g, b):
    """
    Convert rgb color to cmyk color.
    """
    c = 1 - r
    m = 1 - g
    y = 1 - b
    k = min(c,m,y)
    c = min(1, max(0,c-k))
    m = min(1, max(0,m-k))
    y = min(1, max(0,y-k))
    k = min(1, max(0,k))
    return c, m, y, k

def stringToInt(code):
    import struct
    return struct.unpack('>l', code)[0]

class Warnings(object):

    def __init__(self):
        self._warnMessages = set()

    def resetWarnings(self):
        self._warnMessages = set()

    def warn(self, message):
        if message in self._warnMessages:
            return
        sys.stderr.write("*** DrawBot warning: %s ***\n" % message)
        self._warnMessages.add(message)

warnings = Warnings()
<commit_msg>remove lazy imports<commit_after>import AppKit

import sys

# errors
class DrawBotError(TypeError): pass

# default tools

def getDefault(key, defaultValue=None):
    """
    Get a value from the user default for a key.
    """
    defaultsFromFile = AppKit.NSUserDefaults.standardUserDefaults()
    return defaultsFromFile.get(key, defaultValue)

def setDefault(key, value):
    """
    Set a value to the user defaults for a given key.
    """
    defaultsFromFile = AppKit.NSUserDefaults.standardUserDefaults()
    defaultsFromFile.setObject_forKey_(value, key)

def _getNSDefault(key, defaultValue=None):
    data = getDefault(key, defaultValue)
    if isinstance(data, AppKit.NSData):
        return AppKit.NSUnarchiver.unarchiveObjectWithData_(data)
    return data

def _setNSDefault(key, value):
    data = AppKit.NSArchiver.archivedDataWithRootObject_(value)
    setDefault(key, data)

def getFontDefault(key, defaultValue=None):
    return _getNSDefault(key, defaultValue)

def setFontDefault(key, font):
    _setNSDefault(key, font)

def getColorDefault(key, defaultValue=None):
    return _getNSDefault(key, defaultValue)

def setColorDefault(key, color):
    _setNSDefault(key, color)

# color tools

def cmyk2rgb(c, m, y, k):
    """
    Convert cmyk color to rbg color.
    """
    r = 1.0 - min(1.0, c + k)
    g = 1.0 - min(1.0, m + k)
    b = 1.0 - min(1.0, y + k)
    return r, g, b

def rgb2cmyk(r, g, b):
    """
    Convert rgb color to cmyk color.
    """
    c = 1 - r
    m = 1 - g
    y = 1 - b
    k = min(c,m,y)
    c = min(1, max(0,c-k))
    m = min(1, max(0,m-k))
    y = min(1, max(0,y-k))
    k = min(1, max(0,k))
    return c, m, y, k

def stringToInt(code):
    import struct
    return struct.unpack('>l', code)[0]

class Warnings(object):

    def __init__(self):
        self._warnMessages = set()

    def resetWarnings(self):
        self._warnMessages = set()

    def warn(self, message):
        if message in self._warnMessages:
            return
        sys.stderr.write("*** DrawBot warning: %s ***\n" % message)
        self._warnMessages.add(message)

warnings = Warnings()
<|endoftext|>


<commit_before>import re

class Resolver:

	def run(self, file):
		if self.is_spec(file):
			return self.get_source(file)
		else:
			return self.get_spec(file)

	def is_spec(self, file):
		return file.find('_spec.rb') != -1

	def get_source(self, file):
		# find erb, haml
		match = re.search(r'(.erb|.haml)_spec.rb$', file)
		related = []

		if match:
			ext = match.group(0)
			regex = re.escape(ext)
			ext = re.sub(r'_spec.rb', '', ext)
			file = re.sub(regex, ext, file)
		else:
			# simply sub .rb to _spec.rb
			# e.g. foo.rb -> foo_spec.rb
			file = re.sub(r'\_spec.rb$', '.rb', file)

		if file.find('/spec/lib/') > -1:
			# file in lib
			related.append(re.sub(r'/spec/lib/', '/lib/', file))
		else:
			related.append(re.sub(r'/spec/', '/app/', file, 1))
			related.append(re.sub(r'/spec/', '/', file, 1))

		return related

	def get_spec(self, file):
		# find erb, haml
		match = re.search(r'erb$|haml$', file)
		related = []

		if match:
			ext = match.group(0)
			regex = re.escape(ext) + "$"
			file = re.sub(regex, ext + '_spec.rb', file)
		else:
			file = re.sub(r'\.rb$', '_spec.rb', file)

		if file.find('/lib/') > -1:
			related.append(re.sub(r'/lib/', '/spec/lib/', file))
		elif file.find('/app/') > -1:
			related.append(re.sub(r'/app/', '/spec/', file, 1))
		else:
			related.append('/spec' + file)

		return related
<commit_msg>Add slim support to resolver.py<commit_after>import re

class Resolver:

	def run(self, file):
		if self.is_spec(file):
			return self.get_source(file)
		else:
			return self.get_spec(file)

	def is_spec(self, file):
		return file.find('_spec.rb') != -1

	def get_source(self, file):
		# find erb, haml
		match = re.search(r'(.erb|.haml|.slim)_spec.rb$', file)
		related = []

		if match:
			ext = match.group(0)
			regex = re.escape(ext)
			ext = re.sub(r'_spec.rb', '', ext)
			file = re.sub(regex, ext, file)
		else:
			# simply sub .rb to _spec.rb
			# e.g. foo.rb -> foo_spec.rb
			file = re.sub(r'\_spec.rb$', '.rb', file)

		if file.find('/spec/lib/') > -1:
			# file in lib
			related.append(re.sub(r'/spec/lib/', '/lib/', file))
		else:
			related.append(re.sub(r'/spec/', '/app/', file, 1))
			related.append(re.sub(r'/spec/', '/', file, 1))

		return related

	def get_spec(self, file):
		# find erb, haml
		match = re.search(r'erb$|haml$|slim$', file)
		related = []

		if match:
			ext = match.group(0)
			regex = re.escape(ext) + "$"
			file = re.sub(regex, ext + '_spec.rb', file)
		else:
			file = re.sub(r'\.rb$', '_spec.rb', file)

		if file.find('/lib/') > -1:
			related.append(re.sub(r'/lib/', '/spec/lib/', file))
		elif file.find('/app/') > -1:
			related.append(re.sub(r'/app/', '/spec/', file, 1))
		else:
			related.append('/spec' + file)

		return related
<|endoftext|>


<commit_before>import sys
sys.path.insert(0, '/home/projekt/homeStruction/website')
import serial
from time import sleep
import re
import os
import django
from django.utils import timezone

# Initial setup required
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "homeStruction.settings")
django.setup()

from project.models import Lamp

def confirmation(todo, ser):
	MyInt = -1
	sleep(2)
	ser.write('3');
	sleep(1)
	bigchunk = ser.readline()
	sleep(.5)
	words = bigchunk.split()
	if todo == '1lampon':
		MyInt = int(words[3])
		if MyInt == 1:
			return True
	if todo == '1lampoff':
		MyInt = int(words[3])
		if MyInt == 0:
			return True
	if todo == '2lampon':
		MyInt = int(words[2])
		if MyInt == 1:
			return True
	if todo == '2lampoff':
		MyInt = int(words[2])
		if MyInt == 0:
			return True
	if todo == '3lampon':
		MyInt = int(words[4])
		if MyInt == 1:
			return True
	if todo == '3lampoff':
		MyInt = int(words[4])
		if MyInt == 0:
			return True
	if todo == 'opendoor':
		MyInt = int(words[5])
		if MyInt == 72:
			return True
	if todo == 'closedoor':
		MyInt = int(words[5])
		if MyInt == 10:
			return True
	return False

def controlconfirm(todo):
	try:
		ser = serial.Serial('/dev/ttyACM0', 9600)
		if todo == '1lampon':
			ser.write('7')
			if confirmation(todo, ser):
				Lamp.objects.create(value='1on_c', time_recorded=timezone.now())
			else:
				Lamp.objects.create(value='1on_uc', time_recorded=timezone.now())

		if todo == '1lampoff':
			ser.write('8')
			if confirmation(todo, ser):
				Lamp.objects.create(value='1off_c', time_recorded=timezone.now())
			else:
				Lamp.objects.create(value='1off_uc', time_recorded=timezone.now())

		if todo == '2lampon':
			ser.write('1')
			if confirmation(todo, ser):
				Lamp.objects.create(value='2off_c', time_recorded=timezone.now())
			else:
				Lamp.objects.create(value='2off_uc', time_recorded=timezone.now())

		if todo == '2lampoff':
			ser.write('2')
			if confirmation(todo, ser):
				Lamp.objects.create(value='2on_c', time_recorded=timezone.now())
			else:
				Lamp.objects.create(value='2on_uc', time_recorded=timezone.now())

		if todo == '3lampon':
			ser.write('6')
			if confirmation(todo, ser):
				Lamp.objects.create(value='3off_c', time_recorded=timezone.now())
			else:
				Lamp.objects.create(value='3off_uc', time_recorded=timezone.now())

		if todo == '3lampoff':
			ser.write('9')
			if confirmation(todo, ser):
				Lamp.objects.create(value='3on_c', time_recorded=timezone.now())
			else:
				Lamp.objects.create(value='3on_uc', time_recorded=timezone.now())

		if todo == 'opendoor':
			ser.write('5')
			if confirmation(todo, ser):
				Lamp.objects.create(value='od_c', time_recorded=timezone.now())
			else:
				Lamp.objects.create(value='od_uc', time_recorded=timezone.now())

		if todo == 'closedoor':
			ser.write('4')
			if confirmation(todo, ser):
				Lamp.objects.create(value='cd_c', time_recorded=timezone.now())
			else:
				Lamp.objects.create(value='cd_uc', time_recorded=timezone.now())

		ser.close()

	except serial.SerialException:
		Lamp.objects.create(value="ConnError", time_recorded=timezone.now())

<commit_msg>whitespace<commit_after>import sys
sys.path.insert(0, '/home/projekt/homeStruction/website')
import serial
from time import sleep
import re
import os
import django
from django.utils import timezone

# Initial setup required
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "homeStruction.settings")
django.setup()

from project.models import Lamp

script, todo = sys.argv

def confirmation(todo, ser):
	MyInt = -1
	sleep(2)
	ser.write('3');
	sleep(1)
	bigchunk = ser.readline()
	sleep(.5)
	words = bigchunk.split()
	if todo == '1lampon':
		MyInt = int(words[3])
		if MyInt == 1:
			return True
	if todo == '1lampoff':
		MyInt = int(words[3])
		if MyInt == 0:
			return True
	if todo == '2lampon':
		MyInt = int(words[2])
		if MyInt == 1:
			return True
	if todo == '2lampoff':
		MyInt = int(words[2])
		if MyInt == 0:
			return True
	if todo == '3lampon':
		MyInt = int(words[4])
		if MyInt == 1:
			return True
	if todo == '3lampoff':
		MyInt = int(words[4])
		if MyInt == 0:
			return True
	if todo == 'opendoor':
		MyInt = int(words[5])
		if MyInt == 72:
			return True
	if todo == 'closedoor':
		MyInt = int(words[5])
		if MyInt == 10:
			return True
	return False

def controlconfirm(todo):
	try:
		ser = serial.Serial('/dev/ttyACM0', 9600)
		if todo == '1lampon':
			ser.write('7')
			if confirmation(todo, ser):
				Lamp.objects.create(value='1on_c', time_recorded=timezone.now())
			else:
				Lamp.objects.create(value='1on_uc', time_recorded=timezone.now())

		if todo == '1lampoff':
			ser.write('8')
			if confirmation(todo, ser):
				Lamp.objects.create(value='1off_c', time_recorded=timezone.now())
			else:
				Lamp.objects.create(value='1off_uc', time_recorded=timezone.now())

		if todo == '2lampon':
			ser.write('1')
			if confirmation(todo, ser):
				Lamp.objects.create(value='2off_c', time_recorded=timezone.now())
			else:
				Lamp.objects.create(value='2off_uc', time_recorded=timezone.now())

		if todo == '2lampoff':
			ser.write('2')
			if confirmation(todo, ser):
				Lamp.objects.create(value='2on_c', time_recorded=timezone.now())
			else:
				Lamp.objects.create(value='2on_uc', time_recorded=timezone.now())

		if todo == '3lampon':
			ser.write('6')
			if confirmation(todo, ser):
				Lamp.objects.create(value='3off_c', time_recorded=timezone.now())
			else:
				Lamp.objects.create(value='3off_uc', time_recorded=timezone.now())

		if todo == '3lampoff':
			ser.write('9')
			if confirmation(todo, ser):
				Lamp.objects.create(value='3on_c', time_recorded=timezone.now())
			else:
				Lamp.objects.create(value='3on_uc', time_recorded=timezone.now())

		if todo == 'opendoor':
			ser.write('5')
			if confirmation(todo, ser):
				Lamp.objects.create(value='od_c', time_recorded=timezone.now())
			else:
				Lamp.objects.create(value='od_uc', time_recorded=timezone.now())

		if todo == 'closedoor':
			ser.write('4')
			if confirmation(todo, ser):
				Lamp.objects.create(value='cd_c', time_recorded=timezone.now())
			else:
				Lamp.objects.create(value='cd_uc', time_recorded=timezone.now())

		ser.close()

	except serial.SerialException:
		Lamp.objects.create(value="ConnError", time_recorded=timezone.now())

<|endoftext|>


<commit_before>import logging
logger = logging.getLogger(__name__)

from django.utils.html import strip_tags

from mezzanine.blog.models import BlogCategory

from website.jdpages.models import ColumnElement, EventColumnElement
from website.jdpages.models import HomePage
from website.jdpages.models import PageHeaderImageWidget
from website.jdpages.models import get_public_blogposts

def create_column_items(column_widgets):
    """ creates view items for the more column widget models """
    column_items = []
    for widget in column_widgets:
        model_class = widget.column_element.content_type.model_class()
        if model_class == BlogCategory:
            blog_category = widget.column_element.get_object()
            if widget.column_element.subtype == ColumnElement.COMPACT:
                column_items.append(BlogCategoryHeadlineColumnItem(blog_category, widget))
            else:
                column_items.append(BlogCategoryColumnItem(blog_category, widget))
        elif model_class == EventColumnElement:
            event_element = widget.column_element.get_object()
            column_items.append(EventColumnItem(event_element, widget))
    return column_items

class Item(object):
    """ A generic view item with a template and all data needed in the template. """
    def __init__(self, title=""):
        self.title = title

    def get_template_name(self):
        return "none"

    def is_blog_category_sidebar_item(self):
        return isinstance(self, BlogCategorySidebarItem)

    def is_social_media_button_group_item(self):
        return isinstance(self, SocialMediaButtonGroupItem)

class BlogCategoryColumnItem(Item):
    """
    Column view item for a mezzanine BlogCategory.
    Has BlogPostItems as children.
    Shows an excerpt of the last n posts.
    """
    def __init__(self, blogcategory, widget):
        super(BlogCategoryColumnItem, self).__init__(widget.title)
        self.url = blogcategory.get_absolute_url()
        self.children = self.create_children(blogcategory, widget.max_items)

    @staticmethod
    def create_children(blogcategory, max_items):
        children = []
        blogposts = get_public_blogposts(blogcategory)[:max_items]
        for post in blogposts:
            children.append(BlogPostItem(post))
        return children

    def get_template_name(self):
        return "blogcategory_column_item.html"

class BlogCategoryHeadlineColumnItem(BlogCategoryColumnItem):
    """ Column view item for a blog category with headlines only. """
    def __init__(self, blogcategory, widget):
        super(BlogCategoryHeadlineColumnItem, self).__init__(blogcategory, widget)

    def get_template_name(self):
        return "blogcategory_compact_column_item.html"

class BlogPostItem(Item):
    """
    BlogPost view item with data needed to render (part of a) blogpost.
    HTML richtext is stripped from the content.
    """
    def __init__(self, blogpost):
        super(BlogPostItem, self).__init__(blogpost.title)
        self.author = blogpost.user
        self.date = blogpost.publish_date
        self.url = blogpost.get_absolute_url()
        self.content = strip_tags(blogpost.content)

class EventColumnItem(Item):
    """ Column view item for an Event. """
    def __init__(self, event_element, widget):
        super(EventColumnItem, self).__init__(widget.title)
        self.type = event_element.type
        self.max_items = widget.max_items
        self.url = "/events/"

    def get_template_name(self):
        return "events_column_item.html"

class BlogCategorySidebarItem(Item):
    """
    Sidebar view item for a mezzanine BlogCategory.
    Has BlogPostItems as children.
    Shows an excerpt of the last post.
    """
    def __init__(self, blogcategory):
        super(BlogCategorySidebarItem, self).__init__()
        self.children = self.create_children(blogcategory)

    @staticmethod
    def create_children(blogcategory):
        children = []
        blogposts = get_public_blogposts(blogcategory)[:1]
        for post in blogposts:
            children.append(BlogPostItem(post))
        return children

    def get_template_name(self):
        return "blogpost_sidebar_item.html"

class SocialMediaButtonGroupItem(Item):
    """ View item for a list of social media buttons. """
    def __init__(self, buttons):
        super(SocialMediaButtonGroupItem, self).__init__()
        self.children = []
        for button in buttons:
            self.children.append(SocialMediaButtonItem(button))

    def get_template_name(self):
        return "social_media_icons.html"

class SocialMediaButtonItem(Item):
    """ View item for a single social media button, to be shown in a button group. """
    def __init__(self, button):
        super(SocialMediaButtonItem, self).__init__()
        self.url = button.url
        self.icon_url = button.get_icon_url()
        self.media_type = button.get_type_name()

    def mobile_icon_url(self):
        parts = self.icon_url.rsplit('/', 1)
        return "/mobile/".join(parts)

class BannerSidebarItem(Item):
    """ View item for a banner (image) on the sidebar. """
    def __init__(self, widget):
        super(BannerSidebarItem, self).__init__()
        self.image_url = widget.image.url
        self.url = widget.url
        self.description = widget.description

    def get_template_name(self):
        return "banner_sidebar_item.html"

class TwitterSidebarItem(Item):
    """ Sidebar view item for a twitter feed. """
    def get_template_name(self):
        return "twitter_feed_item.html"

class TabsSidebarItem(Item):
    """ Sidebar item for a tabbed view. """
    def get_template_name(self):
        return "tabs_sidebar_item.html"

def get_page_header(page):
    """
    :returns: the page header for a given page.
    Uses parent page image when none is defined.
    Top parent is the HomePage.
    None when there is no Hompage or when the HomePage has no header.
    """

    # Get a random page header, or the first one if there is only one
    image = PageHeaderImageWidget.objects.filter(page=page).order_by('?').first()
    if image is not None:
        return image

    # No image found! If we received an integer, then do not search further
    if isinstance(page, int):
        return None

    # Try from parent
    if page.parent:
        return get_page_header(page.parent)

    # Try from first homepage
    homepage = HomePage.objects.values_list('id').first()
    if len(homepage) != 0:
        # Since we give get_page_header an integer, there is no infinite recursion here...
        return get_page_header(homepage[0])

    return None

def get_homepage_header():
    """ Returns the page header image of the homepage """
    homepage = HomePage.objects.values_list('id').first()
    if len(homepage) == 0:
        return None
    return get_page_header(homepage[0])
<commit_msg>Small streamlining to reduce the number of queries<commit_after>import logging
logger = logging.getLogger(__name__)

from django.utils.html import strip_tags

from mezzanine.blog.models import BlogCategory

from website.jdpages.models import ColumnElement, EventColumnElement
from website.jdpages.models import HomePage
from website.jdpages.models import PageHeaderImageWidget
from website.jdpages.models import get_public_blogposts

def create_column_items(column_widgets):
    """ creates view items for the more column widget models """
    column_items = []
    for widget in column_widgets:
        model_class = widget.column_element.content_type.model_class()
        if model_class == BlogCategory:
            blog_category = widget.column_element.get_object()
            if widget.column_element.subtype == ColumnElement.COMPACT:
                column_items.append(BlogCategoryHeadlineColumnItem(blog_category, widget))
            else:
                column_items.append(BlogCategoryColumnItem(blog_category, widget))
        elif model_class == EventColumnElement:
            event_element = widget.column_element.get_object()
            column_items.append(EventColumnItem(event_element, widget))
    return column_items

class Item(object):
    """ A generic view item with a template and all data needed in the template. """
    def __init__(self, title=""):
        self.title = title

    def get_template_name(self):
        return "none"

    def is_blog_category_sidebar_item(self):
        return isinstance(self, BlogCategorySidebarItem)

    def is_social_media_button_group_item(self):
        return isinstance(self, SocialMediaButtonGroupItem)

class BlogCategoryColumnItem(Item):
    """
    Column view item for a mezzanine BlogCategory.
    Has BlogPostItems as children.
    Shows an excerpt of the last n posts.
    """
    def __init__(self, blogcategory, widget):
        super(BlogCategoryColumnItem, self).__init__(widget.title)
        self.url = blogcategory.get_absolute_url()
        self.children = self.create_children(blogcategory, widget.max_items)

    @staticmethod
    def create_children(blogcategory, max_items):
        blogposts = get_public_blogposts(blogcategory).select_related('user')[:max_items]
        return [BlogPostItem(post) for post in blogposts]

    def get_template_name(self):
        return "blogcategory_column_item.html"

class BlogCategoryHeadlineColumnItem(BlogCategoryColumnItem):
    """ Column view item for a blog category with headlines only. """
    def __init__(self, blogcategory, widget):
        super(BlogCategoryHeadlineColumnItem, self).__init__(blogcategory, widget)

    def get_template_name(self):
        return "blogcategory_compact_column_item.html"

class BlogPostItem(Item):
    """
    BlogPost view item with data needed to render (part of a) blogpost.
    HTML richtext is stripped from the content.
    """
    def __init__(self, blogpost):
        super(BlogPostItem, self).__init__(blogpost.title)
        self.author = blogpost.user
        self.date = blogpost.publish_date
        self.url = blogpost.get_absolute_url()
        self.content = strip_tags(blogpost.content)

class EventColumnItem(Item):
    """ Column view item for an Event. """
    def __init__(self, event_element, widget):
        super(EventColumnItem, self).__init__(widget.title)
        self.type = event_element.type
        self.max_items = widget.max_items
        self.url = "/events/"

    def get_template_name(self):
        return "events_column_item.html"

class BlogCategorySidebarItem(Item):
    """
    Sidebar view item for a mezzanine BlogCategory.
    Has BlogPostItems as children.
    Shows an excerpt of the last post.
    """
    def __init__(self, blogcategory):
        super(BlogCategorySidebarItem, self).__init__()
        self.children = self.create_children(blogcategory)

    @staticmethod
    def create_children(blogcategory):
        blogposts = get_public_blogposts(blogcategory).select_related('user')[:1]
        return [BlogPostItem(post) for post in blogposts]

    def get_template_name(self):
        return "blogpost_sidebar_item.html"

class SocialMediaButtonGroupItem(Item):
    """ View item for a list of social media buttons. """
    def __init__(self, buttons):
        super(SocialMediaButtonGroupItem, self).__init__()
        self.children = []
        for button in buttons:
            self.children.append(SocialMediaButtonItem(button))

    def get_template_name(self):
        return "social_media_icons.html"

class SocialMediaButtonItem(Item):
    """ View item for a single social media button, to be shown in a button group. """
    def __init__(self, button):
        super(SocialMediaButtonItem, self).__init__()
        self.url = button.url
        self.icon_url = button.get_icon_url()
        self.media_type = button.get_type_name()

    def mobile_icon_url(self):
        parts = self.icon_url.rsplit('/', 1)
        return "/mobile/".join(parts)

class BannerSidebarItem(Item):
    """ View item for a banner (image) on the sidebar. """
    def __init__(self, widget):
        super(BannerSidebarItem, self).__init__()
        self.image_url = widget.image.url
        self.url = widget.url
        self.description = widget.description

    def get_template_name(self):
        return "banner_sidebar_item.html"

class TwitterSidebarItem(Item):
    """ Sidebar view item for a twitter feed. """
    def get_template_name(self):
        return "twitter_feed_item.html"

class TabsSidebarItem(Item):
    """ Sidebar item for a tabbed view. """
    def get_template_name(self):
        return "tabs_sidebar_item.html"

def get_page_header(page):
    """
    :returns: the page header for a given page.
    Uses parent page image when none is defined.
    Top parent is the HomePage.
    None when there is no Hompage or when the HomePage has no header.
    """

    # Get a random page header, or the first one if there is only one
    image = PageHeaderImageWidget.objects.filter(page=page).order_by('?').first()
    if image is not None:
        return image

    # No image found! If we received an integer, then do not search further
    if isinstance(page, int):
        return None

    # Try from parent
    if page.parent:
        return get_page_header(page.parent)

    # Try from first homepage
    homepage = HomePage.objects.values_list('id').first()
    if len(homepage) != 0:
        # Since we give get_page_header an integer, there is no infinite recursion here...
        return get_page_header(homepage[0])

    return None

def get_homepage_header():
    """ Returns the page header image of the homepage """
    homepage = HomePage.objects.values_list('id').first()
    if len(homepage) == 0:
        return None
    return get_page_header(homepage[0])
<|endoftext|>


<commit_before>import gym
import numpy as np
import time
from numerical_gradient import *

#Displays numerical evidence that backprop gradients are correct
#Slows down performance dramatically and doesnt affect outcome, so disabled by default
check_gradient = False
verbose = True
print_every = 100

#Some useful numerical values
num_hidden_neurons = 10
learning_rate = 1e-3
gamma = 0.99
num_games = 100000
win_reward_threshold = 30.0

def main():
    env = gym.make('CartPole-v0')
    input_dim = env.observation_space.low.shape[0]

    model = init_model(input_dim, num_hidden_neurons)
    rmsprop_cache = init_rmsprop_cache(model)

    for game in range(num_games):
        print(model['W1'][(0, 0)])
        observation = env.reset()
        observation = observation.reshape(1, input_dim)
        done = False
        reward = 0.0
        observations = [] #List of all observations made throughout game
        hidden_activations = [] #Store hidden layer activations at every stage for backprop
        d_log_probs = [] #Store the derivative of the loss function at every stage
        num_game_steps = 0
        total_reward = 0.0
        while not done:
            #Single step of the game
            env.render()
            probability, hidden_activation = eval_model(model, observation)
            action = decide_action(probability)
            observation, reward, done, _ = env.step(action)
            total_reward += reward
            observation = observation.reshape(1, input_dim)
            d_log_probability = action - probability

            #Store all the values for this game step and proceed
            observations += [observation]
            hidden_activations += [hidden_activation]
            d_log_probs += [d_log_probability]
            num_game_steps += 1
        if verbose:
            print("Game ", game, " final reward: ", total_reward)

        #print averages here?
        if game % print_every == 0:
            pass

        #1 if we won, -1 otherwise
        #If we won, we want to reinforce the behavior so we optimize "uphill" on the reward function
        #Otherwise, we want to optimize downhill
        #RMSProp by default descends, so we want to reverse the direction
        win_modifier = -1 if total_reward >= win_reward_threshold else 1

        observations = np.vstack(observations)
        d_log_probs = np.vstack(d_log_probs)
        hidden_activations = np.vstack(hidden_activations)

        d_log_probs *= -win_modifier

        #Model derivatives for frame 0 of the episode
        #How to get deritaves for all frames without loop?
        model_derivatives = backprop(hidden_activations, d_log_probs, model, observations)
        model = update(model, model_derivatives, rmsprop_cache)

#Initiates model and returns it in the form of a dict
def init_model(input_dim, num_hidden_neurons):
    model = {}
    model['W1'] = np.random.randn(input_dim, num_hidden_neurons) / np.sqrt(input_dim)
    model['b1'] = np.zeros((1, num_hidden_neurons))
    model['W2'] = np.random.randn(num_hidden_neurons) / np.sqrt(num_hidden_neurons)
    model['b2'] = np.zeros(1)
    return model

def init_rmsprop_cache(model):
    rmsprop_cache = {}
    for key, params in model.items():
        rmsprop_cache[key] = np.zeros_like(params)
    return rmsprop_cache

#Standard sigmoid function
def sigmoid(x):
    return 1. / (1. + np.exp(-x))

#Applies rectified linear activation to input
def relu(x):
    x[x<0] = 0
    return x

#Performs a feedforward pass, returns the final output probability and hidden layer activations
def eval_model(model, data):
    hidden_scores = np.dot(data, model['W1']) + model['b1']
    hidden_activations = relu(hidden_scores)
    final_scores = np.dot(hidden_activations, model['W2']) + model['b2']
    probability = sigmoid(final_scores)
    return probability, hidden_activations

#Decides an action to take given the probability of the "1" action
def decide_action(probability):
    if np.random.uniform() < probability:
        return 1
    else:
        return 0

#Backpropagation of a single frame
def backprop(hidden_activations, d_log_prob, model, episode_observations):
    N = episode_observations.shape[0]
    d_b2 = np.sum(d_log_prob, axis=0)
    d_W2 = np.dot(hidden_activations.T, d_log_prob).ravel()
    d_hidden_activations = (model['W2'] * d_log_prob).reshape(N, num_hidden_neurons)
    d_hidden_activations[hidden_activations <= 0] = 0 #ReLU backprop, trivial, no need to check
    d_b1 = np.sum(d_hidden_activations, axis=0)
    d_W1 = np.dot(episode_observations.T, d_hidden_activations)

    if check_gradient:
        d_b2_num = numerical_gradient_layer(lambda b : np.dot(hidden_activations, model['W2']) + b, model['b2'], d_log_prob)
        d_W2_num = numerical_gradient_layer(lambda w : np.dot(hidden_activations, w) + model['b2'], model['W2'], d_log_prob)
        #d_hidden_activations_num = numerical_gradient_layer(lambda x : np.dot(x, model['W2']) + model['b2'], hidden_activations, d_log_prob)
        print('d_b2 error:', np.max(relative_error(d_b2, d_b2_num)))
        #print(d_b2)
        #print(d_b2_num)
        print('d_W2 error:', np.max(relative_error(d_W2, d_W2_num)))
        #print(d_W2)
        #print(d_W2_num)
        d_b1_num = numerical_gradient_layer(lambda b : np.dot(episode_observations, model['W1']) + b, model['b1'], d_hidden_activations)
        d_W1_num = numerical_gradient_layer(lambda w : np.dot(episode_observations, w) + model['b1'], model['W1'], d_hidden_activations)
        print('d_b1 error:', np.max(relative_error(d_b1, d_b1_num)))
        print('d_W1 error:', np.max(relative_error(d_W1, d_W1_num)))

    return {'W1':d_W1, 'b1':d_b1, 'W2':d_W2, 'b2':d_b2}

#RMSProp update of a single matrix
def rmsprop(theta, dtheta, error, learning_rate, decay):
    eps = 1e-8
    error = decay * error + (1 - decay) * dtheta**2
    return theta - learning_rate * dtheta / (np.sqrt(error) + eps), error

def update(model, model_derivatives, rmsprop_cache):
    for key, layer in model.items():
        model[key], rmsprop_cache[key] = rmsprop(layer, model_derivatives[key], rmsprop_cache[key], learning_rate, gamma)
    return model

main()
<commit_msg>CartPole algorithm (slowly) learns<commit_after>import gym
import numpy as np
import time
from numerical_gradient import *

#Displays numerical evidence that backprop gradients are correct
#Slows down performance dramatically and doesnt affect outcome, so disabled by default
check_gradient = False
verbose = False
print_every = 100

#Some useful numerical values
num_hidden_neurons = 10
learning_rate = 7e-4
gamma = 0.99
num_games = 100000
win_reward_threshold = 100.0

def main():
    env = gym.make('CartPole-v0')
    input_dim = env.observation_space.low.shape[0]

    model = init_model(input_dim, num_hidden_neurons)
    rmsprop_cache = init_rmsprop_cache(model)
    num_wins = 0

    for game in range(num_games):
        observation = env.reset()
        observation = observation.reshape(1, input_dim)
        done = False
        reward = 0.0
        observations = [] #List of all observations made throughout game
        hidden_activations = [] #Store hidden layer activations at every stage for backprop
        d_log_probs = [] #Store the derivative of the loss function at every stage
        num_game_steps = 0
        total_reward = 0.0
        while not done:
            #Single step of the game
            env.render()
            probability, hidden_activation = eval_model(model, observation)
            action = decide_action(probability)
            observation, reward, done, _ = env.step(action)
            total_reward += reward
            observation = observation.reshape(1, input_dim)
            d_log_probability = action - probability

            #Store all the values for this game step and proceed
            observations += [observation]
            hidden_activations += [hidden_activation]
            d_log_probs += [d_log_probability]
            num_game_steps += 1
        if verbose:
            print("Game ", game, " final reward: ", total_reward)

        #1 if we won, -1 otherwise
        #If we won, we want to reinforce the behavior so we optimize "uphill" on the reward function
        #Otherwise, we want to optimize downhill
        #RMSProp by default descends, so we want to reverse the direction
        win_modifier = 1 if total_reward >= win_reward_threshold else -1
        if win_modifier == 1:
            num_wins += 1

        #print averages here?
        if game % print_every == 0:
            print("Last set number of wins: ", num_wins)
            num_wins = 0

        observations = np.vstack(observations)
        d_log_probs = np.vstack(d_log_probs)
        hidden_activations = np.vstack(hidden_activations)

        d_log_probs *= -win_modifier

        #Model derivatives for frame 0 of the episode
        #How to get deritaves for all frames without loop?
        model_derivatives = backprop(hidden_activations, d_log_probs, model, observations)
        model = update(model, model_derivatives, rmsprop_cache)

#Initiates model and returns it in the form of a dict
def init_model(input_dim, num_hidden_neurons):
    model = {}
    model['W1'] = np.random.randn(input_dim, num_hidden_neurons) / np.sqrt(input_dim)
    model['b1'] = np.zeros((1, num_hidden_neurons))
    model['W2'] = np.random.randn(num_hidden_neurons) / np.sqrt(num_hidden_neurons)
    model['b2'] = np.zeros(1)
    return model

def init_rmsprop_cache(model):
    rmsprop_cache = {}
    for key, params in model.items():
        rmsprop_cache[key] = np.zeros_like(params)
    return rmsprop_cache

#Standard sigmoid function
def sigmoid(x):
    return 1. / (1. + np.exp(-x))

#Applies rectified linear activation to input
def relu(x):
    x[x<0] = 0
    return x

#Performs a feedforward pass, returns the final output probability and hidden layer activations
def eval_model(model, data):
    hidden_scores = np.dot(data, model['W1']) + model['b1']
    hidden_activations = relu(hidden_scores)
    final_scores = np.dot(hidden_activations, model['W2']) + model['b2']
    probability = sigmoid(final_scores)
    return probability, hidden_activations

#Decides an action to take given the probability of the "1" action
def decide_action(probability):
    if np.random.uniform() < probability:
        return 1
    else:
        return 0

#Backpropagation of a single frame
def backprop(hidden_activations, d_log_prob, model, episode_observations):
    N = episode_observations.shape[0]
    d_b2 = np.sum(d_log_prob, axis=0)
    d_W2 = np.dot(hidden_activations.T, d_log_prob).ravel()
    d_hidden_activations = (model['W2'] * d_log_prob).reshape(N, num_hidden_neurons)
    d_hidden_activations[hidden_activations <= 0] = 0 #ReLU backprop, trivial, no need to check
    d_b1 = np.sum(d_hidden_activations, axis=0)
    d_W1 = np.dot(episode_observations.T, d_hidden_activations)

    if check_gradient:
        d_b2_num = numerical_gradient_layer(lambda b : np.dot(hidden_activations, model['W2']) + b, model['b2'], d_log_prob)
        d_W2_num = numerical_gradient_layer(lambda w : np.dot(hidden_activations, w) + model['b2'], model['W2'], d_log_prob)
        #d_hidden_activations_num = numerical_gradient_layer(lambda x : np.dot(x, model['W2']) + model['b2'], hidden_activations, d_log_prob)
        print('d_b2 error:', np.max(relative_error(d_b2, d_b2_num)))
        #print(d_b2)
        #print(d_b2_num)
        print('d_W2 error:', np.max(relative_error(d_W2, d_W2_num)))
        #print(d_W2)
        #print(d_W2_num)
        d_b1_num = numerical_gradient_layer(lambda b : np.dot(episode_observations, model['W1']) + b, model['b1'], d_hidden_activations)
        d_W1_num = numerical_gradient_layer(lambda w : np.dot(episode_observations, w) + model['b1'], model['W1'], d_hidden_activations)
        print('d_b1 error:', np.max(relative_error(d_b1, d_b1_num)))
        print('d_W1 error:', np.max(relative_error(d_W1, d_W1_num)))

    return {'W1':d_W1, 'b1':d_b1, 'W2':d_W2, 'b2':d_b2}

#RMSProp update of a single matrix
def rmsprop(theta, dtheta, error, learning_rate, decay):
    eps = 1e-8
    error = decay * error + (1 - decay) * dtheta**2
    return theta - learning_rate * dtheta / (np.sqrt(error) + eps), error

def update(model, model_derivatives, rmsprop_cache):
    for key, layer in model.items():
        model[key], rmsprop_cache[key] = rmsprop(layer, model_derivatives[key], rmsprop_cache[key], learning_rate, gamma)
    return model

main()
<|endoftext|>