<commit_before>#!/usr/bin/env python

# Copyright (c) 2013 Google Inc. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

"""
Verifies that msvs_external_builder being set will invoke the provided
msvs_external_builder_build_cmd and msvs_external_builder_clean_cmd, and will
not invoke MSBuild actions and rules.
"""

import os
import TestGyp

test = TestGyp.TestGyp(formats=['msvs'], workdir='workarea_all')

# without the flag set
test.run_gyp('external.gyp')
test.build('external.gyp', target='external')
test.must_not_exist('external_builder.out')
test.must_exist('msbuild_rule.out')
test.must_exist('msbuild_action.out')
test.must_match('msbuild_rule.out', 'msbuild_rule.py hello.z a b c')
test.must_match('msbuild_action.out', 'msbuild_action.py x y z')
os.remove('msbuild_rule.out')
os.remove('msbuild_action.out')

# with the flag set, using Build
try:
  os.environ['GYP_DEFINES'] = 'use_external_builder=1'
  test.run_gyp('external.gyp')
  test.build('external.gyp', target='external')
finally:
  del os.environ['GYP_DEFINES']
test.must_not_exist('msbuild_rule.out')
test.must_not_exist('msbuild_action.out')
test.must_exist('external_builder.out')
test.must_match('external_builder.out', 'external_builder.py build 1 2 3')
os.remove('external_builder.out')

# with the flag set, using Clean
try:
  os.environ['GYP_DEFINES'] = 'use_external_builder=1'
  test.run_gyp('external.gyp')
  test.build('external.gyp', target='external', clean=True)
finally:
  del os.environ['GYP_DEFINES']
test.must_not_exist('msbuild_rule.out')
test.must_not_exist('msbuild_action.out')
test.must_exist('external_builder.out')
test.must_match('external_builder.out', 'external_builder.py clean 4 5')
os.remove('external_builder.out')

test.pass_test()

<commit_msg>don't run external_builder test on < VS2010<commit_after>#!/usr/bin/env python

# Copyright (c) 2013 Google Inc. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

"""
Verifies that msvs_external_builder being set will invoke the provided
msvs_external_builder_build_cmd and msvs_external_builder_clean_cmd, and will
not invoke MSBuild actions and rules.
"""

import os
import sys
import TestGyp

if int(os.environ.get('GYP_MSVS_VERSION', 0)) < 2010:
  sys.exit(0)

test = TestGyp.TestGyp(formats=['msvs'], workdir='workarea_all')

# without the flag set
test.run_gyp('external.gyp')
test.build('external.gyp', target='external')
test.must_not_exist('external_builder.out')
test.must_exist('msbuild_rule.out')
test.must_exist('msbuild_action.out')
test.must_match('msbuild_rule.out', 'msbuild_rule.py hello.z a b c')
test.must_match('msbuild_action.out', 'msbuild_action.py x y z')
os.remove('msbuild_rule.out')
os.remove('msbuild_action.out')

# with the flag set, using Build
try:
  os.environ['GYP_DEFINES'] = 'use_external_builder=1'
  test.run_gyp('external.gyp')
  test.build('external.gyp', target='external')
finally:
  del os.environ['GYP_DEFINES']
test.must_not_exist('msbuild_rule.out')
test.must_not_exist('msbuild_action.out')
test.must_exist('external_builder.out')
test.must_match('external_builder.out', 'external_builder.py build 1 2 3')
os.remove('external_builder.out')

# with the flag set, using Clean
try:
  os.environ['GYP_DEFINES'] = 'use_external_builder=1'
  test.run_gyp('external.gyp')
  test.build('external.gyp', target='external', clean=True)
finally:
  del os.environ['GYP_DEFINES']
test.must_not_exist('msbuild_rule.out')
test.must_not_exist('msbuild_action.out')
test.must_exist('external_builder.out')
test.must_match('external_builder.out', 'external_builder.py clean 4 5')
os.remove('external_builder.out')

test.pass_test()
<|endoftext|>


<commit_before># This file is part of Indico.
# Copyright (C) 2002 - 2017 European Organization for Nuclear Research (CERN).
#
# Indico is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License as
# published by the Free Software Foundation; either version 3 of the
# License, or (at your option) any later version.
#
# Indico is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
# General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Indico; if not, see <http://www.gnu.org/licenses/>.

from __future__ import unicode_literals

from flask import current_app, g

from indico.modules.events.papers.controllers import display, management, templates, paper
from indico.web.flask.wrappers import IndicoBlueprint

_bp = IndicoBlueprint('papers', __name__, url_prefix='/event/<confId>', template_folder='templates',
                      virtual_template_folder='events/papers')

# Display pages
_bp.add_url_rule('/contributions/<int:contrib_id>/paper/submit',
                 'submit_revision', display.RHSubmitPaper, methods=('GET', 'POST'))
_bp.add_url_rule('/papers/<int:contrib_id>/', 'paper_timeline', display.RHPaperTimeline)
_bp.add_url_rule('/papers/templates/<int:template_id>-<filename>', 'download_template',
                 templates.RHDownloadPaperTemplate)

# Management
_bp.add_url_rule('/manage/papers/', 'management', management.RHPapersDashboard)
_bp.add_url_rule('/manage/papers/settings', 'manage_reviewing_settings', management.RHManageReviewingSettings,
                 methods=('GET', 'POST'))
_bp.add_url_rule('/manage/papers/templates/', 'manage_templates', templates.RHManagePaperTemplates)
_bp.add_url_rule('/manage/papers/templates/add', 'upload_template',
                 templates.RHUploadPaperTemplate, methods=('GET', 'POST'))
_bp.add_url_rule('/manage/papers/templates/<int:template_id>-<filename>', 'delete_template',
                 templates.RHDeletePaperTemplate, methods=('DELETE',))
_bp.add_url_rule('/manage/papers/templates/<int:template_id>-<filename>/edit', 'edit_template',
                 templates.RHEditPaperTemplate, methods=('GET', 'POST'))
_bp.add_url_rule('/manage/papers/teams/', 'manage_teams', management.RHManagePaperTeams,
                 methods=('GET', 'POST'))
_bp.add_url_rule('/manage/papers/teams/competences', 'manage_competences', management.RHManageCompetences,
                 methods=('GET', 'POST'))
_bp.add_url_rule('/manage/papers/enable/<any(content,layout):reviewing_type>', 'switch',
                 management.RHSwitchReviewingType, methods=('PUT', 'DELETE'))

# CFP scheduling
_bp.add_url_rule('/manage/papers/schedule', 'schedule_cfp', management.RHScheduleCFP,
                 methods=('GET', 'POST'))
_bp.add_url_rule('/manage/papers/open', 'open_cfp', management.RHOpenCFP, methods=('POST',))
_bp.add_url_rule('/manage/papers/close', 'close_cfp', management.RHCloseCFP, methods=('POST',))

# URLs available in both management and display areas
# Note: When adding a new one here make sure to specify `defaults=defaults`
#       for each rule. Otherwise you may not get the correct one.
for prefix, is_management in (('/manage/papers/assignment-list', True), ('/papers/judging', False)):
    defaults = {'management': is_management}
    _bp.add_url_rule(prefix + '/', 'papers_list', paper.RHPapersList, defaults=defaults)
    _bp.add_url_rule(prefix + '/download', 'download_papers', paper.RHDownloadPapers, methods=('POST',),
                     defaults=defaults)
    _bp.add_url_rule(prefix + '/customize', 'customize_paper_list', paper.RHCustomizePapersList,
                     methods=('GET', 'POST'), defaults=defaults)
    _bp.add_url_rule(prefix + '/judge', 'judge_papers', paper.RHJudgePapers, methods=('GET', 'POST'), defaults=defaults)
    _bp.add_url_rule(prefix + '/assigning/assign', 'assign_papers', paper.RHJudgingAreaAssign,
                     methods=('POST',), defaults=defaults)
    _bp.add_url_rule(prefix + '/assigning/unassign', 'unassign_papers', paper.RHJudgingAreaUnassign,
                     methods=('POST',), defaults=defaults)
    _bp.add_url_rule(prefix + '/assign-role', 'judging_assign_role', paper.RHAssignRole,
                     methods=('POST',), defaults=defaults)

@_bp.url_defaults
def _add_management_flag(endpoint, values):
    if ('management' not in values and
            endpoint.split('.')[0] == _bp.name and
            current_app.url_map.is_endpoint_expecting(endpoint, 'management')):
        values['management'] = g.rh.management

# Legacy URLs
_compat_bp = IndicoBlueprint('compat_papers', __name__, url_prefix='/event/<int:confId>')
# TODO...
<commit_msg>Fix judging area link in conference menu<commit_after># This file is part of Indico.
# Copyright (C) 2002 - 2017 European Organization for Nuclear Research (CERN).
#
# Indico is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License as
# published by the Free Software Foundation; either version 3 of the
# License, or (at your option) any later version.
#
# Indico is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
# General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Indico; if not, see <http://www.gnu.org/licenses/>.

from __future__ import unicode_literals

from flask import current_app, g

from indico.modules.events.papers.controllers import display, management, templates, paper
from indico.web.flask.wrappers import IndicoBlueprint

_bp = IndicoBlueprint('papers', __name__, url_prefix='/event/<confId>', template_folder='templates',
                      virtual_template_folder='events/papers')

# Display pages
_bp.add_url_rule('/contributions/<int:contrib_id>/paper/submit',
                 'submit_revision', display.RHSubmitPaper, methods=('GET', 'POST'))
_bp.add_url_rule('/papers/<int:contrib_id>/', 'paper_timeline', display.RHPaperTimeline)
_bp.add_url_rule('/papers/templates/<int:template_id>-<filename>', 'download_template',
                 templates.RHDownloadPaperTemplate)

# Management
_bp.add_url_rule('/manage/papers/', 'management', management.RHPapersDashboard)
_bp.add_url_rule('/manage/papers/settings', 'manage_reviewing_settings', management.RHManageReviewingSettings,
                 methods=('GET', 'POST'))
_bp.add_url_rule('/manage/papers/templates/', 'manage_templates', templates.RHManagePaperTemplates)
_bp.add_url_rule('/manage/papers/templates/add', 'upload_template',
                 templates.RHUploadPaperTemplate, methods=('GET', 'POST'))
_bp.add_url_rule('/manage/papers/templates/<int:template_id>-<filename>', 'delete_template',
                 templates.RHDeletePaperTemplate, methods=('DELETE',))
_bp.add_url_rule('/manage/papers/templates/<int:template_id>-<filename>/edit', 'edit_template',
                 templates.RHEditPaperTemplate, methods=('GET', 'POST'))
_bp.add_url_rule('/manage/papers/teams/', 'manage_teams', management.RHManagePaperTeams,
                 methods=('GET', 'POST'))
