<commit_before># -*- coding: utf-8 -*-
"""The URL routing."""

class Router(object):

    """Connect view functions to URL rules."""

    def __init__(self):
        self.path_map = {}
        self.view_map = {}

    def add_rule(self, method, path, view):
        """Store the view and rule relation in the two lookup maps.

        The view gets stored under the path and method in the path_map
        matrix. The path/method rule is stored under view in view_map.
        """
        self.path_map.setdefault(path, {})
        rule = self.path_map[path]
        if method in rule:
            raise Exception('Duplicate route: {0} {1}'.format(method, path))
        rule[method] = view
        self.view_map[view] = method, path

    def get_view(self, method, path):
        """Look up the view """
        if path not in self.path_map:
            raise LookupError('No such path')
        if method not in self.path_map[path]:
            raise LookupError('No such method')
        return self.path_map[path][method]

    def path_for(self, view):
        try:
            method, path = self.view_map[view]
            return path
        except KeyError:
            raise Exception('The view %r is not registered to a url' % view)
<commit_msg>Only return the first path mapped to a view<commit_after># -*- coding: utf-8 -*-
"""The URL routing."""

class Router(object):

    """Connect view functions to URL rules."""

    def __init__(self):
        self.path_map = {}
        self.view_map = {}

    def add_rule(self, method, path, view):
        """Store the view and rule relation in the two lookup maps.

        The view gets stored under the path and method in the path_map
        matrix. The path/method rule is stored under view in view_map.
        """
        self.path_map.setdefault(path, {})
        rule = self.path_map[path]
        if method in rule:
            raise Exception('Duplicate route: {0} {1}'.format(method, path))
        rule[method] = view
        if view not in self.view_map:
            self.view_map[view] = method, path

    def get_view(self, method, path):
        """Look up the view """
        if path not in self.path_map:
            raise LookupError('No such path')
        if method not in self.path_map[path]:
            raise LookupError('No such method')
        return self.path_map[path][method]

    def path_for(self, view):
        try:
            method, path = self.view_map[view]
            return path
        except KeyError:
            raise Exception('The view %r is not registered to a url' % view)
<|endoftext|>


<commit_before>"""
Connection utilities
"""
import base64
import paramiko
import os
import logging

from teuthology.config import config
from teuthology.contextutil import safe_while

log = logging.getLogger(__name__)

def split_user(user_at_host):
    """
    break apart user@host fields into user and host.
    """
    try:
        user, host = user_at_host.rsplit('@', 1)
    except ValueError:
        user, host = None, user_at_host
    assert user != '', \
        "Bad input to split_user: {user_at_host!r}".format(user_at_host=user_at_host)
    return user, host

def create_key(keytype, key):
    """
    Create an ssh-rsa or ssh-dss key.
    """
    if keytype == 'ssh-rsa':
        return paramiko.rsakey.RSAKey(data=base64.decodestring(key.encode()))
    elif keytype == 'ssh-dss':
        return paramiko.dsskey.DSSKey(data=base64.decodestring(key.encode()))
    else:
        raise ValueError('keytype must be ssh-rsa or ssh-dss (DSA)')

def connect(user_at_host, host_key=None, keep_alive=False, timeout=60,
            _SSHClient=None, _create_key=None, retry=True, key_filename=None):
    """
    ssh connection routine.

    :param user_at_host: user@host
    :param host_key: ssh key
    :param keep_alive: keep_alive indicator
    :param timeout:    timeout in seconds
    :param _SSHClient: client, default is paramiko ssh client
    :param _create_key: routine to create a key (defaults to local reate_key)
    :param retry:       Whether or not to retry failed connection attempts
                        (eventually giving up if none succeed). Default is True
    :param key_filename:  Optionally override which private key to use.
    :return: ssh connection.
    """
    user, host = split_user(user_at_host)
    if _SSHClient is None:
        _SSHClient = paramiko.SSHClient
    ssh = _SSHClient()

    if _create_key is None:
        _create_key = create_key

    if host_key is None:
        ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
        if config.verify_host_keys is True:
            ssh.load_system_host_keys()

    else:
        keytype, key = host_key.split(' ', 1)
        ssh.get_host_keys().add(
            hostname=host,
            keytype=keytype,
            key=_create_key(keytype, key)
            )

    connect_args = dict(
        hostname=host,
        username=user,
        timeout=timeout
    )

    ssh_config_path = os.path.expanduser("~/.ssh/config")
    if os.path.exists(ssh_config_path):
        ssh_config = paramiko.SSHConfig()
        ssh_config.parse(open(ssh_config_path))
        opts = ssh_config.lookup(host)
        if not key_filename and 'identityfile' in opts:
            key_filename = opts['identityfile']

    if key_filename:
        if not isinstance(key_filename, list):
            key_filename = [key_filename]
        key_filename = [os.path.expanduser(f) for f in key_filename]
        connect_args['key_filename'] = key_filename

    log.debug(connect_args)

    if not retry:
        ssh.connect(**connect_args)
    else:
        # Retries are implemented using safe_while
        with safe_while(sleep=1, action='connect to ' + host) as proceed:
            while proceed():
                try:
                    ssh.connect(**connect_args)
                    break
                except paramiko.AuthenticationException:
                    log.exception(
                        "Error connecting to {host}".format(host=host))
    ssh.get_transport().set_keepalive(keep_alive)
    return ssh
<commit_msg>orchestra: add ed25519key keytype to connection<commit_after>"""
Connection utilities
"""
import base64
import paramiko
import os
import logging

from teuthology.config import config
from teuthology.contextutil import safe_while

log = logging.getLogger(__name__)

def split_user(user_at_host):
    """
    break apart user@host fields into user and host.
    """
    try:
        user, host = user_at_host.rsplit('@', 1)
    except ValueError:
        user, host = None, user_at_host
    assert user != '', \
        "Bad input to split_user: {user_at_host!r}".format(user_at_host=user_at_host)
    return user, host

def create_key(keytype, key):
    """
    Create an ssh-rsa, ssh-dss or ssh-ed25519 key.
    """
    if keytype == 'ssh-rsa':
        return paramiko.rsakey.RSAKey(data=base64.decodestring(key.encode()))
    elif keytype == 'ssh-dss':
        return paramiko.dsskey.DSSKey(data=base64.decodestring(key.encode()))
    elif keytype == 'ssh-ed25519':
        return paramiko.ed25519key.Ed25519Key(data=base64.decodestring(key.encode()))
    else:
        raise ValueError('keytype must be ssh-rsa, ssh-dss (DSA) or ssh-ed25519')

def connect(user_at_host, host_key=None, keep_alive=False, timeout=60,
            _SSHClient=None, _create_key=None, retry=True, key_filename=None):
    """
    ssh connection routine.

    :param user_at_host: user@host
    :param host_key: ssh key
    :param keep_alive: keep_alive indicator
    :param timeout:    timeout in seconds
    :param _SSHClient: client, default is paramiko ssh client
    :param _create_key: routine to create a key (defaults to local reate_key)
    :param retry:       Whether or not to retry failed connection attempts
                        (eventually giving up if none succeed). Default is True
    :param key_filename:  Optionally override which private key to use.
    :return: ssh connection.
    """
    user, host = split_user(user_at_host)
    if _SSHClient is None:
        _SSHClient = paramiko.SSHClient
    ssh = _SSHClient()

    if _create_key is None:
        _create_key = create_key

    if host_key is None:
        ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
        if config.verify_host_keys is True:
            ssh.load_system_host_keys()

    else:
        keytype, key = host_key.split(' ', 1)
        ssh.get_host_keys().add(
            hostname=host,
            keytype=keytype,
            key=_create_key(keytype, key)
            )

    connect_args = dict(
        hostname=host,
        username=user,
        timeout=timeout
    )

    ssh_config_path = os.path.expanduser("~/.ssh/config")
    if os.path.exists(ssh_config_path):
        ssh_config = paramiko.SSHConfig()
        ssh_config.parse(open(ssh_config_path))
        opts = ssh_config.lookup(host)
        if not key_filename and 'identityfile' in opts:
            key_filename = opts['identityfile']

    if key_filename:
        if not isinstance(key_filename, list):
            key_filename = [key_filename]
        key_filename = [os.path.expanduser(f) for f in key_filename]
        connect_args['key_filename'] = key_filename

    log.debug(connect_args)

    if not retry:
        ssh.connect(**connect_args)
    else:
        # Retries are implemented using safe_while
        with safe_while(sleep=1, action='connect to ' + host) as proceed:
            while proceed():
                try:
                    ssh.connect(**connect_args)
                    break
                except paramiko.AuthenticationException:
                    log.exception(
                        "Error connecting to {host}".format(host=host))
    ssh.get_transport().set_keepalive(keep_alive)
    return ssh
<|endoftext|>


<commit_before>import asyncio
import json
import os
import shutil

import requests

from common import console
from common import file

def get_orgs_list():
    console.log("Info", "Getting the list of theme...")
    try:
        return requests.get("https://api.github.com/orgs/silverblog-theme/repos").json()
    except  requests.exceptions.RequestException:
        console.log("Error", "Get the theme list error.")
        exit(1)

