text:
"""
Helper utilities for the Flocker release process.

XXX This script is not automatically checked by buildbot. See
https://clusterhq.atlassian.net/browse/FLOC-397
"""

import json
import os
import sys
import tempfile

from datetime import datetime
from subprocess import check_call

from effect import (
    Effect, sync_perform, ComposedDispatcher)
from effect.do import do

from characteristic import attributes
from git import GitCommandError, Repo
from pytz import UTC

import requests

from twisted.python.filepath import FilePath
from twisted.python.usage import Options, UsageError
from twisted.python.constants import Names, NamedConstant
from twisted.web import template

import flocker
from flocker.common.version import get_package_key_suffix
from flocker.provision._effect import sequence, dispatcher as base_dispatcher

from flocker.common.version import (
    get_doc_version,
    get_pre_release,
    is_pre_release,
    is_release,
    is_weekly_release,
    target_release,
    UnparseableVersion,
)
from flocker.provision._install import ARCHIVE_BUCKET

from .aws import (
    boto_dispatcher,
    UpdateS3RoutingRule,
    UpdateS3ErrorPage,
    ListS3Keys,
    DeleteS3Keys,
    CopyS3Keys,
    DownloadS3KeyRecursively,
    UploadToS3,
    UploadToS3Recursively,
    CreateCloudFrontInvalidation,

)

from .yum import (
    yum_dispatcher,
    CreateRepo,
    DownloadPackagesFromRepository,
)

from .vagrant import vagrant_version
from .homebrew import make_recipe
from .packaging import available_distributions, DISTRIBUTION_NAME_MAP

DEV_ARCHIVE_BUCKET = 'clusterhq-dev-archive'

class NotTagged(Exception):
    """
    Raised if publishing to production and the version being published version
    isn't tagged.
    """

class NotARelease(Exception):
    """
    Raised if trying to publish documentation to, or packages for a version
    that isn't a release.
    """

class DocumentationRelease(Exception):
    """
    Raised if trying to upload packages for a documentation release.
    """

class Environments(Names):
    """
    The environments that documentation can be published to.
    """
    PRODUCTION = NamedConstant()
    STAGING = NamedConstant()

class TagExists(Exception):
    """
    Raised if trying to release a version for which a tag already exists.
    """

class BranchExists(Exception):
    """
    Raised if trying to release a version for which a branch already exists.
    """

class MissingPreRelease(Exception):
    """
    Raised if trying to release a pre-release for which the previous expected
    pre-release does not exist.
    """

class NoPreRelease(Exception):
    """
    Raised if trying to release a marketing release if no pre-release exists.
    """

class PushFailed(Exception):
    """
    Raised if pushing to Git fails.
    """

@attributes([
    'documentation_bucket',
    'cloudfront_cname',
    'dev_bucket',
])
class DocumentationConfiguration(object):
    """
    The configuration for publishing documentation.

    :ivar bytes documentation_bucket: The bucket to publish documentation to.
    :ivar bytes cloudfront_cname: a CNAME associated to the cloudfront
        distribution pointing at the documentation bucket.
    :ivar bytes dev_bucket: The bucket buildbot uploads documentation to.
    """

DOCUMENTATION_CONFIGURATIONS = {
    Environments.PRODUCTION:
        DocumentationConfiguration(
            documentation_bucket="clusterhq-docs",
            cloudfront_cname="docs.clusterhq.com",
            dev_bucket="clusterhq-dev-docs"),
    Environments.STAGING:
        DocumentationConfiguration(
            documentation_bucket="clusterhq-staging-docs",
            cloudfront_cname="docs.staging.clusterhq.com",
            dev_bucket="clusterhq-dev-docs"),
}

@do
def publish_docs(flocker_version, doc_version, environment):
    """
    Publish the Flocker documentation. The documentation for each version of
    Flocker is uploaded to a development bucket on S3 by the build server and
    this copies the documentation for a particular ``flocker_version`` and
    publishes it as ``doc_version``. Attempting to publish documentation to a
    staging environment as a documentation version publishes it as the version
    being updated.

    :param bytes flocker_version: The version of Flocker to publish the
        documentation for.
    :param bytes doc_version: The version to publish the documentation as.
    :param Environments environment: The environment to publish the
        documentation to.
    :raises NotARelease: Raised if trying to publish to a version that isn't a
        release.
    :raises NotTagged: Raised if publishing to production and the version being
        published version isn't tagged.
    """
    if not (is_release(doc_version)
            or is_weekly_release(doc_version)
            or is_pre_release(doc_version)):
        raise NotARelease()

    if environment == Environments.PRODUCTION:
        if get_doc_version(flocker_version) != doc_version:
            raise NotTagged()
    configuration = DOCUMENTATION_CONFIGURATIONS[environment]

    dev_prefix = '%s/' % (flocker_version,)
    version_prefix = 'en/%s/' % (get_doc_version(doc_version),)

    is_dev = not is_release(doc_version)
    if is_dev:
        stable_prefix = "en/devel/"
    else:
        stable_prefix = "en/latest/"

    # Get the list of keys in the new documentation.
    new_version_keys = yield Effect(
        ListS3Keys(bucket=configuration.dev_bucket,
                   prefix=dev_prefix))
    # Get the list of keys already existing for the given version.
    # This should only be non-empty for documentation releases.
    existing_version_keys = yield Effect(
        ListS3Keys(bucket=configuration.documentation_bucket,
                   prefix=version_prefix))

    # Copy the new documentation to the documentation bucket.
    yield Effect(
        CopyS3Keys(source_bucket=configuration.dev_bucket,
                   source_prefix=dev_prefix,
                   destination_bucket=configuration.documentation_bucket,
                   destination_prefix=version_prefix,
                   keys=new_version_keys))

    # Delete any keys that aren't in the new documentation.
    yield Effect(
        DeleteS3Keys(bucket=configuration.documentation_bucket,
                     prefix=version_prefix,
                     keys=existing_version_keys - new_version_keys))

    # Update the key used for error pages if we're publishing to staging or if
    # we're publishing a marketing release to production.
    if ((environment is Environments.STAGING) or
        (environment is Environments.PRODUCTION and not is_dev)):
        yield Effect(
            UpdateS3ErrorPage(bucket=configuration.documentation_bucket,
                              target_prefix=version_prefix))

    # Update the redirect for the stable URL (en/latest/ or en/devel/)
    # to point to the new version. Returns the old target.
    old_prefix = yield Effect(
        UpdateS3RoutingRule(bucket=configuration.documentation_bucket,
                            prefix=stable_prefix,
                            target_prefix=version_prefix))

    # If we have changed versions, get all the keys from the old version
    if old_prefix:
        previous_version_keys = yield Effect(
            ListS3Keys(bucket=configuration.documentation_bucket,
                       prefix=old_prefix))
    else:
        previous_version_keys = set()

    # The changed keys are the new keys, the keys that were deleted from this
    # version, and the keys for the previous version.
    changed_keys = (new_version_keys |
                    existing_version_keys |
                    previous_version_keys)

    # S3 serves /index.html when given /, so any changed /index.html means
    # that / changed as well.
    # Note that we check for '/index.html' but remove 'index.html'
    changed_keys |= {key_name[:-len('index.html')]
                     for key_name in changed_keys
                     if key_name.endswith('/index.html')}

    # Always update the root.
    changed_keys |= {''}

    # The full paths are all the changed keys under the stable prefix, and
    # the new version prefix. This set is slightly bigger than necessary.
    changed_paths = {prefix + key_name
                     for key_name in changed_keys
                     for prefix in [stable_prefix, version_prefix]}

    # Invalidate all the changed paths in cloudfront.
    yield Effect(
        CreateCloudFrontInvalidation(cname=configuration.cloudfront_cname,
                                     paths=changed_paths))

class PublishDocsOptions(Options):
    """
    Arguments for ``publish-docs`` script.
    """

    optParameters = [
        ["flocker-version", None, flocker.__version__,
         "The version of flocker from which the documentation was built."],
        ["doc-version", None, None,
         "The version to publish the documentation as.\n"
         "This will differ from \"flocker-version\" for staging uploads."
         "Attempting to publish documentation as a documentation version "
         "publishes it as the version being updated.\n"
         "``doc-version`` is set to 0.3.0.post1 the documentation will be "
         "published as 0.3.0.\n"],
    ]

    optFlags = [
        ["production", None, "Publish documentation to production."],
    ]

    environment = Environments.STAGING

    def parseArgs(self):
        if self['doc-version'] is None:
            self['doc-version'] = get_doc_version(self['flocker-version'])

        if self['production']:
            self.environment = Environments.PRODUCTION

def publish_docs_main(args, base_path, top_level):
    """
    :param list args: The arguments passed to the script.
    :param FilePath base_path: The executable being run.
    :param FilePath top_level: The top-level of the flocker repository.
    """
    options = PublishDocsOptions()

    try:
        options.parseOptions(args)
    except UsageError as e:
        sys.stderr.write("%s: %s\n" % (base_path.basename(), e))
        raise SystemExit(1)

    try:
        sync_perform(
            dispatcher=ComposedDispatcher([boto_dispatcher, base_dispatcher]),
            effect=publish_docs(
                flocker_version=options['flocker-version'],
                doc_version=options['doc-version'],
                environment=options.environment,
                ))
    except NotARelease:
        sys.stderr.write("%s: Can't publish non-release.\n"
                         % (base_path.basename(),))
        raise SystemExit(1)
    except NotTagged:
        sys.stderr.write(
            "%s: Can't publish non-tagged version to production.\n"
            % (base_path.basename(),))
        raise SystemExit(1)