_bp.add_url_rule('/manage/papers/teams/competences', 'manage_competences', management.RHManageCompetences,
                 methods=('GET', 'POST'))
_bp.add_url_rule('/manage/papers/enable/<any(content,layout):reviewing_type>', 'switch',
                 management.RHSwitchReviewingType, methods=('PUT', 'DELETE'))

# CFP scheduling
_bp.add_url_rule('/manage/papers/schedule', 'schedule_cfp', management.RHScheduleCFP,
                 methods=('GET', 'POST'))
_bp.add_url_rule('/manage/papers/open', 'open_cfp', management.RHOpenCFP, methods=('POST',))
_bp.add_url_rule('/manage/papers/close', 'close_cfp', management.RHCloseCFP, methods=('POST',))

# URLs available in both management and display areas
# Note: When adding a new one here make sure to specify `defaults=defaults`
#       for each rule. Otherwise you may not get the correct one.
for prefix, is_management in (('/manage/papers/assignment-list', True), ('/papers/judging', False)):
    defaults = {'management': is_management}
    _bp.add_url_rule(prefix + '/', 'papers_list', paper.RHPapersList, defaults=defaults)
    _bp.add_url_rule(prefix + '/download', 'download_papers', paper.RHDownloadPapers, methods=('POST',),
                     defaults=defaults)
    _bp.add_url_rule(prefix + '/customize', 'customize_paper_list', paper.RHCustomizePapersList,
                     methods=('GET', 'POST'), defaults=defaults)
    _bp.add_url_rule(prefix + '/judge', 'judge_papers', paper.RHJudgePapers, methods=('GET', 'POST'), defaults=defaults)
    _bp.add_url_rule(prefix + '/assigning/assign', 'assign_papers', paper.RHJudgingAreaAssign,
                     methods=('POST',), defaults=defaults)
    _bp.add_url_rule(prefix + '/assigning/unassign', 'unassign_papers', paper.RHJudgingAreaUnassign,
                     methods=('POST',), defaults=defaults)
    _bp.add_url_rule(prefix + '/assign-role', 'judging_assign_role', paper.RHAssignRole,
                     methods=('POST',), defaults=defaults)

@_bp.url_defaults
def _add_management_flag(endpoint, values):
    if ('management' not in values and
            endpoint.split('.')[0] == _bp.name and
            current_app.url_map.is_endpoint_expecting(endpoint, 'management')):
        # XXX: using getattr because the conference menu builds the url from an
        # RH without the management attribute
        values['management'] = getattr(g.rh, 'management', False)

# Legacy URLs
_compat_bp = IndicoBlueprint('compat_papers', __name__, url_prefix='/event/<int:confId>')
# TODO...
<|endoftext|>


<commit_before>#!/usr/bin/env python

# Import system libraries
import base64
import json
import os

# Import PyPi libraries
from appdirs import AppDirs
import click
import pyotp
import pyperclip

# Set app information
appname = 'iotp'
appauthor = 'Dan Mills'
appversion = '0.0.2'

# Setup appdirs
dirs = AppDirs(appname, appauthor)
keyFile = os.path.join(dirs.user_data_dir, 'keys.json')

def setup_keys():
    """
    Check for data file and directory and create if is doesn't exist

    Returns a dictionary of saved keys
    """
    if not os.path.isdir(dirs.user_data_dir):
        os.makedirs(dirs.user_data_dir)

    try:
        with open(keyFile, 'r') as f:
            keys = json.load(f)
    except ValueError:
        keys = {}
    except IOError:
        open(keyFile, 'w').close()
        keys = {}

    return keys

def save_keys(keys):
    """Takes a dictionary of keys and then saves them to the keys file"""
    with open(keyFile, 'w') as f:
        json.dump(keys, f, indent=True)

def get_totp(key):
    """
    Accepts a BASE32 encoded key and returns the TOTP if it is valid and None
    if it is invalid
    """
    try:
        totp = pyotp.TOTP(key)
        return totp.now()
    except TypeError:
        return None

@click.group()
@click.version_option(appversion)
def cli():
    pass

@cli.command()
@click.argument('service', required=False)
@click.option('--copy', '-c', is_flag=True)
def get(copy, service=None):
    """
    Gets TOTP codes for service specified. If no service is specified it
    it prints codes for all services
    """
    keys = setup_keys()
    if not service:
        for service in keys:
            value = keys[service]
            totp = get_totp(value)
            if totp:
                click.echo('{}: {}'.format(service, totp))

    elif service in keys:
        totp = get_totp(keys[service])
        if totp:
            click.echo('{}: {}'.format(service, totp))
            if copy:
                pyperclip.copy(totp)
        else:
            click.echo('Key is invalid, please reset key')
    else:
        click.echo('{} does not exist'.format(service))

@cli.command()
@click.argument('service')
@click.argument('key')
def set(service, key):
    """Accepts a service and a key and saves it out to the keyFile"""
    keys = setup_keys()
    try:
        base64.b32decode(key)
    except TypeError:
        click.echo('{} is not a valid key'.format(key))
    else:
        keys[service] = key
        save_keys(keys)

@cli.command()
@click.argument('service')
def rm(service):
    """Accepts a service and removes it from the list of services"""
    keys = setup_keys()
    if keys.pop(service, None):
        click.echo('Removed {}'.format(service))
        save_keys(keys)
    else:
        click.echo('{} does not exist'.format(service))

if __name__ == '__main__':
    cli()
<commit_msg>Clean up CLI help<commit_after>#!/usr/bin/env python

# Import system libraries
import base64
import json
import os

# Import PyPi libraries
from appdirs import AppDirs
import click
import pyotp
import pyperclip

# Set app information
appname = 'iotp'
appauthor = 'Dan Mills'
appversion = '0.0.2'

# Setup appdirs
dirs = AppDirs(appname, appauthor)
keyFile = os.path.join(dirs.user_data_dir, 'keys.json')

def setup_keys():
    """
    Check for data file and directory and create if is doesn't exist

    Returns a dictionary of saved keys
    """
    if not os.path.isdir(dirs.user_data_dir):
        os.makedirs(dirs.user_data_dir)

    try:
        with open(keyFile, 'r') as f:
            keys = json.load(f)
    except ValueError:
        keys = {}
    except IOError:
        open(keyFile, 'w').close()
        keys = {}

    return keys

def save_keys(keys):
    """Takes a dictionary of keys and then saves them to the keys file"""
    with open(keyFile, 'w') as f:
        json.dump(keys, f, indent=True)

def get_totp(key):
    """
    Accepts a BASE32 encoded key and returns the TOTP if it is valid and None
    if it is invalid
    """
    try:
        totp = pyotp.TOTP(key)
        return totp.now()
    except TypeError:
        return None

@click.group()
@click.version_option(appversion)
def cli():
    """
    iotp is a Google Authenicator/RFC 6238 compatible application for
    generating Time based One Time Passwords
    """
    pass

@cli.command()
@click.argument('service', required=False)
@click.option('--copy', '-c', is_flag=True, help="Copy TOTP to the clipboard")
def get(copy, service=None):
    """
    Gets TOTP codes for service specified. If no service is specified it
    prints codes for all services
    """
    keys = setup_keys()
    if not service:
        for service in keys:
            value = keys[service]
            totp = get_totp(value)
            if totp:
                click.echo('{}: {}'.format(service, totp))

    elif service in keys:
        totp = get_totp(keys[service])
        if totp:
            click.echo('{}: {}'.format(service, totp))
            if copy:
                pyperclip.copy(totp)
        else:
            click.echo('Key is invalid, please reset key')
    else:
        click.echo('{} does not exist'.format(service))

@cli.command(help="Sets the service key")
@click.argument('service')
@click.argument('key')
def set(service, key):
    """Accepts a service and a key and saves it out to the keyFile."""
    keys = setup_keys()
    try:
        base64.b32decode(key)
    except TypeError:
        click.echo('{} is not a valid key'.format(key))
    else:
        keys[service] = key
        save_keys(keys)

@cli.command(help="Removes the specified service")
@click.argument('service')
def rm(service):
    """Accepts a service and removes it from the list of services."""
    keys = setup_keys()
    if keys.pop(service, None):
        click.echo('Removed {}'.format(service))
        save_keys(keys)
    else:
        click.echo('{} does not exist'.format(service))

if __name__ == '__main__':
    cli()
<|endoftext|>


<commit_before>from typing import List, Dict
from etk.etk_extraction import Extractable, Extraction
from etk.extractor import Extractor, InputType
from etk.segment import Segment
from etk.tokenizer import Tokenizer
from etk.etk_exceptions import InvalidJsonPathError
from etk.knowledge_graph import KnowledgeGraph

class Document(Extractable):
    """
        This class wraps raw CDR documents and provides a convenient API for ETK
        to query elements of the document and to update the document with the results
        of extractors.
        """
    def __init__(self, etk, cdr_document: Dict, mime_type, url) -> None:

        """
        Wrapper object for CDR documents.

        Args:
            etk (ETK): embed the etk object so that docs have access to global info.
            cdr_document (JSON): the raw CDR document received in ETK.

        Returns: the wrapped CDR document

        """
        Extractable.__init__(self)
        self.etk = etk
        self.cdr_document = cdr_document
        self._value = cdr_document
        # TODO do we really need to have a default_tokenizer class variable, as etk already has a tokenizer and can be accessed -> self.etk.tokenizer ???
        self.default_tokenizer = self.etk.default_tokenizer
        self.mime_type = mime_type
        self.url = url
        if self.etk.kg_schema:
            self.kg = KnowledgeGraph(self.etk.kg_schema, self)
            self._value["knowledge_graph"] = self.kg.value

    def select_segments(self, jsonpath: str) -> List[Segment]:
        """
        Dereferences the json_path inside the document and returns the selected elements.
        This method should compile and cache the compiled json_path in case the same path
        is reused by multiple extractors.

        Args:
            jsonpath (str): a valid JSON path.

        Returns: A list of Segments object that contains the elements selected by the json path.
        """
        path = self.etk.invoke_parser(jsonpath)
        try:
            matches = path.find(self.cdr_document)
        except Exception:
            raise InvalidJsonPathError("Invalid Json Path")

        segments = []
        for a_match in matches:
            this_segment = Segment(str(a_match.full_path), a_match.value, self)
            segments.append(this_segment)

        return segments

    def invoke_extractor(self, extractor: Extractor, extractable: Extractable = None, tokenizer: Tokenizer = None,
                         joiner: str = "  ", **options) -> List[Extraction]:

        """
        Invoke the extractor on the given extractable, accumulating all the extractions in a list.

        Args:
            extractor (Extractor):
            extractable (extractable):
            tokenizer: user can pass custom tokenizer if extractor wants token
            joiner: user can pass joiner if extractor wants text
            options: user can pass arguments as a dict to the extract() function of different extractors

        Returns: List of Extraction, containing all the extractions.

        """
        if not extractable:
            extractable = self

        if not tokenizer:
            tokenizer = self.default_tokenizer

        extracted_results = list()

        if extractor.input_type == InputType.TOKENS:
            tokens = extractable.get_tokens(tokenizer)
            if tokens:
                extracted_results = extractor.extract(tokens, **options)

        elif extractor.input_type == InputType.TEXT:
            if isinstance(extractable.value, list):
                print("\n======extractor needs string, got extractable value as list, converting list to string======")
            elif isinstance(extractable.value, dict):
                print("\n======extractor needs string, got extractable value as dict, converting dict to string======")
            text = extractable.get_string(joiner)
            if text:
                extracted_results = extractor.extract(text, **options)

        elif extractor.input_type == InputType.OBJECT:
            extracted_results = extractor.extract(extractable.value, **options)

        elif extractor.input_type == InputType.HTML:
            extracted_results = extractor.extract(extractable.value, **options)

        # TODO: the reason that extractors must return Extraction objects is so that
        # they can communicate back the provenance.

        return extracted_results
        # record provenance:
        #  add a ProvenanceRecord for the extraction
        #  the prov record for each extraction should point to all extractables:
        #  If the extractables are segments, put them in the "input_segments"
        #  If the extractables are extractions, put the prov ids of the extractions in "input_extractions"