def get_local_theme_list():
    directories = file.list_dirs("./templates")
    dir_list = list()
    for item in directories:
        if os.path.exists("./templates/{}/.git".format(item)):
            dir_list.append(item)
    return dir_list

def get_package_info(package_url):
    try:
        return requests.get(package_url).text
    except requests.exceptions.RequestException:
        return None

def install_theme(theme_name, custom):
    import git
    if not os.path.exists("./templates/static"):
        os.mkdir("./templates/static")
    repo_dir = "./templates/{}".format(theme_name)
    if os.path.exists(repo_dir):
        console.log("Error", "This theme has been installed.")
        exit(1)
    console.log("Info", "Get the theme repository...")
    git_repo = "https://github.com/silverblog-theme/{}.git".format(theme_name)
    if custom:
        git_repo = theme_name
    try:
        git.Repo.clone_from(url=git_repo, to_path=repo_dir, depth=1)
    except git.exc.GitCommandError:
        console.log("Error", "Unable to clone theme repository.")
        exit(1)
    config_example_file = "{}/config.example.json".format(repo_dir)
    static_symlink = "./templates/static/{}".format(theme_name)

    if not os.path.exists(static_symlink):
        os.symlink("{}/templates/{}/static".format(os.getcwd(), theme_name), static_symlink)

    if os.path.exists(config_example_file):
        shutil.copyfile(config_example_file, "{}/config.json".format(repo_dir))

    download_static_file(theme_name)
    console.log("Success", "The theme is install successfully!")

def remove_theme(theme_name):
    static_symlink = "./templates/static/{}".format(theme_name)
    if os.path.exists(static_symlink):
        os.remove(static_symlink)

    shutil.rmtree("./templates/" + theme_name)
    console.log("Success", "The theme is removed successfully!")

def upgrade_theme(theme_name):
    import git
    if os.system('cd ./templates/{} && git rev-parse 2> /dev/null > /dev/null'.format(theme_name)) == 0:
        repo = git.Repo("./templates/" + theme_name)
        remote = repo.remote()
        remote.fetch(repo.active_branch)
        if repo.rev_parse("HEAD") != repo.rev_parse("FETCH_HEAD"):
            console.log("Info", "Updating theme, please wait...")
            remote.pull()
            download_static_file(theme_name)
            console.log("Success", "The theme is upgrade successfully!")
            return
    console.log("Info", "No upgrade found.")

def download_static_file(theme_name):
    if not os.path.exists("./templates/{}/package.json".format(theme_name)):
        return
    download_list_file = "./templates/{}/package.json".format(theme_name)
    download_file_location = "./templates/{}/static/library".format(theme_name)
    if os.path.exists(download_file_location):
        shutil.rmtree(download_file_location)
    os.mkdir(download_file_location)
    package_info = json.loads(file.read_file(download_list_file))

    download_list = list()
    if "download" in package_info:
        download_list = package_info["download"]

    loop = asyncio.new_event_loop()
    asyncio.set_event_loop(loop)
    tasks = [download_file(item, download_file_location) for item in download_list]
    loop.run_until_complete(asyncio.wait(tasks))
    loop.close()

@asyncio.coroutine
def get_file(url):
    console.log("info", "Downloading file:" + url)
    return requests.get(url)

@asyncio.coroutine
def download_file(item, location):
    result = yield from get_file(item["url"])
    write_path = location
    if "path" in item and item["path"] != "":
        write_path = "{}/{}".format(location, item["path"])
    if not os.path.exists(write_path):
        os.mkdir(write_path)
    yield from file.async_write_binary_file("{}/{}".format(write_path, item["filename"]), result.content)

def get_readme(theme_name):
    console.log("Info", "Getting the readme of theme...")
    try:
        r = requests.get("https://raw.githubusercontent.com/silverblog-theme/{}/master/README.md".format(theme_name))
        return r.text
    except  requests.exceptions.RequestException:
        console.log("Error", "Get the readme error.")
        exit(1)<commit_msg>修改theme实现<commit_after>import asyncio
import json
import os
import shutil

import requests

from common import console
from common import file

def get_orgs_list():
    console.log("Info", "Getting the list of theme...")
    try:
        return requests.get("https://api.github.com/orgs/silverblogtheme/repos").json()
    except  requests.exceptions.RequestException:
        console.log("Error", "Get the theme list error.")
        exit(1)

def get_local_theme_list():
    directories = file.list_dirs("./templates")
    dir_list = list()
    for item in directories:
        if os.path.exists("./templates/{}/.git".format(item)):
            dir_list.append(item)
    return dir_list

def get_package_info(package_url):
    try:
        return requests.get(package_url).text
    except requests.exceptions.RequestException:
        return None

def install_theme(theme_name, custom):
    import git
    if not os.path.exists("./templates/static"):
        os.mkdir("./templates/static")
    repo_dir = "./templates/{}".format(theme_name)
    if os.path.exists(repo_dir):
        console.log("Error", "This theme has been installed.")
        exit(1)
    console.log("Info", "Get the theme repository...")
    git_repo = "https://github.com/silverblogtheme/{}.git".format(theme_name)
    if custom:
        git_repo = theme_name
    try:
        git.Repo.clone_from(url=git_repo, to_path=repo_dir, depth=1)
    except git.exc.GitCommandError:
        console.log("Error", "Unable to clone theme repository.")
        exit(1)
    if os.path.exists("{}/package-metadata.json".format(repo_dir)):
        config_example_file = "{}/config.example.json".format(repo_dir)
        static_symlink = "./templates/static/{}".format(theme_name)

        if not os.path.exists(static_symlink):
            os.symlink("{}/templates/{}/static".format(os.getcwd(), theme_name), static_symlink)

        if os.path.exists(config_example_file):
            shutil.copyfile(config_example_file, "{}/config.json".format(repo_dir))

        download_static_file(theme_name)
    if not os.path.exists("{}/package-metadata.json".format(repo_dir)) and os.path.exists("{}/install.sh".format(repo_dir)):
        result_code = os.system("cd templates && bash {}/install.sh".format(theme_name))
        if (result_code >> 8) != 0:
            console.log("Error", "An error occurred while executing the install script.")
            exit(1)
    console.log("Success", "The theme is install successfully!")

def remove_theme(theme_name):
    static_symlink = "./templates/static/{}".format(theme_name)
    if os.path.exists(static_symlink):
        os.remove(static_symlink)

    shutil.rmtree("./templates/" + theme_name)
    console.log("Success", "The theme is removed successfully!")

def upgrade_theme(theme_name):
    import git
    if os.system('cd ./templates/{} && git rev-parse 2> /dev/null > /dev/null'.format(theme_name)) == 0:
        repo = git.Repo("./templates/" + theme_name)
        remote = repo.remote()
        remote.fetch(repo.active_branch)
        if repo.rev_parse("HEAD") != repo.rev_parse("FETCH_HEAD"):
            console.log("Info", "Updating theme, please wait...")
            remote.pull()
            download_static_file(theme_name)
            console.log("Success", "The theme is upgrade successfully!")
            return
    console.log("Info", "No upgrade found.")

def download_static_file(theme_name):
    if not os.path.exists("./templates/{}/package-metadata.json".format(theme_name)):
        return
    download_list_file = "./templates/{}/package-metadata.json".format(theme_name)
    download_file_location = "./templates/{}/static/library".format(theme_name)
    if os.path.exists(download_file_location):
        shutil.rmtree(download_file_location)
    os.mkdir(download_file_location)
    package_info = json.loads(file.read_file(download_list_file))

    download_list = list()
    if "download" in package_info:
        download_list = package_info["download"]

    loop = asyncio.new_event_loop()
    asyncio.set_event_loop(loop)
    tasks = [download_file(item, download_file_location) for item in download_list]
    loop.run_until_complete(asyncio.wait(tasks))
    loop.close()

@asyncio.coroutine
def get_file(url):
    console.log("info", "Downloading file:" + url)
    return requests.get(url)

@asyncio.coroutine
def download_file(item, location):
    result = yield from get_file(item["url"])
    write_path = location
    if "path" in item and item["path"] != "":
        write_path = "{}/{}".format(location, item["path"])
    if not os.path.exists(write_path):
        os.mkdir(write_path)
    yield from file.async_write_binary_file("{}/{}".format(write_path, item["filename"]), result.content)

def get_readme(theme_name):
    console.log("Info", "Getting the readme of theme...")
    try:
        r = requests.get("https://raw.githubusercontent.com/silverblog-theme/{}/master/README.md".format(theme_name))
        return r.text
    except  requests.exceptions.RequestException:
        console.log("Error", "Get the readme error.")
        exit(1)<|endoftext|>


<commit_before>import json
import os
import urllib.request

from common import console, file

def get_orgs_list():
    console.log("info", "Getting the list of theme...")
    try:
        return json.loads(
            urllib.request.urlopen("https://api.github.com/orgs/silverblogtheme/repos").read().decode('utf-8'))
    except urllib.error:
        console.log("Error", "Get the topic list error.")
        exit(1)