class UploadOptions(Options):
    """
    Options for uploading artifacts.
    """
    optParameters = [
        ["flocker-version", None, flocker.__version__,
         "The version of Flocker to upload artifacts for."
         "Python packages for " + flocker.__version__ + "will be uploaded.\n"],
        ["target", None, ARCHIVE_BUCKET,
         "The bucket to upload artifacts to.\n"],
        ["build-server", None,
         b'http://build.clusterhq.com',
         "The URL of the build-server.\n"],
        ["homebrew-tap", None, "git@github.com:ClusterHQ/homebrew-tap.git",
         "The Git repository to add a Homebrew recipe to.\n"],
    ]

    def parseArgs(self):
        version = self['flocker-version']

        if not (is_release(version)
                or is_weekly_release(version)
                or is_pre_release(version)):
            raise NotARelease()

        if get_doc_version(version) != version:
            raise DocumentationRelease()

FLOCKER_PACKAGES = [
    b'clusterhq-python-flocker',
    b'clusterhq-flocker-cli',
    b'clusterhq-flocker-node',
]

def publish_homebrew_recipe(homebrew_repo_url, version, source_bucket,
                            scratch_directory, top_level):
    """
    Publish a Homebrew recipe to a Git repository.

    :param git.Repo homebrew_repo: Homebrew tap Git repository. This should
        be an SSH URL so as not to require a username and password.
    :param bytes version: Version of Flocker to publish a recipe for.
    :param bytes source_bucket: S3 bucket to get source distribution from.
    :param FilePath scratch_directory: Temporary directory to create a recipe
        in.
    :param FilePath top_level: The top-level of the flocker repository.
    """
    url_template = 'https://{bucket}.s3.amazonaws.com/python/Flocker-{version}.tar.gz'  # noqa
    sdist_url = url_template.format(bucket=source_bucket, version=version)
    requirements_path = top_level.child('requirements.txt')
    content = make_recipe(
        version=version,
        sdist_url=sdist_url,
        requirements_path=requirements_path,
    )
    homebrew_repo = Repo.clone_from(
        url=homebrew_repo_url,
        to_path=scratch_directory.path)
    recipe = 'flocker-{version}.rb'.format(version=version)
    FilePath(homebrew_repo.working_dir).child(recipe).setContent(content)

    homebrew_repo.index.add([recipe])
    homebrew_repo.index.commit('Add recipe for Flocker version ' + version)

    # Sometimes this raises an index error, and it seems to be a race
    # condition. There should probably be a loop until push succeeds or
    # whatever condition is necessary for it to succeed is met. FLOC-2043.
    push_info = homebrew_repo.remotes.origin.push(homebrew_repo.head)[0]

    if (push_info.flags & push_info.ERROR) != 0:
        raise PushFailed()

@do
def publish_vagrant_metadata(version, box_url, scratch_directory, box_name,
                             target_bucket):
    """
    Publish Vagrant metadata for a given version of a given box.

    :param bytes version: The version of the Vagrant box to publish metadata
        for.
    :param bytes box_url: The URL of the Vagrant box.
    :param FilePath scratch_directory: A directory to create Vagrant metadata
        files in before uploading.
    :param bytes box_name: The name of the Vagrant box to publish metadata for.
    :param bytes target_bucket: S3 bucket to upload metadata to.
    """
    metadata_filename = '{box_name}.json'.format(box_name=box_name)
    # Download recursively because there may not be a metadata file
    yield Effect(DownloadS3KeyRecursively(
        source_bucket=target_bucket,
        source_prefix='vagrant',
        target_path=scratch_directory,
        filter_extensions=(metadata_filename,)))

    metadata = {
        "description": "clusterhq/{box_name} box.".format(box_name=box_name),
        "name": "clusterhq/{box_name}".format(box_name=box_name),
        "versions": [],
    }

    try:
        existing_metadata_file = scratch_directory.children()[0]
    except IndexError:
        pass
    else:
        existing_metadata = json.loads(existing_metadata_file.getContent())
        for version_metadata in existing_metadata['versions']:
            # In the future we may want to have multiple providers for the
            # same version but for now we discard any current providers for
            # the version being added.
            if version_metadata['version'] != vagrant_version(version):
                metadata['versions'].append(version_metadata)

    metadata['versions'].append({
        "version": vagrant_version(version),
        "providers": [
            {
                "url": box_url,
                "name": "virtualbox",
            },
        ],
    })

    # If there is an existing file, overwrite it. Else create a new file.
    new_metadata_file = scratch_directory.child(metadata_filename)
    new_metadata_file.setContent(json.dumps(metadata))

    yield Effect(UploadToS3(
        source_path=scratch_directory,
        target_bucket=target_bucket,
        target_key='vagrant/' + metadata_filename,
        file=new_metadata_file,
        content_type='application/json',
        ))

@do
def update_repo(package_directory, target_bucket, target_key, source_repo,
                packages, flocker_version, distribution):
    """
    Update ``target_bucket`` yum repository with ``packages`` from
    ``source_repo`` repository.

    :param FilePath package_directory: Temporary directory to download
        repository to.
    :param bytes target_bucket: S3 bucket to upload repository to.
    :param bytes target_key: Path within S3 bucket to upload repository to.
    :param bytes source_repo: Repository on the build server to get packages
        from.
    :param list packages: List of bytes, each specifying the name of a package
        to upload to the repository.
    :param bytes flocker_version: The version of flocker to upload packages
        for.
    :param Distribution distribution: The distribution to upload packages for.
    """
    package_directory.createDirectory()

    package_type = distribution.package_type()

    yield Effect(DownloadS3KeyRecursively(
        source_bucket=target_bucket,
        source_prefix=target_key,
        target_path=package_directory,
        filter_extensions=('.' + package_type.value,)))

    downloaded_packages = yield Effect(DownloadPackagesFromRepository(
        source_repo=source_repo,
        target_path=package_directory,
        packages=packages,
        flocker_version=flocker_version,
        distribution=distribution,
        ))

    new_metadata = yield Effect(CreateRepo(
        repository_path=package_directory,
        distribution=distribution,
        ))

    yield Effect(UploadToS3Recursively(
        source_path=package_directory,
        target_bucket=target_bucket,
        target_key=target_key,
        files=downloaded_packages | new_metadata,
        ))

@do
def upload_packages(scratch_directory, target_bucket, version, build_server,
                    top_level):
    """
    The ClusterHQ yum and deb repositories contain packages for Flocker, as
    well as the dependencies which aren't available in CentOS 7. It is
    currently hosted on Amazon S3. When doing a release, we want to add the
    new Flocker packages, while preserving the existing packages in the
    repository. To do this, we download the current repository, add the new
    package, update the metadata, and then upload the repository.

    :param FilePath scratch_directory: Temporary directory to download
        repository to.
    :param bytes target_bucket: S3 bucket to upload repository to.
    :param bytes version: Version to download packages for.
    :param bytes build_server: Server to download new packages from.
    :param FilePath top_level: The top-level of the flocker repository.
    """
    distribution_names = available_distributions(
        flocker_source_path=top_level,
    )

    for distribution_name in distribution_names:
        distribution = DISTRIBUTION_NAME_MAP[distribution_name]
        architecture = distribution.native_package_architecture()

        yield update_repo(
            package_directory=scratch_directory.child(
                b'{}-{}-{}'.format(
                    distribution.name,
                    distribution.version,
                    architecture)),
            target_bucket=target_bucket,
            target_key=os.path.join(
                distribution.name + get_package_key_suffix(version),
                distribution.version,
                architecture),
            source_repo=os.path.join(
                build_server, b'results/omnibus',
                version,
                b'{}-{}'.format(distribution.name, distribution.version)),
            packages=FLOCKER_PACKAGES,
            flocker_version=version,
            distribution=distribution,
        )

packages_template = (
    '<html xmlns:t="http://twistedmatrix.com/ns/twisted.web.template/0.1">\n'
    'This is an index for pip\n'
    '<div t:render="packages"><a>'
    '<t:attr name="href"><t:slot name="package_name" /></t:attr>'
    '<t:slot name="package_name" />'
    '</a><br />\n</div>'
    '</html>'
    )

class PackagesElement(template.Element):
    """A Twisted Web template element to render the Pip index file."""

    def __init__(self, packages):
        template.Element.__init__(self, template.XMLString(packages_template))
        self._packages = packages

    @template.renderer
    def packages(self, request, tag):
        for package in self._packages:
            if package != 'index.html':
                yield tag.clone().fillSlots(package_name=package)

def create_pip_index(scratch_directory, packages):
    """
    Create an index file for pip.

    :param FilePath scratch_directory: Temporary directory to create index in.
    :param list packages: List of bytes, filenames of packages to be in the
        index.
    """
    index_file = scratch_directory.child('index.html')
    with index_file.open('w') as f:
        # Although this returns a Deferred, it works without the reactor
        # because there are no Deferreds in the template evaluation.
        # See this cheat described at
        # https://twistedmatrix.com/documents/15.0.0/web/howto/twisted-templates.html
        template.flatten(None, PackagesElement(packages), f.write)
    return index_file