<commit_msg>add TODO to clarify later<commit_after>from typing import List, Dict
from etk.etk_extraction import Extractable, Extraction
from etk.extractor import Extractor, InputType
from etk.segment import Segment
from etk.tokenizer import Tokenizer
from etk.etk_exceptions import InvalidJsonPathError
from etk.knowledge_graph import KnowledgeGraph

class Document(Extractable):
    """
        This class wraps raw CDR documents and provides a convenient API for ETK
        to query elements of the document and to update the document with the results
        of extractors.
        """
    def __init__(self, etk, cdr_document: Dict, mime_type, url) -> None:

        """
        Wrapper object for CDR documents.

        Args:
            etk (ETK): embed the etk object so that docs have access to global info.
            cdr_document (JSON): the raw CDR document received in ETK.

        Returns: the wrapped CDR document

        """
        Extractable.__init__(self)
        self.etk = etk
        self.cdr_document = cdr_document
        self._value = cdr_document
        # TODO do we really need to have a default_tokenizer class variable, as etk already has a tokenizer and can be accessed -> self.etk.tokenizer ???
        self.default_tokenizer = self.etk.default_tokenizer
        self.mime_type = mime_type
        self.url = url
        if self.etk.kg_schema:
            self.kg = KnowledgeGraph(self.etk.kg_schema, self)
            self._value["knowledge_graph"] = self.kg.value

    def select_segments(self, jsonpath: str) -> List[Segment]:
        """
        Dereferences the json_path inside the document and returns the selected elements.
        This method should compile and cache the compiled json_path in case the same path
        is reused by multiple extractors.

        Args:
            jsonpath (str): a valid JSON path.

        Returns: A list of Segments object that contains the elements selected by the json path.
        """
        path = self.etk.invoke_parser(jsonpath)
        try:
            matches = path.find(self.cdr_document)
        except Exception:
            raise InvalidJsonPathError("Invalid Json Path")

        segments = []
        for a_match in matches:
            this_segment = Segment(str(a_match.full_path), a_match.value, self)
            segments.append(this_segment)

        return segments

    def invoke_extractor(self, extractor: Extractor, extractable: Extractable = None, tokenizer: Tokenizer = None,
                         joiner: str = "  ", **options) -> List[Extraction]:

        """
        Invoke the extractor on the given extractable, accumulating all the extractions in a list.

        Args:
            extractor (Extractor):
            extractable (extractable):
            tokenizer: user can pass custom tokenizer if extractor wants token
            joiner: user can pass joiner if extractor wants text
            options: user can pass arguments as a dict to the extract() function of different extractors

        Returns: List of Extraction, containing all the extractions.

        """
        if not extractable:
            extractable = self

        if not tokenizer:
            tokenizer = self.default_tokenizer

        extracted_results = list()

        if extractor.input_type == InputType.TOKENS:
            tokens = extractable.get_tokens(tokenizer)
            if tokens:
                extracted_results = extractor.extract(tokens, **options)

        elif extractor.input_type == InputType.TEXT:
            # TODO if the input is not as expected, throw an error, this is the case where we try to add 3 + '5'
            if isinstance(extractable.value, list):
                print("\n======extractor needs string, got extractable value as list, converting list to string======")
            elif isinstance(extractable.value, dict):
                print("\n======extractor needs string, got extractable value as dict, converting dict to string======")
            text = extractable.get_string(joiner)
            if text:
                extracted_results = extractor.extract(text, **options)

        elif extractor.input_type == InputType.OBJECT:
            extracted_results = extractor.extract(extractable.value, **options)

        elif extractor.input_type == InputType.HTML:
            extracted_results = extractor.extract(extractable.value, **options)

        # TODO: the reason that extractors must return Extraction objects is so that
        # they can communicate back the provenance.

        return extracted_results
        # record provenance:
        #  add a ProvenanceRecord for the extraction
        #  the prov record for each extraction should point to all extractables:
        #  If the extractables are segments, put them in the "input_segments"
        #  If the extractables are extractions, put the prov ids of the extractions in "input_extractions"
<|endoftext|>


<commit_before># -*- encoding: utf-8 -*-
import random
import string
import subprocess
from distutils.spawn import find_executable

from twisted.python import usage
from twisted.internet import defer, reactor

import txtorcon

from ooni.utils import log
from ooni import nettest

class UsageOptions(usage.Options):
    optParameters = [['timeout', 't', 120,
                      'Specify the timeout after which to consider the Tor bootstrapping process to have failed'],
                    ]

class BridgeReachability(nettest.NetTestCase):
    name = "Bridge Reachability"
    author = "Arturo Filastò"
    version = "0.1"

    usageOptions = UsageOptions

    inputFile = ['file', 'f', None,
                 'File containing bridges to test reachability for. '
                 'They should be one per line IP:ORPort or '
                 'TransportType IP:ORPort (ex. obfs2 127.0.0.1:443)']

    requiredOptions = ['file']

    def setUp(self):
        self.tor_progress = 0
        self.timeout = int(self.localOptions['timeout'])

        self.report['timeout'] = self.timeout
        self.report['transport_name'] = 'vanilla'
        self.report['tor_progress'] = 0
        self.report['tor_progress_tag'] = None
        self.report['tor_progress_summary'] = None
        self.report['bridge_address'] = None

        self.bridge = self.input
        if self.input.startswith('Bridge'):
            self.bridge = self.input.replace('Bridge ', '')
        self.pyobfsproxy_bin = find_executable('obfsproxy')

    def postProcessor(self, measurements):
        if 'successes' not in self.summary:
            self.summary['successes'] = []
        if 'failures' not in self.summary:
            self.summary['failures'] = []

        details = {
            'address': self.report['bridge_address'],
            'transport_name': self.report['transport_name'],
            'tor_progress': self.report['tor_progress']
        }
        if self.report['success']:
            self.summary['successes'].append(details)
        else:
            self.summary['failures'].append(details)
        return self.report

    def displaySummary(self, summary):
        successful_count = {}
        failure_count = {}
        def count(results, counter):
            for result in results:
                if result['transport_name'] not in counter:
                    counter[result['transport_name']] = 0
                counter[result['transport_name']] += 1
        count(summary['successes'], successful_count)
        count(summary['failures'], failure_count)

        working_bridges = ', '.join(["%s %s" % (x['transport_name'], x['address']) for x in summary['successes']])
        failing_bridges = ', '.join(["%s %s (at %s%%)" % (x['transport_name'], x['address'], x['tor_progress']) for x in summary['failures']])

        print "Total successes: %d" % len(summary['successes'])
        print "Total failures: %d" % len(summary['failures'])

        for transport, count in successful_count.items():
            print "%s successes: %d" % (transport.title(), count)
        for transport, count in failure_count.items():
            print "%s failures: %d" % (transport.title(), count)

        print "Working bridges: %s" % working_bridges
        print "Failing bridges: %s" % failing_bridges

    def test_full_tor_connection(self):
        def getTransport(address):
            """
            If the address of the bridge starts with a valid c identifier then
            we consider it to be a bridge.
            Returns:
                The transport_name if it's a transport.
                None if it's not a obfsproxy bridge.
            """
            transport_name = address.split(' ')[0]
            transport_name_chars = string.ascii_letters + string.digits
            if all(c in transport_name_chars for c in transport_name):
                return transport_name
            else:
                return None

        config = txtorcon.TorConfig()
        config.ControlPort = random.randint(2**14, 2**16)
        config.SocksPort = random.randint(2**14, 2**16)

        transport_name = getTransport(self.bridge)
        if transport_name and self.pyobfsproxy_bin:
            config.ClientTransportPlugin = "%s exec %s managed" % (transport_name, self.pyobfsproxy_bin)
            self.report['transport_name'] = transport_name
            self.report['bridge_address'] = self.bridge.split(' ')[1]
        elif transport_name and not self.pyobfsproxy_bin:
            log.err("Unable to test bridge because pyobfsproxy is not installed")
            self.report['success'] = None
            return
        else:
            self.report['bridge_address'] = self.bridge.split(' ')[0]

        config.Bridge = self.bridge
        config.UseBridges = 1
        config.save()

        def updates(prog, tag, summary):
            log.msg("%s: %s%%" % (self.bridge, prog))
            self.report['tor_progress'] = int(prog)
            self.report['tor_progress_tag'] = tag
            self.report['tor_progress_summary'] = summary

        d = txtorcon.launch_tor(config, reactor, timeout=self.timeout,
                                progress_updates=updates)
        @d.addCallback
        def setup_complete(proto):
            log.msg("Successfully connected to %s" % self.bridge)
            self.report['success'] = True

        @d.addErrback
        def setup_failed(failure):
            log.msg("Failed to connect to %s" % self.bridge)
            self.report['success'] = False

        return d
<commit_msg>Terminate the tor process cleanly after we have run a test.<commit_after># -*- encoding: utf-8 -*-
import random
import string
import subprocess
from distutils.spawn import find_executable

from twisted.python import usage
from twisted.internet import defer, reactor, error

import txtorcon

from ooni.utils import log
from ooni import nettest

class UsageOptions(usage.Options):
    optParameters = [['timeout', 't', 120,
                      'Specify the timeout after which to consider the Tor bootstrapping process to have failed'],
                    ]