def get_local_theme_list():
    from common import file
    directories = file.list_dirs("./templates")
    if "static" in directories:
        directories.remove("static")
    return directories
def install_theme(theme_name, orgs_list=None):
    if orgs_list is None:
        orgs_list = get_orgs_list()
    has_theme = False
    full_name = None
    name = None
    for item in orgs_list:
        if item["name"].lower() == theme_name.lower():
            has_theme = True
            full_name = item["full_name"]
            name = item["name"]
    if not has_theme:
        console.log("Error", "Can not find this theme.")
        exit(1)
    r = None
    r_license = None
    console.log("info", "Getting project license...")
    try:
        r_license = urllib.request.urlopen(
            "https://raw.githubusercontent.com/{}/master/LICENSE".format(full_name)).read().decode('utf-8')
    except urllib.error:
        console.log("Error", "Get the project license error.")
        exit(1)
    print("\n{}\n".format(r_license))
    enable_theme = input('I agree to the terms and conditions. [y/N]')
    if enable_theme.lower() == 'yes' or enable_theme.lower() == 'y':
        console.log("info", "Getting the theme installation script...")
        try:
            r = urllib.request.urlopen(
                "https://raw.githubusercontent.com/{}/master/install.sh".format(full_name)).read().decode('utf-8')
        except urllib.error:
            console.log("Error", "Get the theme installation script error.")
            exit(1)
        os.system("cd templates \n" + r)
        console.log("Success", "The theme is installed successfully!")
    return name

def set_theme(theme_name):
    system_info = json.loads(file.read_file("./config/system.json"))
    system_info["Theme"] = theme_name
    file.write_file("./config/system.json", json.dumps(system_info, indent=4, sort_keys=False, ensure_ascii=False))
    console.log("Success", "The theme has been enabled!")

def remove_theme(theme_name):
    import shutil
    shutil.rmtree("./templates/" + theme_name)
    if os.path.exists("./templates/static/" + theme_name):
        shutil.rmtree("./templates/static/" + theme_name)
    console.log("Success", "The theme is uninstalled successfully!")

def upgrade_theme(theme_name):
    import git
    repo = git.Repo("./templates/" + theme_name)
    remote = repo.remote()
    remote.fetch("master")
    if repo.rev_parse("HEAD") != repo.rev_parse("FETCH_HEAD"):
        remote.pull()
        console.log("Success", "The theme is upgrade successfully!")
        exit()
    console.log("Info", "No upgrade found.")
<commit_msg>去除templates目录中的默认目录文件<commit_after>import json
import os
import urllib.request

from common import console, file

def get_orgs_list():
    console.log("info", "Getting the list of theme...")
    try:
        return json.loads(
            urllib.request.urlopen("https://api.github.com/orgs/silverblogtheme/repos").read().decode('utf-8'))
    except urllib.error:
        console.log("Error", "Get the topic list error.")
        exit(1)

def get_local_theme_list():
    from common import file
    directories = file.list_dirs("./templates")
    if "static" in directories:
        directories.remove("static")
    if "include" in directories:
        directories.remove("include")
    return directories
def install_theme(theme_name, orgs_list=None):
    if orgs_list is None:
        orgs_list = get_orgs_list()
    has_theme = False
    full_name = None
    name = None
    for item in orgs_list:
        if item["name"].lower() == theme_name.lower():
            has_theme = True
            full_name = item["full_name"]
            name = item["name"]
    if not has_theme:
        console.log("Error", "Can not find this theme.")
        exit(1)
    r = None
    r_license = None
    console.log("info", "Getting project license...")
    try:
        r_license = urllib.request.urlopen(
            "https://raw.githubusercontent.com/{}/master/LICENSE".format(full_name)).read().decode('utf-8')
    except urllib.error:
        console.log("Error", "Get the project license error.")
        exit(1)
    print("\n{}\n".format(r_license))
    enable_theme = input('I agree to the terms and conditions. [y/N]')
    if enable_theme.lower() == 'yes' or enable_theme.lower() == 'y':
        console.log("info", "Getting the theme installation script...")
        try:
            r = urllib.request.urlopen(
                "https://raw.githubusercontent.com/{}/master/install.sh".format(full_name)).read().decode('utf-8')
        except urllib.error:
            console.log("Error", "Get the theme installation script error.")
            exit(1)
        os.system("cd templates \n" + r)
        console.log("Success", "The theme is installed successfully!")
    return name

def set_theme(theme_name):
    system_info = json.loads(file.read_file("./config/system.json"))
    system_info["Theme"] = theme_name
    file.write_file("./config/system.json", json.dumps(system_info, indent=4, sort_keys=False, ensure_ascii=False))
    console.log("Success", "The theme has been enabled!")

def remove_theme(theme_name):
    import shutil
    shutil.rmtree("./templates/" + theme_name)
    if os.path.exists("./templates/static/" + theme_name):
        shutil.rmtree("./templates/static/" + theme_name)
    console.log("Success", "The theme is uninstalled successfully!")

def upgrade_theme(theme_name):
    import git
    repo = git.Repo("./templates/" + theme_name)
    remote = repo.remote()
    remote.fetch("master")
    if repo.rev_parse("HEAD") != repo.rev_parse("FETCH_HEAD"):
        remote.pull()
        console.log("Success", "The theme is upgrade successfully!")
        exit()
    console.log("Info", "No upgrade found.")
<|endoftext|>


<commit_before>"""Import timetable data "fresh from the cow"
"""
import os
from requests import Session
from ciso8601 import parse_datetime
from django.core.management.base import BaseCommand
from django.conf import settings
from busstops.models import DataSource, Service
from .import_gtfs import download_if_modified
from .import_transxchange import Command as TransXChangeCommand
from .import_passenger import handle_file
from ...models import Route

class Command(BaseCommand):
    @staticmethod
    def add_arguments(parser):
        parser.add_argument('api_key', nargs=1, type=str)

    def handle(self, api_key, **options):
        command = TransXChangeCommand()
        command.undefined_holidays = set()
        command.notes = {}
        command.corrections = {}

        session = Session()

        for operator_id, region_id, operators in settings.BOD_OPERATORS:
            command.operators = operators
            command.region_id = region_id
            command.service_descriptions = {}
            command.service_codes = set()
            command.calendar_cache = {}

            response = session.get('https://data.bus-data.dft.gov.uk/api/v1/dataset/', params={
                'api_key': api_key,
                'noc': operator_id
            })

            sources = []

            for result in response.json()['results']:
                if result['status'] == 'published':
                    filename = result['name']
                    url = result['url']
                    path = os.path.join(settings.DATA_DIR, filename)
                    modified = download_if_modified(path, url)
                    print(modified, path)

                    command.source, created = DataSource.objects.get_or_create({'name': filename}, url=url)
                    print(command.source.datetime)
                    if not created:
                        command.source.name = filename
                    command.source.datetime = parse_datetime(result['modified'])
                    sources.append(command.source)

                    handle_file(command, filename)
                    print(result)

                    command.source.save(update_fields=['name', 'datetime'])

            print(Route.objects.filter(service__operator__in=operators.values()).exclude(source__in=sources).delete())
            print(Service.objects.filter(operator__in=operators.values(), current=True,
                                         route=None).update(current=False))
<commit_msg>only import Bus Open Data datasets when modified date in API has changed<commit_after>"""Import timetable data "fresh from the cow"
"""
import os
from requests import Session
from ciso8601 import parse_datetime
from django.core.management.base import BaseCommand
from django.conf import settings
from busstops.models import DataSource, Service
from .import_gtfs import download_if_modified
from .import_transxchange import Command as TransXChangeCommand
from .import_passenger import handle_file
from ...models import Route

class Command(BaseCommand):
    @staticmethod
    def add_arguments(parser):
        parser.add_argument('api_key', nargs=1, type=str)

    def handle(self, api_key, **options):
        command = TransXChangeCommand()
        command.undefined_holidays = set()
        command.notes = {}
        command.corrections = {}

        session = Session()

        for operator_id, region_id, operators in settings.BOD_OPERATORS:
            command.operators = operators
            command.region_id = region_id
            command.service_descriptions = {}
            command.service_codes = set()
            command.calendar_cache = {}

            response = session.get('https://data.bus-data.dft.gov.uk/api/v1/dataset/', params={
                'api_key': api_key,
                'noc': operator_id
            })

            sources = []

            for result in response.json()['results']:
                if result['status'] == 'published':
                    filename = result['name']
                    url = result['url']
                    path = os.path.join(settings.DATA_DIR, filename)

                    modified = parse_datetime(result['modified'])

                    command.source, created = DataSource.objects.get_or_create({'name': filename}, url=url)

                    if command.source.datetime != modified:
                        print(result)
                        command.source.datetime = modified
                        download_if_modified(path, url)
                        handle_file(command, filename)

                        if not created:
                            command.source.name = filename
                        command.source.save(update_fields=['name', 'datetime'])

                    sources.append(command.source)

            print(sources)
            print(operators.values())
            print(Route.objects.filter(service__operator__in=operators.values()))
            print(Route.objects.filter(service__operator__in=operators.values()).exclude(source__in=sources))
            print(Route.objects.filter(service__operator__in=operators.values()).exclude(source__in=sources).delete())
            print(Service.objects.filter(operator__in=operators.values(), current=True,
                                         route=None).update(current=False))