@do
def upload_pip_index(scratch_directory, target_bucket):
    """
    Upload an index file for pip to S3.

    :param FilePath scratch_directory: Temporary directory to create index in.
    :param bytes target_bucket: S3 bucket to upload index to.
    """
    packages = yield Effect(
        ListS3Keys(bucket=target_bucket,
                   prefix='python/'))

    index_path = create_pip_index(
        scratch_directory=scratch_directory,
        packages=packages)

    yield Effect(
        UploadToS3(
            source_path=scratch_directory,
            target_bucket=target_bucket,
            target_key='python/index.html',
            file=index_path,
        ))

@do
def upload_python_packages(scratch_directory, target_bucket, top_level,
                           output, error):
    """
    The repository contains source distributions and binary distributions
    (wheels) for Flocker. It is currently hosted on Amazon S3.

    :param FilePath scratch_directory: Temporary directory to create packages
        in.
    :param bytes target_bucket: S3 bucket to upload packages to.
    :param FilePath top_level: The top-level of the flocker repository.
    """
    # XXX This has a side effect so it should be an Effect
    # https://clusterhq.atlassian.net/browse/FLOC-1731
    check_call([
        'python', 'setup.py',
        'sdist', '--dist-dir={}'.format(scratch_directory.path),
        'bdist_wheel', '--dist-dir={}'.format(scratch_directory.path)],
        cwd=top_level.path, stdout=output, stderr=error)

    files = set([file.basename() for file in scratch_directory.children()])
    yield Effect(UploadToS3Recursively(
        source_path=scratch_directory,
        target_bucket=target_bucket,
        target_key='python',
        files=files,
        ))

def publish_artifacts_main(args, base_path, top_level):
    """
    Publish release artifacts.

    :param list args: The arguments passed to the scripts.
    :param FilePath base_path: The executable being run.
    :param FilePath top_level: The top-level of the flocker repository.
    """
    options = UploadOptions()

    try:
        options.parseOptions(args)
    except UsageError as e:
        sys.stderr.write("%s: %s\n" % (base_path.basename(), e))
        raise SystemExit(1)
    except NotARelease:
        sys.stderr.write("%s: Can't publish artifacts for a non-release.\n"
                         % (base_path.basename(),))
        raise SystemExit(1)
    except DocumentationRelease:
        sys.stderr.write("%s: Can't publish artifacts for a documentation "
                         "release.\n" % (base_path.basename(),))
        raise SystemExit(1)

    dispatcher = ComposedDispatcher([boto_dispatcher, yum_dispatcher,
                                     base_dispatcher])

    scratch_directory = FilePath(tempfile.mkdtemp(
        prefix=b'flocker-upload-'))
    scratch_directory.child('packages').createDirectory()
    scratch_directory.child('python').createDirectory()
    scratch_directory.child('pip').createDirectory()
    scratch_directory.child('vagrant').createDirectory()
    scratch_directory.child('homebrew').createDirectory()

    box_type = "flocker-tutorial"
    vagrant_prefix = 'vagrant/tutorial/'

    box_name = "{box_type}-{version}.box".format(
        box_type=box_type,
        version=options['flocker-version'],
    )

    box_url = "https://{bucket}.s3.amazonaws.com/{key}".format(
        bucket=options['target'],
        key=vagrant_prefix + box_name,
    )

    try:
        sync_perform(
            dispatcher=dispatcher,
            effect=sequence([
                upload_packages(
                    scratch_directory=scratch_directory.child('packages'),
                    target_bucket=options['target'],
                    version=options['flocker-version'],
                    build_server=options['build-server'],
                    top_level=top_level,
                ),
                upload_python_packages(
                    scratch_directory=scratch_directory.child('python'),
                    target_bucket=options['target'],
                    top_level=top_level,
                    output=sys.stdout,
                    error=sys.stderr,
                ),
                upload_pip_index(
                    scratch_directory=scratch_directory.child('pip'),
                    target_bucket=options['target'],
                ),
                Effect(
                    CopyS3Keys(
                        source_bucket=DEV_ARCHIVE_BUCKET,
                        source_prefix=vagrant_prefix,
                        destination_bucket=options['target'],
                        destination_prefix=vagrant_prefix,
                        keys=[box_name],
                    )
                ),
                publish_vagrant_metadata(
                    version=options['flocker-version'],
                    box_url=box_url,
                    scratch_directory=scratch_directory.child('vagrant'),
                    box_name=box_type,
                    target_bucket=options['target'],
                ),
            ]),
        )

        publish_homebrew_recipe(
            homebrew_repo_url=options['homebrew-tap'],
            version=options['flocker-version'],
            source_bucket=options['target'],
            scratch_directory=scratch_directory.child('homebrew'),
            top_level=top_level,
        )

    finally:
        scratch_directory.remove()

def calculate_base_branch(version, path):
    """
    The branch a release branch is created from depends on the release
    type and sometimes which pre-releases have preceeded this.

    :param bytes version: The version of Flocker to get a base branch for.
    :param bytes path: See :func:`git.Repo.init`.
    :returns: The base branch from which the new release branch was created.
    """
    if not (is_release(version)
            or is_weekly_release(version)
            or is_pre_release(version)):
        raise NotARelease()

    repo = Repo(path=path, search_parent_directories=True)
    existing_tags = [tag for tag in repo.tags if tag.name == version]

    if existing_tags:
        raise TagExists()

    release_branch_prefix = 'release/flocker-'

    if is_weekly_release(version):
        base_branch_name = 'master'
    elif is_pre_release(version) and get_pre_release(version) == 1:
        base_branch_name = 'master'
    elif get_doc_version(version) != version:
        base_branch_name = release_branch_prefix + get_doc_version(version)
    else:
        if is_pre_release(version):
            target_version = target_release(version)
        else:
            target_version = version

        pre_releases = []
        for tag in repo.tags:
            try:
                if (is_pre_release(tag.name) and
                    target_version == target_release(tag.name)):
                    pre_releases.append(tag.name)
            except UnparseableVersion:
                # The Flocker repository contains versions which are not
                # currently considered valid versions.
                pass

        if not pre_releases:
            raise NoPreRelease()

        latest_pre_release = sorted(
            pre_releases,
            key=lambda pre_release: get_pre_release(pre_release))[-1]

        if (is_pre_release(version) and get_pre_release(version) >
                get_pre_release(latest_pre_release) + 1):
            raise MissingPreRelease()

        base_branch_name = release_branch_prefix + latest_pre_release

    # We create a new branch from a branch, not a tag, because a maintenance
    # or documentation change may have been applied to the branch and not the
    # tag.
    # The branch must be available locally for the next step.
    repo.git.checkout(base_branch_name)

    return (
        branch for branch in repo.branches if
        branch.name == base_branch_name).next()

def create_release_branch(version, base_branch):
    """
    checkout a new Git branch to make changes on and later tag as a release.

    :param bytes version: The version of Flocker to create a release branch
        for.
    :param base_branch: See :func:`git.Head`. The branch to create the release
        branch from.
    """
    try:
        base_branch.checkout(b='release/flocker-' + version)
    except GitCommandError:
        raise BranchExists()

class CreateReleaseBranchOptions(Options):
    """
    Arguments for ``create-release-branch`` script.
    """

    optParameters = [
        ["flocker-version", None, None,
         "The version of Flocker to create a release branch for."],
    ]

    def parseArgs(self):
        if self['flocker-version'] is None:
            raise UsageError("`--flocker-version` must be specified.")

def create_release_branch_main(args, base_path, top_level):
    """
    Create a release branch.

    :param list args: The arguments passed to the script.
    :param FilePath base_path: The executable being run.
    :param FilePath top_level: The top-level of the flocker repository.
    """
    options = CreateReleaseBranchOptions()

    try:
        options.parseOptions(args)
    except UsageError as e:
        sys.stderr.write("%s: %s\n" % (base_path.basename(), e))
        raise SystemExit(1)

    version = options['flocker-version']
    path = FilePath(__file__).path

    try:
        base_branch = calculate_base_branch(version=version, path=path)
        create_release_branch(version=version, base_branch=base_branch)
    except NotARelease:
        sys.stderr.write("%s: Can't create a release branch for non-release.\n"
                         % (base_path.basename(),))
        raise SystemExit(1)
    except TagExists:
        sys.stderr.write("%s: Tag already exists for this release.\n"
                         % (base_path.basename(),))
        raise SystemExit(1)
    except NoPreRelease:
        sys.stderr.write("%s: No (previous) pre-release exists for this "
                         "release.\n" % (base_path.basename(),))
        raise SystemExit(1)
    except BranchExists:
        sys.stderr.write("%s: The release branch already exists.\n"
                         % (base_path.basename(),))
        raise SystemExit(1)

class TestRedirectsOptions(Options):
    """
    Arguments for ``test-redirects`` script.
    """
    optParameters = [
        ["doc-version", None, flocker.__version__,
         "The version which the documentation sites are expected to redirect "
         "to.\n"
        ],
    ]

    optFlags = [
        ["production", None, "Check the production documentation site."],
    ]

    environment = Environments.STAGING

    def parseArgs(self):
        if self['production']:
            self.environment = Environments.PRODUCTION