class BridgeReachability(nettest.NetTestCase):
    name = "Bridge Reachability"
    author = "Arturo Filastò"
    version = "0.1"

    usageOptions = UsageOptions

    inputFile = ['file', 'f', None,
                 'File containing bridges to test reachability for. '
                 'They should be one per line IP:ORPort or '
                 'TransportType IP:ORPort (ex. obfs2 127.0.0.1:443)']

    requiredOptions = ['file']

    def setUp(self):
        self.tor_progress = 0
        self.timeout = int(self.localOptions['timeout'])

        self.report['timeout'] = self.timeout
        self.report['transport_name'] = 'vanilla'
        self.report['tor_progress'] = 0
        self.report['tor_progress_tag'] = None
        self.report['tor_progress_summary'] = None
        self.report['bridge_address'] = None

        self.bridge = self.input
        if self.input.startswith('Bridge'):
            self.bridge = self.input.replace('Bridge ', '')
        self.pyobfsproxy_bin = find_executable('obfsproxy')

    def postProcessor(self, measurements):
        if 'successes' not in self.summary:
            self.summary['successes'] = []
        if 'failures' not in self.summary:
            self.summary['failures'] = []

        details = {
            'address': self.report['bridge_address'],
            'transport_name': self.report['transport_name'],
            'tor_progress': self.report['tor_progress']
        }
        if self.report['success']:
            self.summary['successes'].append(details)
        else:
            self.summary['failures'].append(details)
        return self.report

    def displaySummary(self, summary):
        successful_count = {}
        failure_count = {}
        def count(results, counter):
            for result in results:
                if result['transport_name'] not in counter:
                    counter[result['transport_name']] = 0
                counter[result['transport_name']] += 1
        count(summary['successes'], successful_count)
        count(summary['failures'], failure_count)

        working_bridges = ', '.join(["%s %s" % (x['transport_name'], x['address']) for x in summary['successes']])
        failing_bridges = ', '.join(["%s %s (at %s%%)" % (x['transport_name'], x['address'], x['tor_progress']) for x in summary['failures']])

        print "Total successes: %d" % len(summary['successes'])
        print "Total failures: %d" % len(summary['failures'])

        for transport, count in successful_count.items():
            print "%s successes: %d" % (transport.title(), count)
        for transport, count in failure_count.items():
            print "%s failures: %d" % (transport.title(), count)

        print "Working bridges: %s" % working_bridges
        print "Failing bridges: %s" % failing_bridges

    def test_full_tor_connection(self):
        def getTransport(address):
            """
            If the address of the bridge starts with a valid c identifier then
            we consider it to be a bridge.
            Returns:
                The transport_name if it's a transport.
                None if it's not a obfsproxy bridge.
            """
            transport_name = address.split(' ')[0]
            transport_name_chars = string.ascii_letters + string.digits
            if all(c in transport_name_chars for c in transport_name):
                return transport_name
            else:
                return None

        config = txtorcon.TorConfig()
        config.ControlPort = random.randint(2**14, 2**16)
        config.SocksPort = random.randint(2**14, 2**16)

        transport_name = getTransport(self.bridge)
        if transport_name and self.pyobfsproxy_bin:
            config.ClientTransportPlugin = "%s exec %s managed" % (transport_name, self.pyobfsproxy_bin)
            self.report['transport_name'] = transport_name
            self.report['bridge_address'] = self.bridge.split(' ')[1]
        elif transport_name and not self.pyobfsproxy_bin:
            log.err("Unable to test bridge because pyobfsproxy is not installed")
            self.report['success'] = None
            return
        else:
            self.report['bridge_address'] = self.bridge.split(' ')[0]

        config.Bridge = self.bridge
        config.UseBridges = 1
        config.save()

        def updates(prog, tag, summary):
            log.msg("%s: %s%%" % (self.bridge, prog))
            self.report['tor_progress'] = int(prog)
            self.report['tor_progress_tag'] = tag
            self.report['tor_progress_summary'] = summary

        d = txtorcon.launch_tor(config, reactor, timeout=self.timeout,
                                progress_updates=updates)
        @d.addCallback
        def setup_complete(proto):
            try:
                proto.transport.signalProcess('TERM')
            except error.ProcessExitedAlready:
                proto.transport.loseConnection()
            log.msg("Successfully connected to %s" % self.bridge)
            self.report['success'] = True

        @d.addErrback
        def setup_failed(failure):
            log.msg("Failed to connect to %s" % self.bridge)
            self.report['success'] = False

        return d
<|endoftext|>


<commit_before># -*- coding: utf-8 -*-

"""
    eve.flaskapp
    ~~~~~~~~~~~~

    This module implements the central WSGI application object as a Flask
    subclass.

    :copyright: (c) 2012 by Nicola Iarocci.
    :license: BSD, see LICENSE for more details.
"""

import eve
import sys
import os
from flask import Flask
from werkzeug.routing import BaseConverter
from werkzeug.serving import WSGIRequestHandler
from eve.io.mongo import Mongo, Validator
from eve.exceptions import ConfigException
from eve.endpoints import collections_endpoint, item_endpoint, home_endpoint
from eve.utils import api_prefix

class EveWSGIRequestHandler(WSGIRequestHandler):
    """ Extend werkzeug request handler to include current Eve version in all
    responses, which is super-handy for debugging.
    """
    @property
    def server_version(self):
        return 'Eve/%s ' % eve.__version__ + super(EveWSGIRequestHandler,
                                                   self).server_version

class RegexConverter(BaseConverter):
    """ Extend werkzeug routing by supporting regex for urls/API endpoints """
    def __init__(self, url_map, *items):
        super(RegexConverter, self).__init__(url_map)
        self.regex = items[0]

class Eve(Flask):
    """The main Eve object. On initialization it will load Eve settings, then
    configure and enable the API endpoints. The API is launched by executing
    the code below:::

        app = Eve()
        app.run()

    :param import_name: the name of the application package
    :param settings: the name of the settings file.  Defaults to `settings.py`.
    :param validator: custom validation class. Must be a
                      :class:`~cerberus.Validator` subclass. Defaults to
                      :class:`eve.io.mongo.Validator`.
    :param data: the data layer class. Must be a :class:`~eve.io.DataLayer`
                 subclass. Defaults to :class:`~eve.io.Mongo`.
    :param kwargs: optional, standard, Flask parameters.
    """
    def __init__(self, import_name=__package__, settings='settings.py',
                 validator=Validator, data=Mongo, **kwargs):
        """Eve main WSGI app is implemented as a Flask subclass. Since we want
        to be able to launch our API by simply invoking Flask's run() method,
        we need to enhance our super-class a little bit.

        The tasks we need to accomplish are:

            1. enbale regex routing
            2. load and validate custom API settings,
            3. enable API endpoints
            4. set the validator class used to validate incoming objects
            5. activate the chosen data layer
        """

        # TODO should we support standard Flask parameters as well?
        super(Eve, self).__init__(import_name, **kwargs)
        # enable regex routing
        self.url_map.converters['regex'] = RegexConverter
        self.validator = validator
        self.settings = settings

        self.load_config()
        self.validate_domain_struct()
        self.set_defaults()
        self.validate_config()
        #self.validate_schemas()
        self._add_url_rules()

        # instantiate the data layer. Defaults to eve.io.Mongo
        self.data = data(self)

    def run(self, host=None, port=None, debug=None, **options):
        """Pass our own subclass of :class:`werkzeug.serving.WSGIRequestHandler
        to Flask.

        :param host: the hostname to listen on. Set this to ``'0.0.0.0'`` to
                     have the server available externally as well. Defaults to
                     ``'127.0.0.1'``.
        :param port: the port of the webserver. Defaults to ``5000``.
        :param debug: if given, enable or disable debug mode.
                      See :attr:`debug`.
        :param options: the options to be forwarded to the underlying
                        Werkzeug server.  See
                        :func:`werkzeug.serving.run_simple` for more
                        information.        """

        options.setdefault('request_handler', EveWSGIRequestHandler)
        super(Eve, self).run(host, port, debug, **options)

    def load_config(self):
        """API settings are loaded from standard python modules. First from
        `settings.py`(or alternative name/path passed as an argument) and
        then, when defined, from the file specified in the
        `EVE_SETTINGS` environment variable.

        Since we are a Flask subclass, any configuration value supported by
        Flask itself is available (besides Eve's proper settings).
        """

        # TODO maybe move these to default_settings.py or package __init__
        default_module = 'eve.default_settings'
        envvar = 'EVE_SETTINGS'

        # load defaults
        self.config.from_object(default_module)

        # overwrite the defaults with custom user settings:
        if os.path.isabs(self.settings):
            pyfile = self.settings
        else:
            # assume the path is relative to the calling script folder
            abspath = os.path.abspath(os.path.dirname(sys.argv[0]))
            pyfile = os.path.join(abspath, self.settings)
        self.config.from_pyfile(pyfile)

        #overwrite settings with custom environment variable
        if os.environ.get(envvar):
            self.config.from_envvar(envvar)

    def validate_domain_struct(self):
        """ Validates that Eve configuration settings conform to the
        requirements.
        """
        try:
            domain = self.config['DOMAIN']
        except:
            raise ConfigException('DOMAIN dictionary missing or wrong.')
        if not isinstance(domain, dict):
            raise ConfigException('DOMAIN must be a dict.')
        if len(domain) == 0:
            raise ConfigException('DOMAIN must contain at least one resource.')

    def validate_config(self):
        """ Makes sure that REST methods expressed in the configuration
        settings are supported.

        .. versionadded:: 0.0.2
            Support for DELETE resource method.
        """

        supported_resource_methods = ['GET', 'POST', 'DELETE']
        supported_item_methods = ['GET', 'PATCH', 'DELETE']

        # make sure that global resource methods are supported.
        self.validate_methods(supported_resource_methods,
                              self.config.get('RESOURCE_METHODS'),
                              'resource')

        # make sure that global item methods are supported.
        self.validate_methods(supported_item_methods,
                              self.config.get('ITEM_METHODS'),
                              'item')

        # make sure that individual resource/item methods are supported.
        for resource, settings in self.config['DOMAIN'].items():
            self.validate_methods(supported_resource_methods,
                                  settings['methods'],
                                  '[%s] resource ' % resource)
            self.validate_methods(supported_item_methods,
                                  settings['item_methods'],
                                  '[%s] item ' % resource)

            # while a resource schema is optional for read-only access,
            # it is mandatory for write-access to resource/items.
            if 'POST' in settings['methods'] or \
               'PATCH' in settings['item_methods']:
                if len(settings['schema']) == 0:
                    raise ConfigException('A resource schema must be provided '
                                          'when POST or PATCH methods are '
                                          'allowed for a resource (%s).' %
                                          resource)

            self.validate_schema(settings['schema'])

    def validate_methods(self, allowed, proposed, item):
        """ Compares allowed and proposed methods, raising a `ConfigException`
        when they don't match.

        :param allowed: a list of supported (allowed) methods.
        :param proposed: a list of proposed methods.
        :param item: name of the item to which the methods would be applied.
                     Used when raising the exception.
        """
        diff = set(proposed) - set(allowed)
        if diff:
            raise ConfigException('Unallowed %s method(s): %s. '
                                  'Supported: %s' %
                                  (item, ', '.join(diff),
                                   ', '.join(allowed)))

    def validate_schema(self, schema):
        # TODO are there other mandatory settings items? Validate them here
        offender = None
        if eve.DATE_CREATED in schema:
            offender = eve.DATE_CREATED
        if eve.LAST_UPDATED in schema:
            offender = eve.LAST_UPDATED
        if eve.ID_FIELD in schema:
            offender = eve.ID_FIELD
        if offender:
            raise ConfigException('"%s" field not allowed in schema (will be '
                                  'handled automatically).' % offender)

    def set_defaults(self):
        """ When not provided, fills individual resource settings with default
        or global configuration settings.

        .. versionchanged:: 0.0.4
           'datasource' default values.
           'defaults' helper set, built here in order to facilitate processing
           of future POST requests.

        .. versionchanged:: 0.0.3
           `item_title` default value.
        """

        for resource, settings in self.config['DOMAIN'].items():
            settings.setdefault('url', resource)
            settings.setdefault('methods', self.config['RESOURCE_METHODS'])
            settings.setdefault('cache_control', self.config['CACHE_CONTROL'])
            settings.setdefault('cache_expires', self.config['CACHE_EXPIRES'])

            settings.setdefault('item_lookup_field',
                                self.config['ITEM_LOOKUP_FIELD'])
            settings.setdefault('item_url', self.config['ITEM_URL'])
            settings.setdefault('item_title',
                                resource.rstrip('s').capitalize())
            settings.setdefault('item_cache_control',
                                self.config['ITEM_CACHE_CONTROL'])
            settings.setdefault('item_lookup', self.config['ITEM_LOOKUP'])
            if settings['item_lookup']:
                item_methods = self.config['ITEM_METHODS']
            else:
                item_methods = eve.ITEM_METHODS
            settings.setdefault('item_methods', item_methods)

            datasource = {}
            settings.setdefault('datasource', datasource)
            settings['datasource'].setdefault('source', resource)
            settings['datasource'].setdefault('filter', None)

            # empty schemas are allowed for read-only access to resources
            schema = settings.setdefault('schema', {})

            # TODO fill schema{} defaults, like field type, etc.

            # `dates` helper set contains the names of the schema fields
            # defined as `datetime` types. It will come in handy when
            # we will be parsing incoming documents

            # TODO support date fields for embedded documents.
            settings['dates'] = \
                set(field for field, definition in schema.items()
                    if definition.get('type') == 'datetime')

            # 'defaults' helper set contains the names of fields with
            # default values in their schema definition.

            # TODO support default values for embedded documents.
            settings['defaults'] = \
                set(field for field, definition in schema.items()
                    if definition.get('default'))

    def _add_url_rules(self):
        """ Builds the API url map. Methods are enabled for each mapped
        endpoint, as configured in the settings.

        .. versionchanged:: 0.0.4
           config.SOURCES. Maps resources to their datasources.

        .. versionchanged:: 0.0.3
           Support for API_VERSION as an endpoint prefix.
        """
        # helpers
        resources = {}     # maps urls to resources (DOMAIN keys)
        urls = {}          # maps resources to urls
        datasources = {}   # maps resources to their datasources

        prefix = api_prefix(self.config['URL_PREFIX'],
                            self.config['API_VERSION'])

        # home page (API entry point)
        self.add_url_rule('%s/' % prefix, 'home', home_endpoint)

        for resource, settings in self.config['DOMAIN'].items():
            resources[settings['url']] = resource
            urls[resource] = settings['url']
            datasources[resource] = settings['datasource']

            # resource endpoint
            url = '/<regex("%s"):url>/' % settings['url']
            url = '%s%s' % (prefix, url)
            self.add_url_rule(url, view_func=collections_endpoint,
                              methods=settings['methods'])

            # item endpoint
            if settings['item_lookup'] is True:
                item_url = '%s<regex("%s"):%s>/' % \
                    (url,
                     settings['item_url'],
                     settings['item_lookup_field'])

                self.add_url_rule(item_url, view_func=item_endpoint,
                                  methods=settings['item_methods'])
                if 'PATCH' in settings['item_methods']:
                    # support for POST with X-HTTM-Method-Override header,
                    # for clients not supporting PATCH. Also see
                    # item_endpoint() in endpoints.py
                    self.add_url_rule(item_url, view_func=item_endpoint,
                                      methods=['POST'])

                # also enable an alternative lookup/endpoint if allowed
                add_lookup = settings.get('additional_lookup')
                if add_lookup:
                    item_url = '%s<regex("%s"):%s>/' % (url,
                                                        add_lookup['url'],
                                                        add_lookup['field'])
                    self.add_url_rule(item_url, view_func=item_endpoint,
                                      methods=['GET'])
        self.config['RESOURCES'] = resources
        self.config['URLS'] = urls
        self.config['SOURCES'] = datasources