<|endoftext|>


<commit_before>import httplib
import httpverbs
import json
import loggers
import readline
import sys
from urlparse import urlparse
from urllib import urlencode

class HttpShell(object):
    def __init__(self, args):
        self.http_commands = {
             "head": self.head,
             "get": self.get,
             "post": self.post,
             "put": self.put,
             "delete": self.delete,
             "cd": self.set_path,
        }

        self.meta_commands = {
             "help": self.help,
             "?": self.help,
             "headers": self.modify_headers,
             "tackons": self.modify_tackons,
             "open": self.open_host,
             "debuglevel": self.set_debuglevel,
             "quit": self.exit
        }

        # dispatch map is http + meta maps
        self.dispatch = dict(
            self.http_commands.items() + self.meta_commands.items())

        self.url = None
        self.path = None
        self.query = None

        self.args = args
        self.headers = {}
        self.tackons = {}

        self.debuglevel = 0

        # all printing is done via the logger, that way a non-ANSI printer
        # will be a lot easier to add retroactively
        self.logger = loggers.AnsiLogger()

        # sets up tab command completion
        readline.set_completer(self.complete)
        readline.parse_and_bind("tab: complete")

        # setup host and initinal path
        self.init_host(self.args.url)

    # dispatch methods

    def head(self, path, pipe=None):
        httpverbs.HttpHead(
            self.connect(path), path, pipe, self.logger).run(self.headers)

    def get(self, path, pipe=None):
        httpverbs.HttpGet(
            self.connect(path), path, pipe, self.logger).run(self.headers)

    def post(self, path, pipe=None):
        body = self.input_body()

        if body:
            httpverbs.HttpPost(self.connect(path),
                path, pipe, body, self.logger).run(self.headers)

    def put(self, path, pipe=None):
        body = self.input_body()

        if body:
            httpverbs.HttpPut(self.connect(path),
                path, pipe, body, self.logger).run(self.headers)

    def delete(self, path, pipe=None):
        httpverbs.HttpDelete(
            self.connect(path), path, pipe, self.logger).run(self.headers)

    def help(self):
        self.logger.print_help()

    # handles .headers meta-command
    def modify_headers(self, header=None):
        if header and len(header) > 0:
            # header will be header:[value]
            a = header.split(":", 1)
            key = a[0]
            if len(a) > 1:
                value = a[1]

                if len(value) > 0:
                    self.headers[key] = value
                elif key in self.headers:
                    del self.headers[key]  # if no value provided, delete
            else:
                self.logger.print_error("Invalid syntax.")
        else:
            # print send headers
            self.logger.print_headers(self.headers.items(), sending=True)

    # handles params meta-command
    def modify_tackons(self, args=None):
        if args and len(args) > 0:
            # args will be param:[value]

            if not "=" in args[0]:
                key = "".join(args)
                value = ""
                self.tackons[key] = value
            else:
                a = args[0].split("=", 1)
                key = a[0]

                if len(a) > 1:
                    value = a[1]

                if len(value) > 0:
                    self.tackons[key] = value
                elif key in self.tackons:
                    del self.tackons[key]  # if no value provided, delete
        else:
            # print send tackons
            self.logger.print_tackons(self.tackons.items())

    # changes the current host
    def open_host(self, url=None):
        if url:
            self.init_host(url)

    # handles cd <path> command
    def set_path(self, path):
        path = path.split("?")[0]  # chop off any query params

        if path == "..":
            path = "".join(self.path.rsplit("/", 1)[:1])

        self.path = path if path else "/"

    def set_debuglevel(self, level=None):
        if not level:
            self.logger.print_text(str(self.debuglevel))
        else:
            try:
                self.debuglevel = int(level)
            except:
                pass

    def init_host(self, url):
        # url parse needs a proceeding "//" for default scheme param to work
        if not "//" in url[:8]:
            url = "//" + url

        self.url = urlparse(url, "http")
        self.path = self.url.path if self.url.path else "/"
        self.query = self.url.query

    # converts tackon dict to query params
    def dict_to_query(self, map):
        l = []
        for k, v in sorted(map.items()):
            s = k
            if(v):
                s += "=" + str(v)
            l.append(s)

        return "&".join(l)

    # combine two query strings into one
    def combine_queries(self, a, b):
        s = ""
        if a and len(a) > 0:
            s = a
            if b and len(b) > 0:
                s += "&"
        if b and len(b) > 0:
            s += b

        return s

    # modifies the path for tackon query params
    def mod_path(self, path, query=None):
        q = self.combine_queries(
                query, self.dict_to_query(self.tackons))

        if len(q) > 0:
            return path + "?" + q
        else:
            return path

    # readline complete handler
    def complete(self, text, state):
        match = [s for s in self.dispatch.keys() if s
            and s.startswith(text)] + [None]

        return match[state]

    # connecting is done on-demand from the dispatch methods
    def connect(self, path):
        self.logger.print_text("Connecting to {0}://{1}{2}\n".format(
             self.url.scheme, self.url.netloc, path))

        host = self.url.netloc
        port = None
        connection = None

        # handle user-supplied ports from command line
        if ":" in host:
            split = host.split(":")
            host = split[0]
            port = split[1]

        if(self.url.scheme == "https"):
            connection = httplib.HTTPSConnection(host, port if port else 443)
        else:
            connection = httplib.HTTPConnection(host, port if port else 80)

        connection.set_debuglevel(self.debuglevel)

        return connection

    # read lines of input for POST/PUT
    def input_body(self):
        list = []

        while True:
            line = raw_input("... ")
            if len(line) == 0:
                break
            list.append(line)

        # join list to form string
        params = "".join(list)

        if params[:2] == "@{":  # magic JSON -> urlencode invoke char
            params = self.json_to_urlencode(params[1:])

        return params

    # converts JSON to url encoded for easier posting forms
    def json_to_urlencode(self, json_string):
        params = None

        try:
            o = json.loads(json_string)
            params = urlencode(o)
        except ValueError:
            self.logger.print_error("Malformed JSON.")

        return params

    def input_loop(self):
        command = None

        while command != ".quit":
            try:
                prompt = "{0}:{1}> ".format(self.url.netloc, self.path)

                # a valid command line will be <command> [path] [| filter]
                input = raw_input(prompt).split()

                # ignore blank input
                if not input or len(input) == 0:
                    continue

                # command will be element 0 in the array from split
                command = input.pop(0)

                if command in self.dispatch:
                    # push arguments to the stack for command
                    args = self.parse_args(input, command)

                    # invoke command via dispatch table
                    try:
                        self.dispatch[command](*args)
                    except Exception as e:
                        self.logger.print_error(
                           "Error: {0}".format(e))
                else:
                    self.logger.print_error("Invalid command.")
            except (EOFError, KeyboardInterrupt):
                break

        print
        self.exit()

    # parses input to set up the call stack for dispatch commands
    def parse_args(self, args, command):
        stack = []

        # ignore meta-commands
        if command not in self.meta_commands:
            path = None
            pipe = None

            if len(args) > 0:
                # element 0 of args array will be the path element
                path = args.pop(0)

                # there's a pipe in my path!
                # user didn't use whitespace between path and pipe character
                # also accounts for if the user did not supply a path
                if "|" in path:
                    s = path.split("|", 1)
                    path = s.pop(0)
                    args.insert(0, "".join(s))

                # pipe, if exists, will be first element in array now
                if len(args) > 0:
                    pipe = " ".join(args).strip()

                    if pipe[0] == "|":
                        pipe = pipe[1:]

                # account for requests from relative dirs
                if path and not path[0] in "/.":
                    path = "{0}{1}{2}".format(
                        self.path,
                        "/" if self.path[-1] != "/" else "",
                        path)

            # push the path on the stack for command method
            # if it's empty the user did not supply one so use self.path
            if path:
                query = None
                a = path.split("?")  # chop query params

                if len(a) > 1:
                    path = a[0]
                    query = a[1]
                stack.append(self.mod_path(path, query))
            else:
                stack.append(self.mod_path(self.path, self.query))

            if pipe:
                stack.append(pipe)
        else:
            if len(args) > 0:
                # meta-commands to their own arg parsing
                stack.append(" ".join(args))

        return stack

    def exit(self, args=None):
        sys.exit(0)
<commit_msg>Remove artifact code<commit_after>import httplib
import httpverbs
import json
import loggers
import readline
import sys
from urlparse import urlparse
from urllib import urlencode