def get_expected_redirects(flocker_version):
    """
    Get the expected redirects for a given version of Flocker, if that version
    has been published successfully. Documentation versions (e.g. 0.3.0.post2)
    are published to their release version counterparts (e.g. 0.3.0).

    :param bytes flocker_version: The version of Flocker for which to get
        expected redirects.

    :return: Dictionary mapping paths to the path to which they are expected to
        redirect.
    """
    published_version = get_doc_version(flocker_version)

    if is_release(published_version):
        expected_redirects = {
            '/': '/en/' + published_version + '/',
            '/en/': '/en/' + published_version + '/',
            '/en/latest': '/en/' + published_version + '/',
            '/en/latest/faq/index.html':
                '/en/' + published_version + '/faq/index.html',
        }
    else:
        expected_redirects = {
            '/en/devel': '/en/' + published_version + '/',
            '/en/devel/faq/index.html':
                '/en/' + published_version + '/faq/index.html',
        }

    return expected_redirects

def test_redirects_main(args, base_path, top_level):
    """
    Tests redirects to Flocker documentation.

    :param list args: The arguments passed to the script.
    :param FilePath base_path: The executable being run.
    :param FilePath top_level: The top-level of the flocker repository.
    """
    options = TestRedirectsOptions()

    try:
        options.parseOptions(args)
    except UsageError as e:
        sys.stderr.write("%s: %s\n" % (base_path.basename(), e))
        raise SystemExit(1)

    expected_redirects = get_expected_redirects(
        flocker_version=options['doc-version'])
    document_configuration = DOCUMENTATION_CONFIGURATIONS[options.environment]
    base_url = 'https://' + document_configuration.cloudfront_cname

    failed_redirects = []

    for path in expected_redirects:
        original_url = base_url + path
        expected_url = base_url + expected_redirects[path]
        final_url = requests.get(original_url).url

        if expected_url != final_url:
            failed_redirects.append(original_url)

            message = (
                "'{original_url}' expected to redirect to '{expected_url}', "
                "instead redirects to '{final_url}'.\n").format(
                    original_url=original_url,
                    expected_url=expected_url,
                    final_url=final_url,
            )

            sys.stderr.write(message)

    if len(failed_redirects):
         raise SystemExit(1)
    else:
        print 'All tested redirects work correctly.'

class PublishDevBoxOptions(Options):
    """
    Options for publishing a Vagrant development box.
    """
    optParameters = [
        ["flocker-version", None, flocker.__version__,
         "The version of Flocker to upload a development box for.\n"],
        ["target", None, ARCHIVE_BUCKET,
         "The bucket to upload a development box to.\n"],
    ]

def publish_dev_box_main(args, base_path, top_level):
    """
    Publish a development Vagrant box.

    :param list args: The arguments passed to the script.
    :param FilePath base_path: The executable being run.
    :param FilePath top_level: The top-level of the flocker repository.
    """
    options = PublishDevBoxOptions()

    try:
        options.parseOptions(args)
    except UsageError as e:
        sys.stderr.write("%s: %s\n" % (base_path.basename(), e))
        raise SystemExit(1)

    scratch_directory = FilePath(tempfile.mkdtemp(
        prefix=b'flocker-upload-'))
    scratch_directory.child('vagrant').createDirectory()

    box_type = "flocker-dev"
    prefix = 'vagrant/dev/'

    box_name = "{box_type}-{version}.box".format(
        box_type=box_type,
        version=options['flocker-version'],
    )

    box_url = "https://{bucket}.s3.amazonaws.com/{key}".format(
        bucket=options['target'],
        key=prefix + box_name,
    )

    sync_perform(
        dispatcher=ComposedDispatcher([boto_dispatcher, base_dispatcher]),
        effect=sequence([
            Effect(
                CopyS3Keys(
                    source_bucket=DEV_ARCHIVE_BUCKET,
                    source_prefix=prefix,
                    destination_bucket=options['target'],
                    destination_prefix=prefix,
                    keys=[box_name],
                )
            ),
            publish_vagrant_metadata(
                version=options['flocker-version'],
                box_url=box_url,
                scratch_directory=scratch_directory.child('vagrant'),
                box_name=box_type,
                target_bucket=options['target'],
            ),
        ]),
    )

def update_license_file(args, top_level, year=datetime.now(UTC).year):
    """
    Update the LICENSE file to include the current year.

    :param list args: The arguments passed to the script.
    :param FilePath top_level: The top-level of the flocker repository.
    """
    license_template = top_level.child('admin').child('LICENSE.template')
    with license_template.open() as input_file:
        with top_level.child('LICENSE').open('w') as output_file:
            output_file.write(input_file.read().format(current_year=year))


text:
using System.Collections.Generic;
using UnityEngine;

namespace FairyGUI
{
	/// <summary>
	///
	/// </summary>
	public class BitmapFont : BaseFont
	{
		/// <summary>
		///
		/// </summary>
		public class BMGlyph
		{
			public int offsetX;
			public int offsetY;
			public int width;
			public int height;
			public int advance;
			public int lineHeight;
			public Vector2[] uv = new Vector2[4];
			public int channel;//0-n/a, 1-r,2-g,3-b,4-alpha
		}

		/// <summary>
		///
		/// </summary>
		public int size;

		/// <summary>
		///
		/// </summary>
		public bool resizable;

		/// <summary>
		///
		/// </summary>
		public string url;

		Dictionary<int, BMGlyph> _dict;
		float scale;

		public BitmapFont(PackageItem item)
		{
			this.packageItem = item;
			this.name = UIPackage.URL_PREFIX + packageItem.owner.id + packageItem.id;
			this.url = UIPackage.URL_PREFIX + packageItem.owner.name + "/" + packageItem.name;
			this.canTint = true;
			this.canLight = false;
			this.canOutline = true;
			this.hasChannel = false;
			this.shader = ShaderConfig.bmFontShader;

			_dict = new Dictionary<int, BMGlyph>();
			this.scale = 1;
		}

		public void AddChar(char ch, BMGlyph glyph)
		{
			_dict[ch] = glyph;
		}

		override public void SetFormat(TextFormat format, float fontSizeScale)
		{
			if (resizable)
				this.scale = (float)format.size / size * fontSizeScale;
		}

		override public bool GetGlyphSize(char ch, out float width, out float height)
		{
			BMGlyph bg;
			if (ch == ' ')
			{
				width = Mathf.CeilToInt(size * scale / 2);
				height = Mathf.CeilToInt(size * scale);
				return true;
			}
			else if (_dict.TryGetValue((int)ch, out bg))
			{
				width = Mathf.CeilToInt(bg.advance * scale);
				height = Mathf.CeilToInt(bg.lineHeight * scale);
				return true;
			}
			else
			{
				width = 0;
				height = 0;
				return false;
			}
		}

		override public bool GetGlyph(char ch, GlyphInfo glyph)
		{
			BMGlyph bg;
			if (ch == ' ')
			{
				glyph.width = Mathf.CeilToInt(size * scale / 2);
				glyph.height = Mathf.CeilToInt(size * scale);
				glyph.vert.xMin = 0;
				glyph.vert.xMax = 0;
				glyph.vert.yMin = 0;
				glyph.vert.yMax = 0;
				glyph.uv[0] = glyph.uv[1] = glyph.uv[2] = glyph.uv[3] = Vector2.zero;
				glyph.channel = 0;
				return true;
			}
			else if (_dict.TryGetValue((int)ch, out bg))
			{
				glyph.width = Mathf.CeilToInt(bg.advance * scale);
				glyph.height = Mathf.CeilToInt(bg.lineHeight * scale);
				glyph.vert.xMin = bg.offsetX * scale;
				glyph.vert.xMax = (bg.offsetX + bg.width) * scale;
				glyph.vert.yMin = (-bg.height - bg.offsetY) * scale;
				glyph.vert.yMax = -bg.offsetY * scale;
				glyph.uv[0] = bg.uv[0];
				glyph.uv[1] = bg.uv[1];
				glyph.uv[2] = bg.uv[2];
				glyph.uv[3] = bg.uv[3];
				glyph.channel = bg.channel;
				return true;
			}
			else
				return false;
		}
	}
}

redpajama_set_name: RedPajamaGithub


text:
#ifndef UTIL_LOCKS_H
#define UTIL_LOCKS_H

/**
 * \file
 * Locking primitives.
 * If pthreads is available, these are used.
 * If no locking exists, they do nothing.
 *
 * The idea is to have different sorts of locks for different tasks.
 * This allows the locking code to be ported more easily.
 *
 * Types of locks that are supported.
 *   o lock_rw: lock that has many readers and one writer (to a data entry).
 *   o lock_basic: simple mutex. Blocking, one person has access only.
 *     This lock is meant for non performance sensitive uses.
 *   o lock_quick: speed lock. For performance sensitive locking of critical
 *     sections. Could be implemented by a mutex or a spinlock.
 *
 * Also thread creation and deletion functions are defined here.
 */

#include "util/log.h"

/**
 * The following macro is used to check the return value of the
 * pthread calls. They return 0 on success and an errno on error.
 * The errno is logged to the logfile with a descriptive comment.
 */