<commit_msg>minor refactoring<commit_after># -*- coding: utf-8 -*-

"""
    eve.flaskapp
    ~~~~~~~~~~~~

    This module implements the central WSGI application object as a Flask
    subclass.

    :copyright: (c) 2012 by Nicola Iarocci.
    :license: BSD, see LICENSE for more details.
"""

import eve
import sys
import os
from flask import Flask
from werkzeug.routing import BaseConverter
from werkzeug.serving import WSGIRequestHandler
from eve.io.mongo import Mongo, Validator
from eve.exceptions import ConfigException
from eve.endpoints import collections_endpoint, item_endpoint, home_endpoint
from eve.utils import api_prefix

class EveWSGIRequestHandler(WSGIRequestHandler):
    """ Extend werkzeug request handler to include current Eve version in all
    responses, which is super-handy for debugging.
    """
    @property
    def server_version(self):
        return 'Eve/%s ' % eve.__version__ + super(EveWSGIRequestHandler,
                                                   self).server_version

class RegexConverter(BaseConverter):
    """ Extend werkzeug routing by supporting regex for urls/API endpoints """
    def __init__(self, url_map, *items):
        super(RegexConverter, self).__init__(url_map)
        self.regex = items[0]

class Eve(Flask):
    """The main Eve object. On initialization it will load Eve settings, then
    configure and enable the API endpoints. The API is launched by executing
    the code below:::

        app = Eve()
        app.run()

    :param import_name: the name of the application package
    :param settings: the name of the settings file.  Defaults to `settings.py`.
    :param validator: custom validation class. Must be a
                      :class:`~cerberus.Validator` subclass. Defaults to
                      :class:`eve.io.mongo.Validator`.
    :param data: the data layer class. Must be a :class:`~eve.io.DataLayer`
                 subclass. Defaults to :class:`~eve.io.Mongo`.
    :param kwargs: optional, standard, Flask parameters.
    """
    def __init__(self, import_name=__package__, settings='settings.py',
                 validator=Validator, data=Mongo, **kwargs):
        """Eve main WSGI app is implemented as a Flask subclass. Since we want
        to be able to launch our API by simply invoking Flask's run() method,
        we need to enhance our super-class a little bit.

        The tasks we need to accomplish are:

            1. enbale regex routing
            2. load and validate custom API settings,
            3. enable API endpoints
            4. set the validator class used to validate incoming objects
            5. activate the chosen data layer
        """

        # TODO should we support standard Flask parameters as well?
        super(Eve, self).__init__(import_name, **kwargs)
        # enable regex routing
        self.url_map.converters['regex'] = RegexConverter
        self.validator = validator
        self.settings = settings

        self.load_config()
        self.validate_domain_struct()
        self.set_defaults()
        self.validate_config()
        #self.validate_schemas()
        self._add_url_rules()

        # instantiate the data layer. Defaults to eve.io.Mongo
        self.data = data(self)

    def run(self, host=None, port=None, debug=None, **options):
        """Pass our own subclass of :class:`werkzeug.serving.WSGIRequestHandler
        to Flask.

        :param host: the hostname to listen on. Set this to ``'0.0.0.0'`` to
                     have the server available externally as well. Defaults to
                     ``'127.0.0.1'``.
        :param port: the port of the webserver. Defaults to ``5000``.
        :param debug: if given, enable or disable debug mode.
                      See :attr:`debug`.
        :param options: the options to be forwarded to the underlying
                        Werkzeug server.  See
                        :func:`werkzeug.serving.run_simple` for more
                        information.        """

        options.setdefault('request_handler', EveWSGIRequestHandler)
        super(Eve, self).run(host, port, debug, **options)

    def load_config(self):
        """API settings are loaded from standard python modules. First from
        `settings.py`(or alternative name/path passed as an argument) and
        then, when defined, from the file specified in the
        `EVE_SETTINGS` environment variable.

        Since we are a Flask subclass, any configuration value supported by
        Flask itself is available (besides Eve's proper settings).
        """

        # TODO maybe move these to default_settings.py or package __init__
        default_module = 'eve.default_settings'
        envvar = 'EVE_SETTINGS'

        # load defaults
        self.config.from_object(default_module)

        # overwrite the defaults with custom user settings:
        if os.path.isabs(self.settings):
            pyfile = self.settings
        else:
            # assume the path is relative to the calling script folder
            abspath = os.path.abspath(os.path.dirname(sys.argv[0]))
            pyfile = os.path.join(abspath, self.settings)
        self.config.from_pyfile(pyfile)

        #overwrite settings with custom environment variable
        if os.environ.get(envvar):
            self.config.from_envvar(envvar)

    def validate_domain_struct(self):
        """ Validates that Eve configuration settings conform to the
        requirements.
        """
        try:
            domain = self.config['DOMAIN']
        except:
            raise ConfigException('DOMAIN dictionary missing or wrong.')
        if not isinstance(domain, dict):
            raise ConfigException('DOMAIN must be a dict.')
        if len(domain) == 0:
            raise ConfigException('DOMAIN must contain at least one resource.')

    def validate_config(self):
        """ Makes sure that REST methods expressed in the configuration
        settings are supported.

        .. versionadded:: 0.0.2
            Support for DELETE resource method.
        """

        supported_resource_methods = ['GET', 'POST', 'DELETE']
        supported_item_methods = ['GET', 'PATCH', 'DELETE']

        # make sure that global resource methods are supported.
        self.validate_methods(supported_resource_methods,
                              self.config.get('RESOURCE_METHODS'),
                              'resource')

        # make sure that global item methods are supported.
        self.validate_methods(supported_item_methods,
                              self.config.get('ITEM_METHODS'),
                              'item')

        # make sure that individual resource/item methods are supported.
        for resource, settings in self.config['DOMAIN'].items():
            self.validate_methods(supported_resource_methods,
                                  settings['methods'],
                                  '[%s] resource ' % resource)
            self.validate_methods(supported_item_methods,
                                  settings['item_methods'],
                                  '[%s] item ' % resource)

            # while a resource schema is optional for read-only access,
            # it is mandatory for write-access to resource/items.
            if 'POST' in settings['methods'] or \
               'PATCH' in settings['item_methods']:
                if len(settings['schema']) == 0:
                    raise ConfigException('A resource schema must be provided '
                                          'when POST or PATCH methods are '
                                          'allowed for a resource (%s).' %
                                          resource)

            self.validate_schema(settings['schema'])

    def validate_methods(self, allowed, proposed, item):
        """ Compares allowed and proposed methods, raising a `ConfigException`
        when they don't match.

        :param allowed: a list of supported (allowed) methods.
        :param proposed: a list of proposed methods.
        :param item: name of the item to which the methods would be applied.
                     Used when raising the exception.
        """
        diff = set(proposed) - set(allowed)
        if diff:
            raise ConfigException('Unallowed %s method(s): %s. '
                                  'Supported: %s' %
                                  (item, ', '.join(diff),
                                   ', '.join(allowed)))

    def validate_schema(self, schema):
        # TODO are there other mandatory settings items? Validate them here
        offender = None
        if eve.DATE_CREATED in schema:
            offender = eve.DATE_CREATED
        if eve.LAST_UPDATED in schema:
            offender = eve.LAST_UPDATED
        if eve.ID_FIELD in schema:
            offender = eve.ID_FIELD
        if offender:
            raise ConfigException('"%s" field not allowed in schema (will be '
                                  'handled automatically).' % offender)

    def set_defaults(self):
        """ When not provided, fills individual resource settings with default
        or global configuration settings.

        .. versionchanged:: 0.0.4
           'datasource' default values.
           'defaults' helper set, built here in order to facilitate processing
           of future POST requests.

        .. versionchanged:: 0.0.3
           `item_title` default value.
        """

        for resource, settings in self.config['DOMAIN'].items():
            settings.setdefault('url', resource)
            settings.setdefault('methods', self.config['RESOURCE_METHODS'])
            settings.setdefault('cache_control', self.config['CACHE_CONTROL'])
            settings.setdefault('cache_expires', self.config['CACHE_EXPIRES'])

            settings.setdefault('item_lookup_field',
                                self.config['ITEM_LOOKUP_FIELD'])
            settings.setdefault('item_url', self.config['ITEM_URL'])
            settings.setdefault('item_title',
                                resource.rstrip('s').capitalize())
            settings.setdefault('item_cache_control',
                                self.config['ITEM_CACHE_CONTROL'])
            settings.setdefault('item_lookup', self.config['ITEM_LOOKUP'])
            if settings['item_lookup']:
                item_methods = self.config['ITEM_METHODS']
            else:
                item_methods = eve.ITEM_METHODS
            settings.setdefault('item_methods', item_methods)

            datasource = {}
            settings.setdefault('datasource', datasource)
            settings['datasource'].setdefault('source', resource)
            settings['datasource'].setdefault('filter', None)

            # empty schemas are allowed for read-only access to resources
            schema = settings.setdefault('schema', {})

            # TODO fill schema{} defaults, like field type, etc.

            # `dates` helper set contains the names of the schema fields
            # defined as `datetime` types. It will come in handy when
            # we will be parsing incoming documents

            # TODO support date fields for embedded documents.
            settings['dates'] = \
                set(field for field, definition in schema.items()
                    if definition.get('type') == 'datetime')

            # 'defaults' helper set contains the names of fields with
            # default values in their schema definition.

            # TODO support default values for embedded documents.
            settings['defaults'] = \
                set(field for field, definition in schema.items()
                    if definition.get('default'))

    def _add_url_rules(self):
        """ Builds the API url map. Methods are enabled for each mapped
        endpoint, as configured in the settings.

        .. versionchanged:: 0.0.4
           config.SOURCES. Maps resources to their datasources.

        .. versionchanged:: 0.0.3
           Support for API_VERSION as an endpoint prefix.
        """
        # helpers
        resources = {}     # maps urls to resources (DOMAIN keys)
        urls = {}          # maps resources to urls
        datasources = {}   # maps resources to their datasources

        prefix = api_prefix(self.config['URL_PREFIX'],
                            self.config['API_VERSION'])

        # home page (API entry point)
        self.add_url_rule('%s/' % prefix, 'home', home_endpoint)

        for resource, settings in self.config['DOMAIN'].items():
            resources[settings['url']] = resource
            urls[resource] = settings['url']
            datasources[resource] = settings['datasource']

            # resource endpoint
            url = '%s/<regex("%s"):url>/' % (prefix, settings['url'])
            self.add_url_rule(url, view_func=collections_endpoint,
                              methods=settings['methods'])

            # item endpoint
            if settings['item_lookup']:
                item_url = '%s<regex("%s"):%s>/' % \
                    (url,
                     settings['item_url'],
                     settings['item_lookup_field'])

                self.add_url_rule(item_url, view_func=item_endpoint,
                                  methods=settings['item_methods'])
                if 'PATCH' in settings['item_methods']:
                    # support for POST with X-HTTM-Method-Override header
                    # for clients not supporting PATCH. Also see
                    # item_endpoint() in endpoints.py
                    self.add_url_rule(item_url, view_func=item_endpoint,
                                      methods=['POST'])

                # also enable an alternative lookup/endpoint if allowed
                add_lookup = settings.get('additional_lookup')
                if add_lookup:
                    item_url = '%s<regex("%s"):%s>/' % (url,
                                                        add_lookup['url'],
                                                        add_lookup['field'])
                    self.add_url_rule(item_url, view_func=item_endpoint,
                                      methods=['GET'])
        self.config['RESOURCES'] = resources
        self.config['URLS'] = urls
        self.config['SOURCES'] = datasources