class HttpShell(object):
    def __init__(self, args):
        self.http_commands = {
             "head": self.head,
             "get": self.get,
             "post": self.post,
             "put": self.put,
             "delete": self.delete,
             "cd": self.set_path,
        }

        self.meta_commands = {
             "help": self.help,
             "?": self.help,
             "headers": self.modify_headers,
             "tackons": self.modify_tackons,
             "open": self.open_host,
             "debuglevel": self.set_debuglevel,
             "quit": self.exit
        }

        # dispatch map is http + meta maps
        self.dispatch = dict(
            self.http_commands.items() + self.meta_commands.items())

        self.url = None
        self.path = None
        self.query = None

        self.args = args
        self.headers = {}
        self.tackons = {}

        self.debuglevel = 0

        # all printing is done via the logger, that way a non-ANSI printer
        # will be a lot easier to add retroactively
        self.logger = loggers.AnsiLogger()

        # sets up tab command completion
        readline.set_completer(self.complete)
        readline.parse_and_bind("tab: complete")

        # setup host and initinal path
        self.init_host(self.args.url)

    # dispatch methods

    def head(self, path, pipe=None):
        httpverbs.HttpHead(
            self.connect(path), path, pipe, self.logger).run(self.headers)

    def get(self, path, pipe=None):
        httpverbs.HttpGet(
            self.connect(path), path, pipe, self.logger).run(self.headers)

    def post(self, path, pipe=None):
        body = self.input_body()

        if body:
            httpverbs.HttpPost(self.connect(path),
                path, pipe, body, self.logger).run(self.headers)

    def put(self, path, pipe=None):
        body = self.input_body()

        if body:
            httpverbs.HttpPut(self.connect(path),
                path, pipe, body, self.logger).run(self.headers)

    def delete(self, path, pipe=None):
        httpverbs.HttpDelete(
            self.connect(path), path, pipe, self.logger).run(self.headers)

    def help(self):
        self.logger.print_help()

    # handles .headers meta-command
    def modify_headers(self, header=None):
        if header and len(header) > 0:
            # header will be header:[value]
            a = header.split(":", 1)
            key = a[0]
            if len(a) > 1:
                value = a[1]

                if len(value) > 0:
                    self.headers[key] = value
                elif key in self.headers:
                    del self.headers[key]  # if no value provided, delete
            else:
                self.logger.print_error("Invalid syntax.")
        else:
            # print send headers
            self.logger.print_headers(self.headers.items(), sending=True)

    # handles params meta-command
    def modify_tackons(self, args=None):
        if args and len(args) > 0:
            # args will be param:[value]

            if not "=" in args[0]:
                key = "".join(args)
                value = ""
                self.tackons[key] = value
            else:
                a = args[0].split("=", 1)
                key = a[0]

                if len(a) > 1:
                    value = a[1]

                if len(value) > 0:
                    self.tackons[key] = value
                elif key in self.tackons:
                    del self.tackons[key]  # if no value provided, delete
        else:
            # print send tackons
            self.logger.print_tackons(self.tackons.items())

    # changes the current host
    def open_host(self, url=None):
        if url:
            self.init_host(url)

    # handles cd <path> command
    def set_path(self, path):
        path = path.split("?")[0]  # chop off any query params

        if path == "..":
            path = "".join(self.path.rsplit("/", 1)[:1])

        self.path = path if path else "/"

    def set_debuglevel(self, level=None):
        if not level:
            self.logger.print_text(str(self.debuglevel))
        else:
            try:
                self.debuglevel = int(level)
            except:
                pass

    def init_host(self, url):
        # url parse needs a proceeding "//" for default scheme param to work
        if not "//" in url[:8]:
            url = "//" + url

        self.url = urlparse(url, "http")
        self.path = self.url.path if self.url.path else "/"
        self.query = self.url.query

    # converts tackon dict to query params
    def dict_to_query(self, map):
        l = []
        for k, v in sorted(map.items()):
            s = k
            if(v):
                s += "=" + str(v)
            l.append(s)

        return "&".join(l)

    # combine two query strings into one
    def combine_queries(self, a, b):
        s = ""
        if a and len(a) > 0:
            s = a
            if b and len(b) > 0:
                s += "&"
        if b and len(b) > 0:
            s += b

        return s

    # modifies the path for tackon query params
    def mod_path(self, path, query=None):
        q = self.combine_queries(
                query, self.dict_to_query(self.tackons))

        if len(q) > 0:
            return path + "?" + q
        else:
            return path

    # readline complete handler
    def complete(self, text, state):
        match = [s for s in self.dispatch.keys() if s
            and s.startswith(text)] + [None]

        return match[state]

    # connecting is done on-demand from the dispatch methods
    def connect(self, path):
        self.logger.print_text("Connecting to {0}://{1}{2}\n".format(
             self.url.scheme, self.url.netloc, path))

        host = self.url.netloc
        port = None
        connection = None

        # handle user-supplied ports from command line
        if ":" in host:
            split = host.split(":")
            host = split[0]
            port = split[1]

        if(self.url.scheme == "https"):
            connection = httplib.HTTPSConnection(host, port if port else 443)
        else:
            connection = httplib.HTTPConnection(host, port if port else 80)

        connection.set_debuglevel(self.debuglevel)

        return connection

    # read lines of input for POST/PUT
    def input_body(self):
        list = []

        while True:
            line = raw_input("... ")
            if len(line) == 0:
                break
            list.append(line)

        # join list to form string
        params = "".join(list)

        if params[:2] == "@{":  # magic JSON -> urlencode invoke char
            params = self.json_to_urlencode(params[1:])

        return params

    # converts JSON to url encoded for easier posting forms
    def json_to_urlencode(self, json_string):
        params = None

        try:
            o = json.loads(json_string)
            params = urlencode(o)
        except ValueError:
            self.logger.print_error("Malformed JSON.")

        return params

    def input_loop(self):
        command = None

        while True:
            try:
                prompt = "{0}:{1}> ".format(self.url.netloc, self.path)

                # a valid command line will be <command> [path] [| filter]
                input = raw_input(prompt).split()

                # ignore blank input
                if not input or len(input) == 0:
                    continue

                # command will be element 0 in the array from split
                command = input.pop(0)

                if command in self.dispatch:
                    # push arguments to the stack for command
                    args = self.parse_args(input, command)

                    # invoke command via dispatch table
                    try:
                        self.dispatch[command](*args)
                    except Exception as e:
                        self.logger.print_error(
                           "Error: {0}".format(e))
                else:
                    self.logger.print_error("Invalid command.")
            except (EOFError, KeyboardInterrupt):
                break

        print
        self.exit()

    # parses input to set up the call stack for dispatch commands
    def parse_args(self, args, command):
        stack = []

        # ignore meta-commands
        if command not in self.meta_commands:
            path = None
            pipe = None

            if len(args) > 0:
                # element 0 of args array will be the path element
                path = args.pop(0)

                # there's a pipe in my path!
                # user didn't use whitespace between path and pipe character
                # also accounts for if the user did not supply a path
                if "|" in path:
                    s = path.split("|", 1)
                    path = s.pop(0)
                    args.insert(0, "".join(s))

                # pipe, if exists, will be first element in array now
                if len(args) > 0:
                    pipe = " ".join(args).strip()

                    if pipe[0] == "|":
                        pipe = pipe[1:]

                # account for requests from relative dirs
                if path and not path[0] in "/.":
                    path = "{0}{1}{2}".format(
                        self.path,
                        "/" if self.path[-1] != "/" else "",
                        path)

            # push the path on the stack for command method
            # if it's empty the user did not supply one so use self.path
            if path:
                query = None
                a = path.split("?")  # chop query params

                if len(a) > 1:
                    path = a[0]
                    query = a[1]
                stack.append(self.mod_path(path, query))
            else:
                stack.append(self.mod_path(self.path, self.query))

            if pipe:
                stack.append(pipe)
        else:
            if len(args) > 0:
                # meta-commands to their own arg parsing
                stack.append(" ".join(args))

        return stack

    def exit(self, args=None):
        sys.exit(0)
<|endoftext|>


<commit_before>from inspect import isfunction
import logging, itertools, pickle, base64, hashlib
from datetime import datetime, date

import simplejson
from lxml import etree

from django.db import models
from django.http import HttpRequest, HttpResponse, HttpResponseBadRequest, HttpResponseNotAllowed, HttpResponseForbidden, Http404
from django.template import RequestContext
from django.shortcuts import render_to_response
from django.core.urlresolvers import reverse, resolve, NoReverseMatch
from django.core.cache import cache
from django.conf import settings

logger = logging.getLogger('core.requests')

from .http import MediaType
from .simplify import simplify_value, simplify_model, serialize_to_xml

def renderer(format, mimetypes=(), priority=0, name=None):
    """
    Decorates a view method to say that it renders a particular format and mimetypes.

    Use as:
        @renderer(format="foo")
        def render_foo(self, request, context, template_name): ...
    or
        @renderer(format="foo", mimetypes=("application/x-foo",))
        def render_foo(self, request, context, template_name): ...

    The former case will inherit mimetypes from the previous renderer for that
    format in the MRO. Where there isn't one, it will default to the empty
    tuple.

    Takes an optional priority argument to resolve ties between renderers.
    """

    def g(f):
        f.is_renderer = True
        f.format = format
        f.mimetypes = set(MediaType(mimetype, priority) for mimetype in mimetypes)
        f.name = name
        return f
    return g

