<commit_before>from copy import deepcopy

from django.conf import settings
from django.db.models.fields import Field, CharField, TextField, FloatField
from django.utils import six
from django.utils.functional import lazy
from django.utils.translation import get_language

from . import CompositeField

LANGUAGES = map(lambda lang: lang[0], getattr(settings, 'LANGUAGES', ()))

class LocalizedField(CompositeField):

    def __init__(self, field_class, verbose_name=None, *args, **kwargs):
        self.languages = kwargs.pop('languages', LANGUAGES)
        if not self.languages:
            raise RuntimeError('Set LANGUAGES in your settings.py or pass a non empty "languages" argument before using LocalizedCharField')
        super(LocalizedField, self).__init__()
        self.verbose_name = verbose_name
        kwargs['verbose_name'] = verbose_name
        for language in self.languages:
            self[language] = field_class(*args, **kwargs)

    def contribute_to_class(self, cls, field_name):
        if self.verbose_name is None:
            self.verbose_name = field_name.replace('_', ' ')
        for language in self:
            # verbose_name must be lazy in order for the admin to show the
            # translated verbose_names of the fields
            self[language].verbose_name = lazy(lambda language: self.verbose_name + ' (' + language + ')', six.text_type)(language)
        super(LocalizedField, self).contribute_to_class(cls, field_name)

    def get_proxy(self, model):
        return LocalizedField.Proxy(self, model)

    def get_col(self, alias, field):
        current_field = self.current_field
        return current_field.get_col(alias, current_field)

    @property
    def current_field(self):
        language = get_language() or settings.LANGUAGE_CODE
        base_lang = language.split('-')[0]
        return self[base_lang]

    class Proxy(CompositeField.Proxy):

        def __bool__(self):
            return bool(six.text_type(self))

        def __unicode__(self):
            return unicode(self.current_with_fallback)

        def __setattr__(self, name, value):
            if name == 'current':
                language = get_language() or settings.LANGUAGE_CODE
                base_lang = language.split('-')[0]
                return setattr(self, base_lang, value)
            if name == 'all':
                for language in self._composite_field.languages:
                    setattr(self, language, value)
                return value
            else:
                return super(LocalizedField.Proxy, self).__setattr__(name, value)

        @property
        def current(self):
            language = get_language() or settings.LANGUAGE_CODE
            base_lang = language.split('-')[0]
            return getattr(self, base_lang)

        @property
        def current_with_fallback(self):
            language = get_language() or settings.LANGUAGE_CODE
            translation = None
            # 1. complete language code
            print language
            translation = getattr(self, language, None)
            if translation:
                return translation
            # 2. base of language code
            if '-' in language:
                base_lang = language.split('-')[0]
                translation = getattr(self, base_lang, None)
                if translation:
                    return translation
            # 3. first available translation
            for language in settings.LANGUAGES:
                base_lang = language[0].split('-')[0]
                translation = getattr(self, base_lang, None)
                if translation:
                    return translation
            return ''

class LocalizedCharField(LocalizedField):

    def __init__(self, *args, **kwargs):
        super(LocalizedCharField, self).__init__(CharField, *args, **kwargs)

class LocalizedTextField(LocalizedField):

    def __init__(self, *args, **kwargs):
        super(LocalizedTextField, self).__init__(TextField, *args, **kwargs)
<commit_msg>Remove print statement (Oops!)<commit_after>from copy import deepcopy

from django.conf import settings
from django.db.models.fields import Field, CharField, TextField, FloatField
from django.utils import six
from django.utils.functional import lazy
from django.utils.translation import get_language

from . import CompositeField

LANGUAGES = map(lambda lang: lang[0], getattr(settings, 'LANGUAGES', ()))

class LocalizedField(CompositeField):

    def __init__(self, field_class, verbose_name=None, *args, **kwargs):
        self.languages = kwargs.pop('languages', LANGUAGES)
        if not self.languages:
            raise RuntimeError('Set LANGUAGES in your settings.py or pass a non empty "languages" argument before using LocalizedCharField')
        super(LocalizedField, self).__init__()
        self.verbose_name = verbose_name
        kwargs['verbose_name'] = verbose_name
        for language in self.languages:
            self[language] = field_class(*args, **kwargs)

    def contribute_to_class(self, cls, field_name):
        if self.verbose_name is None:
            self.verbose_name = field_name.replace('_', ' ')
        for language in self:
            # verbose_name must be lazy in order for the admin to show the
            # translated verbose_names of the fields
            self[language].verbose_name = lazy(lambda language: self.verbose_name + ' (' + language + ')', six.text_type)(language)
        super(LocalizedField, self).contribute_to_class(cls, field_name)

    def get_proxy(self, model):
        return LocalizedField.Proxy(self, model)

    def get_col(self, alias, field):
        current_field = self.current_field
        return current_field.get_col(alias, current_field)

    @property
    def current_field(self):
        language = get_language() or settings.LANGUAGE_CODE
        base_lang = language.split('-')[0]
        return self[base_lang]

    class Proxy(CompositeField.Proxy):

        def __bool__(self):
            return bool(six.text_type(self))

        def __unicode__(self):
            return unicode(self.current_with_fallback)

        def __setattr__(self, name, value):
            if name == 'current':
                language = get_language() or settings.LANGUAGE_CODE
                base_lang = language.split('-')[0]
                return setattr(self, base_lang, value)
            if name == 'all':
                for language in self._composite_field.languages:
                    setattr(self, language, value)
                return value
            else:
                return super(LocalizedField.Proxy, self).__setattr__(name, value)

        @property
        def current(self):
            language = get_language() or settings.LANGUAGE_CODE
            base_lang = language.split('-')[0]
            return getattr(self, base_lang)

        @property
        def current_with_fallback(self):
            language = get_language() or settings.LANGUAGE_CODE
            translation = None
            # 1. complete language code
            translation = getattr(self, language, None)
            if translation:
                return translation
            # 2. base of language code
            if '-' in language:
                base_lang = language.split('-')[0]
                translation = getattr(self, base_lang, None)
                if translation:
                    return translation
            # 3. first available translation
            for language in settings.LANGUAGES:
                base_lang = language[0].split('-')[0]
                translation = getattr(self, base_lang, None)
                if translation:
                    return translation
            return ''

class LocalizedCharField(LocalizedField):

    def __init__(self, *args, **kwargs):
        super(LocalizedCharField, self).__init__(CharField, *args, **kwargs)

class LocalizedTextField(LocalizedField):

    def __init__(self, *args, **kwargs):
        super(LocalizedTextField, self).__init__(TextField, *args, **kwargs)
<|endoftext|>


<commit_before>import numpy as np

import compressible.eos as eos

def derive_primitives(myd, varnames):
    """
    derive desired primitive variables from conserved state
    """

    # get the variables we need
    dens = myd.get_var("density")
    xmom = myd.get_var("x-momentum")
    ymom = myd.get_var("y-momentum")
    ener = myd.get_var("energy")

    derived_vars = []

    u = xmom/dens
    v = ymom/dens

    e = (ener - 0.5*dens*(u*u + v*v))/dens

    gamma = myd.get_aux("gamma")
    p = eos.pres(gamma, dens, e)

    if isinstance(varnames, str):
        wanted = [varnames]
    else:
        wanted = list(varnames)

    for var in wanted:

        if var == "velocity":
            derived_vars.append(u)
            derived_vars.append(v)

        elif var in ["e", "eint"]:
            derived_vars.append(e)

        elif var in ["p", "pressure"]:
            derived_vars.append(p)

        elif var == "primitive":
            derived_vars.append(dens)
            derived_vars.append(u)
            derived_vars.append(v)
            derived_vars.append(p)

        elif var == "soundspeed":
            derived_vars.append(np.sqrt(gamma*p/dens))

    return derived_vars
<commit_msg>if we return only a single derived variable, then it should not be in a list<commit_after>import numpy as np

import compressible.eos as eos

def derive_primitives(myd, varnames):
    """
    derive desired primitive variables from conserved state
    """

    # get the variables we need
    dens = myd.get_var("density")
    xmom = myd.get_var("x-momentum")
    ymom = myd.get_var("y-momentum")
    ener = myd.get_var("energy")

    derived_vars = []

    u = xmom/dens
    v = ymom/dens

    e = (ener - 0.5*dens*(u*u + v*v))/dens

    gamma = myd.get_aux("gamma")
    p = eos.pres(gamma, dens, e)

    if isinstance(varnames, str):
        wanted = [varnames]
    else:
        wanted = list(varnames)

    for var in wanted:

        if var == "velocity":
            derived_vars.append(u)
            derived_vars.append(v)

        elif var in ["e", "eint"]:
            derived_vars.append(e)

        elif var in ["p", "pressure"]:
            derived_vars.append(p)

        elif var == "primitive":
            derived_vars.append(dens)
            derived_vars.append(u)
            derived_vars.append(v)
            derived_vars.append(p)

        elif var == "soundspeed":
            derived_vars.append(np.sqrt(gamma*p/dens))

    if len(derived_vars) > 1:
        return derived_vars
    else:
        return derived_vars[0]

<|endoftext|>


<commit_before># Django settings for example_project project.
import os

import dj_database_url

def project_dir(*paths):
    base = os.path.realpath(os.path.dirname(__file__))
    return os.path.join(base, *paths)

DEBUG = True
TEMPLATE_DEBUG = DEBUG

DATABASES = {'default': dj_database_url.config(default='sqlite:///' +
    project_dir('example_project.sqlite'))}