<|endoftext|>


<commit_before>import pytest

# verify with actual value
import statistics
import math

import pydp as dp
from conftest import expect_near, percentile

kDataSize = 10000
data_floats = [200.0 * i / kDataSize for i in range(kDataSize)]
data_ints = [int(200 * i / kDataSize) for i in range(kDataSize)]
type_data_algorithm = [
    ("int", data_ints, dp.algorithms.laplacian.Max),
    ("float", data_floats, dp.algorithms.laplacian.Max),
    ("int", data_ints, dp.algorithms.laplacian.Min),
    ("float", data_floats, dp.algorithms.laplacian.Min),
    ("int", data_ints, dp.algorithms.laplacian.Median),
    ("float", data_floats, dp.algorithms.laplacian.Median),
]

# NOTE: One needs to use https://pypi.org/project/pytest-lazy-fixture/ to have fixtues in parameters.
# Using none fixtured data instead of adding a pytest-lazy-fixture.
@pytest.mark.parametrize("dtype, data", [("int", data_ints), ("float", data_floats)])
def test_min(data, dtype):

    minn = dp.algorithms.laplacian.Min(
        dtype=dtype, epsilon=1.0, lower_bound=0, upper_bound=2048
    )
    assert expect_near(min(data), minn.quick_result(data), 10)
    assert expect_near(0, minn.quick_result(data), 10)

@pytest.mark.parametrize("dtype, data", [("int", data_ints), ("float", data_floats)])
def test_max(data, dtype):
    maxx = dp.algorithms.laplacian.Max(
        dtype=dtype, epsilon=1.0, lower_bound=0, upper_bound=2048
    )
    assert 190 < maxx.quick_result(data) < 210

    assert expect_near(max(data), maxx.quick_result(data), 10)

@pytest.mark.parametrize("dtype, data", [("int", data_ints), ("float", data_floats)])
def test_median(data, dtype):

    median = dp.algorithms.laplacian.Median(
        dtype=dtype, epsilon=1.0, lower_bound=0, upper_bound=2048
    )

    assert expect_near(statistics.median(data), median.quick_result(data), 20)

@pytest.mark.parametrize("dtype", ["int", "float"])
def test_percentile_getter(dtype):

    expected_percentile = 0.45

    dp_percentile = dp.algorithms.laplacian.Percentile(
        dtype=dtype,
        epsilon=1.0,
        percentile=expected_percentile,
        lower_bound=0,
        upper_bound=2048,
    )
    assert dp_percentile.percentile == expected_percentile

@pytest.mark.parametrize("dtype, data, order_statistic", type_data_algorithm)
def test_order_statistic_datatypes(data, dtype, order_statistic):

    order_statistic_1 = order_statistic(dtype=dtype, epsilon=1.0)
    order_statistic_2 = order_statistic(
        dtype=dtype, epsilon=1.0, lower_bound=0, upper_bound=2048
    )
    res = order_statistic_2.quick_result(data)

    assert isinstance(order_statistic_1, order_statistic)
    assert isinstance(order_statistic_2, order_statistic)

    assert isinstance(res, type(data[0]))

@pytest.mark.parametrize(
    "dtype, data, dp_percentile",
    [
        ("int", data_ints, dp.algorithms.laplacian.Percentile),
        ("float", data_floats, dp.algorithms.laplacian.Percentile),
    ],
)
def test_percentile_datatypes(data, dtype, dp_percentile):

    dp_percentile_2 = dp_percentile(
        dtype=dtype, epsilon=1.0, percentile=0.45, lower_bound=0, upper_bound=2048
    )
    res = dp_percentile_2.quick_result(data)

    assert isinstance(dp_percentile_2, dp_percentile)

    assert isinstance(res, float)

# TODO Yet some more tests
<commit_msg>changed upperbound to a more reaslistic values<commit_after>import pytest

# verify with actual value
import statistics
import math

import pydp as dp
from conftest import expect_near, percentile

kDataSize = 10000
data_floats = [200.0 * i / kDataSize for i in range(kDataSize)]
data_ints = [int(200 * i / kDataSize) for i in range(kDataSize)]
type_data_algorithm = [
    ("int", data_ints, dp.algorithms.laplacian.Max),
    ("float", data_floats, dp.algorithms.laplacian.Max),
    ("int", data_ints, dp.algorithms.laplacian.Min),
    ("float", data_floats, dp.algorithms.laplacian.Min),
    ("int", data_ints, dp.algorithms.laplacian.Median),
    ("float", data_floats, dp.algorithms.laplacian.Median),
]

# NOTE: One needs to use https://pypi.org/project/pytest-lazy-fixture/ to have fixtues in parameters.
# Using none fixtured data instead of adding a pytest-lazy-fixture.
@pytest.mark.parametrize("dtype, data", [("int", data_ints), ("float", data_floats)])
def test_min(data, dtype):

    minn = dp.algorithms.laplacian.Min(
        dtype=dtype, epsilon=1.0, lower_bound=0, upper_bound=200
    )
    assert expect_near(min(data), minn.quick_result(data), 10)
    assert expect_near(0, minn.quick_result(data), 10)