class BaseViewMetaclass(type):
    def __new__(cls, name, bases, dict):

        # Pull the renderers from the bases into a couple of new dicts for
        # this view's renderers
        formats_by_mimetype = {}
        formats = {}
        for base in reversed(bases):
            if hasattr(base, 'FORMATS'):
                formats.update(base.FORMATS)
                formats_by_mimetype.update(base.FORMATS_BY_MIMETYPE)

        for key, value in dict.items():
            # If the method is a renderer we add it to our dicts. We can't add
            # the functions right now because we want them bound to the view
            # instance that hasn't yet been created. Instead, add the keys (strs)
            # and we'll replace them with the bound instancemethods in BaseView.__init__.
            if isfunction(value) and getattr(value, 'is_renderer', False):
                if value.mimetypes is not None:
                    mimetypes = value.mimetypes
                elif value.format in formats:
                    mimetypes = formats[value.format].mimetypes
                else:
                    mimetypes = ()
                for mimetype in mimetypes:
                    formats_by_mimetype[mimetype] = key
                formats[value.format] = key

        dict.update({
            'FORMATS': formats,
            'FORMATS_BY_MIMETYPE': formats_by_mimetype,
        })

        # Create our view.
        view = type.__new__(cls, name, bases, dict)

        return view

class BaseView(object):
    __metaclass__ = BaseViewMetaclass

    ALLOWABLE_METHODS = ('GET', 'POST', 'DELETE', 'HEAD', 'OPTIONS', 'PUT')

    def method_not_allowed(self, request):
        return HttpResponseNotAllowed([m for m in self.ALLOWABLE_METHODS if hasattr(self, 'handle_%s' % m)])

    def not_acceptable(self, request):
        response = HttpResponse("The desired media type is not supported for this resource.", mimetype="text/plain")
        response.status_code = 406
        return response

    def bad_request(self, request):
        response = HttpResponse(
            'Your request was malformed.',
            status=400,
        )
        return response

    def initial_context(self, request, *args, **kwargs):
        return {}

    def __init__(self):
        # Resolve renderer names to bound instancemethods. Also turn the
        # FORMATS_BY_MIMETYPE dict into a list of pairs ordered by descending priority.
        self.FORMATS = dict((key, getattr(self, value)) for key, value in self.FORMATS.items())
        formats_sorted = sorted(self.FORMATS_BY_MIMETYPE.items(), key=lambda x: x[0].priority, reverse=True)
        self.FORMATS_BY_MIMETYPE = tuple((key, getattr(self, value)) for (key, value) in formats_sorted)

    def __unicode__(self):
        cls = type(self)
        return ".".join((cls.__module__, cls.__name__))

    def __call__(self, request, *args, **kwargs):
        method_name = 'handle_%s' % request.method
        if hasattr(self, method_name):
            method = getattr(self, method_name)
            request.renderers = self.get_renderers(request)
            if request.renderers and request.renderers[0].format == 'html' and \
               getattr(method, 'cached', False) and request.method in ('GET', 'HEAD') and not request.GET:
                key = hashlib.sha1('pickled-response:%s' % request.build_absolute_uri()).hexdigest()
                pickled_response = cache.get(key)
                if pickled_response is not None:
                    try:
                        return pickle.loads(base64.b64decode(pickled_response))
                    except Exception:
                        pass
                context = self.initial_context(request, *args, **kwargs)
                response = method(request, context, *args, **kwargs)
                pickled_response = base64.b64encode(pickle.dumps(response))
                cache.set(key, pickled_response, settings.CACHE_TIMES['page'])
                return response
            context = self.initial_context(request, *args, **kwargs)
            response = method(request, context, *args, **kwargs)
            return response
        else:
            return self.method_not_allowed(request)

    def handle_HEAD(self, request, *args, **kwargs):
        """
        Provides a default HEAD handler that strips the content from the
        response returned by the GET handler.
        """
        if hasattr(self, 'handle_GET'):
            response = self.handle_GET(request, *args, **kwargs)
        else:
            response = self.method_not_acceptable(request)
        response.content = ''
        return response

    def get_zoom(self, request, default=16):
        try:
            zoom = int(request.GET['zoom'])
        except (ValueError, KeyError):
            zoom = default
        else:
            zoom = min(max(10, zoom), 18)
        return zoom

    def get_renderers(self, request):
        if 'format' in request.REQUEST:
            formats = request.REQUEST['format'].split(',')
            renderers, seen_formats = [], set()
            for format in formats:
                if format in self.FORMATS and format not in seen_formats:
                    renderers.append(self.FORMATS[format])
        elif request.META.get('HTTP_ACCEPT'):
            accepts = self.parse_accept_header(request.META['HTTP_ACCEPT'])
            renderers = MediaType.resolve(accepts, self.FORMATS_BY_MIMETYPE)
        else:
            renderers = [self.FORMATS['html']]
        return renderers

    def render(self, request, context, template_name):

        status_code = context.pop('status_code', 200)

        for renderer in request.renderers:
            try:
                response = renderer(request, context, template_name)
                response.status_code = status_code
                response['Access-Control-Allow-Origin'] = '*'
                return response
            except NotImplementedError:
                continue
        else:
            tried_mimetypes = list(itertools.chain(*[r.mimetypes for r in request.renderers]))
            response = HttpResponse("""\
Your Accept header didn't contain any supported media ranges.

Supported ranges are:

 * %s\n""" % '\n * '.join(sorted('%s (%s)' % (f[0].value, f[1].format) for f in self.FORMATS_BY_MIMETYPE if not f[0] in tried_mimetypes)), mimetype="text/plain")
            response.status_code = 406 # Not Acceptable
            return response

    @classmethod
    def parse_accept_header(cls, accept):
        media_types = []
        for media_type in accept.split(','):
            try:
                media_types.append(MediaType(media_type))
            except ValueError:
                pass
        return media_types

    def render_to_format(self, request, context, template_name, format):
        render_method = self.FORMATS[format]
        status_code = context.pop('status_code', 200)
        response = render_method(request, context, template_name)
        response.status_code = status_code
        return response

    #@renderer(format="json", mimetypes=('application/json',), name='JSON')
    def render_json(self, request, context, template_name):
        callback = request.GET.get('callback', request.GET.get('jsonp', None))
        context = simplify_value(context)
        content = simplejson.dumps(context)
        if callback:
            content = '%s(%s);' % (callback, content)
            mimetype = 'application/javascript'
        else:
            mimetype = 'application/json'

        return HttpResponse(content, mimetype=mimetype)

    #@renderer(format="js", mimetypes=('text/javascript','application/javascript',), name='JavaScript')
    def render_js(self, request, context, template_name):
        callback = request.GET.get('callback', request.GET.get('jsonp', 'callback'))
        content = simplejson.dumps(simplify_value(context))
        content = "%s(%s);" % (callback, content)
        return HttpResponse(content, mimetype="application/javascript")

    @renderer(format="html", mimetypes=('text/html', 'application/xhtml+xml'), priority=1, name='HTML')
    def render_html(self, request, context, template_name):
        if template_name is None:
            raise NotImplementedError
        return render_to_response(template_name+'.html',
                                  context, context_instance=RequestContext(request),
                                  mimetype='text/html')

    #@renderer(format="xml", mimetypes=('application/xml', 'text/xml'), name='XML')
    def render_xml(self, request, context, template_name):
        context = simplify_value(context)
        return HttpResponse(etree.tostring(serialize_to_xml(context), encoding='UTF-8'), mimetype="application/xml")

    # We don't want to depend on YAML. If it's there offer it as a renderer, otherwise ignore it.
    try:
        __import__('yaml') # Try importing, but don't stick the result in locals.
        @renderer(format="yaml", mimetypes=('application/x-yaml',), priority=-1, name='YAML')
        def render_yaml(self, request, context, template_name):
            import yaml
            context = simplify_value(context)
            return HttpResponse(yaml.safe_dump(context), mimetype="application/x-yaml")
    except ImportError, e:
        pass

def ReverseView(request):
    try:
        name = request.GET['name']
        args = request.GET.getlist('arg')

        path = reverse(name, args=args)
        view, view_args, view_kwargs = resolve(path)
        return HttpResponse("http://%s%s" % (
            request.META['HTTP_HOST'],
            path,
        ), mimetype='text/plain')
    except NoReverseMatch:
        raise Http404
    except KeyError:
        return HttpResponseBadRequest()
<commit_msg>Disabled YAML renderer.<commit_after>from inspect import isfunction
import logging, itertools, pickle, base64, hashlib
from datetime import datetime, date

import simplejson
from lxml import etree

from django.db import models
from django.http import HttpRequest, HttpResponse, HttpResponseBadRequest, HttpResponseNotAllowed, HttpResponseForbidden, Http404
from django.template import RequestContext
from django.shortcuts import render_to_response
from django.core.urlresolvers import reverse, resolve, NoReverseMatch
from django.core.cache import cache
from django.conf import settings

logger = logging.getLogger('core.requests')

from .http import MediaType
from .simplify import simplify_value, simplify_model, serialize_to_xml