#define LOCKRET(func) do {\
	int lockret_err;		\
	if( (lockret_err=(func)) != 0)		\
		log_err("%s at %d could not " #func ": %s", \
		__FILE__, __LINE__, strerror(lockret_err));	\
 	} while(0)

/** DEBUG: use thread debug whenever possible */
#if defined(HAVE_PTHREAD) && defined(HAVE_PTHREAD_SPINLOCK_T) && defined(ENABLE_LOCK_CHECKS)
#  define USE_THREAD_DEBUG
#endif

#ifdef USE_THREAD_DEBUG
/******************* THREAD DEBUG ************************/
/* (some) checking; to detect races and deadlocks. */
#include "testcode/checklocks.h"

#else /* USE_THREAD_DEBUG */
#define lock_protect(lock, area, size) /* nop */
#define lock_unprotect(lock, area) /* nop */
#define lock_get_mem(lock) (0) /* nothing */
#define checklock_start() /* nop */
#define checklock_stop() /* nop */

#ifdef HAVE_PTHREAD
#include <pthread.h>

/******************* PTHREAD ************************/

/** use pthread mutex for basic lock */
typedef pthread_mutex_t lock_basic_t;
/** small front for pthread init func, NULL is default attrs. */
#define lock_basic_init(lock) LOCKRET(pthread_mutex_init(lock, NULL))
#define lock_basic_destroy(lock) LOCKRET(pthread_mutex_destroy(lock))
#define lock_basic_lock(lock) LOCKRET(pthread_mutex_lock(lock))
#define lock_basic_unlock(lock) LOCKRET(pthread_mutex_unlock(lock))

#ifndef HAVE_PTHREAD_RWLOCK_T
/** in case rwlocks are not supported, use a mutex. */
typedef pthread_mutex_t lock_rw_t;
#define lock_rw_init(lock) LOCKRET(pthread_mutex_init(lock, NULL))
#define lock_rw_destroy(lock) LOCKRET(pthread_mutex_destroy(lock))
#define lock_rw_rdlock(lock) LOCKRET(pthread_mutex_lock(lock))
#define lock_rw_wrlock(lock) LOCKRET(pthread_mutex_lock(lock))
#define lock_rw_unlock(lock) LOCKRET(pthread_mutex_unlock(lock))
#else /* HAVE_PTHREAD_RWLOCK_T */
/** we use the pthread rwlock */
typedef pthread_rwlock_t lock_rw_t;
/** small front for pthread init func, NULL is default attrs. */
#define lock_rw_init(lock) LOCKRET(pthread_rwlock_init(lock, NULL))
#define lock_rw_destroy(lock) LOCKRET(pthread_rwlock_destroy(lock))
#define lock_rw_rdlock(lock) LOCKRET(pthread_rwlock_rdlock(lock))
#define lock_rw_wrlock(lock) LOCKRET(pthread_rwlock_wrlock(lock))
#define lock_rw_unlock(lock) LOCKRET(pthread_rwlock_unlock(lock))
#endif /* HAVE_PTHREAD_RWLOCK_T */

#ifndef HAVE_PTHREAD_SPINLOCK_T
/** in case spinlocks are not supported, use a mutex. */
typedef pthread_mutex_t lock_quick_t;
/** small front for pthread init func, NULL is default attrs. */
#define lock_quick_init(lock) LOCKRET(pthread_mutex_init(lock, NULL))
#define lock_quick_destroy(lock) LOCKRET(pthread_mutex_destroy(lock))
#define lock_quick_lock(lock) LOCKRET(pthread_mutex_lock(lock))
#define lock_quick_unlock(lock) LOCKRET(pthread_mutex_unlock(lock))

#else /* HAVE_PTHREAD_SPINLOCK_T */
/** use pthread spinlock for the quick lock */
typedef pthread_spinlock_t lock_quick_t;
/**
 * allocate process private since this is available whether
 * Thread Process-Shared Synchronization is supported or not.
 * This means only threads inside this process may access the lock.
 * (not threads from another process that shares memory).
 * spinlocks are not supported on all pthread platforms.
 */
#define lock_quick_init(lock) LOCKRET(pthread_spin_init(lock, PTHREAD_PROCESS_PRIVATE))
#define lock_quick_destroy(lock) LOCKRET(pthread_spin_destroy(lock))
#define lock_quick_lock(lock) LOCKRET(pthread_spin_lock(lock))
#define lock_quick_unlock(lock) LOCKRET(pthread_spin_unlock(lock))

#endif /* HAVE SPINLOCK */

/** Thread creation */
typedef pthread_t ub_thread_t;
/** Pass where to store tread_t in thr. Use default NULL attributes. */
#define ub_thread_create(thr, func, arg) LOCKRET(pthread_create(thr, NULL, func, arg))
/** get self id. */
#define ub_thread_self() pthread_self()
/** wait for another thread to terminate */
#define ub_thread_join(thread) LOCKRET(pthread_join(thread, NULL))
typedef pthread_key_t ub_thread_key_t;
#define ub_thread_key_create(key, f) LOCKRET(pthread_key_create(key, f))
#define ub_thread_key_set(key, v) LOCKRET(pthread_setspecific(key, v))
#define ub_thread_key_get(key) pthread_getspecific(key)

#else /* we do not HAVE_PTHREAD */
#ifdef HAVE_SOLARIS_THREADS

/******************* SOLARIS THREADS ************************/
#include <synch.h>
#include <thread.h>

typedef rwlock_t lock_rw_t;
#define lock_rw_init(lock) LOCKRET(rwlock_init(lock, USYNC_THREAD, NULL))
#define lock_rw_destroy(lock) LOCKRET(rwlock_destroy(lock))
#define lock_rw_rdlock(lock) LOCKRET(rw_rdlock(lock))
#define lock_rw_wrlock(lock) LOCKRET(rw_wrlock(lock))
#define lock_rw_unlock(lock) LOCKRET(rw_unlock(lock))

/** use basic mutex */
typedef mutex_t lock_basic_t;
#define lock_basic_init(lock) LOCKRET(mutex_init(lock, USYNC_THREAD, NULL))
#define lock_basic_destroy(lock) LOCKRET(mutex_destroy(lock))
#define lock_basic_lock(lock) LOCKRET(mutex_lock(lock))
#define lock_basic_unlock(lock) LOCKRET(mutex_unlock(lock))

/** No spinlocks in solaris threads API. Use a mutex. */
typedef mutex_t lock_quick_t;
#define lock_quick_init(lock) LOCKRET(mutex_init(lock, USYNC_THREAD, NULL))
#define lock_quick_destroy(lock) LOCKRET(mutex_destroy(lock))
#define lock_quick_lock(lock) LOCKRET(mutex_lock(lock))
#define lock_quick_unlock(lock) LOCKRET(mutex_unlock(lock))

/** Thread creation, create a default thread. */
typedef thread_t ub_thread_t;
#define ub_thread_create(thr, func, arg) LOCKRET(thr_create(NULL, NULL, func, arg, NULL, thr))
#define ub_thread_self() thr_self()
#define ub_thread_join(thread) LOCKRET(thr_join(thread, NULL, NULL))
typedef thread_key_t ub_thread_key_t;
#define ub_thread_key_create(key, f) LOCKRET(thr_keycreate(key, f))
#define ub_thread_key_set(key, v) LOCKRET(thr_setspecific(key, v))
void* ub_thread_key_get(ub_thread_key_t key);

#else /* we do not HAVE_SOLARIS_THREADS and no PTHREADS */
/******************* WINDOWS THREADS ************************/
#ifdef HAVE_WINDOWS_THREADS
#include <windows.h>

/* Use a mutex */
typedef LONG lock_rw_t;
#define lock_rw_init(lock) lock_basic_init(lock)
#define lock_rw_destroy(lock) lock_basic_destroy(lock)
#define lock_rw_rdlock(lock) lock_basic_lock(lock)
#define lock_rw_wrlock(lock) lock_basic_lock(lock)
#define lock_rw_unlock(lock) lock_basic_unlock(lock)

/** the basic lock is a mutex, implemented opaquely, for error handling. */
typedef LONG lock_basic_t;
void lock_basic_init(lock_basic_t* lock);
void lock_basic_destroy(lock_basic_t* lock);
void lock_basic_lock(lock_basic_t* lock);
void lock_basic_unlock(lock_basic_t* lock);

/** on windows no spinlock, use mutex too. */
typedef LONG lock_quick_t;
#define lock_quick_init(lock) lock_basic_init(lock)
#define lock_quick_destroy(lock) lock_basic_destroy(lock)
#define lock_quick_lock(lock) lock_basic_lock(lock)
#define lock_quick_unlock(lock) lock_basic_unlock(lock)

/** Thread creation, create a default thread. */
typedef HANDLE ub_thread_t;
void ub_thread_create(ub_thread_t* thr, void* (*func)(void*), void* arg);
ub_thread_t ub_thread_self(void);
void ub_thread_join(ub_thread_t thr);
typedef DWORD ub_thread_key_t;
void ub_thread_key_create(ub_thread_key_t* key, void* f);
void ub_thread_key_set(ub_thread_key_t key, void* v);
void* ub_thread_key_get(ub_thread_key_t key);