@pytest.mark.parametrize("dtype, data", [("int", data_ints), ("float", data_floats)])
def test_max(data, dtype):
    maxx = dp.algorithms.laplacian.Max(
        dtype=dtype, epsilon=1.0, lower_bound=0, upper_bound=200
    )
    assert 190 < maxx.quick_result(data) < 210

    assert expect_near(max(data), maxx.quick_result(data), 10)

@pytest.mark.parametrize("dtype, data", [("int", data_ints), ("float", data_floats)])
def test_median(data, dtype):

    median = dp.algorithms.laplacian.Median(
        dtype=dtype, epsilon=1.0, lower_bound=0, upper_bound=200
    )

    assert expect_near(statistics.median(data), median.quick_result(data), 20)

@pytest.mark.parametrize("dtype", ["int", "float"])
def test_percentile_getter(dtype):

    expected_percentile = 0.45

    dp_percentile = dp.algorithms.laplacian.Percentile(
        dtype=dtype,
        epsilon=1.0,
        percentile=expected_percentile,
        lower_bound=0,
        upper_bound=200,
    )
    assert dp_percentile.percentile == expected_percentile

@pytest.mark.parametrize("dtype, data, order_statistic", type_data_algorithm)
def test_order_statistic_datatypes(data, dtype, order_statistic):

    order_statistic_1 = order_statistic(dtype=dtype, epsilon=1.0)
    order_statistic_2 = order_statistic(
        dtype=dtype, epsilon=1.0, lower_bound=0, upper_bound=200
    )
    res = order_statistic_2.quick_result(data)

    assert isinstance(order_statistic_1, order_statistic)
    assert isinstance(order_statistic_2, order_statistic)

    assert isinstance(res, type(data[0]))

@pytest.mark.parametrize(
    "dtype, data, dp_percentile",
    [
        ("int", data_ints, dp.algorithms.laplacian.Percentile),
        ("float", data_floats, dp.algorithms.laplacian.Percentile),
    ],
)
def test_percentile_datatypes(data, dtype, dp_percentile):

    dp_percentile_2 = dp_percentile(
        dtype=dtype, epsilon=1.0, percentile=0.45, lower_bound=0, upper_bound=200
    )
    res = dp_percentile_2.quick_result(data)

    assert isinstance(dp_percentile_2, dp_percentile)

    assert isinstance(res, float)

# TODO Yet some more tests
<|endoftext|>


<commit_before>"""config URL Configuration

The `urlpatterns` list routes URLs to views. For more information please see:
    https://docs.djangoproject.com/en/2.2/topics/http/urls/
Examples:
Function views
    1. Add an import:  from my_app import views
    2. Add a URL to urlpatterns:  path('', views.home, name='home')
Class-based views
    1. Add an import:  from other_app.views import Home
    2. Add a URL to urlpatterns:  path('', Home.as_view(), name='home')
Including another URLconf
    1. Import the include() function: from django.urls import include, path
    2. Add a URL to urlpatterns:  path('blog/', include('blog.urls'))
"""
from django.conf import settings
from django.urls import path, include
from main.admin import admin_site

urlpatterns = [
    path('', include('main.urls')),
    path('search/', include('search.urls')),
    path('admin/', admin_site.urls),
]

# use django-debug-toolbar if installed
if settings.DEBUG:
    try:
        import debug_toolbar
        urlpatterns += [path('__debug__/', include(debug_toolbar.urls))]
    except ImportError:
        pass
<commit_msg>Serve the Django admin at /django-admin, so it doesn't hide the Rails admin, which is served at /admin.<commit_after>"""config URL Configuration

The `urlpatterns` list routes URLs to views. For more information please see:
    https://docs.djangoproject.com/en/2.2/topics/http/urls/
Examples:
Function views
    1. Add an import:  from my_app import views
    2. Add a URL to urlpatterns:  path('', views.home, name='home')
Class-based views
    1. Add an import:  from other_app.views import Home
    2. Add a URL to urlpatterns:  path('', Home.as_view(), name='home')
Including another URLconf
    1. Import the include() function: from django.urls import include, path
    2. Add a URL to urlpatterns:  path('blog/', include('blog.urls'))