def renderer(format, mimetypes=(), priority=0, name=None):
    """
    Decorates a view method to say that it renders a particular format and mimetypes.

    Use as:
        @renderer(format="foo")
        def render_foo(self, request, context, template_name): ...
    or
        @renderer(format="foo", mimetypes=("application/x-foo",))
        def render_foo(self, request, context, template_name): ...

    The former case will inherit mimetypes from the previous renderer for that
    format in the MRO. Where there isn't one, it will default to the empty
    tuple.

    Takes an optional priority argument to resolve ties between renderers.
    """

    def g(f):
        f.is_renderer = True
        f.format = format
        f.mimetypes = set(MediaType(mimetype, priority) for mimetype in mimetypes)
        f.name = name
        return f
    return g

class BaseViewMetaclass(type):
    def __new__(cls, name, bases, dict):

        # Pull the renderers from the bases into a couple of new dicts for
        # this view's renderers
        formats_by_mimetype = {}
        formats = {}
        for base in reversed(bases):
            if hasattr(base, 'FORMATS'):
                formats.update(base.FORMATS)
                formats_by_mimetype.update(base.FORMATS_BY_MIMETYPE)

        for key, value in dict.items():
            # If the method is a renderer we add it to our dicts. We can't add
            # the functions right now because we want them bound to the view
            # instance that hasn't yet been created. Instead, add the keys (strs)
            # and we'll replace them with the bound instancemethods in BaseView.__init__.
            if isfunction(value) and getattr(value, 'is_renderer', False):
                if value.mimetypes is not None:
                    mimetypes = value.mimetypes
                elif value.format in formats:
                    mimetypes = formats[value.format].mimetypes
                else:
                    mimetypes = ()
                for mimetype in mimetypes:
                    formats_by_mimetype[mimetype] = key
                formats[value.format] = key

        dict.update({
            'FORMATS': formats,
            'FORMATS_BY_MIMETYPE': formats_by_mimetype,
        })

        # Create our view.
        view = type.__new__(cls, name, bases, dict)

        return view

class BaseView(object):
    __metaclass__ = BaseViewMetaclass

    ALLOWABLE_METHODS = ('GET', 'POST', 'DELETE', 'HEAD', 'OPTIONS', 'PUT')

    def method_not_allowed(self, request):
        return HttpResponseNotAllowed([m for m in self.ALLOWABLE_METHODS if hasattr(self, 'handle_%s' % m)])

    def not_acceptable(self, request):
        response = HttpResponse("The desired media type is not supported for this resource.", mimetype="text/plain")
        response.status_code = 406
        return response

    def bad_request(self, request):
        response = HttpResponse(
            'Your request was malformed.',
            status=400,
        )
        return response

    def initial_context(self, request, *args, **kwargs):
        return {}

    def __init__(self):
        # Resolve renderer names to bound instancemethods. Also turn the
        # FORMATS_BY_MIMETYPE dict into a list of pairs ordered by descending priority.
        self.FORMATS = dict((key, getattr(self, value)) for key, value in self.FORMATS.items())
        formats_sorted = sorted(self.FORMATS_BY_MIMETYPE.items(), key=lambda x: x[0].priority, reverse=True)
        self.FORMATS_BY_MIMETYPE = tuple((key, getattr(self, value)) for (key, value) in formats_sorted)

    def __unicode__(self):
        cls = type(self)
        return ".".join((cls.__module__, cls.__name__))

    def __call__(self, request, *args, **kwargs):
        method_name = 'handle_%s' % request.method
        if hasattr(self, method_name):
            method = getattr(self, method_name)
            request.renderers = self.get_renderers(request)
            if request.renderers and request.renderers[0].format == 'html' and \
               getattr(method, 'cached', False) and request.method in ('GET', 'HEAD') and not request.GET:
                key = hashlib.sha1('pickled-response:%s' % request.build_absolute_uri()).hexdigest()
                pickled_response = cache.get(key)
                if pickled_response is not None:
                    try:
                        return pickle.loads(base64.b64decode(pickled_response))
                    except Exception:
                        pass
                context = self.initial_context(request, *args, **kwargs)
                response = method(request, context, *args, **kwargs)
                pickled_response = base64.b64encode(pickle.dumps(response))
                cache.set(key, pickled_response, settings.CACHE_TIMES['page'])
                return response
            context = self.initial_context(request, *args, **kwargs)
            response = method(request, context, *args, **kwargs)
            return response
        else:
            return self.method_not_allowed(request)

    def handle_HEAD(self, request, *args, **kwargs):
        """
        Provides a default HEAD handler that strips the content from the
        response returned by the GET handler.
        """
        if hasattr(self, 'handle_GET'):
            response = self.handle_GET(request, *args, **kwargs)
        else:
            response = self.method_not_acceptable(request)
        response.content = ''
        return response

    def get_zoom(self, request, default=16):
        try:
            zoom = int(request.GET['zoom'])
        except (ValueError, KeyError):
            zoom = default
        else:
            zoom = min(max(10, zoom), 18)
        return zoom

    def get_renderers(self, request):
        if 'format' in request.REQUEST:
            formats = request.REQUEST['format'].split(',')
            renderers, seen_formats = [], set()
            for format in formats:
                if format in self.FORMATS and format not in seen_formats:
                    renderers.append(self.FORMATS[format])
        elif request.META.get('HTTP_ACCEPT'):
            accepts = self.parse_accept_header(request.META['HTTP_ACCEPT'])
            renderers = MediaType.resolve(accepts, self.FORMATS_BY_MIMETYPE)
        else:
            renderers = [self.FORMATS['html']]
        return renderers

    def render(self, request, context, template_name):

        status_code = context.pop('status_code', 200)

        for renderer in request.renderers:
            try:
                response = renderer(request, context, template_name)
                response.status_code = status_code
                response['Access-Control-Allow-Origin'] = '*'
                return response
            except NotImplementedError:
                continue
        else:
            tried_mimetypes = list(itertools.chain(*[r.mimetypes for r in request.renderers]))
            response = HttpResponse("""\
Your Accept header didn't contain any supported media ranges.

Supported ranges are:

 * %s\n""" % '\n * '.join(sorted('%s (%s)' % (f[0].value, f[1].format) for f in self.FORMATS_BY_MIMETYPE if not f[0] in tried_mimetypes)), mimetype="text/plain")
            response.status_code = 406 # Not Acceptable
            return response

    @classmethod
    def parse_accept_header(cls, accept):
        media_types = []
        for media_type in accept.split(','):
            try:
                media_types.append(MediaType(media_type))
            except ValueError:
                pass
        return media_types

    def render_to_format(self, request, context, template_name, format):
        render_method = self.FORMATS[format]
        status_code = context.pop('status_code', 200)
        response = render_method(request, context, template_name)
        response.status_code = status_code
        return response

    #@renderer(format="json", mimetypes=('application/json',), name='JSON')
    def render_json(self, request, context, template_name):
        callback = request.GET.get('callback', request.GET.get('jsonp', None))
        context = simplify_value(context)
        content = simplejson.dumps(context)
        if callback:
            content = '%s(%s);' % (callback, content)
            mimetype = 'application/javascript'
        else:
            mimetype = 'application/json'

        return HttpResponse(content, mimetype=mimetype)

    #@renderer(format="js", mimetypes=('text/javascript','application/javascript',), name='JavaScript')
    def render_js(self, request, context, template_name):
        callback = request.GET.get('callback', request.GET.get('jsonp', 'callback'))
        content = simplejson.dumps(simplify_value(context))
        content = "%s(%s);" % (callback, content)
        return HttpResponse(content, mimetype="application/javascript")

    @renderer(format="html", mimetypes=('text/html', 'application/xhtml+xml'), priority=1, name='HTML')
    def render_html(self, request, context, template_name):
        if template_name is None:
            raise NotImplementedError
        return render_to_response(template_name+'.html',
                                  context, context_instance=RequestContext(request),
                                  mimetype='text/html')

    #@renderer(format="xml", mimetypes=('application/xml', 'text/xml'), name='XML')
    def render_xml(self, request, context, template_name):
        context = simplify_value(context)
        return HttpResponse(etree.tostring(serialize_to_xml(context), encoding='UTF-8'), mimetype="application/xml")

    # We don't want to depend on YAML. If it's there offer it as a renderer, otherwise ignore it.
    try:
        __import__('yaml') # Try importing, but don't stick the result in locals.
        #@renderer(format="yaml", mimetypes=('application/x-yaml',), priority=-1, name='YAML')
        def render_yaml(self, request, context, template_name):
            import yaml
            context = simplify_value(context)
            return HttpResponse(yaml.safe_dump(context), mimetype="application/x-yaml")
    except ImportError, e:
        pass

def ReverseView(request):
    try:
        name = request.GET['name']
        args = request.GET.getlist('arg')

        path = reverse(name, args=args)
        view, view_args, view_kwargs = resolve(path)
        return HttpResponse("http://%s%s" % (
            request.META['HTTP_HOST'],
            path,
        ), mimetype='text/plain')
    except NoReverseMatch:
        raise Http404
    except KeyError:
        return HttpResponseBadRequest()