# Local time zone for this installation. Choices can be found here:
# http://en.wikipedia.org/wiki/List_of_tz_zones_by_name
# although not all choices may be available on all operating systems.
# In a Windows environment this must be set to your system time zone.
TIME_ZONE = 'America/Chicago'

# Language code for this installation. All choices can be found here:
# http://www.i18nguy.com/unicode/language-identifiers.html
LANGUAGE_CODE = 'en-us'

SITE_ID = 1

# If you set this to False, Django will not format dates, numbers and
# calendars according to the current locale.
USE_L10N = True

# If you set this to False, Django will not use timezone-aware datetimes.
USE_TZ = True

STATIC_URL = '/static/'

SECRET_KEY = 'lolimasekrit'

ROOT_URLCONF = 'example_project.urls'

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

INSTALLED_APPS = (
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.sites',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'django.contrib.admin',
    'example_project.polls',

    # my app
    'django_object_actions',

    # dev helpers
    'django_extensions',
    # testing
    'django_nose',
)

TEST_RUNNER = 'django_nose.NoseTestSuiteRunner'

# STFU, Django 1.7
SILENCED_SYSTEM_CHECKS = [
    '1_7.W001',
]
<commit_msg>doc when to delete this weird setting<commit_after># Django settings for example_project project.
import os

import dj_database_url

def project_dir(*paths):
    base = os.path.realpath(os.path.dirname(__file__))
    return os.path.join(base, *paths)

DEBUG = True
TEMPLATE_DEBUG = DEBUG

DATABASES = {'default': dj_database_url.config(default='sqlite:///' +
    project_dir('example_project.sqlite'))}

# Local time zone for this installation. Choices can be found here:
# http://en.wikipedia.org/wiki/List_of_tz_zones_by_name
# although not all choices may be available on all operating systems.
# In a Windows environment this must be set to your system time zone.
TIME_ZONE = 'America/Chicago'

# Language code for this installation. All choices can be found here:
# http://www.i18nguy.com/unicode/language-identifiers.html
LANGUAGE_CODE = 'en-us'

SITE_ID = 1

# If you set this to False, Django will not format dates, numbers and
# calendars according to the current locale.
USE_L10N = True

# If you set this to False, Django will not use timezone-aware datetimes.
USE_TZ = True

STATIC_URL = '/static/'

SECRET_KEY = 'lolimasekrit'

ROOT_URLCONF = 'example_project.urls'

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

INSTALLED_APPS = (
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.sites',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'django.contrib.admin',
    'example_project.polls',

    # my app
    'django_object_actions',

    # dev helpers
    'django_extensions',
    # testing
    'django_nose',
)

TEST_RUNNER = 'django_nose.NoseTestSuiteRunner'

# STFU, Django 1.7
# To be deleted once Django 1.8 testing begins
SILENCED_SYSTEM_CHECKS = [
    '1_7.W001',
]
<|endoftext|>


<commit_before>import base64
import datetime
import json
import re
import zlib

import elasticsearch
from elasticsearch_raven.postfix import postfix_encoded_data

class Message:
    def __init__(self, headers, body):
        self._body = body
        self._headers = headers

    @classmethod
    def from_message(cls, message):
        return cls(message.headers, message.body)

    @property
    def body(self):
        return self._body

    @property
    def headers(self):
        return self._headers

class SentryMessage(Message):
    def __init__(self, headers, body):
        super().__init__(headers, body)
        self._compressed = True

    @classmethod
    def create_from_udp(cls, data):
        byte_headers, data = data.split(b'\n\n')
        headers = cls.parse_headers(str(byte_headers.decode('utf-8')))
        data = base64.b64decode(data)
        return cls(headers, data)

    @staticmethod
    def parse_headers(unparsed_headers):
        m = re.search(r'sentry_key=(?P<sentry_key>[^=]+), sentry_secret='
                      r'(?P<sentry_secret>[^=]+)$', unparsed_headers)
        return m.groupdict()

    @classmethod
    def create_from_http(cls, unparsed_headers, data):
        headers = cls.parse_headers(unparsed_headers)
        data = base64.b64decode(data)
        return cls(headers, data)

    @property
    def body(self):
        if self._compressed:
            self._body = json.loads(
                zlib.decompress(self._body).decode('utf-8'))
            self._compressed = False
        return self._body

class ElasticsearchMessage(Message):
    def __init__(self, headers, body):
        super().__init__(headers, body)
        postfix_encoded_data(self._body)

class ElasticsearchTransport:
    def __init__(self, host, use_ssl=False):
        self._host = host
        self._use_ssl = use_ssl

    def send(self, message):
        message = ElasticsearchMessage.from_message(message)
        dated_index = message.body['project'].format(datetime.datetime.now())
        http_auth = '{}:{}'.format(message.headers['sentry_key'],
                                   message.headers['sentry_secret'])
        connection = elasticsearch.Elasticsearch(hosts=[self._host],
                                                 http_auth=http_auth,
                                                 use_ssl=self._use_ssl)
        connection.index(body=message.body, index=dated_index,
                         doc_type='raven-log')
<commit_msg>Retry connection.<commit_after>import base64
import datetime
import json
import logging
import re
import time
import zlib

import elasticsearch
from elasticsearch_raven.postfix import postfix_encoded_data

elasticsearch_logger = logging.getLogger('elasticsearch')
elasticsearch_logger.setLevel(logging.ERROR)

class Message:
    def __init__(self, headers, body):
        self._body = body
        self._headers = headers

    @classmethod
    def from_message(cls, message):
        return cls(message.headers, message.body)

    @property
    def body(self):
        return self._body

    @property
    def headers(self):
        return self._headers

class SentryMessage(Message):
    def __init__(self, headers, body):
        super().__init__(headers, body)
        self._compressed = True

    @classmethod
    def create_from_udp(cls, data):
        byte_headers, data = data.split(b'\n\n')
        headers = cls.parse_headers(str(byte_headers.decode('utf-8')))
        data = base64.b64decode(data)
        return cls(headers, data)

    @staticmethod
    def parse_headers(unparsed_headers):
        m = re.search(r'sentry_key=(?P<sentry_key>[^=]+), sentry_secret='
                      r'(?P<sentry_secret>[^=]+)$', unparsed_headers)
        return m.groupdict()

    @classmethod
    def create_from_http(cls, unparsed_headers, data):
        headers = cls.parse_headers(unparsed_headers)
        data = base64.b64decode(data)
        return cls(headers, data)

    @property
    def body(self):
        if self._compressed:
            self._body = json.loads(
                zlib.decompress(self._body).decode('utf-8'))
            self._compressed = False
        return self._body

class ElasticsearchMessage(Message):
    def __init__(self, headers, body):
        super().__init__(headers, body)
        postfix_encoded_data(self._body)

class ElasticsearchTransport:
    def __init__(self, host, use_ssl=False):
        self._host = host
        self._use_ssl = use_ssl

    def send(self, message):
        message = ElasticsearchMessage.from_message(message)
        dated_index = message.body['project'].format(datetime.datetime.now())
        http_auth = '{}:{}'.format(message.headers['sentry_key'],
                                   message.headers['sentry_secret'])
        connection = elasticsearch.Elasticsearch(hosts=[self._host],
                                                 http_auth=http_auth,
                                                 use_ssl=self._use_ssl)
        for retry in retry_loop(15 * 60, delay=1, back_off=1.5):
            try:
                connection.index(body=message.body, index=dated_index,
                                 doc_type='raven-log')
            except elasticsearch.exceptions.ConnectionError as e:
                retry(e)

def retry_loop(timeout, delay, back_off=1.0):
    start_time = time.time()
    exceptions = []

    def retry(exception):
        exceptions.append(exception)

    while True:
        yield retry
        if not exceptions:
            return
        if time.time() - start_time > timeout:
            break
        else:
            exceptions.clear()
        time.sleep(delay)
        delay *= back_off

    raise exceptions[0]
<|endoftext|>


<commit_before>#!/usr/bin/env python3
# Copyright 2020 Pants project contributors (see CONTRIBUTORS.md).
# Licensed under the Apache License, Version 2.0 (see LICENSE).

import argparse
import json
import os
import subprocess
from pathlib import Path

from common import banner, die

# NB: We expect the `aws` CLI to already be installed.

AWS_COMMAND_PREFIX = ["aws", "--no-sign-request", "--region", "us-east-1"]

def main() -> None:
    if not Path("src/python/pants").is_dir():
        raise ValueError(
            "This script assumes that you are in the Pants build root. Instead, you are at "
            f"{Path.cwd()}."
        )
    args = create_parser().parse_args()
    pex_url = f"s3://{args.aws_bucket}/{args.pex_key}"
    native_engine_so_local_path = f"./src/python/pants/engine/internals/native_engine.so"

    # NB: we must set `$PY` before calling `bootstrap()` to ensure that we use the exact same
    # Python interpreter when calculating the hash of `native_engine.so` as the one we use when
    # calling `ci.py --bootstrap`.
    python_version = create_parser().parse_args().python_version
    if "PY" not in os.environ:
        os.environ["PY"] = f"python{python_version}"

    native_engine_so_hash = calculate_native_engine_so_hash()
    native_engine_so_aws_key = (
        f"{args.native_engine_so_key_prefix}/{native_engine_so_hash}/native_engine.so"
    )
    native_engine_so_aws_url = f"s3://{args.aws_bucket}/{native_engine_so_aws_key}"

    if native_engine_so_in_s3_cache(
        aws_bucket=args.aws_bucket, native_engine_so_aws_key=native_engine_so_aws_key
    ):
        banner(
            f"`native_engine.so` found in the AWS S3 cache at {native_engine_so_aws_url}. "
            f"Downloading to avoid unnecessary Rust compilation."
        )
        get_native_engine_so(
            native_engine_so_aws_url=native_engine_so_aws_url,
            native_engine_so_local_path=native_engine_so_local_path,
        )
    else:
        banner(
            f"`native_engine.so` not found in the AWS S3 cache at {native_engine_so_aws_url}. "
            f"Recompiling Rust..."
        )

    bootstrap_pants_pex(python_version)

    if native_engine_so_in_s3_cache(
        aws_bucket=args.aws_bucket, native_engine_so_aws_key=native_engine_so_aws_key
    ):
        banner(f"`native_engine.so` already cached at {native_engine_so_aws_url}. Skipping deploy.")
    else:
        banner(f"Deploying `native_engine.so` to {native_engine_so_aws_url}.")
        deploy_native_engine_so(
            native_engine_so_aws_url=native_engine_so_aws_url,
            native_engine_so_local_path=native_engine_so_local_path,
        )

    banner(f"Deploying `pants.pex` to {pex_url}.")
    deploy_pants_pex(pex_url=pex_url)