#else /* we do not HAVE_SOLARIS_THREADS, PTHREADS or WINDOWS_THREADS */

/******************* NO THREADS ************************/
#define THREADS_DISABLED 1
/** In case there is no thread support, define locks to do nothing */
typedef int lock_rw_t;
#define lock_rw_init(lock) /* nop */
#define lock_rw_destroy(lock) /* nop */
#define lock_rw_rdlock(lock) /* nop */
#define lock_rw_wrlock(lock) /* nop */
#define lock_rw_unlock(lock) /* nop */

/** define locks to do nothing */
typedef int lock_basic_t;
#define lock_basic_init(lock) /* nop */
#define lock_basic_destroy(lock) /* nop */
#define lock_basic_lock(lock) /* nop */
#define lock_basic_unlock(lock) /* nop */

/** define locks to do nothing */
typedef int lock_quick_t;
#define lock_quick_init(lock) /* nop */
#define lock_quick_destroy(lock) /* nop */
#define lock_quick_lock(lock) /* nop */
#define lock_quick_unlock(lock) /* nop */

/** Thread creation, threads do not exist */
typedef pid_t ub_thread_t;
/** ub_thread_create is simulated with fork (extremely heavy threads,
  * with no shared memory). */
#define ub_thread_create(thr, func, arg) \
	ub_thr_fork_create(thr, func, arg)
#define ub_thread_self() getpid()
#define ub_thread_join(thread) ub_thr_fork_wait(thread)
void ub_thr_fork_wait(ub_thread_t thread);
void ub_thr_fork_create(ub_thread_t* thr, void* (*func)(void*), void* arg);
typedef void* ub_thread_key_t;
#define ub_thread_key_create(key, f) (*(key)) = NULL
#define ub_thread_key_set(key, v) (key) = (v)
#define ub_thread_key_get(key) (key)

#endif /* HAVE_WINDOWS_THREADS */
#endif /* HAVE_SOLARIS_THREADS */
#endif /* HAVE_PTHREAD */
#endif /* USE_THREAD_DEBUG */

/**
 * Block all signals for this thread.
 * fatal exit on error.
 */
void ub_thread_blocksigs(void);

/**
 * unblock one signal for this thread.
 */
void ub_thread_sig_unblock(int sig);

#endif /* UTIL_LOCKS_H */