<|endoftext|>


<commit_before># -*- coding: utf-8 -*-
##############################################################################
#
#    Author: Nicolas Bessi. Copyright Camptocamp SA
#
#    This program is free software: you can redistribute it and/or modify
#    it under the terms of the GNU Affero General Public License as
#    published by the Free Software Foundation, either version 3 of the
#    License, or (at your option) any later version.
#
#    This program is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#    GNU Affero General Public License for more details.
#
#    You should have received a copy of the GNU Affero General Public License
#    along with this program.  If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
from openerp.osv.orm import Model
from openerp.tools import mod10r

class AccountInvoice(Model):

    _inherit = "account.invoice"

    def onchange_partner_id(self, cursor, uid, ids, invoice_type, partner_id,
                            date_invoice=False, payment_term=False,
                            partner_bank_id=False, company_id=False):
        """ Function that is call when the partner of the invoice is changed
        it will retrieve and set the good bank partner bank"""
        #context not define in signature of function in account module
        context = {}
        res = super(AccountInvoice, self).onchange_partner_id(cursor, uid, ids, invoice_type, partner_id,
                                                              date_invoice=False, payment_term=False,
                                                              partner_bank_id=False, company_id=False)
        bank_id = False
        if partner_id:
            if invoice_type in ('in_invoice', 'in_refund'):
                p = self.pool.get('res.partner').browse(cursor, uid, partner_id, context)
                if p.bank_ids:
                    bank_id = p.bank_ids[0].id
                res['value']['partner_bank_id'] = bank_id
            else:
                user = self.pool.get('res.users').browse(cursor, uid, uid, context)
                bank_ids = user.company_id.partner_id.bank_ids
                if bank_ids:
                    res['value']['partner_bank_id'] = bank_ids[0].id

        if partner_bank_id != bank_id:
            to_update = self.onchange_partner_bank(cursor, uid, ids, bank_id)
            res['value'].update(to_update['value'])
        return res

    def onchange_partner_bank(self, cursor, user, ids, partner_bank_id):
        """update the reference invoice_type depending of the partner bank"""
        res = {'value': {}}
        partner_bank_obj = self.pool.get('res.partner.bank')
        if partner_bank_id:
            partner_bank = partner_bank_obj.browse(cursor, user, partner_bank_id)
            if partner_bank.state in ('bvr', 'bv'):
                res['value']['reference_type'] = 'bvr'
        return res

    def _check_reference_type(self, cursor, user, ids, context=None):
        """Check the supplier invoice reference type depending
        on the BVR reference type and the invoice partner bank type"""
        for invoice in self.browse(cursor, user, ids):
            if invoice.type in 'in_invoice':
                if invoice.partner_bank_id and invoice.partner_bank_id.state in ('bvr', 'bv') and \
                        invoice.reference_type != 'bvr':
                    return False
        return True

    def _check_bvr(self, cr, uid, ids, context=None):
        """
        Function to validate a bvr reference like :
        0100054150009>132000000000000000000000014+ 1300132412>
        The validation is based on l10n_ch
        """
        invoices = self.browse(cr, uid, ids)
        for invoice in invoices:
            if invoice.reference_type == 'bvr' and invoice.state != 'draft':
                if not invoice.reference:
                    return False
                ## In this case
                # <010001000060190> 052550152684006+ 43435>
                # the reference 052550152684006 do not match modulo 10
                #
                if mod10r(invoice.reference[:-1]) != invoice.reference and \
                        len(invoice.reference) == 15:
                    return True
                #
                if mod10r(invoice.reference[:-1]) != invoice.reference:
                    return False
        return True

    _constraints = [
        (_check_bvr, 'Error: Invalid Bvr Number (wrong checksum).',
            ['reference']),
        (_check_reference_type, 'Error: BVR reference is required.',
            ['reference_type']),
    ]

    # We can not use _default as we need invoice type
    def create(self, cursor, uid, vals, context=None):
        """We override create in order to have customer invoices
        generated by the comercial flow as on change partner is
        not systemtically call"""
        if context is None:
            context = {}
        # In his great wisdom OpnERP allows type to be implicitely set in context
        type_defined = vals.get('type') or context.get('type') or False
        if type_defined == 'out_invoice' and not vals.get('partner_bank_id'):
            user = self.pool.get('res.users').browse(cursor, uid, uid, context=context)
            bank_ids = user.company_id.partner_id.bank_ids
            if bank_ids:
                vals['partner_bank_id'] = bank_ids[0].id
        return super(AccountInvoice, self).create(cursor, uid, vals, context=context)
<commit_msg>[FIX]only bvr requiered bvr ref<commit_after># -*- coding: utf-8 -*-
##############################################################################
#
#    Author: Nicolas Bessi. Copyright Camptocamp SA
#
#    This program is free software: you can redistribute it and/or modify
#    it under the terms of the GNU Affero General Public License as
#    published by the Free Software Foundation, either version 3 of the
#    License, or (at your option) any later version.
#
#    This program is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#    GNU Affero General Public License for more details.
#
#    You should have received a copy of the GNU Affero General Public License
#    along with this program.  If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
from openerp.osv.orm import Model
from openerp.tools import mod10r

class AccountInvoice(Model):

    _inherit = "account.invoice"

    def onchange_partner_id(self, cursor, uid, ids, invoice_type, partner_id,
                            date_invoice=False, payment_term=False,
                            partner_bank_id=False, company_id=False):
        """ Function that is call when the partner of the invoice is changed
        it will retrieve and set the good bank partner bank"""
        #context not define in signature of function in account module
        context = {}
        res = super(AccountInvoice, self).onchange_partner_id(cursor, uid, ids, invoice_type, partner_id,
                                                              date_invoice=False, payment_term=False,
                                                              partner_bank_id=False, company_id=False)
        bank_id = False
        if partner_id:
            if invoice_type in ('in_invoice', 'in_refund'):
                p = self.pool.get('res.partner').browse(cursor, uid, partner_id, context)
                if p.bank_ids:
                    bank_id = p.bank_ids[0].id
                res['value']['partner_bank_id'] = bank_id
            else:
                user = self.pool.get('res.users').browse(cursor, uid, uid, context)
                bank_ids = user.company_id.partner_id.bank_ids
                if bank_ids:
                    res['value']['partner_bank_id'] = bank_ids[0].id
        if partner_bank_id != bank_id:
            to_update = self.onchange_partner_bank(cursor, uid, ids, bank_id)
            res['value'].update(to_update['value'])
        return res

    def onchange_partner_bank(self, cursor, user, ids, partner_bank_id):
        """update the reference invoice_type depending of the partner bank"""
        res = {'value': {}}
        partner_bank_obj = self.pool.get('res.partner.bank')
        if partner_bank_id:
            partner_bank = partner_bank_obj.browse(cursor, user, partner_bank_id)
            if partner_bank.state == 'bvr':
                res['value']['reference_type'] = 'bvr'
            else:
                res['value']['reference_type'] = 'none'

        return res

    def _check_reference_type(self, cursor, user, ids, context=None):
        """Check the supplier invoice reference type depending
        on the BVR reference type and the invoice partner bank type"""
        for invoice in self.browse(cursor, user, ids):
            if invoice.type in 'in_invoice':
                if invoice.partner_bank_id and invoice.partner_bank_id.state == 'bvr' and \
                        invoice.reference_type != 'bvr':
                    return False
        return True

    def _check_bvr(self, cr, uid, ids, context=None):
        """
        Function to validate a bvr reference like :
        0100054150009>132000000000000000000000014+ 1300132412>
        The validation is based on l10n_ch
        """
        invoices = self.browse(cr, uid, ids)
        for invoice in invoices:
            if invoice.reference_type == 'bvr' and invoice.state != 'draft':
                if not invoice.reference:
                    return False
                ## In this case
                # <010001000060190> 052550152684006+ 43435>
                # the reference 052550152684006 do not match modulo 10
                #
                if mod10r(invoice.reference[:-1]) != invoice.reference and \
                        len(invoice.reference) == 15:
                    return True
                #
                if mod10r(invoice.reference[:-1]) != invoice.reference:
                    return False
        return True

    _constraints = [
        (_check_bvr, 'Error: Invalid Bvr Number (wrong checksum).',
            ['reference']),
        (_check_reference_type, 'Error: BVR reference is required.',
            ['reference_type']),
    ]

    # We can not use _default as we need invoice type
    def create(self, cursor, uid, vals, context=None):
        """We override create in order to have customer invoices
        generated by the comercial flow as on change partner is
        not systemtically call"""
        if context is None:
            context = {}
        # In his great wisdom OpnERP allows type to be implicitely set in context
        type_defined = vals.get('type') or context.get('type') or False
        if type_defined == 'out_invoice' and not vals.get('partner_bank_id'):
            user = self.pool.get('res.users').browse(cursor, uid, uid, context=context)
            bank_ids = user.company_id.partner_id.bank_ids
            if bank_ids:
                vals['partner_bank_id'] = bank_ids[0].id
        return super(AccountInvoice, self).create(cursor, uid, vals, context=context)
<|endoftext|>