def create_parser() -> argparse.ArgumentParser:
    parser = argparse.ArgumentParser()
    parser.add_argument("--aws-bucket", required=True, help="Name of the S3 bucket.")
    parser.add_argument(
        "--pex-key", required=True, help="Key to use with S3 for the bootstrapped pants.pex"
    )
    parser.add_argument(
        "--native-engine-so-key-prefix",
        required=True,
        help=(
            "The key prefix for `native_engine.so`, which will get combined with the unique hash "
            "to determine the key."
        ),
    )
    parser.add_argument(
        "--python-version",
        type=float,
        required=True,
        help="The Python version to bootstrap pants.pex with.",
    )
    return parser

def calculate_native_engine_so_hash() -> str:
    return (
        subprocess.run(
            ["build-support/bin/native/print_engine_hash.sh"], stdout=subprocess.PIPE, check=True,
        )
        .stdout.decode()
        .strip()
    )

def native_engine_so_in_s3_cache(*, aws_bucket: str, native_engine_so_aws_key: str) -> bool:
    ls_output = subprocess.run(
        [
            *AWS_COMMAND_PREFIX,
            "s3api",
            "list-object-versions",
            "--bucket",
            aws_bucket,
            "--prefix",
            native_engine_so_aws_key,
            "--max-items",
            "2",
        ],
        stdout=subprocess.PIPE,
        check=True,
    ).stdout.decode()
    if not ls_output:
        return False
    num_versions = len(json.loads(ls_output)["Versions"])
    if num_versions > 1:
        die(
            f"Multiple copies found of {native_engine_so_aws_key} in AWS S3. This is not allowed "
            "as a security precaution. Please raise this failure in the #infra channel "
            "in Slack so that we may investigate how this happened and delete the duplicate "
            "copy from S3."
        )
    return True

def bootstrap_pants_pex(python_version: float) -> None:
    subprocess.run(
        [
            "./build-support/bin/ci.py",
            "--bootstrap",
            "--bootstrap-try-to-skip-rust-compilation",
            "--python-version",
            str(python_version),
        ],
        check=True,
    )

def get_native_engine_so(
    *, native_engine_so_aws_url: str, native_engine_so_local_path: str
) -> None:
    subprocess.run(
        [*AWS_COMMAND_PREFIX, "s3", "cp", native_engine_so_aws_url, native_engine_so_local_path],
        check=True,
    )

def _deploy(file_path: str, s3_url: str) -> None:
    subprocess.run([*AWS_COMMAND_PREFIX, "s3", "cp", file_path, s3_url], check=True)

def deploy_native_engine_so(
    *, native_engine_so_aws_url: str, native_engine_so_local_path: str
) -> None:
    _deploy(file_path=native_engine_so_local_path, s3_url=native_engine_so_aws_url)

def deploy_pants_pex(pex_url: str) -> None:
    _deploy(f"./pants.pex", pex_url)

if __name__ == "__main__":
    main()