text:
<!--
  Author:       Sam Ruby (http://intertwingly.net/) and Mark Pilgrim (http://diveintomark.org/)
  Copyright:    Copyright (c) 2002 Sam Ruby and Mark Pilgrim
-->

<!--
  Description:  root element must be known
  Expect:       UndefinedElement{parent:root}
-->

<unknown>
<channel>
<title>Test case: missing RSS element</title>
<link>http://purl.org/rss/2.0/</link>
<description>root element must be rss</description>
</channel>
</unknown>


text:
(function () {
  "use strict";

  angular
    .module('mnFocus', [])
    .directive('mnFocus', mnFocusDirective);

  function mnFocusDirective($parse) {
    var mnFocus = {
      link: link
    };

    return mnFocus;

    function link($scope, $element, $attrs) {

      if ($attrs.mnFocus === "") {
        return $element[0].focus();
      }

      var getter = $parse($attrs.mnFocus);
      var setter = getter.assign;
      $scope.$watch($attrs.mnFocus, function (focus) {
        focus && $element[0].focus();
      });

      if (setter) {
        var handler = function handler() {
          setter($scope, false);
        }
        $element.on('blur', handler);
        $scope.$on('$destroy', function () {
          $element.off('blur', handler);
        })
      }
    }
  }
})();


text:
// Copyright 2009 the Sputnik authors.  All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.

/**
* @name: S15.2_A1;
* @section: 15.2;
* @assertion: Object is the property of global;
* @description: Checking if Object equals to this.Object;
*/

obj=Object;

thisobj=this.Object;

if(obj!==thisobj){
  $ERROR('Object is the property of global');
}


text:
$symbol_pound!/bin/bash
javadoc -docletpath target/${artifactId}-${version}-jar-with-dependencies.jar -doclet ${package}.Doclet "$symbol_dollar@"


text:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@color/colorMainActivity"
    android:baselineAligned="false" android:orientation="horizontal"
    tools:context="com.androidheads.vienna.escalero.MainActivity">

    <RelativeLayout
        android:id="@+id/rltable"
        android:layout_width="0dp"
        android:layout_height="match_parent"
        android:layout_weight="45"
        android:orientation="vertical" >

        <com.androidheads.vienna.escalero.TableView
            android:id="@+id/tableView"
            android:layout_width="wrap_content"
            android:layout_height="match_parent"
            android:layout_marginBottom="0dip" />

    </RelativeLayout>

    <RelativeLayout
        android:id="@+id/rlboard"
        android:layout_toRightOf="@+id/rltable"
        android:layout_width="0dp"
        android:layout_height="match_parent"
        android:layout_weight="55"
        android:orientation="vertical" >

        <RelativeLayout
            android:id="@+id/rl1"
            xmlns:android="http://schemas.android.com/apk/res/android"
            xmlns:tools="http://schemas.android.com/tools"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_above="@+id/btnPlayerRound"
            android:layout_marginLeft="@dimen/view_horizontal_margin_12"
            android:layout_marginRight="@dimen/view_horizontal_margin_12"
            android:layout_marginBottom="@dimen/view_horizontal_margin_12"
            tools:context="com.androidheads.vienna.escalero.MainActivity" >

            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_alignParentBottom="true"
                android:weightSum="6"
                android:orientation="horizontal" >
                <ImageView
                    android:id="@+id/radio0"
                    android:onClick="myClickHandler"
                    android:layout_width="0dp"
                    android:layout_height="wrap_content"
                    android:layout_weight="1"
                    android:scaleType="fitXY"
                    android:adjustViewBounds="true"
                    android:layout_marginRight="@dimen/view_horizontal_margin_4"
                    android:background="@drawable/entry" />
                <ImageView
                    android:id="@+id/radio1"
                    android:onClick="myClickHandler"
                    android:layout_toRightOf="@+id/radio0"
                    android:layout_width="0dp"
                    android:layout_height="wrap_content"
                    android:layout_weight="1"
                    android:scaleType="fitXY"
                    android:adjustViewBounds="true"
                    android:layout_marginRight="@dimen/view_horizontal_margin_4"
                    android:button="@null"
                    android:background="@drawable/entry" />
                <ImageView
                    android:id="@+id/radio2"
                    android:onClick="myClickHandler"
                    android:layout_toRightOf="@+id/radio1"
                    android:layout_width="0dp"
                    android:layout_height="wrap_content"
                    android:layout_weight="1"
                    android:scaleType="fitXY"
                    android:adjustViewBounds="true"
                    android:layout_marginRight="@dimen/view_horizontal_margin_4"
                    android:background="@drawable/entry" />
                <ImageView
                    android:id="@+id/radio3"
                    android:onClick="myClickHandler"
                    android:layout_toRightOf="@+id/radio2"
                    android:layout_width="0dp"
                    android:layout_height="wrap_content"
                    android:layout_weight="1"
                    android:scaleType="fitXY"
                    android:adjustViewBounds="true"
                    android:layout_marginRight="@dimen/view_horizontal_margin_4"
                    android:background="@drawable/entry"/>
                <ImageView
                    android:id="@+id/radio4"
                    android:onClick="myClickHandler"
                    android:layout_toRightOf="@+id/radio3"
                    android:layout_width="0dp"
                    android:layout_height="wrap_content"
                    android:layout_weight="1"
                    android:scaleType="fitXY"
                    android:adjustViewBounds="true"
                    android:layout_marginRight="@dimen/view_horizontal_margin_4"
                    android:background="@drawable/entry" />
                <ImageView
                    android:id="@+id/radio5"
                    android:onClick="myClickHandler"
                    android:layout_toRightOf="@+id/radio4"
                    android:layout_width="0dp"
                    android:layout_height="wrap_content"
                    android:layout_weight="1"
                    android:scaleType="fitXY"
                    android:adjustViewBounds="true"
                    android:background="@drawable/entry" />
            </LinearLayout>

        </RelativeLayout>

        <RelativeLayout
            android:id="@+id/rl2"
            xmlns:android="http://schemas.android.com/apk/res/android"
            xmlns:tools="http://schemas.android.com/tools"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_above="@+id/btnPlayerRound"
            tools:context="com.androidheads.vienna.escalero.MainActivity">

            <LinearLayout
                android:id="@+id/ll3"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_alignParentBottom="true"
                android:weightSum="7"
                android:orientation="horizontal" >
                <ImageView
                    android:id="@+id/diceA_1"
                    android:src="@drawable/qm"
                    android:layout_width="0dp"
                    android:layout_height="wrap_content"
                    android:layout_weight="1"
                    android:scaleType="fitXY"
                    android:layout_marginBottom="@dimen/view_horizontal_margin_4"
                    android:layout_marginLeft="@dimen/view_horizontal_margin_4" />
                <ImageView
                    android:id="@+id/diceA_2"
                    android:src="@drawable/qm"
                    android:layout_width="0dp"
                    android:layout_height="wrap_content"
                    android:layout_weight="1"
                    android:scaleType="fitXY"
                    android:layout_marginBottom="@dimen/view_horizontal_margin_4"
                    android:layout_marginLeft="@dimen/view_horizontal_margin_4" />
                <ImageView
                    android:id="@+id/diceA_3"
                    android:src="@drawable/qm"
                    android:layout_width="0dp"
                    android:layout_height="wrap_content"
                    android:layout_weight="1"
                    android:scaleType="fitXY"
                    android:layout_marginBottom="@dimen/view_horizontal_margin_4"
                    android:layout_marginLeft="@dimen/view_horizontal_margin_4" />
                <ImageView
                    android:id="@+id/diceA_4"
                    android:src="@drawable/qm"
                    android:layout_width="0dp"
                    android:layout_height="wrap_content"
                    android:layout_weight="1"
                    android:scaleType="fitXY"
                    android:layout_marginBottom="@dimen/view_horizontal_margin_4"
                    android:layout_marginLeft="@dimen/view_horizontal_margin_4" />
                <ImageView
                    android:id="@+id/diceA_5"
                    android:src="@drawable/qm"
                    android:layout_width="0dp"
                    android:layout_height="wrap_content"
                    android:layout_weight="1"
                    android:scaleType="fitXY"
                    android:layout_marginBottom="@dimen/view_horizontal_margin_4"
                    android:layout_marginLeft="@dimen/view_horizontal_margin_4" />
            </LinearLayout>

            <TextView
                android:id="@+id/btnPlayerInfo"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginBottom="2dp"
                android:layout_marginRight="2dp"
                style="@style/c4aTV1"
                android:background="@color/colorTextBackground"
                android:textColor="@color/colorText"
                android:textSize="@dimen/text_size_16"
                android:paddingLeft="2dp"
                android:paddingRight="2dp"
                android:layout_alignParentRight="true"
                android:layout_alignBottom="@+id/ll3" />

            <LinearLayout
                android:id="@+id/ll2"
                android:layout_above="@+id/ll3"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_alignParentRight="true"
                android:weightSum="7"
                android:orientation="horizontal" >
                <ImageView
                    android:id="@+id/diceD_1"
                    android:src="@drawable/transparent"
                    android:layout_width="0dp"
                    android:layout_height="wrap_content"
                    android:layout_weight="1"
                    android:scaleType="fitXY"
                    android:layout_marginBottom="@dimen/view_horizontal_margin_4"
                    android:layout_marginLeft="@dimen/view_horizontal_margin_4" />
                <ImageView
                    android:id="@+id/diceD_2"
                    android:src="@drawable/transparent"
                    android:layout_width="0dp"
                    android:layout_height="wrap_content"
                    android:layout_weight="1"
                    android:scaleType="fitXY"
                    android:layout_marginBottom="@dimen/view_horizontal_margin_4"
                    android:layout_marginLeft="@dimen/view_horizontal_margin_4" />
                <ImageView
                    android:id="@+id/diceD_3"
                    android:src="@drawable/transparent"
                    android:layout_width="0dp"
                    android:layout_height="wrap_content"
                    android:layout_weight="1"
                    android:scaleType="fitXY"
                    android:layout_marginBottom="@dimen/view_horizontal_margin_4"
                    android:layout_marginLeft="@dimen/view_horizontal_margin_4" />
                <ImageView
                    android:id="@+id/diceD_4"
                    android:src="@drawable/transparent"
                    android:layout_width="0dp"
                    android:layout_height="wrap_content"
                    android:layout_weight="1"
                    android:scaleType="fitXY"
                    android:layout_marginBottom="@dimen/view_horizontal_margin_4"
                    android:layout_marginLeft="@dimen/view_horizontal_margin_4" />
                <ImageView
                    android:id="@+id/diceD_5"
                    android:src="@drawable/transparent"
                    android:layout_width="0dp"
                    android:layout_height="wrap_content"
                    android:layout_weight="1"
                    android:scaleType="fitXY"
                    android:layout_marginBottom="@dimen/view_horizontal_margin_4"
                    android:layout_marginLeft="@dimen/view_horizontal_margin_4" />
            </LinearLayout>

            <ImageView
                android:id="@+id/doubleA"
                android:src="@drawable/d1s"
                android:scaleType="fitXY"
                android:onClick="myClickHandler"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_alignParentRight="true"
                android:layout_alignBottom="@+id/ll2"
                android:layout_marginBottom="@dimen/view_horizontal_margin_4"
                android:layout_marginRight="@dimen/button_margin"
                android:layout_marginLeft="10dp" />
            <TextView
                android:id="@+id/btnPlayerInfo2"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginBottom="2dp"
                android:layout_marginRight="2dp"
                style="@style/c4aTV1"
                android:background="@color/colorTextBackground"
                android:textColor="@color/colorText"
                android:textSize="@dimen/text_size_16"
                android:paddingLeft="2dp"
                android:paddingRight="2dp"
                android:layout_alignParentRight="true"
                android:layout_alignBottom="@+id/ll2" />

            <TextView
                android:id="@+id/txtPlayerEps"
                android:layout_alignBottom="@+id/ll2"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_centerHorizontal="true"
                android:layout_marginTop="@dimen/margin_0"
                android:layout_marginBottom="@dimen/view_width_80"
                android:textColor="@color/colorPlayerB"
                android:textSize="@dimen/text_size_16" />
            <TextView
                android:id="@+id/txtPlayers"
                android:layout_above="@id/txtPlayerEps"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_centerHorizontal="true"
                android:layout_marginTop="@dimen/margin_0"
                android:layout_marginBottom="@dimen/margin_0"
                android:textColor="@color/colorPlayerB"
                android:textSize="@dimen/text_size_16" />

        </RelativeLayout>

        <ImageView
            android:id="@+id/btnMenu"
            android:src="@drawable/button_menu"
            android:onClick="myClickHandler"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="@dimen/view_horizontal_margin_4"
            android:layout_marginBottom="@dimen/view_horizontal_margin_4"
            android:layout_marginLeft="@dimen/button_margin"
            android:layout_alignParentLeft="true"
            android:layout_alignParentBottom="true"/>

        <ImageView
            android:id="@+id/btnDice"
            android:src="@drawable/button_dice"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="@dimen/view_horizontal_margin_4"
            android:layout_marginBottom="@dimen/view_horizontal_margin_4"
            android:layout_marginLeft="@dimen/view_horizontal_margin_4"
            android:layout_marginRight="@dimen/button_margin"
            android:layout_alignParentRight="true"
            android:layout_alignParentBottom="true"/>

        <ImageView
            android:id="@+id/btnPlayerIcon"
            android:src="@drawable/button_human_a"
            android:onClick="myClickHandler"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="@dimen/view_horizontal_margin_4"
            android:layout_marginBottom="@dimen/button_margin"
            android:layout_marginLeft="@dimen/view_horizontal_margin_4"
            android:layout_toLeftOf="@+id/btnDice"
            android:layout_alignParentBottom="true"/>

        <TextView
            android:id="@+id/btnPlayerName"
            style="@style/c4aTV1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="@dimen/view_horizontal_margin_4"
            android:layout_marginBottom="@dimen/button_margin"
            android:layout_marginLeft="@dimen/view_horizontal_margin_4"
            android:background="@color/colorTextBackground"
            android:textColor="@color/colorText"
            android:textSize="@dimen/text_size_16"
            android:paddingLeft="2dp"
            android:paddingRight="2dp"
            android:layout_toLeftOf="@+id/btnPlayerIcon"
            android:layout_alignParentBottom="true"
            android:hint="@string/yourName" />

        <TextView
            android:id="@+id/btnPlayerRound"
            style="@style/c4aTV1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:gravity="right"
            android:layout_marginTop="@dimen/view_horizontal_margin_4"
            android:layout_marginBottom="@dimen/button_margin"
            android:layout_marginLeft="@dimen/view_horizontal_margin_4"
            android:background="@color/colorTextBackground"
            android:textColor="@color/colorText"
            android:textSize="@dimen/text_size_16"
            android:paddingLeft="2dp"
            android:paddingRight="2dp"
            android:layout_alignParentRight="true"
            android:layout_above="@+id/btnPlayerName" />

        <TextView
            android:id="@+id/btnPlayerResult"
            style="@style/c4aTV1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:gravity="center"
            android:layout_marginTop="@dimen/view_horizontal_margin_4"
            android:layout_marginBottom="@dimen/button_margin"
            android:layout_marginLeft="@dimen/view_horizontal_margin_4"
            android:background="@color/colorTextBackground"
            android:textColor="@color/colorText"
            android:textSize="@dimen/text_size_16"
            android:paddingLeft="@dimen/button_margin"
            android:paddingRight="@dimen/button_margin"
            android:layout_toLeftOf="@+id/btnPlayerRound"
            android:layout_toRightOf="@+id/btnMenu"
            android:layout_above="@+id/btnPlayerName" />

        <RelativeLayout
            android:id="@+id/rl3"
            xmlns:android="http://schemas.android.com/apk/res/android"
            xmlns:tools="http://schemas.android.com/tools"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_above="@+id/btnPlayerRound"
            tools:context="com.androidheads.vienna.escalero.MainActivity">

            <com.androidheads.vienna.escalero.BoardView
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:id="@+id/diceBoard"
                android:layout_alignParentTop="true"
                android:layout_alignParentLeft="true"
                android:layout_alignParentStart="true" />

        </RelativeLayout>

        <ProgressBar
            android:id="@+id/progressDialog"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_centerHorizontal="true"
            android:layout_centerVertical="true"
            android:visibility="gone" />

    </RelativeLayout>

</LinearLayout>


text:
package io.github.aosn.mosaic.domain.model.poll;

import io.github.aosn.mosaic.MosaicApplication;
import io.github.aosn.mosaic.domain.model.auth.User;
import lombok.*;

import javax.persistence.*;
import java.io.Serializable;
import java.util.Date;

/**
 * Vote entity.
 *
 * @author mikan
 * @since 0.1
 */
@Entity
@Table(name = "votes")
@Builder
@NoArgsConstructor
@AllArgsConstructor
@ToString
public class Vote implements Serializable {

    private static final long serialVersionUID = MosaicApplication.MOSAIC_SERIAL_VERSION_UID;

    @Id
    @Column
    @GeneratedValue
    private Long id;

    @Column(nullable = false)
    @Temporal(TemporalType.TIMESTAMP)
    @Getter
    private Date date;

    @JoinColumn(nullable = false)
    @ManyToOne
    @Getter
    private User user;

    @JoinColumn(nullable = false)
    @ManyToOne
    @Getter
    private Book book;

    @JoinColumn(nullable = false)
    @ManyToOne
    private Poll poll;
}


text:
export const handler = async (params) => {
  params.url.page = params.url.page || 1

  let user = await app.models.user.profileByID({ userID: params.url.id, visitorGroupID: params.session.group_id })

  if ( user ) {
    let posts = await ( async () => {
      var start = ( params.url.page - 1 ) * 25,
            end = start + 25
      return await app.models.user.posts({
        userID: params.url.id,
        visitorGroupID: params.session.group_id,
        start: start,
        end: end
      })
    })()

    let ipHistory, matchingUsersByIP

    if ( params.url.id !== params.session.user_id && params.session.moderate_users ) {
      [
        ipHistory,
        matchingUsersByIP
      ] = await Promise.all([
        app.models.user.ipHistory({ userID: params.url.id }),
        ( async () => {
          if ( params.url.logID ) {
            return await app.models.user.matchingUsersByIP({ logID: params.url.logID })
          } else {
            return false
          }
        })()
      ])
    }

    return {
      public: {
        talkPrivately: params.session.talk_privately && user.id !== params.session.user_id,
        editProfile: user.id === params.session.user_id,
        moderateUser: params.url.id !== params.session.user_id && params.session.moderate_users,
        user: user,
        posts: posts,
        ipHistory: ipHistory,
        matchingUsersByIP: matchingUsersByIP,
        pagination: app.toolbox.helpers.paginate(app.config.comitium.basePath + 'user/' + user.url + '/id/' + user.id, params.url.page, user.post_count)
      }
    }
  } else {
    let err = new Error
    err.statusCode = 404
    throw err
  }
}

export const activate = async (params) => {
  let activate = await app.models.user.activate({
    id: params.url.id || false,
    activationCode: params.url.activationCode || false,
    reactivation: params.url.reactivation || false
  })

  if ( activate.success || ( !activate.success && activate.reason === 'accountAlreadyActivated' ) ) {
    return {
      view: 'activate',
      public: {
        activate: activate
      },
      include: {
        'sign-in': {
          controller: 'sign-in',
          view: 'sign-in-partial'
        }
      }
    }
  } else {
    return {
      view: 'activate',
      public: {
        activate: activate
      }
    }
  }
}

export const ban = async (params, request) => {
  let access = await app.toolbox.access.userBan({ userID: params.url.id, user: params.session })

  if ( access === true ) {
    await app.models.user.ban({ userID: params.url.id })
    // End the banned user's session immediately
    app.session.end('user_id', +params.url.id) // URL params are always strings, so cast to number
    return {
      redirect: request.headers.referer
    }
  } else {
    return access
  }
}

export const cleanup = async (params) => {
  let access = await app.toolbox.access.userBan({ userID: params.url.id, user: params.session })

  if ( access === true ) {
    let user = await app.models.user.info({ userID: params.url.id }),
        topics = await app.models.user.topics({ userID: params.url.id })

    return {
      public: {
        user: user,
        topics: topics
      },
      view: 'cleanup'
    }
  } else {
    return access
  }
}

export const cleanupForm = async (params, request) => {
  if ( request.method === 'POST' ) {
    let access = await app.toolbox.access.userBan({ userID: params.form.userID, user: params.session })

    if ( access === true ) {
      await app.models.user.trashTopics({ userID: params.form.userID })
      return {
        redirect: app.config.comitium.baseUrl + 'user/id/' + params.form.userID
      }
    } else {
      return access
    }
  } else {
    return cleanup(params)
  }
}

export const head = async (params) => {
  return await app.models.user.metaData({ userID: params.url.id })
}

export const liftBan = async (params, request) => {
  let access = await app.toolbox.access.userBan({ userID: params.url.id, user: params.session })

  if ( access === true ) {
    await app.models.user.liftBan({ userID: params.url.id })
    // End the user's session immediately
    app.session.end('user_id', +params.url.id) // URL params are always strings, so cast to number
    return {
      redirect: request.headers.referer
    }
  } else {
    return access
  }
}

export const banIP = async (params, request) => {
  let access = await app.toolbox.access.userIPBan({ user: params.session })

  if ( access === true ) {
    let log = await app.models.user.logByID({ logID: params.url.logID })

    await app.models.user.banIP({
      ip: log.ip,
      adminUserID: params.session.user_id,
      time: app.toolbox.helpers.isoDate()
    })

    // End all active sessions with matching IPs
    app.session.end('ip', log.ip.replace('/32', ''))

    return {
      redirect: request.headers.referer
    }
  } else {
    return access
  }
}


text:
<!--
  ~ This file is part of the Alice package.
  ~
  ~ (c) Nelmio <hello@nelm.io>
  ~
  ~ For the full copyright and license information, please view the LICENSE
  ~ file that was distributed with this source code.
  -->

<container xmlns="http://symfony.com/schema/dic/services"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd">

    <services>

        <service id="nelmio_alice.generator.resolver.parameter_bag"
                 alias="nelmio_alice.generator.resolver.parameter_bag.remove_conflicting_parameters" />

        <service id="nelmio_alice.generator.resolver.parameter_bag.remove_conflicting_parameters"
                 class="Nelmio\Alice\Generator\Resolver\Parameter\RemoveConflictingParametersParameterBagResolver">
            <argument type="service" id="nelmio_alice.generator.resolver.parameter_bag.simple" />
        </service>

        <service id="nelmio_alice.generator.resolver.parameter_bag.simple"
                 class="Nelmio\Alice\Generator\Resolver\Parameter\SimpleParameterBagResolver">
            <argument type="service" id="nelmio_alice.generator.resolver.parameter.registry" />
        </service>

        <service id="nelmio_alice.generator.resolver.parameter.registry"
                 class="Nelmio\Alice\Generator\Resolver\Parameter\ParameterResolverRegistry">
            <!-- Injected via a compiler pass -->
        </service>

        <!-- Chainables -->
        <service id="nelmio_alice.generator.resolver.parameter.chainable.static_parameter_resolver"
                 class="Nelmio\Alice\Generator\Resolver\Parameter\Chainable\StaticParameterResolver">
            <tag name="nelmio_alice.generator.resolver.parameter.chainable_resolver" />
        </service>

        <service id="nelmio_alice.generator.resolver.parameter.chainable.array_parameter_resolver"
                 class="Nelmio\Alice\Generator\Resolver\Parameter\Chainable\ArrayParameterResolver">
            <tag name="nelmio_alice.generator.resolver.parameter.chainable_resolver" />
        </service>

        <service id="nelmio_alice.generator.resolver.parameter.chainable.recursive_parameter_resolver"
                 class="Nelmio\Alice\Generator\Resolver\Parameter\Chainable\RecursiveParameterResolver">
            <argument type="service" id="nelmio_alice.generator.resolver.parameter.chainable.string_parameter_resolver" />
            <argument>%nelmio_alice.loading_limit%</argument>

            <tag name="nelmio_alice.generator.resolver.parameter.chainable_resolver" />
        </service>

        <service id="nelmio_alice.generator.resolver.parameter.chainable.string_parameter_resolver"
                 class="Nelmio\Alice\Generator\Resolver\Parameter\Chainable\StringParameterResolver" />

    </services>

</container>


text:
/**
 * Created by semianchuk on 23.04.16.
 */

import React, { Component } from 'react'
import config from './../config'

export default class FotoFolder extends Component {

    constructor(props) {
        super(props)
    }

    handleClick(){
        this.props.onClick(this.props.data).bind(this);
    }

    render() {
        const id = this.props.id;
        const typeHouse = this.props.type;

        return (

                {
                    !this.props.data.Images ?
                        "Загрузка..."
                        :
                        this.props.data.Images.map((val, index) =>

                                <button className={this.props.edit=='true' ? 'show-block' : 'hide-block'} onClick = {this.props.remove} data-id={val.id}>Remove</button>

                        )
                }

            );
    }
};