"""
from django.conf import settings
from django.urls import path, include
from main.admin import admin_site

urlpatterns = [
    path('', include('main.urls')),
    path('search/', include('search.urls')),
    path('django-admin/', admin_site.urls),
]

# use django-debug-toolbar if installed
if settings.DEBUG:
    try:
        import debug_toolbar
        urlpatterns += [path('__debug__/', include(debug_toolbar.urls))]
    except ImportError:
        pass
<|endoftext|>


<commit_before># coding: utf8
from __future__ import unicode_literals
from flask import request, render_template
from flask.json import JSONEncoder
from flaskapi.mediatypes import MediaType
import json

class BaseRenderer(object):
    media_type = None
    charset = 'utf-8'

    # handles_empty_responses

    def render(self, data, media_type, **options):
        msg = '`render()` method must be implemented for class "%s"'
        raise NotImplementedError(msg % self.__class__.__name__)

class JSONRenderer(BaseRenderer):
    media_type = 'application/json'
    charset = None

    def render(self, data, media_type, **options):
        indent = options.get('indent')
        return json.dumps(data, cls=JSONEncoder, ensure_ascii=False, indent=indent)

class BrowsableAPIRenderer(BaseRenderer):
    media_type = 'text/html'

    def render(self, data, media_type, **options):
        # Render the content as it would have been if the client
        # had requested 'Accept: */*'.
        available_renderers = [
            renderer for renderer in request.renderer_classes
            if not issubclass(renderer, BrowsableAPIRenderer)
        ]
        assert available_renderers, 'BrowsableAPIRenderer cannot be the only renderer'
        mock_renderer = available_renderers[0]()
        mock_media_type = MediaType(mock_renderer.media_type)
        mock_content = mock_renderer.render(data, mock_media_type, indent=4)

        status = options['status']
        headers = options['headers']
        headers['Content-Type'] = str(mock_media_type)

        return render_template('base.html', request=request, status=status, headers=headers, content=mock_content)
<commit_msg>Remove request from context since it's already included<commit_after># coding: utf8
from __future__ import unicode_literals
from flask import request, render_template
from flask.json import JSONEncoder
from flaskapi.mediatypes import MediaType
import json

class BaseRenderer(object):
    media_type = None
    charset = 'utf-8'

    # handles_empty_responses

    def render(self, data, media_type, **options):
        msg = '`render()` method must be implemented for class "%s"'
        raise NotImplementedError(msg % self.__class__.__name__)

class JSONRenderer(BaseRenderer):
    media_type = 'application/json'
    charset = None

    def render(self, data, media_type, **options):
        indent = options.get('indent')
        return json.dumps(data, cls=JSONEncoder, ensure_ascii=False, indent=indent)

class BrowsableAPIRenderer(BaseRenderer):
    media_type = 'text/html'

    def render(self, data, media_type, **options):
        # Render the content as it would have been if the client
        # had requested 'Accept: */*'.
        available_renderers = [
            renderer for renderer in request.renderer_classes
            if not issubclass(renderer, BrowsableAPIRenderer)
        ]
        assert available_renderers, 'BrowsableAPIRenderer cannot be the only renderer'
        mock_renderer = available_renderers[0]()
        mock_media_type = MediaType(mock_renderer.media_type)
        mock_content = mock_renderer.render(data, mock_media_type, indent=4)

        status = options['status']
        headers = options['headers']
        headers['Content-Type'] = str(mock_media_type)

        return render_template('base.html', status=status, headers=headers, content=mock_content)
<|endoftext|>


<commit_before>import os
import unittest
from base_test import BaseTest
from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait

class NavigationTest(BaseTest, unittest.TestCase):

    def job_name(self):
        return 'Navigation test'

    def test_navigation(self):
        self.driver.get('http://localhost:8000/1005-5/2012-12121')
        WebDriverWait(self.driver, 30).until(
            lambda driver: driver.find_element_by_css_selector('html.js'))

        self.driver.execute_script('poffset = document.getElementById("1005-5-b-2").offsetTop')
        self.driver.execute_script('window.scrollTo(0, poffset)')
        # wayfinding header should update
        WebDriverWait(self.driver, 10).until(
            lambda driver: driver.find_element_by_xpath('//*[@id="active-title"]').text == u'\u00A71005.5(b)(1)')

        fwd_link = self.driver.find_element_by_xpath('//*[@id="1005-5"]/nav/ul/li[2]/a')
        fwd_link.click()
        # should navigate to next section
        WebDriverWait(self.driver, 30).until(
            lambda driver: driver.find_element_by_id('1005-6'))

        self.driver.back()

        # should go back to 1005-5
        self.driver.find_element_by_xpath('//*[@id="1005-5"]')
        back_link = self.driver.find_element_by_xpath('//*[@id="1005-5"]/nav/ul/li[1]/a')
        back_link.click()
        # should navigate to 1005-4
        WebDriverWait(self.driver, 30).until(
            lambda driver: driver.find_element_by_id('1005-4'))

if __name__ == '__main__':
    unittest.main()
<commit_msg>accomodate different header offsets<commit_after>import os
import unittest
from base_test import BaseTest
from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait

class NavigationTest(BaseTest, unittest.TestCase):

    def job_name(self):
        return 'Navigation test'

    def test_navigation(self):
        self.driver.get('http://localhost:8000/1005-5/2012-12121')
        WebDriverWait(self.driver, 30).until(
            lambda driver: driver.find_element_by_css_selector('html.js'))

        self.driver.execute_script('poffset = document.getElementById("1005-5-b-2").offsetTop')
        self.driver.execute_script('window.scrollTo(0, poffset)')
        # wayfinding header should update
        WebDriverWait(self.driver, 10).until(
            lambda driver: driver.find_element_by_xpath('//*[@id="active-title"]').text in
            (u'\u00A71005.5(b)(1)', u'\u00A71005.5(b)'))

        fwd_link = self.driver.find_element_by_xpath('//*[@id="1005-5"]/nav/ul/li[2]/a')
        fwd_link.click()
        # should navigate to next section
        WebDriverWait(self.driver, 30).until(
            lambda driver: driver.find_element_by_id('1005-6'))

        self.driver.back()

        # should go back to 1005-5
        self.driver.find_element_by_xpath('//*[@id="1005-5"]')
        back_link = self.driver.find_element_by_xpath('//*[@id="1005-5"]/nav/ul/li[1]/a')
        back_link.click()
        # should navigate to 1005-4
        WebDriverWait(self.driver, 30).until(
            lambda driver: driver.find_element_by_id('1005-4'))

if __name__ == '__main__':
    unittest.main()
<|endoftext|>


<commit_before># -*- coding: utf-8 -*-
##
##
## This file is part of Indico.
## Copyright (C) 2002 - 2014 European Organization for Nuclear Research (CERN).
##
## Indico is free software; you can redistribute it and/or
## modify it under the terms of the GNU General Public License as
## published by the Free Software Foundation; either version 3 of the
## License, or (at your option) any later version.
##
## Indico is distributed in the hope that it will be useful, but
## WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
## General Public License for more details.
##
## You should have received a copy of the GNU General Public License
## along with Indico;if not, see <http://www.gnu.org/licenses/>.

from MaKaC.conference import ConferenceHolder

from indico.web.http_api.hooks.base import HTTPAPIHook
from indico.web.http_api.hooks.event import EventBaseHook
from indico.web.http_api.util import get_query_parameter

from indico.util.date_time import format_datetime, format_date

@HTTPAPIHook.register
class CheckInHook(EventBaseHook):
    RE = r'(?P<event>[\w\s]+)/registrant/(?P<registrant_id>[\w\s]+)/checkin'
    NO_CACHE = True
    COMMIT = True

    def _getParams(self):
        super(CheckInHook, self)._getParams()
        self._check_in = get_query_parameter(self._queryParams, ["checked_in"]) == "yes"
        self._secret = get_query_parameter(self._queryParams, ["secret"])
        registrant_id = self._pathParams["registrant_id"]
        self._conf = ConferenceHolder().getById(self._pathParams['event'])
        self._registrant = self._conf.getRegistrantById(registrant_id)
        self._type = "checkin"

    def _hasAccess(self, aw):
        return self._conf.canManageRegistration(aw.getUser()) and self._secret == self._registrant.getCheckInUUID()

    def export_checkin(self, aw):
        self._registrant.setCheckedIn(self._check_in)
        checkin_date = format_datetime(self._registrant.getAdjustedCheckInDate(), format="short")
        return {
            "checkin_in": self._check_in,
            "checkin_date": checkin_date if self._check_in else None
        }

@HTTPAPIHook.register
class RegistrantHook(EventBaseHook):
    RE = r'(?P<event>[\w\s]+)/registrant/(?P<registrant_id>[\w\s]+)'
    NO_CACHE = True

    def _getParams(self):
        super(RegistrantHook, self)._getParams()
        self._secret = get_query_parameter(self._queryParams, ["secret"])
        self._conf = ConferenceHolder().getById(self._pathParams['event'])
        registrant_id = self._pathParams["registrant_id"]
        self._registrant = self._conf.getRegistrantById(registrant_id)
        self._type = "registrant"

    def _hasAccess(self, aw):
        return self._conf.canManageRegistration(aw.getUser()) and self._secret == self._registrant.getCheckInUUID()

    def export_registrant(self, aw):
        registration_date = format_datetime(self._registrant.getAdjustedRegistrationDate(), format="short")
        checkin_date = format_datetime(self._registrant.getAdjustedCheckInDate(), format="short")
        self._registrant.getPayed()
        result = {
            "registrant_id": self._registrant.getId(),
            "full_name": self._registrant.getFullName(title=True, firstNameFirst=True),
            "checked_in": self._registrant.isCheckedIn(),
            "checkin_date": checkin_date if self._registrant.isCheckedIn() else None,
            "registration_date": registration_date,
            "payed": self._registrant.getPayed() if self._conf.getModPay().isActivated() else None,
            "pay_amount": self._registrant.getTotal() if self._conf.getModPay().isActivated() else None
        }
        regForm = self._conf.getRegistrationForm()
        personalData = regForm.getPersonalData().getRegistrantValues(self._registrant)
        result.update(personalData)
        return result

@HTTPAPIHook.register
class RegistrantsHook(EventBaseHook):
    RE = r'(?P<event>[\w\s]+)/registrants'
    NO_CACHE = True

    def _getParams(self):
        super(RegistrantsHook, self)._getParams()
        self._conf_id = self._pathParams['event']
        self._type = "registrants"
        self._conf = ConferenceHolder().getById(self._conf_id)

    def _hasAccess(self, aw):
        return self._conf.canManageRegistration(aw.getUser())

    def export_registrants(self, aw):
        registrants = self._conf.getRegistrantsList()
        registrant_list = []
        for registrant in registrants:
            reg = {
                "registrant_id": registrant.getId(),
                "checked_in": registrant.isCheckedIn(),
                "full_name": registrant.getFullName(title=True, firstNameFirst=True),
                "secret": registrant.getCheckInUUID(),
            }
            regForm = self._conf.getRegistrationForm()
            reg.update(regForm.getPersonalData().getRegistrantValues(registrant))
            registrant_list.append(reg)
        return {"registrants": registrant_list}
<commit_msg>[FIX] Registration HTTP API permissions<commit_after># -*- coding: utf-8 -*-
##
##
## This file is part of Indico.
## Copyright (C) 2002 - 2014 European Organization for Nuclear Research (CERN).
##
## Indico is free software; you can redistribute it and/or
## modify it under the terms of the GNU General Public License as
## published by the Free Software Foundation; either version 3 of the
## License, or (at your option) any later version.
##
## Indico is distributed in the hope that it will be useful, but
## WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
## General Public License for more details.
##
## You should have received a copy of the GNU General Public License
## along with Indico;if not, see <http://www.gnu.org/licenses/>.

from MaKaC.conference import ConferenceHolder

from indico.web.http_api.hooks.base import HTTPAPIHook
from indico.web.http_api.hooks.event import EventBaseHook
from indico.web.http_api.util import get_query_parameter

from indico.util.date_time import format_datetime, format_date

@HTTPAPIHook.register
class CheckInHook(EventBaseHook):
    RE = r'(?P<event>[\w\s]+)/registrant/(?P<registrant_id>[\w\s]+)/checkin'
    NO_CACHE = True
    COMMIT = True

    def _getParams(self):
        super(CheckInHook, self)._getParams()
        self._check_in = get_query_parameter(self._queryParams, ["checked_in"]) == "yes"
        self._secret = get_query_parameter(self._queryParams, ["secret"])
        registrant_id = self._pathParams["registrant_id"]
        self._conf = ConferenceHolder().getById(self._pathParams['event'])
        self._registrant = self._conf.getRegistrantById(registrant_id)
        self._type = "checkin"

    def _hasAccess(self, aw):
        return (self._conf.canManageRegistration(aw.getUser()) or self._conf.canModify(aw)) \
            and self._secret == self._registrant.getCheckInUUID()

    def export_checkin(self, aw):
        self._registrant.setCheckedIn(self._check_in)
        checkin_date = format_datetime(self._registrant.getAdjustedCheckInDate(), format="short")
        return {
            "checkin_in": self._check_in,
            "checkin_date": checkin_date if self._check_in else None
        }

@HTTPAPIHook.register
class RegistrantHook(EventBaseHook):
    RE = r'(?P<event>[\w\s]+)/registrant/(?P<registrant_id>[\w\s]+)'
    NO_CACHE = True

    def _getParams(self):
        super(RegistrantHook, self)._getParams()
        self._secret = get_query_parameter(self._queryParams, ["secret"])
        self._conf = ConferenceHolder().getById(self._pathParams['event'])
        registrant_id = self._pathParams["registrant_id"]
        self._registrant = self._conf.getRegistrantById(registrant_id)
        self._type = "registrant"

    def _hasAccess(self, aw):
        return (self._conf.canManageRegistration(aw.getUser()) or self._conf.canModify(aw)) \
            and self._secret == self._registrant.getCheckInUUID()

    def export_registrant(self, aw):
        registration_date = format_datetime(self._registrant.getAdjustedRegistrationDate(), format="short")
        checkin_date = format_datetime(self._registrant.getAdjustedCheckInDate(), format="short")
        self._registrant.getPayed()
        result = {
            "registrant_id": self._registrant.getId(),
            "full_name": self._registrant.getFullName(title=True, firstNameFirst=True),
            "checked_in": self._registrant.isCheckedIn(),
            "checkin_date": checkin_date if self._registrant.isCheckedIn() else None,
            "registration_date": registration_date,
            "payed": self._registrant.getPayed() if self._conf.getModPay().isActivated() else None,
            "pay_amount": self._registrant.getTotal() if self._conf.getModPay().isActivated() else None
        }
        regForm = self._conf.getRegistrationForm()
        personalData = regForm.getPersonalData().getRegistrantValues(self._registrant)
        result.update(personalData)
        return result

@HTTPAPIHook.register
class RegistrantsHook(EventBaseHook):
    RE = r'(?P<event>[\w\s]+)/registrants'
    NO_CACHE = True

    def _getParams(self):
        super(RegistrantsHook, self)._getParams()
        self._conf_id = self._pathParams['event']
        self._type = "registrants"
        self._conf = ConferenceHolder().getById(self._conf_id)

    def _hasAccess(self, aw):
        return self._conf.canManageRegistration(aw.getUser()) or self._conf.canModify(aw)

    def export_registrants(self, aw):
        registrants = self._conf.getRegistrantsList()
        registrant_list = []
        for registrant in registrants:
            reg = {
                "registrant_id": registrant.getId(),
                "checked_in": registrant.isCheckedIn(),
                "full_name": registrant.getFullName(title=True, firstNameFirst=True),
                "secret": registrant.getCheckInUUID(),
            }
            regForm = self._conf.getRegistrationForm()
            reg.update(regForm.getPersonalData().getRegistrantValues(registrant))
            registrant_list.append(reg)
        return {"registrants": registrant_list}
<|endoftext|>


<commit_before>from fabric import api as fab
from fabricio import tasks, docker
from fabricio.misc import AvailableVagrantHosts

fab.env.roledefs.update(
    # you can set default roles definitions here
    web='localhost',
)

@tasks.infrastructure
def vagrant():
    fab.env.update(
        roledefs={
            'web': AvailableVagrantHosts(),
        },
    )

nginx = tasks.DockerTasks(
    service=docker.Container(
        name='nginx',
        image='nginx:stable-alpine',
        options=dict(
            publish='80:80',
        ),
    ),
    roles=['web'],
)
<commit_msg>fixed default roledefs<commit_after>from fabric import api as fab
from fabricio import tasks, docker
from fabricio.misc import AvailableVagrantHosts

fab.env.roledefs.update(
    # you can set default roles definitions here
    web=['localhost'],
)

@tasks.infrastructure
def vagrant():
    fab.env.update(
        roledefs={
            'web': AvailableVagrantHosts(),
        },
    )

nginx = tasks.DockerTasks(
    service=docker.Container(
        name='nginx',
        image='nginx:stable-alpine',
        options=dict(
            publish='80:80',
        ),
    ),
    roles=['web'],
)
<|endoftext|>