<commit_msg>Fix AWS S3 script breaking from a KeyError (#9840)<commit_after>#!/usr/bin/env python3
# Copyright 2020 Pants project contributors (see CONTRIBUTORS.md).
# Licensed under the Apache License, Version 2.0 (see LICENSE).

import argparse
import json
import os
import subprocess
from pathlib import Path

from common import banner, die

# NB: We expect the `aws` CLI to already be installed.

AWS_COMMAND_PREFIX = ["aws", "--no-sign-request", "--region", "us-east-1"]

def main() -> None:
    if not Path("src/python/pants").is_dir():
        raise ValueError(
            "This script assumes that you are in the Pants build root. Instead, you are at "
            f"{Path.cwd()}."
        )
    args = create_parser().parse_args()
    pex_url = f"s3://{args.aws_bucket}/{args.pex_key}"
    native_engine_so_local_path = f"./src/python/pants/engine/internals/native_engine.so"

    # NB: we must set `$PY` before calling `bootstrap()` to ensure that we use the exact same
    # Python interpreter when calculating the hash of `native_engine.so` as the one we use when
    # calling `ci.py --bootstrap`.
    python_version = create_parser().parse_args().python_version
    if "PY" not in os.environ:
        os.environ["PY"] = f"python{python_version}"

    native_engine_so_hash = calculate_native_engine_so_hash()
    native_engine_so_aws_key = (
        f"{args.native_engine_so_key_prefix}/{native_engine_so_hash}/native_engine.so"
    )
    native_engine_so_aws_url = f"s3://{args.aws_bucket}/{native_engine_so_aws_key}"

    if native_engine_so_in_s3_cache(
        aws_bucket=args.aws_bucket, native_engine_so_aws_key=native_engine_so_aws_key
    ):
        banner(
            f"`native_engine.so` found in the AWS S3 cache at {native_engine_so_aws_url}. "
            f"Downloading to avoid unnecessary Rust compilation."
        )
        get_native_engine_so(
            native_engine_so_aws_url=native_engine_so_aws_url,
            native_engine_so_local_path=native_engine_so_local_path,
        )
    else:
        banner(
            f"`native_engine.so` not found in the AWS S3 cache at {native_engine_so_aws_url}. "
            f"Recompiling Rust..."
        )

    bootstrap_pants_pex(python_version)

    if native_engine_so_in_s3_cache(
        aws_bucket=args.aws_bucket, native_engine_so_aws_key=native_engine_so_aws_key
    ):
        banner(f"`native_engine.so` already cached at {native_engine_so_aws_url}. Skipping deploy.")
    else:
        banner(f"Deploying `native_engine.so` to {native_engine_so_aws_url}.")
        deploy_native_engine_so(
            native_engine_so_aws_url=native_engine_so_aws_url,
            native_engine_so_local_path=native_engine_so_local_path,
        )

    banner(f"Deploying `pants.pex` to {pex_url}.")
    deploy_pants_pex(pex_url=pex_url)

def create_parser() -> argparse.ArgumentParser:
    parser = argparse.ArgumentParser()
    parser.add_argument("--aws-bucket", required=True, help="Name of the S3 bucket.")
    parser.add_argument(
        "--pex-key", required=True, help="Key to use with S3 for the bootstrapped pants.pex"
    )
    parser.add_argument(
        "--native-engine-so-key-prefix",
        required=True,
        help=(
            "The key prefix for `native_engine.so`, which will get combined with the unique hash "
            "to determine the key."
        ),
    )
    parser.add_argument(
        "--python-version",
        type=float,
        required=True,
        help="The Python version to bootstrap pants.pex with.",
    )
    return parser

def calculate_native_engine_so_hash() -> str:
    return (
        subprocess.run(
            ["build-support/bin/native/print_engine_hash.sh"], stdout=subprocess.PIPE, check=True,
        )
        .stdout.decode()
        .strip()
    )

def native_engine_so_in_s3_cache(*, aws_bucket: str, native_engine_so_aws_key: str) -> bool:
    ls_output = subprocess.run(
        [
            *AWS_COMMAND_PREFIX,
            "s3api",
            "list-object-versions",
            "--bucket",
            aws_bucket,
            "--prefix",
            native_engine_so_aws_key,
            "--max-items",
            "2",
        ],
        stdout=subprocess.PIPE,
        check=True,
    ).stdout.decode()
    if not ls_output:
        return False
    versions = json.loads(ls_output).get("Versions")
    if versions is None:
        return False
    if len(versions) > 1:
        die(
            f"Multiple copies found of {native_engine_so_aws_key} in AWS S3. This is not allowed "
            "as a security precaution. Please raise this failure in the #infra channel "
            "in Slack so that we may investigate how this happened and delete the duplicate "
            "copy from S3."
        )
    return True

def bootstrap_pants_pex(python_version: float) -> None:
    subprocess.run(
        [
            "./build-support/bin/ci.py",
            "--bootstrap",
            "--bootstrap-try-to-skip-rust-compilation",
            "--python-version",
            str(python_version),
        ],
        check=True,
    )

def get_native_engine_so(
    *, native_engine_so_aws_url: str, native_engine_so_local_path: str
) -> None:
    subprocess.run(
        [*AWS_COMMAND_PREFIX, "s3", "cp", native_engine_so_aws_url, native_engine_so_local_path],
        check=True,
    )

def _deploy(file_path: str, s3_url: str) -> None:
    subprocess.run([*AWS_COMMAND_PREFIX, "s3", "cp", file_path, s3_url], check=True)

def deploy_native_engine_so(
    *, native_engine_so_aws_url: str, native_engine_so_local_path: str
) -> None:
    _deploy(file_path=native_engine_so_local_path, s3_url=native_engine_so_aws_url)

def deploy_pants_pex(pex_url: str) -> None:
    _deploy(f"./pants.pex", pex_url)

if __name__ == "__main__":
    main()
<|endoftext|>


<commit_before>#
# Copyright (c) 2006 rPath, Inc.
#
# This program is distributed under the terms of the Common Public License,
# version 1.0. A copy of this license should have been distributed with this
# source file in a file called LICENSE. If it is not present, the license
# is always available at http://www.opensource.org/licenses/cpl.php.
#
# 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 Common Public License for
# full details.
#

import os
import stat
import struct
import tempfile

from conary import callbacks
from conary.files import InodeStream
from conary.streams import *

JOURNAL_VERSION = 1

_JOURNAL_ENTRY_OLD_NAME  = 1
_JOURNAL_ENTRY_NEW_NAME  = 2
_JOURNAL_ENTRY_NEW_INODE = 3

_INFO_STREAM_PERMS = 1
_INFO_STREAM_MTIME = 2
_INFO_STREAM_OWNER = 3
_INFO_STREAM_GROUP = 4

JOURNAL_ENTRY_RENAME  = 0
JOURNAL_ENTRY_BACKUP  = 1
JOURNAL_ENTRY_CREATE  = 2
JOURNAL_ENTRY_REMOVE  = 3
JOURNAL_ENTRY_MKDIR   = 4
JOURNAL_ENTRY_BACKDIR = 5

class InodeInfo(StreamSet):

    streamDict = {
          _INFO_STREAM_PERMS : (SMALL, ShortStream,  "perms"),
          _INFO_STREAM_MTIME : (SMALL, MtimeStream,  "mtime"),
          _INFO_STREAM_OWNER : (SMALL, IntStream,    "uid"  ),
          _INFO_STREAM_GROUP : (SMALL, IntStream,    "gid"  )
        }
    __slots__ = [ "perms", "mtime", "uid", "gid" ]

class JournalEntry(StreamSet):

    streamDict = {
          _JOURNAL_ENTRY_OLD_NAME  : (DYNAMIC, StringStream, "old" ),
          _JOURNAL_ENTRY_NEW_NAME  : (DYNAMIC, StringStream, "new" ),
          _JOURNAL_ENTRY_NEW_INODE : (SMALL,   InodeInfo,    "inode" )
        }
    __slots__ = [ "old", "new", "inode" ]

class NoopJobJournal:

    def __init__(self):
        pass

    def rename(self, origName, newName):
        pass

    def create(self, name):
        pass

    def mkdir(self, name):
        pass

    def remove(self, name):
        pass

    def backup(self, target, skipDirs = False):
        pass

    def commit(self):
        pass

    def revert(self):
        pass

class JobJournal(NoopJobJournal):

    # this is designed to be readable back to front, not front to back

    @staticmethod
    def _normpath(path):
        return os.path.normpath(path).replace('//', '/')

    def __init__(self, path, root = '/', create = False, callback = None):
        NoopJobJournal.__init__(self)
        # normpath leaves a leading // (probably for windows?)
        self.root = self._normpath(root)
        if root:
            self.rootLen = len(self.root)
        else:
            self.rootLen = 0

        self.hSize = struct.calcsize("!H")
        self.hdrSize = struct.calcsize("!BH")

        if callback is None:
            self.callback = callbacks.UpdateCallback()
        else:
            self.callback = callback

        if create:
            self.immutable = False
            self.fd = os.open(path,
                              os.O_RDWR | os.O_CREAT | os.O_TRUNC, 0600)
            os.write(self.fd, struct.pack("!H", JOURNAL_VERSION))
        else:
            self.immutable = True
            self.fd = os.open(path, os.O_RDONLY)
            ver = struct.unpack("!H", os.read(self.fd, self.hSize))[0]
            assert(ver == JOURNAL_VERSION)

    def close(self):
        if self.fd is not None:
            os.close(self.fd)
            self.fd = None

    def _record(self, kind, origName, newName):
        assert(not self.immutable)
        s = JournalEntry()
        s.old.set(origName[self.rootLen:])
        s.new.set(newName[self.rootLen:])
        frz = s.freeze()
        os.write(self.fd, frz)
        os.write(self.fd, struct.pack("!BH", kind, len(frz)))

    def _backup(self, origName, newName, statBuf, kind = JOURNAL_ENTRY_BACKUP):
        assert(not self.immutable)
        s = JournalEntry()
        s.old.set(origName[self.rootLen:])
        s.new.set(newName[self.rootLen:])

        s.inode.mtime.set(statBuf.st_mtime)
        s.inode.uid.set(statBuf.st_uid)
        s.inode.gid.set(statBuf.st_gid)
        s.inode.perms.set(statBuf.st_mode & 07777)

        frz = s.freeze()
        os.write(self.fd, frz)
        os.write(self.fd, struct.pack("!BH", kind, len(frz)))

    def _backdir(self, name, statBuf):
        self._backup("", name, statBuf, kind = JOURNAL_ENTRY_BACKDIR)

    def rename(self, origName, newName):
        origName = self._normpath(origName)
        newName = self._normpath(newName)
        self._record(JOURNAL_ENTRY_RENAME, origName, newName)

    def create(self, name):
        name = self._normpath(name)
        self._record(JOURNAL_ENTRY_CREATE, '', name)

    def mkdir(self, name):
        name = self._normpath(name)
        self._record(JOURNAL_ENTRY_MKDIR, '', name)

    def remove(self, name):
        name = self._normpath(name)
        self._record(JOURNAL_ENTRY_REMOVE, '', name)

    def backup(self, target, skipDirs = False):
        try:
            sb = os.lstat(target)
        except OSError:
            sb = None

        if sb:
            path = os.path.dirname(target)
            name = os.path.basename(target)

            tmpfd, tmpname = tempfile.mkstemp(name, '.ct', path)
            os.close(tmpfd)
            os.unlink(tmpname)
            if not stat.S_ISDIR(sb.st_mode):
                self._backup(target, tmpname, sb)
                os.link(target, tmpname)
            elif not skipDirs:
                self._backdir(target, sb)

    def commit(self):
        for kind, entry in self:
            if kind == JOURNAL_ENTRY_BACKUP:
                os.unlink(self.root + entry.new())
        self.close()

    def revert(self):
        for kind, entry in self:
            try:
                if kind == JOURNAL_ENTRY_BACKUP:
                    what = "restore"
                    path = self.root + entry.old()
                    os.rename(self.root + entry.new(), path)
                    os.chown(path, entry.inode.uid(), entry.inode.gid())
                    os.chmod(path, entry.inode.perms())
                    os.utime(path, (entry.inode.mtime(), entry.inode.mtime()))
                elif kind == JOURNAL_ENTRY_RENAME:
                    what = "restore"
                    os.rename(self.root + entry.new(), self.root + entry.old())
                elif kind == JOURNAL_ENTRY_CREATE:
                    what = "remove"
                    os.unlink(self.root + entry.new())
                elif kind == JOURNAL_ENTRY_MKDIR:
                    what = "remove"
                    os.rmdir(self.root + entry.new())
                elif kind == JOURNAL_ENTRY_REMOVE:
                    pass
                elif kind == JOURNAL_ENTRY_BACKDIR:
                    pass
                else:
                    self.callback.warning('unknown journal entry %d', kind)
            except OSError, e:
                self.callback.warning('could not %s file %s: %s',
                                      what, self.root + entry.new(), e.strerror)
        self.close()

    def __iter__(self):
        self.immutable = False
        next = os.fstat(self.fd).st_size - self.hdrSize
        while next > 0:
            os.lseek(self.fd, next, 0)
            kind, size = struct.unpack("!BH", os.read(self.fd, self.hdrSize))

            os.lseek(self.fd, next - size, 0)
            frz = os.read(self.fd, size)
            s = JournalEntry(frz)
            yield kind, s
            next = next - self.hdrSize - size
<commit_msg>normalize the target on backup<commit_after>#
# Copyright (c) 2006 rPath, Inc.
#
# This program is distributed under the terms of the Common Public License,
# version 1.0. A copy of this license should have been distributed with this
# source file in a file called LICENSE. If it is not present, the license
# is always available at http://www.opensource.org/licenses/cpl.php.
#
# 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 Common Public License for
# full details.
#

import os
import stat
import struct
import tempfile

from conary import callbacks
from conary.files import InodeStream
from conary.streams import *

JOURNAL_VERSION = 1

_JOURNAL_ENTRY_OLD_NAME  = 1
_JOURNAL_ENTRY_NEW_NAME  = 2
_JOURNAL_ENTRY_NEW_INODE = 3

_INFO_STREAM_PERMS = 1
_INFO_STREAM_MTIME = 2
_INFO_STREAM_OWNER = 3
_INFO_STREAM_GROUP = 4

JOURNAL_ENTRY_RENAME  = 0
JOURNAL_ENTRY_BACKUP  = 1
JOURNAL_ENTRY_CREATE  = 2
JOURNAL_ENTRY_REMOVE  = 3
JOURNAL_ENTRY_MKDIR   = 4
JOURNAL_ENTRY_BACKDIR = 5

class InodeInfo(StreamSet):

    streamDict = {
          _INFO_STREAM_PERMS : (SMALL, ShortStream,  "perms"),
          _INFO_STREAM_MTIME : (SMALL, MtimeStream,  "mtime"),
          _INFO_STREAM_OWNER : (SMALL, IntStream,    "uid"  ),
          _INFO_STREAM_GROUP : (SMALL, IntStream,    "gid"  )
        }
    __slots__ = [ "perms", "mtime", "uid", "gid" ]

class JournalEntry(StreamSet):

    streamDict = {
          _JOURNAL_ENTRY_OLD_NAME  : (DYNAMIC, StringStream, "old" ),
          _JOURNAL_ENTRY_NEW_NAME  : (DYNAMIC, StringStream, "new" ),
          _JOURNAL_ENTRY_NEW_INODE : (SMALL,   InodeInfo,    "inode" )
        }
    __slots__ = [ "old", "new", "inode" ]

class NoopJobJournal:

    def __init__(self):
        pass

    def rename(self, origName, newName):
        pass

    def create(self, name):
        pass

    def mkdir(self, name):
        pass

    def remove(self, name):
        pass

    def backup(self, target, skipDirs = False):
        pass

    def commit(self):
        pass

    def revert(self):
        pass

class JobJournal(NoopJobJournal):

    # this is designed to be readable back to front, not front to back

    @staticmethod
    def _normpath(path):
        return os.path.normpath(path).replace('//', '/')

    def __init__(self, path, root = '/', create = False, callback = None):
        NoopJobJournal.__init__(self)
        # normpath leaves a leading // (probably for windows?)
        self.root = self._normpath(root)
        if root:
            self.rootLen = len(self.root)
        else:
            self.rootLen = 0

        self.hSize = struct.calcsize("!H")
        self.hdrSize = struct.calcsize("!BH")

        if callback is None:
            self.callback = callbacks.UpdateCallback()
        else:
            self.callback = callback

        if create:
            self.immutable = False
            self.fd = os.open(path,
                              os.O_RDWR | os.O_CREAT | os.O_TRUNC, 0600)
            os.write(self.fd, struct.pack("!H", JOURNAL_VERSION))
        else:
            self.immutable = True
            self.fd = os.open(path, os.O_RDONLY)
            ver = struct.unpack("!H", os.read(self.fd, self.hSize))[0]
            assert(ver == JOURNAL_VERSION)

    def close(self):
        if self.fd is not None:
            os.close(self.fd)
            self.fd = None

    def _record(self, kind, origName, newName):
        assert(not self.immutable)
        s = JournalEntry()
        s.old.set(origName[self.rootLen:])
        s.new.set(newName[self.rootLen:])
        frz = s.freeze()
        os.write(self.fd, frz)
        os.write(self.fd, struct.pack("!BH", kind, len(frz)))

    def _backup(self, origName, newName, statBuf, kind = JOURNAL_ENTRY_BACKUP):
        assert(not self.immutable)
        s = JournalEntry()
        s.old.set(origName[self.rootLen:])
        s.new.set(newName[self.rootLen:])

        s.inode.mtime.set(statBuf.st_mtime)
        s.inode.uid.set(statBuf.st_uid)
        s.inode.gid.set(statBuf.st_gid)
        s.inode.perms.set(statBuf.st_mode & 07777)

        frz = s.freeze()
        os.write(self.fd, frz)
        os.write(self.fd, struct.pack("!BH", kind, len(frz)))

    def _backdir(self, name, statBuf):
        self._backup("", name, statBuf, kind = JOURNAL_ENTRY_BACKDIR)

    def rename(self, origName, newName):
        origName = self._normpath(origName)
        newName = self._normpath(newName)
        self._record(JOURNAL_ENTRY_RENAME, origName, newName)

    def create(self, name):
        name = self._normpath(name)
        self._record(JOURNAL_ENTRY_CREATE, '', name)

    def mkdir(self, name):
        name = self._normpath(name)
        self._record(JOURNAL_ENTRY_MKDIR, '', name)

    def remove(self, name):
        name = self._normpath(name)
        self._record(JOURNAL_ENTRY_REMOVE, '', name)

    def backup(self, target, skipDirs = False):
        target = self._normpath(target)
        try:
            sb = os.lstat(target)
        except OSError:
            sb = None

        if sb:
            path = os.path.dirname(target)
            name = os.path.basename(target)

            tmpfd, tmpname = tempfile.mkstemp(name, '.ct', path)
            os.close(tmpfd)
            os.unlink(tmpname)
            if not stat.S_ISDIR(sb.st_mode):
                self._backup(target, tmpname, sb)
                os.link(target, tmpname)
            elif not skipDirs:
                self._backdir(target, sb)

    def commit(self):
        for kind, entry in self:
            if kind == JOURNAL_ENTRY_BACKUP:
                os.unlink(self.root + entry.new())
        self.close()

    def revert(self):
        for kind, entry in self:
            try:
                if kind == JOURNAL_ENTRY_BACKUP:
                    what = "restore"
                    path = self.root + entry.old()
                    os.rename(self.root + entry.new(), path)
                    os.chown(path, entry.inode.uid(), entry.inode.gid())
                    os.chmod(path, entry.inode.perms())
                    os.utime(path, (entry.inode.mtime(), entry.inode.mtime()))
                elif kind == JOURNAL_ENTRY_RENAME:
                    what = "restore"
                    os.rename(self.root + entry.new(), self.root + entry.old())
                elif kind == JOURNAL_ENTRY_CREATE:
                    what = "remove"
                    os.unlink(self.root + entry.new())
                elif kind == JOURNAL_ENTRY_MKDIR:
                    what = "remove"
                    os.rmdir(self.root + entry.new())
                elif kind == JOURNAL_ENTRY_REMOVE:
                    pass
                elif kind == JOURNAL_ENTRY_BACKDIR:
                    pass
                else:
                    self.callback.warning('unknown journal entry %d', kind)
            except OSError, e:
                self.callback.warning('could not %s file %s: %s',
                                      what, self.root + entry.new(), e.strerror)
        self.close()

    def __iter__(self):
        self.immutable = False
        next = os.fstat(self.fd).st_size - self.hdrSize
        while next > 0:
            os.lseek(self.fd, next, 0)
            kind, size = struct.unpack("!BH", os.read(self.fd, self.hdrSize))

            os.lseek(self.fd, next - size, 0)
            frz = os.read(self.fd, size)
            s = JournalEntry(frz)
            yield kind, s
            next = next - self.hdrSize - size
<|endoftext|>


<commit_before>
import sys,os;
import cPickle;
import string;
import re;

sys.path.append( "../../opengl_stub" )
parsed_file = open( "../../glapi_parser/gl_header.parsed", "rb" )
gl_mapping = cPickle.load( parsed_file )

import stub_common;

print """#include <stdio.h>
#include "cr_error.h"
#include "cr_spu.h"
#include "cr_glwrapper.h"
#include "printspu.h"

#if defined(WINDOWS)
#define PRINT_APIENTRY __stdcall
#else
#define PRINT_APIENTRY
#endif

#define PRINT_UNUSED(x) ((void)x)"""

keys = gl_mapping.keys()
keys.sort();

printf_mapping = {
	'GLint':      '%d',
	'GLshort':    '%d',
	'GLbyte':     '%d',
	'GLubyte':    '%u',
	'GLuint':     '%u',
	'GLushort':   '%u',
	'GLenum':     '%s',
	'GLfloat':    '%f',
	'GLclampf':   '%f',
	'GLdouble':   '%lf',
	'GLclampd':   '%lf',
	'GLbitfield': '0x%x',
	'GLboolean':  '%s',
	'GLsizei':    '%u'
}

for func_name in keys:
	if stub_common.FindSpecial( 'printspu_unimplemented', func_name ): continue
	if stub_common.FindSpecial( 'printspu_special', func_name ): continue
	(return_type, names, types) = gl_mapping[func_name]
	print '\n%s PRINT_APIENTRY print%s%s' % (return_type, func_name, stub_common.ArgumentString( names, types ))
	print '{'
	print '\tfprintf( stderr, "%s(' % func_name ,

	printfstr = ""
	argstr = ", "
	for i in range(len(names)):
		name = names[i]
		type = types[i]

		if printf_mapping.has_key( type ):
			escape_char = printf_mapping[type];
			printfstr += "%s" % escape_char
			if type == 'GLenum':
				argstr += 'printspuEnumToStr( %s )' % name
			elif type == 'GLboolean':
				argstr += '%s ? "true" : "false"' % name
			else:
				argstr += name

		else:
			argstr = ""
			printfstr = ""
			break;
		if i != len(names) - 1:
			printfstr += ", "
			argstr += ", "

	print '%s )\\n"%s );' % ( printfstr, argstr )

	if return_type != "void":
		print '\treturn',
	else:
		print '\t',
	print 'print_spu.passthrough.%s%s;' % ( func_name, stub_common.CallString( names ) )
	print '}'

print 'SPUNamedFunctionTable print_table[] = {'
for index in range(len(keys)):
	func_name = keys[index]
	if stub_common.FindSpecial( 'printspu_unimplemented', func_name ): continue
	if index != len(keys) - 1:
		print '\t{ "%s", (SPUGenericFunction) print%s },' % (func_name, func_name )
	else:
		print '\t{ "%s", (SPUGenericFunction) print%s }' % (func_name, func_name )
print '};'
<commit_msg>Added vector support to printouts<commit_after>
import sys,os;
import cPickle;
import string;
import re;

sys.path.append( "../../opengl_stub" )
parsed_file = open( "../../glapi_parser/gl_header.parsed", "rb" )
gl_mapping = cPickle.load( parsed_file )

import stub_common;

print """#include <stdio.h>
#include "cr_error.h"
#include "cr_spu.h"
#include "cr_glwrapper.h"
#include "printspu.h"

#if defined(WINDOWS)
#define PRINT_APIENTRY __stdcall
#else
#define PRINT_APIENTRY
#endif

#define PRINT_UNUSED(x) ((void)x)"""

keys = gl_mapping.keys()
keys.sort();

printf_mapping = {
	'GLint':      '%d',
	'GLshort':    '%d',
	'GLbyte':     '%d',
	'GLubyte':    '%u',
	'GLuint':     '%u',
	'GLushort':   '%u',
	'GLenum':     '%s',
	'GLfloat':    '%f',
	'GLclampf':   '%f',
	'GLdouble':   '%lf',
	'GLclampd':   '%lf',
	'GLbitfield': '0x%x',
	'GLboolean':  '%s',
	'GLsizei':    '%u'
}

for func_name in keys:
	if stub_common.FindSpecial( 'printspu_unimplemented', func_name ): continue
	if stub_common.FindSpecial( 'printspu_special', func_name ): continue
	(return_type, names, types) = gl_mapping[func_name]
	print '\n%s PRINT_APIENTRY print%s%s' % (return_type, func_name, stub_common.ArgumentString( names, types ))
	print '{'
	print '\tfprintf( stderr, "%s(' % func_name ,

	printfstr = ""
	argstr = ", "

	vector_nelem = stub_common.IsVector( func_name )
	if vector_nelem != 0:
		printfstr += '['
		vector_arg_type = re.sub( r'\*', '', types[0] )
		vector_arg_type = re.sub( r'const ', '', vector_arg_type )
		vector_arg_type = string.strip( vector_arg_type );
		for index in range( vector_nelem ):
			if printf_mapping.has_key( vector_arg_type ):
				printfstr += printf_mapping[vector_arg_type]
				argstr += '%s[%d]' % (names[0], index)
			if index != vector_nelem - 1:
				printfstr += ", "
				argstr += ", "
		printfstr += ']'
	else:
		for i in range(len(names)):
			name = names[i]
			type = types[i]

			if printf_mapping.has_key( type ):
				printfstr += printf_mapping[type];
				if type == 'GLenum':
					argstr += 'printspuEnumToStr( %s )' % name
				elif type == 'GLboolean':
					argstr += '%s ? "true" : "false"' % name
				else:
					argstr += name
			else:
				argstr = ""
				printfstr = ""
				break;
			if i != len(names) - 1:
				printfstr += ", "
				argstr += ", "

	print '%s )\\n"%s );' % ( printfstr, argstr )

	if return_type != "void":
		print '\treturn',
	else:
		print '\t',
	print 'print_spu.passthrough.%s%s;' % ( func_name, stub_common.CallString( names ) )
	print '}'

print 'SPUNamedFunctionTable print_table[] = {'
for index in range(len(keys)):
	func_name = keys[index]
	if stub_common.FindSpecial( 'printspu_unimplemented', func_name ): continue
	if index != len(keys) - 1:
		print '\t{ "%s", (SPUGenericFunction) print%s },' % (func_name, func_name )
	else:
		print '\t{ "%s", (SPUGenericFunction) print%s }' % (func_name, func_name )
print '};'
<|endoftext|>


<commit_before>from sqlalchemy.sql import text
import transaction
import zope

from c2corg_api.scripts.migration.documents.versions import tables_union
from c2corg_api.models.association import Association, AssociationLog
from c2corg_api.scripts.migration.batch import SimpleBatch
from c2corg_api.scripts.migration.migrate_base import MigrateBase

# TODO currently only importing associations for document types imported so far
associations_query_count =\
    'select count(*) from (' \
    '  select a.main_id, a.linked_id from app_documents_associations a ' \
    '  inner join (' + tables_union + \
    '  ) u on u.id = a.main_id and u.redirects_to is null ' \
    '  inner join (' + tables_union + \
    '  ) v on v.id = a.linked_id and v.redirects_to is null ' \
    '  group by a.main_id, a.linked_id) t;'

associations_query = \
    'select main_id, linked_id from app_documents_associations a ' \
    'inner join (' + tables_union + \
    ') u on u.id = a.main_id and u.redirects_to is null ' \
    'inner join (' + tables_union + \
    ') v on v.id = a.linked_id and v.redirects_to is null ' \
    'group by a.main_id, a.linked_id;'

association_log_query_count =\
    'select count(*) from (' \
    '  select associations_log_id from app_associations_log a ' \
    '  inner join (' + tables_union + \
    '  ) u on u.id = a.main_id and u.redirects_to is null ' \
    '  inner join (' + tables_union + \
    '  ) v on v.id = a.linked_id and v.redirects_to is null ' \
    '  group by associations_log_id) t;'

association_log_query = \
    'select ' \
    '  associations_log_id, main_id, linked_id, user_id, is_creation, ' \
    '  written_at from app_associations_log a ' \
    'inner join (' + tables_union + \
    ') u on u.id = a.main_id and u.redirects_to is null ' \
    'inner join (' + tables_union + \
    ') v on v.id = a.linked_id and v.redirects_to is null ' \
    'group by associations_log_id;'

class MigrateAssociations(MigrateBase):
    """Migrate associations and association log. And also set the main waypoint
    and `title_prefix` for routes.
    """

    def migrate(self):
        self._migrate(
            'associations',
            associations_query_count, associations_query, Association,
            self.get_association)
        self._migrate(
            'associations_log',
            association_log_query_count, association_log_query, AssociationLog,
            self.get_log)
        self._set_route_main_waypoint()
        self._set_route_locale_title_prefix()

    def get_association(self, row):
        return dict(
            parent_document_id=row.main_id,
            child_document_id=row.linked_id
        )

    def get_log(self, row):
        return dict(
            parent_document_id=row.main_id,
            child_document_id=row.linked_id,
            user_id=row.user_id,
            is_creation=row.is_creation,
            written_at=row.written_at
        )

    def _migrate(self, label, query_count, query, model, get_entity):
        self.start(label)

        total_count = self.connection_source.execute(
            text(query_count)).fetchone()[0]

        print('Total: {0} rows'.format(total_count))

        query = text(query)
        batch = SimpleBatch(
            self.session_target, self.batch_size, model)
        with transaction.manager, batch:
            count = 0
            for entity_in in self.connection_source.execute(query):
                count += 1
                # ignore associations for these documents because the
                # documents are broken (no latest version)
                if entity_in.main_id not in [224228, 436917] and \
                        entity_in.linked_id not in [224228, 436917]:
                    batch.add(get_entity(entity_in))
                self.progress(count, total_count)

            # the transaction will not be committed automatically when doing
            # a bulk insertion. `mark_changed` forces a commit.
            zope.sqlalchemy.mark_changed(self.session_target)
        self.stop()

    def _remove_duplicate_associations(self):
        """In v5 there are some double associations between documents, for
        example two associations R1 -> R2 and R2 -> R1. The following two
        queries remove these duplicates, so that there is only one.
        """
        print('Removing duplicate associations')
        with transaction.manager:
            self.session_target.execute(SQL_DELETE_DUPLICATE_ASSOCIATONS_LOG)
            self.session_target.execute(SQL_DELETE_DUPLICATE_ASSOCIATONS)
            zope.sqlalchemy.mark_changed(self.session_target)
        print('Done')

    def _set_route_main_waypoint(self):
        """Set the field `main_waypoint_id` to the highest associated waypoint.
        """
        print('Set main waypoint for routes')
        with transaction.manager:
            self.session_target.execute(SQL_SET_MAIN_WAYPOINT_ID)
            zope.sqlalchemy.mark_changed(self.session_target)
        print('Done')

    def _set_route_locale_title_prefix(self):
        """Set the `title_prefix` field for all route locales that have a
        main waypoint. First set the field for route locales, where there is
        a locale of the main waypoint in the same lang. Then with a 2nd
        query set the remaining rows by selecting the "best" locale of the main
        waypoint.
        """
        with transaction.manager:
            print('Set title prefix for route locales (same lang)')
            self.session_target.execute(SQL_SET_TITLE_PREFIX_SAME_CULTURE)
            print('Set title prefix for route locales (other lang)')
            self.session_target.execute(SQL_SET_TITLE_PREFIX_OTHER_CULTURE)
            zope.sqlalchemy.mark_changed(self.session_target)
        print('Done')

SQL_SET_MAIN_WAYPOINT_ID = """
with v as (select t.r_id, t.w_id
  from (select
    u.r_id, u.w_id, dense_rank() over(
      partition by u.r_id order by u.elevation desc) as rank
    from ((select r.document_id as r_id, wp.document_id as w_id, wp.elevation
      from guidebook.documents r
        join guidebook.associations a on r.document_id = a.parent_document_id
        join guidebook.documents d on a.child_document_id = d.document_id and
          d.type = 'w'
        join guidebook.waypoints wp on d.document_id = wp.document_id and
          wp.waypoint_type in ('summit', 'virtual', 'pass', 'lake', 'bisse',
                               'waterfall', 'climbing_outdoor', 'cave',
                               'locality', 'waterpoint', 'misc')
      where r.type = 'r')
    union (select r.document_id as r_id, wp.document_id as w_id, wp.elevation
      from guidebook.documents r
        join guidebook.associations a on r.document_id = a.child_document_id
        join guidebook.documents d on a.parent_document_id = d.document_id and
          d.type = 'w'
        join guidebook.waypoints wp on d.document_id = wp.document_id and
          wp.waypoint_type in ('summit', 'virtual', 'pass', 'lake', 'bisse',
                               'waterfall', 'climbing_outdoor', 'cave',
                               'locality', 'waterpoint', 'misc')
      where r.type = 'r')) u
  ) t where t.rank = 1)
update guidebook.routes r
  set main_waypoint_id = v.w_id
from v
where v.r_id = r.document_id;"""

SQL_SET_TITLE_PREFIX_SAME_CULTURE = """
with v as (select rl.id, l2.title
  from guidebook.routes_locales rl join guidebook.documents_locales l1
    on rl.id = l1.id
  join guidebook.routes r on l1.document_id = r.document_id
  join guidebook.documents_locales l2
    on r.main_waypoint_id = l2.document_id and l2.lang = l1.lang)
update guidebook.routes_locales l
  set title_prefix = v.title
from v
where v.id = l.id;
"""

SQL_SET_TITLE_PREFIX_OTHER_CULTURE = """
with v as (select t.id, t.title
  from (select rl.id, l2.title, dense_rank() over(
    partition by rl.id
    order by
      l2.lang != 'fr',
      l2.lang != 'en',
      l2.lang != 'it',
      l2.lang != 'de',
      l2.lang != 'es',
      l2.lang != 'ca'
    ) as rank
    from guidebook.routes_locales rl join guidebook.documents_locales l1
      on rl.id = l1.id and rl.title_prefix is null
    join guidebook.routes r on l1.document_id = r.document_id
    join guidebook.documents_locales l2
      on r.main_waypoint_id = l2.document_id) t
  where t.rank = 1)
update guidebook.routes_locales l
  set title_prefix = v.title
from v
where v.id = l.id;
"""

SQL_DELETE_DUPLICATE_ASSOCIATONS_LOG = """
delete from guidebook.association_log l
  using (
    select
      duplicate_link[1] as document_id_1,
      duplicate_link[2] as document_id_2
    from (
      select (SELECT ARRAY(SELECT unnest(
        ARRAY[a.parent_document_id, a.child_document_id]) ORDER BY 1))
        duplicate_link
      from guidebook.associations a join guidebook.associations b
        on a.parent_document_id = b.child_document_id and
           a.child_document_id = b.parent_document_id
      group by duplicate_link) t) v
  where l.parent_document_id = v.document_id_1 and
        l.child_document_id = v.document_id_2;
"""

SQL_DELETE_DUPLICATE_ASSOCIATONS = """
delete from guidebook.associations assoc
  using (
    select
      duplicate_link[1] as document_id_1,
      duplicate_link[2] as document_id_2
    from (
      select (SELECT ARRAY(SELECT unnest(
        ARRAY[a.parent_document_id, a.child_document_id]) ORDER BY 1))
        duplicate_link
      from guidebook.associations a join guidebook.associations b
        on a.parent_document_id = b.child_document_id and
           a.child_document_id = b.parent_document_id
      group by duplicate_link) t) v
  where assoc.parent_document_id = v.document_id_1 and
        assoc.child_document_id = v.document_id_2;
"""
<commit_msg>Migrate association type<commit_after>from c2corg_api.models.image import IMAGE_TYPE
from c2corg_api.models.outing import OUTING_TYPE
from c2corg_api.models.route import ROUTE_TYPE
from c2corg_api.models.user_profile import USERPROFILE_TYPE
from c2corg_api.models.waypoint import WAYPOINT_TYPE
from sqlalchemy.sql import text
import transaction
import zope

from c2corg_api.scripts.migration.documents.versions import tables_union
from c2corg_api.models.association import Association, AssociationLog
from c2corg_api.scripts.migration.batch import SimpleBatch
from c2corg_api.scripts.migration.migrate_base import MigrateBase

# TODO currently only importing associations for document types imported so far
associations_query_count =\
    'select count(*) from (' \
    '  select a.main_id, a.linked_id from app_documents_associations a ' \
    '  inner join (' + tables_union + \
    '  ) u on u.id = a.main_id and u.redirects_to is null ' \
    '  inner join (' + tables_union + \
    '  ) v on v.id = a.linked_id and v.redirects_to is null ' \
    '  where a.type not in (\'ai\', \'mi\') ' \
    '  group by a.main_id, a.linked_id) t;'

associations_query = \
    'select main_id, linked_id, type from app_documents_associations a ' \
    'inner join (' + tables_union + \
    ') u on u.id = a.main_id and u.redirects_to is null ' \
    'inner join (' + tables_union + \
    ') v on v.id = a.linked_id and v.redirects_to is null ' \
    'where type not in (\'ai\', \'mi\') ' \
    'group by a.main_id, a.linked_id;'

association_log_query_count =\
    'select count(*) from (' \
    '  select associations_log_id from app_associations_log a ' \
    '  inner join (' + tables_union + \
    '  ) u on u.id = a.main_id and u.redirects_to is null ' \
    '  inner join (' + tables_union + \
    '  ) v on v.id = a.linked_id and v.redirects_to is null ' \
    '  where a.type not in (\'ai\', \'mi\') ' \
    '  group by associations_log_id) t;'

association_log_query = \
    'select ' \
    '  associations_log_id, main_id, linked_id, type, user_id, is_creation, ' \
    '  written_at from app_associations_log a ' \
    'inner join (' + tables_union + \
    ') u on u.id = a.main_id and u.redirects_to is null ' \
    'inner join (' + tables_union + \
    ') v on v.id = a.linked_id and v.redirects_to is null ' \
    'where type not in (\'ai\', \'mi\') ' \
    'group by associations_log_id;'

class MigrateAssociations(MigrateBase):
    """Migrate associations and association log. And also set the main waypoint
    and `title_prefix` for routes.
    """

    def migrate(self):
        self._migrate(
            'associations',
            associations_query_count, associations_query, Association,
            self.get_association)
        self._migrate(
            'associations_log',
            association_log_query_count, association_log_query, AssociationLog,
            self.get_log)
        self._set_route_main_waypoint()
        self._set_route_locale_title_prefix()

    def get_association(self, row):
        parent_type, child_type = self._convert_type(row)
        return dict(
            parent_document_id=row.main_id,
            parent_document_type=parent_type,
            child_document_id=row.linked_id,
            child_document_type=child_type
        )

    def get_log(self, row):
        parent_type, child_type = self._convert_type(row)
        return dict(
            parent_document_id=row.main_id,
            parent_document_type=parent_type,
            child_document_id=row.linked_id,
            child_document_type=child_type,
            user_id=row.user_id,
            is_creation=row.is_creation,
            written_at=row.written_at
        )

    def _migrate(self, label, query_count, query, model, get_entity):
        self.start(label)

        total_count = self.connection_source.execute(
            text(query_count)).fetchone()[0]

        print('Total: {0} rows'.format(total_count))

        query = text(query)
        batch = SimpleBatch(
            self.session_target, self.batch_size, model)
        with transaction.manager, batch:
            count = 0
            for entity_in in self.connection_source.execute(query):
                count += 1
                # ignore associations for these documents because the
                # documents are broken (no latest version)
                if entity_in.main_id not in [224228, 436917] and \
                        entity_in.linked_id not in [224228, 436917]:
                    batch.add(get_entity(entity_in))
                self.progress(count, total_count)

            # the transaction will not be committed automatically when doing
            # a bulk insertion. `mark_changed` forces a commit.
            zope.sqlalchemy.mark_changed(self.session_target)
        self.stop()

    def _remove_duplicate_associations(self):
        """In v5 there are some double associations between documents, for
        example two associations R1 -> R2 and R2 -> R1. The following two
        queries remove these duplicates, so that there is only one.
        """
        print('Removing duplicate associations')
        with transaction.manager:
            self.session_target.execute(SQL_DELETE_DUPLICATE_ASSOCIATONS_LOG)
            self.session_target.execute(SQL_DELETE_DUPLICATE_ASSOCIATONS)
            zope.sqlalchemy.mark_changed(self.session_target)
        print('Done')

    def _set_route_main_waypoint(self):
        """Set the field `main_waypoint_id` to the highest associated waypoint.
        """
        print('Set main waypoint for routes')
        with transaction.manager:
            self.session_target.execute(SQL_SET_MAIN_WAYPOINT_ID)
            zope.sqlalchemy.mark_changed(self.session_target)
        print('Done')

    def _set_route_locale_title_prefix(self):
        """Set the `title_prefix` field for all route locales that have a
        main waypoint. First set the field for route locales, where there is
        a locale of the main waypoint in the same lang. Then with a 2nd
        query set the remaining rows by selecting the "best" locale of the main
        waypoint.
        """
        with transaction.manager:
            print('Set title prefix for route locales (same lang)')
            self.session_target.execute(SQL_SET_TITLE_PREFIX_SAME_CULTURE)
            print('Set title prefix for route locales (other lang)')
            self.session_target.execute(SQL_SET_TITLE_PREFIX_OTHER_CULTURE)
            zope.sqlalchemy.mark_changed(self.session_target)
        print('Done')

    def _convert_type(self, row):
        old_type = row.type
        old_parent_type = old_type[0]
        old_child_type = old_type[1]
        parent_type = ASSOCIATION_TYPES[old_parent_type]
        child_type = ASSOCIATION_TYPES[old_child_type]

        return parent_type, child_type

ASSOCIATION_TYPES = {
    # 'x': REPORT_TYPE,
    'p': WAYPOINT_TYPE,     # parking
    'u': USERPROFILE_TYPE,  # user
    # 'b': BOOK_TYPE,       # book
    'i': IMAGE_TYPE,        # image
    # 'a': AREA_TYPE,       # area: ignored
    'o': OUTING_TYPE,       # outing
    'f': WAYPOINT_TYPE,     # product
    # 'c': ARTICLE_TYPE,    # article
    'h': WAYPOINT_TYPE,     # hut
    'r': ROUTE_TYPE,        # route
    # 'w': ?,               # portal?
    's': WAYPOINT_TYPE,     # summit
    't': WAYPOINT_TYPE,     # site
    # 'm': MAP_TYPE         # map: ignored
}

SQL_SET_MAIN_WAYPOINT_ID = """
with v as (select t.r_id, t.w_id
  from (select
    u.r_id, u.w_id, dense_rank() over(
      partition by u.r_id order by u.elevation desc) as rank
    from ((select r.document_id as r_id, wp.document_id as w_id, wp.elevation
      from guidebook.documents r
        join guidebook.associations a on r.document_id = a.parent_document_id
        join guidebook.documents d on a.child_document_id = d.document_id and
          d.type = 'w'
        join guidebook.waypoints wp on d.document_id = wp.document_id and
          wp.waypoint_type in ('summit', 'virtual', 'pass', 'lake', 'bisse',
                               'waterfall', 'climbing_outdoor', 'cave',
                               'locality', 'waterpoint', 'misc')
      where r.type = 'r')
    union (select r.document_id as r_id, wp.document_id as w_id, wp.elevation
      from guidebook.documents r
        join guidebook.associations a on r.document_id = a.child_document_id
        join guidebook.documents d on a.parent_document_id = d.document_id and
          d.type = 'w'
        join guidebook.waypoints wp on d.document_id = wp.document_id and
          wp.waypoint_type in ('summit', 'virtual', 'pass', 'lake', 'bisse',
                               'waterfall', 'climbing_outdoor', 'cave',
                               'locality', 'waterpoint', 'misc')
      where r.type = 'r')) u
  ) t where t.rank = 1)
update guidebook.routes r
  set main_waypoint_id = v.w_id
from v
where v.r_id = r.document_id;"""

SQL_SET_TITLE_PREFIX_SAME_CULTURE = """
with v as (select rl.id, l2.title
  from guidebook.routes_locales rl join guidebook.documents_locales l1
    on rl.id = l1.id
  join guidebook.routes r on l1.document_id = r.document_id
  join guidebook.documents_locales l2
    on r.main_waypoint_id = l2.document_id and l2.lang = l1.lang)
update guidebook.routes_locales l
  set title_prefix = v.title
from v
where v.id = l.id;
"""

SQL_SET_TITLE_PREFIX_OTHER_CULTURE = """
with v as (select t.id, t.title
  from (select rl.id, l2.title, dense_rank() over(
    partition by rl.id
    order by
      l2.lang != 'fr',
      l2.lang != 'en',
      l2.lang != 'it',
      l2.lang != 'de',
      l2.lang != 'es',
      l2.lang != 'ca'
    ) as rank
    from guidebook.routes_locales rl join guidebook.documents_locales l1
      on rl.id = l1.id and rl.title_prefix is null
    join guidebook.routes r on l1.document_id = r.document_id
    join guidebook.documents_locales l2
      on r.main_waypoint_id = l2.document_id) t
  where t.rank = 1)
update guidebook.routes_locales l
  set title_prefix = v.title
from v
where v.id = l.id;
"""

SQL_DELETE_DUPLICATE_ASSOCIATONS_LOG = """
delete from guidebook.association_log l
  using (
    select
      duplicate_link[1] as document_id_1,
      duplicate_link[2] as document_id_2
    from (
      select (SELECT ARRAY(SELECT unnest(
        ARRAY[a.parent_document_id, a.child_document_id]) ORDER BY 1))
        duplicate_link
      from guidebook.associations a join guidebook.associations b
        on a.parent_document_id = b.child_document_id and
           a.child_document_id = b.parent_document_id
      group by duplicate_link) t) v
  where l.parent_document_id = v.document_id_1 and
        l.child_document_id = v.document_id_2;
"""

SQL_DELETE_DUPLICATE_ASSOCIATONS = """
delete from guidebook.associations assoc
  using (
    select
      duplicate_link[1] as document_id_1,
      duplicate_link[2] as document_id_2
    from (
      select (SELECT ARRAY(SELECT unnest(
        ARRAY[a.parent_document_id, a.child_document_id]) ORDER BY 1))
        duplicate_link
      from guidebook.associations a join guidebook.associations b
        on a.parent_document_id = b.child_document_id and
           a.child_document_id = b.parent_document_id
      group by duplicate_link) t) v
  where assoc.parent_document_id = v.document_id_1 and
        assoc.child_document_id = v.document_id_2;
"""
<|endoftext|>


<commit_before>from win_unc.connecting import UncDirectoryConnection, UncDirectoryMount
from win_unc.internal.current_state import get_current_net_use_table

__all__ = ['get_current_connections', 'get_connection_for_unc_directory']

def get_current_connections():
    net_use = get_current_net_use_table()
    return [_get_connection_or_mount(row['remote'], row['local']) for row in net_use.rows]

def get_connection_for_unc_directory(unc):
    net_use = get_current_net_use_table()
    matching = net_use.get_matching_rows(remote=unc)
    return _get_connection_or_mount(matching[0]['remote'], matching[0]['local']) if matching else None

def _get_connection_or_mount(unc, disk_drive=None):
    return UncDirectoryMount(unc, disk_drive) if disk_drive else UncDirectoryConnection(unc)
<commit_msg>Add get_connection_for_disk_drive<commit_after>from win_unc.connecting import UncDirectoryConnection, UncDirectoryMount
from win_unc.internal.current_state import get_current_net_use_table

__all__ = ['get_current_connections', 'get_connection_for_unc_directory']

def get_current_connections():
    net_use = get_current_net_use_table()
    return [_get_connection_or_mount(row['remote'], row['local']) for row in net_use.rows]

def get_connection_for_unc_directory(unc):
    net_use = get_current_net_use_table()
    matching = net_use.get_matching_rows(remote=unc)
    return _get_connection_or_mount(matching[0]['remote'], matching[0]['local']) if matching else None

def get_connection_for_disk_drive(disk_drive):
    net_use = get_current_net_use_table()
    matching = net_use.get_matching_rows(local=disk_drive)
    return UncDirectoryMount(matching[0]['remote'], matching[0]['local']) if matching else None

def _get_connection_or_mount(unc, disk_drive=None):
    return UncDirectoryMount(unc, disk_drive) if disk_drive else UncDirectoryConnection(unc)
<|endoftext|>


<commit_before>VERSION = __version__ = (0, 1, 3, 'rc', 0)
__author__ = 'sax'

def get_version(version=None):
    """Derives a PEP386-compliant version number from VERSION."""
    if version is None:
        version = VERSION
    assert len(version) == 5
    assert version[3] in ('alpha', 'beta', 'rc', 'final')

    parts = 2 if version[2] == 0 else 3
    main = '.'.join(str(x) for x in version[:parts])

    sub = ''
    if version[3] == 'alpha' and version[4] == 0:
        import concurrency

        path = concurrency.__path__[0]
        head_path = '%s/../.git/logs/HEAD' % path
        try:
            for line in open(head_path): pass
            revision = line.split()[0]
        except IOError:
            raise Exception('Alpha version is are only allowed as git clone')
        sub = '.dev%s' % revision

    elif version[3] != 'final':
        mapping = {'alpha': 'a', 'beta': 'b', 'rc': 'c'}
        sub = mapping[version[3]] + str(version[4])

    return main + sub
<commit_msg>0.1.3 final<commit_after>VERSION = __version__ = (0, 1, 3, 'final', 0)
__author__ = 'sax'

def get_version(version=None):
    """Derives a PEP386-compliant version number from VERSION."""
    if version is None:
        version = VERSION
    assert len(version) == 5
    assert version[3] in ('alpha', 'beta', 'rc', 'final')

    parts = 2 if version[2] == 0 else 3
    main = '.'.join(str(x) for x in version[:parts])

    sub = ''
    if version[3] == 'alpha' and version[4] == 0:
        import concurrency

        path = concurrency.__path__[0]
        head_path = '%s/../.git/logs/HEAD' % path
        try:
            for line in open(head_path): pass
            revision = line.split()[0]
        except IOError:
            raise Exception('Alpha version is are only allowed as git clone')
        sub = '.dev%s' % revision

    elif version[3] != 'final':
        mapping = {'alpha': 'a', 'beta': 'b', 'rc': 'c'}
        sub = mapping[version[3]] + str(version[4])

    return main + sub
<|endoftext|>


<commit_before>"""Fab tasks that execute things on a remote server."""
from django.conf import settings

from fabric.api import run

from development_fabfile.fabfile.utils import require_server

@require_server
def run_restart_apache():
    """
    Restarts apache on the given server.

    Usage::

        fab <server> run_restart_apache

    """
    run('{0}restart'.format(settings.SERVER_APACHE_BIN_DIR))
<commit_msg>Added `fab <server> run_git_pull` task.<commit_after>"""Fab tasks that execute things on a remote server."""
from django.conf import settings

from fabric.api import cd, run

from development_fabfile.fabfile.utils import require_server

@require_server
def run_restart_apache():
    """
    Restarts apache on the given server.

    Usage::

        fab <server> run_restart_apache

    """
    run('{0}restart'.format(settings.SERVER_APACHE_BIN_DIR))

def run_git_pull():
    """
    Pulls the latest code and updates submodules.

    Usage::

        fab <server> run_git_pull

    """
    with cd(settings.SERVER_REPO_ROOT):
        run('git pull && git submodule init && git submodule update')
<|endoftext|>