<commit_before># Copyright 2022 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

import json
import re
import subprocess
import uuid

import backoff
import pytest
import requests

@backoff.on_exception(backoff.expo, Exception, max_tries=3)
def gcloud_cli(command):
    """
    Runs the gcloud CLI with given options, parses the json formatted output
    and returns the resulting Python object.

    Usage: gcloud_cli(options)
        options: command line options

    Example:
        result = gcloud_cli("app deploy --no-promote")
        print(f"Deployed version {result['versions'][0]['id']}")

    Raises Exception with the stderr output of the last attempt on failure.
    """
    output = subprocess.run(
        f"gcloud {command} --quiet --format=json",
        capture_output=True,
        shell=True,
        check=True,
    )
    try:
        entries = json.loads(output.stdout)
        return entries
    except Exception:
        print("Failed to read log")
        print(f"gcloud stderr was {output.stderr}")

    raise Exception(output.stderr)

@pytest.fixture
def version():
    """Launch a new version of the app for testing, and yield the
    project and version number so tests can invoke it, then delete it.
    """

    result = gcloud_cli(f"app deploy --no-promote --version={uuid.uuid4().hex}")
    version_id = result["versions"][0]["id"]
    project_id = result["versions"][0]["project"]

    yield project_id, version_id

    gcloud_cli(f"app versions delete {version_id}")

def test_upload_and_view(version):
    project_id, version_id = version
    version_hostname = f"{version_id}-dot-{project_id}.appspot.com"

    # Check that version is serving form in home page
    response = requests.get(f"https://{version_hostname}/")
    assert response.status_code == 200
    assert '<form action="' in response.text

    matches = re.search(r'action="(.*?)"', response.text)
    assert matches is not None
    upload_url = matches.group(1)

    with open("./main.py", "rb") as f:
        response = requests.post(upload_url, files={"file": f})

    assert response.status_code == 200
    assert b"from google.appengine.api" in response.content
<commit_msg>fix: May need slight wait before responsive (#8500)<commit_after># Copyright 2022 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

import json
import re
import subprocess
import time
import uuid

import backoff
import pytest
import requests

@backoff.on_exception(backoff.expo, Exception, max_tries=3)
def gcloud_cli(command):
    """
    Runs the gcloud CLI with given options, parses the json formatted output
    and returns the resulting Python object.

    Usage: gcloud_cli(options)
        options: command line options

    Example:
        result = gcloud_cli("app deploy --no-promote")
        print(f"Deployed version {result['versions'][0]['id']}")

    Raises Exception with the stderr output of the last attempt on failure.
    """
    output = subprocess.run(
        f"gcloud {command} --quiet --format=json",
        capture_output=True,
        shell=True,
        check=True,
    )
    try:
        entries = json.loads(output.stdout)
        return entries
    except Exception:
        print("Failed to read log")
        print(f"gcloud stderr was {output.stderr}")

    raise Exception(output.stderr)

@pytest.fixture
def version():
    """Launch a new version of the app for testing, and yield the
    project and version number so tests can invoke it, then delete it.
    """

    result = gcloud_cli(f"app deploy --no-promote --version={uuid.uuid4().hex}")
    version_id = result["versions"][0]["id"]
    project_id = result["versions"][0]["project"]

    time.sleep(10)      # There may be a short delay before responsive
    yield project_id, version_id

    gcloud_cli(f"app versions delete {version_id}")

def test_upload_and_view(version):
    project_id, version_id = version
    version_hostname = f"{version_id}-dot-{project_id}.appspot.com"

    # Check that version is serving form in home page
    response = requests.get(f"https://{version_hostname}/")
    assert response.status_code == 200
    assert '<form action="' in response.text

    matches = re.search(r'action="(.*?)"', response.text)
    assert matches is not None
    upload_url = matches.group(1)

    with open("./main.py", "rb") as f:
        response = requests.post(upload_url, files={"file": f})

    assert response.status_code == 200
    assert b"from google.appengine.api" in response.content
<|endoftext|>


<commit_before>import logging
from ...common.interfaces import AbstractPlugin, GeneratorPlugin
from .reader import AndroidReader, AndroidStatsReader
try:
    from volta.core.core import Core as VoltaCore
except Exception:
    raise RuntimeError("Please install volta. https://github.com/yandex-load/volta")

logger = logging.getLogger(__name__)

class Plugin(AbstractPlugin, GeneratorPlugin):
    SECTION = "android"
    SECTION_META = "meta"

    def __init__(self, core, cfg, cfg_updater):
        try:
            super(Plugin, self).__init__(core, cfg, cfg_updater)
            self.device = None
            self.cfg = cfg['volta_options']
            for key, value in self.cfg.iteritems():
                if not isinstance(value, dict):
                    logger.debug('Malformed VoltaConfig key: %s value %s', key, value)
                    raise RuntimeError('Malformed VoltaConfig passed, key: %s. Should by dict' % key)
        except AttributeError:
            logger.error('Failed to read Volta config', exc_info=True)
        try:
            self.volta_core = VoltaCore(self.cfg)
        except Exception as exc:
            raise RuntimeError('Volta Config validation error', exc)

    @staticmethod
    def get_key():
        return __file__

    def get_available_options(self):
        opts = ["volta_options"]
        return opts

    def configure(self):
        self.volta_core.configure()

    def prepare_test(self):
        aggregator = self.core.job.aggregator_plugin
        if aggregator:
            aggregator.reader = AndroidReader()
            aggregator.stats_reader = AndroidStatsReader()
        self.core.add_artifact_file(self.volta_core.currents_fname)
        [self.core.add_artifact_file(fname) for fname in self.volta_core.event_fnames.values()]

    def start_test(self):
        self.volta_core.start_test()

    def is_test_finished(self):
        if hasattr(self.volta_core, 'phone'):
            if hasattr(self.volta_core.phone, 'test_performer'):
                if not self.volta_core.phone.test_performer._finished:
                    logger.debug('Waiting for phone test for finish...')
                    return -1
                else:
                    return self.volta_core.phone.test_performer.retcode

    def end_test(self, retcode):
        self.volta_core.end_test()
        return retcode

    def get_info(self):
        return AndroidInfo()

    def post_process(self, retcode):
        self.volta_core.post_process()
        return retcode

class AndroidInfo(object):
    def __init__(self):
        self.address = ''
        self.port = 80
        self.ammo_file = ''
        self.duration = 0
        self.loop_count = 1
        self.instances = 1
        self.rps_schedule = ''
<commit_msg>don't cut traceback in volta plugin<commit_after>import logging
from ...common.interfaces import AbstractPlugin, GeneratorPlugin
from .reader import AndroidReader, AndroidStatsReader
try:
    from volta.core.core import Core as VoltaCore
except Exception:
    raise RuntimeError("Please install volta. https://github.com/yandex-load/volta")

logger = logging.getLogger(__name__)

class Plugin(AbstractPlugin, GeneratorPlugin):
    SECTION = "android"
    SECTION_META = "meta"

    def __init__(self, core, cfg, cfg_updater):
        try:
            super(Plugin, self).__init__(core, cfg, cfg_updater)
            self.device = None
            self.cfg = cfg['volta_options']
            for key, value in self.cfg.iteritems():
                if not isinstance(value, dict):
                    logger.debug('Malformed VoltaConfig key: %s value %s', key, value)
                    raise RuntimeError('Malformed VoltaConfig passed, key: %s. Should by dict' % key)
        except AttributeError:
            logger.error('Failed to read Volta config', exc_info=True)
        self.volta_core = VoltaCore(self.cfg)

    @staticmethod
    def get_key():
        return __file__

    def get_available_options(self):
        opts = ["volta_options"]
        return opts

    def configure(self):
        self.volta_core.configure()

    def prepare_test(self):
        aggregator = self.core.job.aggregator_plugin
        if aggregator:
            aggregator.reader = AndroidReader()
            aggregator.stats_reader = AndroidStatsReader()
        self.core.add_artifact_file(self.volta_core.currents_fname)
        [self.core.add_artifact_file(fname) for fname in self.volta_core.event_fnames.values()]

    def start_test(self):
        self.volta_core.start_test()

    def is_test_finished(self):
        if hasattr(self.volta_core, 'phone'):
            if hasattr(self.volta_core.phone, 'test_performer'):
                if not self.volta_core.phone.test_performer._finished:
                    logger.debug('Waiting for phone test for finish...')
                    return -1
                else:
                    return self.volta_core.phone.test_performer.retcode

    def end_test(self, retcode):
        self.volta_core.end_test()
        return retcode

    def get_info(self):
        return AndroidInfo()

    def post_process(self, retcode):
        self.volta_core.post_process()
        return retcode

class AndroidInfo(object):
    def __init__(self):
        self.address = ''
        self.port = 80
        self.ammo_file = ''
        self.duration = 0
        self.loop_count = 1
        self.instances = 1
        self.rps_schedule = ''
<|endoftext|>


<commit_before>import logging

from ..DataUploader import Plugin as DataUploaderPlugin
from .reader import AndroidReader, AndroidStatsReader
from ...common.interfaces import AbstractPlugin, GeneratorPlugin

try:
    from volta.core.core import Core as VoltaCore
except Exception:
    raise RuntimeError("Please install volta. https://github.com/yandex-load/volta")

logger = logging.getLogger(__name__)

class Plugin(AbstractPlugin, GeneratorPlugin):
    SECTION = "android"
    SECTION_META = "meta"

    def __init__(self, core, cfg, cfg_updater):
        self.stats_reader = None
        self.reader = None
        self.core = core
        try:
            super(Plugin, self).__init__(core, cfg, cfg_updater)
            self.device = None
            self.cfg = cfg['volta_options']
            for key, value in self.cfg.iteritems():
                if not isinstance(value, dict):
                    logger.debug('Malformed VoltaConfig key: %s value %s', key, value)
                    raise RuntimeError('Malformed VoltaConfig passed, key: %s. Should by dict' % key)
        except AttributeError:
            logger.error('Failed to read Volta config', exc_info=True)
        self.volta_core = VoltaCore(self.cfg)

    @staticmethod
    def get_key():
        return __file__

    def get_available_options(self):
        opts = ["volta_options"]
        return opts

    def configure(self):
        self.volta_core.configure()

    def get_reader(self):
        if self.reader is None:
            self.reader = AndroidReader()
        return self.reader

    def get_stats_reader(self):
        if self.stats_reader is None:
            self.stats_reader = AndroidStatsReader()
        return self.stats_reader

    def prepare_test(self):
        self.core.add_artifact_file(self.volta_core.currents_fname)
        [self.core.add_artifact_file(fname) for fname in self.volta_core.event_fnames.values()]

    def start_test(self):
        try:
            self.volta_core.start_test()
        except:
            logger.info('Failed to start test of Android plugin', exc_info=True)

    def is_test_finished(self):
        try:
            if hasattr(self.volta_core, 'phone'):
                if hasattr(self.volta_core.phone, 'test_performer'):
                    if not self.volta_core.phone.test_performer:
                        logger.warning('There is no test performer process on the phone, interrupting test')
                        return 1
                    if not self.volta_core.phone.test_performer.is_finished():
                        logger.debug('Waiting for phone test to finish...')
                        return -1
                    else:
                        return self.volta_core.phone.test_performer.retcode
        except:
            logger.error('Unknown exception of Android plugin. Interrupting test', exc_info=True)
            return 1

    def end_test(self, retcode):
        try:
            self.volta_core.end_test()
            uploaders = self.core.get_plugins_of_type(DataUploaderPlugin)
            for uploader in uploaders:
                response = uploader.lp_job.api_client.link_mobile_job(
                    lp_key=uploader.lp_job.number,
                    mobile_key=self.volta_core.uploader.jobno
                )
                logger.info(
                    'Linked mobile job %s to %s for plugin: %s. Response: %s',
                    self.volta_core.uploader.jobno, uploader.lp_job.number, uploader.backend_type, response
                )
        except:
            logger.error('Failed to complete end_test of Android plugin', exc_info=True)
            retcode = 1
        return retcode

    def get_info(self):
        return AndroidInfo()

    def post_process(self, retcode):
        try:
            self.volta_core.post_process()
        except:
            logger.error('Failed to complete post_process of Android plugin', exc_info=True)
            retcode = 1
        return retcode

class AndroidInfo(object):
    def __init__(self):
        self.address = ''
        self.port = 80
        self.ammo_file = ''
        self.duration = 0
        self.loop_count = 1
        self.instances = 1
        self.rps_schedule = ''
<commit_msg>fixme's, bugfix finish test when start_test got exception<commit_after>import logging

from ..DataUploader import Plugin as DataUploaderPlugin
from .reader import AndroidReader, AndroidStatsReader
from ...common.interfaces import AbstractPlugin, GeneratorPlugin

try:
    from volta.core.core import Core as VoltaCore
except Exception:
    raise RuntimeError("Please install volta. https://github.com/yandex-load/volta")

logger = logging.getLogger(__name__)

class Plugin(AbstractPlugin, GeneratorPlugin):
    SECTION = "android"
    SECTION_META = "meta"

    def __init__(self, core, cfg, cfg_updater):
        self.stats_reader = None
        self.reader = None
        super(Plugin, self).__init__(core, cfg, cfg_updater)
        self.device = None
        try:
            self.cfg = cfg['volta_options']
            for key, value in self.cfg.iteritems():
                if not isinstance(value, dict):
                    logger.debug('Malformed VoltaConfig key: %s value %s', key, value)
                    raise RuntimeError('Malformed VoltaConfig passed, key: %s. Should by dict' % key)
        except AttributeError:
            logger.error('Failed to read Volta config', exc_info=True)
        self.volta_core = VoltaCore(self.cfg)

    @staticmethod
    def get_key():
        return __file__

    def get_available_options(self):
        opts = ["volta_options"]
        return opts

    def configure(self):
        self.volta_core.configure()

    def get_reader(self):
        if self.reader is None:
            self.reader = AndroidReader()
        return self.reader

    def get_stats_reader(self):
        if self.stats_reader is None:
            self.stats_reader = AndroidStatsReader()
        return self.stats_reader

    def prepare_test(self):
        self.core.add_artifact_file(self.volta_core.currents_fname)
        [self.core.add_artifact_file(fname) for fname in self.volta_core.event_fnames.values()]

    def start_test(self):
        try:
            self.volta_core.start_test()
        # FIXME raise/catch appropriate exception here
        except:
            logger.info('Failed to start test of Android plugin', exc_info=True)
            return 1

    def is_test_finished(self):
        try:
            if hasattr(self.volta_core, 'phone'):
                if hasattr(self.volta_core.phone, 'test_performer'):
                    if not self.volta_core.phone.test_performer:
                        logger.warning('There is no test performer process on the phone, interrupting test')
                        return 1
                    if not self.volta_core.phone.test_performer.is_finished():
                        logger.debug('Waiting for phone test to finish...')
                        return -1
                    else:
                        return self.volta_core.phone.test_performer.retcode
        # FIXME raise/catch appropriate exception here
        except:
            logger.error('Unknown exception of Android plugin. Interrupting test', exc_info=True)
            return 1

    def end_test(self, retcode):
        try:
            self.volta_core.end_test()
            uploaders = self.core.get_plugins_of_type(DataUploaderPlugin)
            for uploader in uploaders:
                response = uploader.lp_job.api_client.link_mobile_job(
                    lp_key=uploader.lp_job.number,
                    mobile_key=self.volta_core.uploader.jobno
                )
                logger.info(
                    'Linked mobile job %s to %s for plugin: %s. Response: %s',
                    self.volta_core.uploader.jobno, uploader.lp_job.number, uploader.backend_type, response
                )
        # FIXME raise/catch appropriate exception here
        except:
            logger.error('Failed to complete end_test of Android plugin', exc_info=True)
            retcode = 1
        return retcode

    def get_info(self):
        return AndroidInfo()

    def post_process(self, retcode):
        try:
            self.volta_core.post_process()
        # FIXME raise/catch appropriate exception here
        except:
            logger.error('Failed to complete post_process of Android plugin', exc_info=True)
            retcode = 1
        return retcode

class AndroidInfo(object):
    def __init__(self):
        self.address = ''
        self.port = 80
        self.ammo_file = ''
        self.duration = 0
        self.loop_count = 1
        self.instances = 1
        self.rps_schedule = ''
<|endoftext|>


<commit_before># coding: utf-8
from __future__ import unicode_literals

import re

from .common import InfoExtractor
from ..utils import parse_duration

class SWRMediathekIE(InfoExtractor):
    _VALID_URL = r'https?://(?:www\.)?swrmediathek\.de/(?:content/)?player\.htm\?show=(?P<id>[\da-f]{8}-[\da-f]{4}-[\da-f]{4}-[\da-f]{4}-[\da-f]{12})'

    _TESTS = [{
        'url': 'http://swrmediathek.de/player.htm?show=849790d0-dab8-11e3-a953-0026b975f2e6',
        'md5': '8c5f6f0172753368547ca8413a7768ac',
        'info_dict': {
            'id': '849790d0-dab8-11e3-a953-0026b975f2e6',
            'ext': 'mp4',
            'title': 'SWR odysso',
            'description': 'md5:2012e31baad36162e97ce9eb3f157b8a',
            'thumbnail': r're:^http:.*\.jpg$',
            'duration': 2602,
            'upload_date': '20140515',
            'uploader': 'SWR Fernsehen',
            'uploader_id': '990030',
        },
    }, {
        'url': 'http://swrmediathek.de/player.htm?show=0e1a8510-ddf2-11e3-9be3-0026b975f2e6',
        'md5': 'b10ab854f912eecc5a6b55cd6fc1f545',
        'info_dict': {
            'id': '0e1a8510-ddf2-11e3-9be3-0026b975f2e6',
            'ext': 'mp4',
            'title': 'Nachtcafé - Alltagsdroge Alkohol - zwischen Sektempfang und Komasaufen',
            'description': 'md5:e0a3adc17e47db2c23aab9ebc36dbee2',
            'thumbnail': r're:http://.*\.jpg',
            'duration': 5305,
            'upload_date': '20140516',
            'uploader': 'SWR Fernsehen',
            'uploader_id': '990030',
        },
    }, {
        'url': 'http://swrmediathek.de/player.htm?show=bba23e10-cb93-11e3-bf7f-0026b975f2e6',
        'md5': '4382e4ef2c9d7ce6852535fa867a0dd3',
        'info_dict': {
            'id': 'bba23e10-cb93-11e3-bf7f-0026b975f2e6',
            'ext': 'mp3',
            'title': 'Saša Stanišic: Vor dem Fest',
            'description': 'md5:5b792387dc3fbb171eb709060654e8c9',
            'thumbnail': r're:http://.*\.jpg',
            'duration': 3366,
            'upload_date': '20140520',
            'uploader': 'SWR 2',
            'uploader_id': '284670',
        }
    }]

    def _real_extract(self, url):
        mobj = re.match(self._VALID_URL, url)
        video_id = mobj.group('id')

        video = self._download_json(
            'http://swrmediathek.de/AjaxEntry?ekey=%s' % video_id, video_id, 'Downloading video JSON')

        attr = video['attr']
        media_type = attr['entry_etype']

        formats = []
        for entry in video['sub']:
            if entry['name'] != 'entry_media':
                continue

            entry_attr = entry['attr']
            codec = entry_attr['val0']
            quality = int(entry_attr['val1'])

            fmt = {
                'url': entry_attr['val2'],
                'quality': quality,
            }

            if media_type == 'Video':
                fmt.update({
                    'format_note': ['144p', '288p', '544p', '720p'][quality - 1],
                    'vcodec': codec,
                })
            elif media_type == 'Audio':
                fmt.update({
                    'acodec': codec,
                })
            formats.append(fmt)

        self._sort_formats(formats)

        return {
            'id': video_id,
            'title': attr['entry_title'],
            'description': attr['entry_descl'],
            'thumbnail': attr['entry_image_16_9'],
            'duration': parse_duration(attr['entry_durat']),
            'upload_date': attr['entry_pdatet'][:-4],
            'uploader': attr['channel_title'],
            'uploader_id': attr['channel_idkey'],
            'formats': formats,
        }
<commit_msg>[swrmediathek] improve extraction<commit_after># coding: utf-8
from __future__ import unicode_literals

from .common import InfoExtractor
from ..utils import (
    parse_duration,
    int_or_none,
    determine_protocol,
)

class SWRMediathekIE(InfoExtractor):
    _VALID_URL = r'https?://(?:www\.)?swrmediathek\.de/(?:content/)?player\.htm\?show=(?P<id>[\da-f]{8}-[\da-f]{4}-[\da-f]{4}-[\da-f]{4}-[\da-f]{12})'

    _TESTS = [{
        'url': 'http://swrmediathek.de/player.htm?show=849790d0-dab8-11e3-a953-0026b975f2e6',
        'md5': '8c5f6f0172753368547ca8413a7768ac',
        'info_dict': {
            'id': '849790d0-dab8-11e3-a953-0026b975f2e6',
            'ext': 'mp4',
            'title': 'SWR odysso',
            'description': 'md5:2012e31baad36162e97ce9eb3f157b8a',
            'thumbnail': r're:^http:.*\.jpg$',
            'duration': 2602,
            'upload_date': '20140515',
            'uploader': 'SWR Fernsehen',
            'uploader_id': '990030',
        },
    }, {
        'url': 'http://swrmediathek.de/player.htm?show=0e1a8510-ddf2-11e3-9be3-0026b975f2e6',
        'md5': 'b10ab854f912eecc5a6b55cd6fc1f545',
        'info_dict': {
            'id': '0e1a8510-ddf2-11e3-9be3-0026b975f2e6',
            'ext': 'mp4',
            'title': 'Nachtcafé - Alltagsdroge Alkohol - zwischen Sektempfang und Komasaufen',
            'description': 'md5:e0a3adc17e47db2c23aab9ebc36dbee2',
            'thumbnail': r're:http://.*\.jpg',
            'duration': 5305,
            'upload_date': '20140516',
            'uploader': 'SWR Fernsehen',
            'uploader_id': '990030',
        },
        '_skip': 'redirect to http://swrmediathek.de/index.htm?hinweis=swrlink',
    }, {
        'url': 'http://swrmediathek.de/player.htm?show=bba23e10-cb93-11e3-bf7f-0026b975f2e6',
        'md5': '4382e4ef2c9d7ce6852535fa867a0dd3',
        'info_dict': {
            'id': 'bba23e10-cb93-11e3-bf7f-0026b975f2e6',
            'ext': 'mp3',
            'title': 'Saša Stanišic: Vor dem Fest',
            'description': 'md5:5b792387dc3fbb171eb709060654e8c9',
            'thumbnail': r're:http://.*\.jpg',
            'duration': 3366,
            'upload_date': '20140520',
            'uploader': 'SWR 2',
            'uploader_id': '284670',
        },
        '_skip': 'redirect to http://swrmediathek.de/index.htm?hinweis=swrlink',
    }]

    def _real_extract(self, url):
        video_id = self._match_id(url)

        video = self._download_json(
            'http://swrmediathek.de/AjaxEntry?ekey=%s' % video_id,
            video_id, 'Downloading video JSON')

        attr = video['attr']
        title = attr['entry_title']
        media_type = attr.get('entry_etype')

        formats = []
        for entry in video.get('sub', []):
            if entry.get('name') != 'entry_media':
                continue

            entry_attr = entry.get('attr', {})
            f_url = entry_attr.get('val2')
            if not f_url:
                continue
            codec = entry_attr.get('val0')
            if codec == 'm3u8':
                formats.extend(self._extract_m3u8_formats(
                    f_url, video_id, 'mp4', 'm3u8_native',
                    m3u8_id='hls', fatal=False))
            elif codec == 'f4m':
                formats.extend(self._extract_f4m_formats(
                    f_url + '?hdcore=3.7.0', video_id,
                    f4m_id='hds', fatal=False))
            else:
                formats.append({
                    'format_id': determine_protocol({'url': f_url}),
                    'url': f_url,
                    'quality': int_or_none(entry_attr.get('val1')),
                    'vcodec': codec if media_type == 'Video' else 'none',
                    'acodec': codec if media_type == 'Audio' else None,
                })
        self._sort_formats(formats)

        upload_date = None
        entry_pdatet = attr.get('entry_pdatet')
        if entry_pdatet:
            upload_date = entry_pdatet[:-4]

        return {
            'id': video_id,
            'title': title,
            'description': attr.get('entry_descl'),
            'thumbnail': attr.get('entry_image_16_9'),
            'duration': parse_duration(attr.get('entry_durat')),
            'upload_date': upload_date,
            'uploader': attr.get('channel_title'),
            'uploader_id': attr.get('channel_idkey'),
            'formats': formats,
        }
<|endoftext|>


<commit_before>from django.template.context import RequestContext
from django.shortcuts import render_to_response
from django.http import HttpResponse
from piston.emitters import Emitter
from api.views import display_spatial_query, display_aoi_uploader
from util.ncconv.experimental import ocg_converter
from util.ncconv.experimental.ocg_stat import OcgStat
from django.conf import settings
import time

import logging
logger = logging.getLogger(__name__)

class OpenClimateEmitter(Emitter):
    """
    Superclass for all OpenClimateGIS emitters.
    """

    def render(self,request):
        return(self._render_(request))

    def _render_(self,request):
        raise(NotImplementedError)

class IdentityEmitter(OpenClimateEmitter):
    """
    The standard Django Piston emitter does unnecessary computations when an
    emitter is searching for the raw data from its associated handler.
    """

    def construct(self):
        return self.data

class HelloWorldEmitter(OpenClimateEmitter):

    def _render_(self,request):
        names = [n['name'] for n in self.construct()]
        msg = 'Hello, World!! The climate model names are:

{0}'.format('
'.join(names))
        return HttpResponse(msg)

class HTMLEmitter(IdentityEmitter):
    """Emits an HTML representation
    """
    def _render_(self,request):

        logger.info("starting HTMLEmitter.render()...")

        c = RequestContext(request)

        template_name = request.url_args.get('template_name')
        is_collection = request.url_args.get('is_collection')

        ## return data from the construct method of the resource's handler
        try:
            data = self.construct()
            logger.debug("len(data) = {0}".format(len(data)))
        except:
            data = []
            logger.debug("data is None!")

        ## if we need the query form generate and pass accordingly
        if template_name == 'query.html':
            response = display_spatial_query(request)
        elif template_name == 'aoi_upload.html':
            response = display_aoi_uploader(request)
        else:
            response = render_to_response(
                template_name=template_name,
                dictionary={'data':data, 'is_collection':is_collection},
                context_instance=c,
            )

        logger.info("...ending HTMLEmitter.render()")

        return(response)
Emitter.register('html', HTMLEmitter, 'text/html; charset=utf-8')

class SubOcgDataEmitter(IdentityEmitter):
    __converter__ = None
    __file_ext__ = ''

    def _render_(self,request):
        logger.info("starting {0}.render()...".format(self.__converter__.__name__))
#        import ipdb;ipdb.set_trace()
        self.sub = self.construct()
        self.db = self.get_db()
        self.request = request
        if request.ocg.query.use_stat:
            st = OcgStat(self.db,
                         self.sub,
                         request.ocg.query.grouping,
                         procs=settings.MAXPROCESSES)
            st.calculate_load(self.request.ocg.query.functions)
        self.cfvar = request.ocg.simulation_output.variable.code
        self.converter = self.get_converter()
        logger.info("...ending {0}.render()...".format(self.__converter__.__name__))
        return(self.get_response())

    def get_db(self):
        return(self.sub.to_db(procs=settings.MAXPROCESSES))

    def get_converter(self):
        return(self.__converter__(self.db,
                                  self.cfvar+self.__file_ext__,
                                  use_stat=self.request.ocg.query.use_stat))

    def get_response(self):
        return(self.converter.response())

class ZippedSubOcgDataEmitter(SubOcgDataEmitter):

    def _render_(self,request):
        base_response = super(ZippedSubOcgDataEmitter,self)._render_(request)
        response = HttpResponse()
        response['Content-Disposition'] = 'attachment; filename={0}.zip'.\
            format(request.ocg.simulation_output.variable.code)
        response['Content-length'] = str(len(base_response))
        response['Content-Type'] = 'application/zip'
        response.write(base_response)
        return(response)

    def get_converter(self):
        meta = ocg_converter.MetacontentConverter(self.request)
        return(self.__converter__(self.db,
                                  self.cfvar+self.__file_ext__,
                                  use_stat=self.request.ocg.query.use_stat,
                                  meta=meta))

class MetacontentEmitter(SubOcgDataEmitter):

    def _render_(self,request):
        converter = ocg_converter.MetacontentConverter(request)
        response = converter.response()
        return(response)

class SqliteEmitter(ZippedSubOcgDataEmitter):
    __converter__ = ocg_converter.SqliteConverter
    __file_ext__ = ''

    def get_db(self):
        return(self.sub.as_sqlite(to_disk=True))

class ShapefileEmitter(ZippedSubOcgDataEmitter):
    """
    Emits zipped shapefile (.shz)
    """
    __converter__ = ocg_converter.ShpConverter
    __file_ext__ = '.shp'

class LinkedShapefileEmitter(ZippedSubOcgDataEmitter):
    __converter__ = ocg_converter.LinkedShpConverter
    __file_ext__ = '.lshz'

class KmlEmitter(SubOcgDataEmitter):
    """
    Emits raw KML (.kml)
    """

    __converter__ = ocg_converter.KmlConverter
    __file_ext__ = '.kml'

    def _response_(self):
        return(self.converter())

    def get_response(self):
        return(self.converter.response(self.request))

class KmzEmitter(KmlEmitter):
    """
    Subclass of KmlEmitter. Emits KML in a zipped format (.kmz)
    """

    __converter__ = ocg_converter.KmzConverter
    __file_ext__ = '.kmz'

#    def _render_(self,request):
#        logger.info("starting KmzEmitter.render()...")
#        kml = super(KmzEmitter,self).render(request)
#        iobuffer = io.BytesIO()
#        zf = zipfile.ZipFile(
#            iobuffer,
#            mode='w',
#            compression=zipfile.ZIP_DEFLATED,
#        )
#        try:
#            zf.writestr('doc.kml',kml)
#        finally:
#            zf.close()
#        iobuffer.flush()
#        zip_stream = iobuffer.getvalue()
#        iobuffer.close()
#        logger.info("...ending KmzEmitter.render()")
#        return(zip_stream)

class GeoJsonEmitter(SubOcgDataEmitter):
    """
    JSON format for geospatial data (.json)
    """
    __converter__ = ocg_converter.GeojsonConverter
    __file_ext__ = '.json'

class CsvEmitter(SubOcgDataEmitter):
    """
    Tabular CSV format. (.csv)
    """
    __converter__ = ocg_converter.CsvConverter
    __file_ext__ = '.csv'

class LinkedCsvEmitter(ZippedSubOcgDataEmitter):
    __converter__ = ocg_converter.LinkedCsvConverter
    __file_ext__ = ''

class NcEmitter(SubOcgDataEmitter):
    __converter__ = ocg_converter.NcConverter
    __file_ext__ = '.nc'

    def get_response(self):
        from util.ncconv.experimental.ocg_dataset.dataset import OcgDataset
        ds = OcgDataset(self.request.ocg.dataset_uri,**self.request.ocg.ocg_opts)
        return(self.converter.response(self.sub,ds))

Emitter.register('shz',ShapefileEmitter,'application/zip; charset=utf-8')
Emitter.register('lshz',LinkedShapefileEmitter,'application/zip; charset=utf-8')
#Emitter.unregister('json')
Emitter.register('kml',KmlEmitter,'application/vnd.google-earth.kml+xml')
Emitter.register('kmz',KmzEmitter,'application/vnd.google-earth.kmz')
Emitter.register('geojson',GeoJsonEmitter,'text/plain; charset=utf-8')
Emitter.register('csv',CsvEmitter,'text/csv; charset=utf-8')
Emitter.register('kcsv',LinkedCsvEmitter,'application/zip; charset=utf-8')
Emitter.register('sqlite',SqliteEmitter,'application/zip; charset=utf-8')
Emitter.register('nc',NcEmitter,'application/x-netcdf; charset=utf-8')
Emitter.register('meta',MetacontentEmitter,'text/plain; charset=utf-8')<commit_msg>fixed problem with named function in sqlite emitter.<commit_after>from django.template.context import RequestContext
from django.shortcuts import render_to_response
from django.http import HttpResponse
from piston.emitters import Emitter
from api.views import display_spatial_query, display_aoi_uploader
from util.ncconv.experimental import ocg_converter
from util.ncconv.experimental.ocg_stat import OcgStat
from django.conf import settings
import time

import logging
logger = logging.getLogger(__name__)

class OpenClimateEmitter(Emitter):
    """
    Superclass for all OpenClimateGIS emitters.
    """

    def render(self,request):
        return(self._render_(request))

    def _render_(self,request):
        raise(NotImplementedError)

class IdentityEmitter(OpenClimateEmitter):
    """
    The standard Django Piston emitter does unnecessary computations when an
    emitter is searching for the raw data from its associated handler.
    """

    def construct(self):
        return self.data

class HelloWorldEmitter(OpenClimateEmitter):

    def _render_(self,request):
        names = [n['name'] for n in self.construct()]
        msg = 'Hello, World!! The climate model names are:

{0}'.format('
'.join(names))
        return HttpResponse(msg)

class HTMLEmitter(IdentityEmitter):
    """Emits an HTML representation
    """
    def _render_(self,request):

        logger.info("starting HTMLEmitter.render()...")

        c = RequestContext(request)

        template_name = request.url_args.get('template_name')
        is_collection = request.url_args.get('is_collection')

        ## return data from the construct method of the resource's handler
        try:
            data = self.construct()
            logger.debug("len(data) = {0}".format(len(data)))
        except:
            data = []
            logger.debug("data is None!")

        ## if we need the query form generate and pass accordingly
        if template_name == 'query.html':
            response = display_spatial_query(request)
        elif template_name == 'aoi_upload.html':
            response = display_aoi_uploader(request)
        else:
            response = render_to_response(
                template_name=template_name,
                dictionary={'data':data, 'is_collection':is_collection},
                context_instance=c,
            )

        logger.info("...ending HTMLEmitter.render()")

        return(response)
Emitter.register('html', HTMLEmitter, 'text/html; charset=utf-8')

class SubOcgDataEmitter(IdentityEmitter):
    __converter__ = None
    __file_ext__ = ''

    def _render_(self,request):
        logger.info("starting {0}.render()...".format(self.__converter__.__name__))
#        import ipdb;ipdb.set_trace()
        self.sub = self.construct()
        self.db = self.get_db()
        self.request = request
        if request.ocg.query.use_stat:
            st = OcgStat(self.db,
                         self.sub,
                         request.ocg.query.grouping,
                         procs=settings.MAXPROCESSES)
            st.calculate_load(self.request.ocg.query.functions)
        self.cfvar = request.ocg.simulation_output.variable.code
        self.converter = self.get_converter()
        logger.info("...ending {0}.render()...".format(self.__converter__.__name__))
        return(self.get_response())

    def get_db(self):
        return(self.sub.to_db(procs=settings.MAXPROCESSES))

    def get_converter(self):
        return(self.__converter__(self.db,
                                  self.cfvar+self.__file_ext__,
                                  use_stat=self.request.ocg.query.use_stat))

    def get_response(self):
        return(self.converter.response())

class ZippedSubOcgDataEmitter(SubOcgDataEmitter):

    def _render_(self,request):
        base_response = super(ZippedSubOcgDataEmitter,self)._render_(request)
        response = HttpResponse()
        response['Content-Disposition'] = 'attachment; filename={0}.zip'.\
            format(request.ocg.simulation_output.variable.code)
        response['Content-length'] = str(len(base_response))
        response['Content-Type'] = 'application/zip'
        response.write(base_response)
        return(response)

    def get_converter(self):
        meta = ocg_converter.MetacontentConverter(self.request)
        return(self.__converter__(self.db,
                                  self.cfvar+self.__file_ext__,
                                  use_stat=self.request.ocg.query.use_stat,
                                  meta=meta))

class MetacontentEmitter(SubOcgDataEmitter):

    def _render_(self,request):
        converter = ocg_converter.MetacontentConverter(request)
        response = converter.response()
        return(response)

class SqliteEmitter(ZippedSubOcgDataEmitter):
    __converter__ = ocg_converter.SqliteConverter
    __file_ext__ = ''

    def get_db(self):
        return(self.sub.to_db(to_disk=True,procs=settings.MAXPROCESSES))

class ShapefileEmitter(ZippedSubOcgDataEmitter):
    """
    Emits zipped shapefile (.shz)
    """
    __converter__ = ocg_converter.ShpConverter
    __file_ext__ = '.shp'

class LinkedShapefileEmitter(ZippedSubOcgDataEmitter):
    __converter__ = ocg_converter.LinkedShpConverter
    __file_ext__ = '.lshz'

class KmlEmitter(SubOcgDataEmitter):
    """
    Emits raw KML (.kml)
    """

    __converter__ = ocg_converter.KmlConverter
    __file_ext__ = '.kml'

    def _response_(self):
        return(self.converter())

    def get_response(self):
        return(self.converter.response(self.request))

class KmzEmitter(KmlEmitter):
    """
    Subclass of KmlEmitter. Emits KML in a zipped format (.kmz)
    """

    __converter__ = ocg_converter.KmzConverter
    __file_ext__ = '.kmz'

#    def _render_(self,request):
#        logger.info("starting KmzEmitter.render()...")
#        kml = super(KmzEmitter,self).render(request)
#        iobuffer = io.BytesIO()
#        zf = zipfile.ZipFile(
#            iobuffer,
#            mode='w',
#            compression=zipfile.ZIP_DEFLATED,
#        )
#        try:
#            zf.writestr('doc.kml',kml)
#        finally:
#            zf.close()
#        iobuffer.flush()
#        zip_stream = iobuffer.getvalue()
#        iobuffer.close()
#        logger.info("...ending KmzEmitter.render()")
#        return(zip_stream)

class GeoJsonEmitter(SubOcgDataEmitter):
    """
    JSON format for geospatial data (.json)
    """
    __converter__ = ocg_converter.GeojsonConverter
    __file_ext__ = '.json'

class CsvEmitter(SubOcgDataEmitter):
    """
    Tabular CSV format. (.csv)
    """
    __converter__ = ocg_converter.CsvConverter
    __file_ext__ = '.csv'

class LinkedCsvEmitter(ZippedSubOcgDataEmitter):
    __converter__ = ocg_converter.LinkedCsvConverter
    __file_ext__ = ''

class NcEmitter(SubOcgDataEmitter):
    __converter__ = ocg_converter.NcConverter
    __file_ext__ = '.nc'

    def get_response(self):
        from util.ncconv.experimental.ocg_dataset.dataset import OcgDataset
        ds = OcgDataset(self.request.ocg.dataset_uri,**self.request.ocg.ocg_opts)
        return(self.converter.response(self.sub,ds))

Emitter.register('shz',ShapefileEmitter,'application/zip; charset=utf-8')
Emitter.register('lshz',LinkedShapefileEmitter,'application/zip; charset=utf-8')
#Emitter.unregister('json')
Emitter.register('kml',KmlEmitter,'application/vnd.google-earth.kml+xml')
Emitter.register('kmz',KmzEmitter,'application/vnd.google-earth.kmz')
Emitter.register('geojson',GeoJsonEmitter,'text/plain; charset=utf-8')
Emitter.register('csv',CsvEmitter,'text/csv; charset=utf-8')
Emitter.register('kcsv',LinkedCsvEmitter,'application/zip; charset=utf-8')
Emitter.register('sqlite',SqliteEmitter,'application/zip; charset=utf-8')
Emitter.register('nc',NcEmitter,'application/x-netcdf; charset=utf-8')
Emitter.register('meta',MetacontentEmitter,'text/plain; charset=utf-8')<|endoftext|>


<commit_before>"""
Google OpenId, OAuth2, OAuth1, Google+ Sign-in backends, docs at:
    http://psa.matiasaguirre.net/docs/backends/google.html
"""
from ..utils import handle_http_errors
from .open_id import OpenIdAuth
from .oauth import BaseOAuth2, BaseOAuth1
from ..exceptions import AuthMissingParameter

class BaseGoogleAuth(object):
    def get_user_id(self, details, response):
        """Use google email as unique id"""
        if self.setting('USE_UNIQUE_USER_ID', False):
            return response['id']
        else:
            return details['email']

    def get_user_details(self, response):
        """Return user details from Google API account"""
        if 'email' in response:
            email = response['email']
        elif 'emails' in response:
            email = response['emails'][0]['value']
        else:
            email = ''

        if isinstance(response.get('name'), dict):
            names = response.get('name') or {}
            name, given_name, family_name = (
                response.get('displayName', ''),
                names.get('givenName', ''),
                names.get('familyName', '')
            )
        else:
            name, given_name, family_name = (
                response.get('name', ''),
                response.get('given_name', ''),
                response.get('family_name', '')
            )

        fullname, first_name, last_name = self.get_user_names(
            name, given_name, family_name
        )
        return {'username': email.split('@', 1)[0],
                'email': email,
                'fullname': fullname,
                'first_name': first_name,
                'last_name': last_name}

class BaseGoogleOAuth2API(BaseGoogleAuth):
    def user_data(self, access_token, *args, **kwargs):
        """Return user data from Google API"""
        return self.get_json(
            'https://www.googleapis.com/plus/v1/people/me',
            params={
                'access_token': access_token,
                'alt': 'json'
            }
        )

    def revoke_token_params(self, token, uid):
        return {'token': token}

    def revoke_token_headers(self, token, uid):
        return {'Content-type': 'application/json'}

class GoogleOAuth2(BaseGoogleOAuth2API, BaseOAuth2):
    """Google OAuth2 authentication backend"""
    name = 'google-oauth2'
    REDIRECT_STATE = False
    AUTHORIZATION_URL = 'https://accounts.google.com/o/oauth2/auth'
    ACCESS_TOKEN_URL = 'https://accounts.google.com/o/oauth2/token'
    ACCESS_TOKEN_METHOD = 'POST'
    REVOKE_TOKEN_URL = 'https://accounts.google.com/o/oauth2/revoke'
    REVOKE_TOKEN_METHOD = 'GET'
    # The order of the default scope is important
    DEFAULT_SCOPE = ['openid', 'email', 'profile']
    EXTRA_DATA = [
        ('refresh_token', 'refresh_token', True),
        ('expires_in', 'expires'),
        ('token_type', 'token_type', True)
    ]

class GooglePlusAuth(BaseGoogleOAuth2API, BaseOAuth2):
    name = 'google-plus'
    REDIRECT_STATE = False
    STATE_PARAMETER = False
    AUTHORIZATION_URL = 'https://accounts.google.com/o/oauth2/auth'
    ACCESS_TOKEN_URL = 'https://accounts.google.com/o/oauth2/token'
    ACCESS_TOKEN_METHOD = 'POST'
    REVOKE_TOKEN_URL = 'https://accounts.google.com/o/oauth2/revoke'
    REVOKE_TOKEN_METHOD = 'GET'
    DEFAULT_SCOPE = [
        'https://www.googleapis.com/auth/plus.login',
        'https://www.googleapis.com/auth/plus.me',
    ]
    EXTRA_DATA = [
        ('id', 'user_id'),
        ('refresh_token', 'refresh_token', True),
        ('expires_in', 'expires'),
        ('access_type', 'access_type', True),
        ('code', 'code')
    ]

    def auth_complete_params(self, state=None):
        params = super(GooglePlusAuth, self).auth_complete_params(state)
        if self.data.get('access_token'):
            # Don't add postmessage if this is plain server-side workflow
            params['redirect_uri'] = 'postmessage'
        return params

    @handle_http_errors
    def auth_complete(self, *args, **kwargs):
        if 'access_token' in self.data:  # Client-side workflow
            token = self.data.get('access_token')
            response = self.get_json(
                'https://www.googleapis.com/oauth2/v3/tokeninfo',
                params={'access_token': token}
            )
            self.process_error(response)
            return self.do_auth(token, response=response, *args, **kwargs)
        elif 'code' in self.data:  # Server-side workflow
            response = self.request_access_token(
                self.ACCESS_TOKEN_URL,
                data=self.auth_complete_params(),
                headers=self.auth_headers(),
                method=self.ACCESS_TOKEN_METHOD
            )
            self.process_error(response)
            return self.do_auth(response['access_token'],
                                response=response,
                                *args, **kwargs)
        else:
            raise AuthMissingParameter(self, 'access_token or code')

class GoogleOAuth(BaseGoogleAuth, BaseOAuth1):
    """Google OAuth authorization mechanism"""
    name = 'google-oauth'
    AUTHORIZATION_URL = 'https://www.google.com/accounts/OAuthAuthorizeToken'
    REQUEST_TOKEN_URL = 'https://www.google.com/accounts/OAuthGetRequestToken'
    ACCESS_TOKEN_URL = 'https://www.google.com/accounts/OAuthGetAccessToken'
    DEFAULT_SCOPE = ['https://www.googleapis.com/auth/userinfo#email']

    def user_data(self, access_token, *args, **kwargs):
        """Return user data from Google API"""
        return self.get_querystring(
            'https://www.googleapis.com/userinfo/email',
            auth=self.oauth_auth(access_token)
        )

    def get_key_and_secret(self):
        """Return Google OAuth Consumer Key and Consumer Secret pair, uses
        anonymous by default, beware that this marks the application as not
        registered and a security badge is displayed on authorization page.
        http://code.google.com/apis/accounts/docs/OAuth_ref.html#SigningOAuth
        """
        key_secret = super(GoogleOAuth, self).get_key_and_secret()
        if key_secret == (None, None):
            key_secret = ('anonymous', 'anonymous')
        return key_secret

class GoogleOpenId(OpenIdAuth):
    name = 'google'
    URL = 'https://www.google.com/accounts/o8/id'

    def get_user_id(self, details, response):
        """
        Return user unique id provided by service. For google user email
        is unique enought to flag a single user. Email comes from schema:
        http://axschema.org/contact/email
        """
        return details['email']
<commit_msg>access token info using id_token<commit_after>"""
Google OpenId, OAuth2, OAuth1, Google+ Sign-in backends, docs at:
    http://psa.matiasaguirre.net/docs/backends/google.html
"""
from ..utils import handle_http_errors
from .open_id import OpenIdAuth
from .oauth import BaseOAuth2, BaseOAuth1
from ..exceptions import AuthMissingParameter

class BaseGoogleAuth(object):
    def get_user_id(self, details, response):
        """Use google email as unique id"""
        if self.setting('USE_UNIQUE_USER_ID', False):
            return response['id']
        else:
            return details['email']

    def get_user_details(self, response):
        """Return user details from Google API account"""
        if 'email' in response:
            email = response['email']
        elif 'emails' in response:
            email = response['emails'][0]['value']
        else:
            email = ''

        if isinstance(response.get('name'), dict):
            names = response.get('name') or {}
            name, given_name, family_name = (
                response.get('displayName', ''),
                names.get('givenName', ''),
                names.get('familyName', '')
            )
        else:
            name, given_name, family_name = (
                response.get('name', ''),
                response.get('given_name', ''),
                response.get('family_name', '')
            )

        fullname, first_name, last_name = self.get_user_names(
            name, given_name, family_name
        )
        return {'username': email.split('@', 1)[0],
                'email': email,
                'fullname': fullname,
                'first_name': first_name,
                'last_name': last_name}

class BaseGoogleOAuth2API(BaseGoogleAuth):
    def user_data(self, access_token, *args, **kwargs):
        """Return user data from Google API"""
        return self.get_json(
            'https://www.googleapis.com/plus/v1/people/me',
            params={
                'access_token': access_token,
                'alt': 'json'
            }
        )

    def revoke_token_params(self, token, uid):
        return {'token': token}

    def revoke_token_headers(self, token, uid):
        return {'Content-type': 'application/json'}

class GoogleOAuth2(BaseGoogleOAuth2API, BaseOAuth2):
    """Google OAuth2 authentication backend"""
    name = 'google-oauth2'
    REDIRECT_STATE = False
    AUTHORIZATION_URL = 'https://accounts.google.com/o/oauth2/auth'
    ACCESS_TOKEN_URL = 'https://accounts.google.com/o/oauth2/token'
    ACCESS_TOKEN_METHOD = 'POST'
    REVOKE_TOKEN_URL = 'https://accounts.google.com/o/oauth2/revoke'
    REVOKE_TOKEN_METHOD = 'GET'
    # The order of the default scope is important
    DEFAULT_SCOPE = ['openid', 'email', 'profile']
    EXTRA_DATA = [
        ('refresh_token', 'refresh_token', True),
        ('expires_in', 'expires'),
        ('token_type', 'token_type', True)
    ]

class GooglePlusAuth(BaseGoogleOAuth2API, BaseOAuth2):
    name = 'google-plus'
    REDIRECT_STATE = False
    STATE_PARAMETER = False
    AUTHORIZATION_URL = 'https://accounts.google.com/o/oauth2/auth'
    ACCESS_TOKEN_URL = 'https://accounts.google.com/o/oauth2/token'
    ACCESS_TOKEN_METHOD = 'POST'
    REVOKE_TOKEN_URL = 'https://accounts.google.com/o/oauth2/revoke'
    REVOKE_TOKEN_METHOD = 'GET'
    DEFAULT_SCOPE = [
        'https://www.googleapis.com/auth/plus.login',
        'https://www.googleapis.com/auth/plus.me',
    ]
    EXTRA_DATA = [
        ('id', 'user_id'),
        ('refresh_token', 'refresh_token', True),
        ('expires_in', 'expires'),
        ('access_type', 'access_type', True),
        ('code', 'code')
    ]

    def auth_complete_params(self, state=None):
        params = super(GooglePlusAuth, self).auth_complete_params(state)
        if self.data.get('access_token'):
            # Don't add postmessage if this is plain server-side workflow
            params['redirect_uri'] = 'postmessage'
        return params

    @handle_http_errors
    def auth_complete(self, *args, **kwargs):
        if 'access_token' in self.data:  # Client-side workflow
            token = self.data.get('access_token')
            response = self.get_json(
                'https://www.googleapis.com/oauth2/v3/tokeninfo',
                params={'access_token': token}
            )
            self.process_error(response)
            return self.do_auth(token, response=response, *args, **kwargs)
        elif 'code' in self.data:  # Server-side workflow
            response = self.request_access_token(
                self.ACCESS_TOKEN_URL,
                data=self.auth_complete_params(),
                headers=self.auth_headers(),
                method=self.ACCESS_TOKEN_METHOD
            )
            self.process_error(response)
            return self.do_auth(response['access_token'],
                                response=response,
                                *args, **kwargs)
        elif 'id_token' in self.data: # Client-side workflow
            token = self.data.get('id_token')
            response = self.get_json(
                'https://www.googleapis.com/oauth2/v3/tokeninfo',
                params={'id_token': token}
            )
            self.process_error(response)
            return self.do_auth(token, response=response, *args, **kwargs)
	else:
            raise AuthMissingParameter(self, 'access_token or code')

class GoogleOAuth(BaseGoogleAuth, BaseOAuth1):
    """Google OAuth authorization mechanism"""
    name = 'google-oauth'
    AUTHORIZATION_URL = 'https://www.google.com/accounts/OAuthAuthorizeToken'
    REQUEST_TOKEN_URL = 'https://www.google.com/accounts/OAuthGetRequestToken'
    ACCESS_TOKEN_URL = 'https://www.google.com/accounts/OAuthGetAccessToken'
    DEFAULT_SCOPE = ['https://www.googleapis.com/auth/userinfo#email']

    def user_data(self, access_token, *args, **kwargs):
        """Return user data from Google API"""
        return self.get_querystring(
            'https://www.googleapis.com/userinfo/email',
            auth=self.oauth_auth(access_token)
        )

    def get_key_and_secret(self):
        """Return Google OAuth Consumer Key and Consumer Secret pair, uses
        anonymous by default, beware that this marks the application as not
        registered and a security badge is displayed on authorization page.
        http://code.google.com/apis/accounts/docs/OAuth_ref.html#SigningOAuth
        """
        key_secret = super(GoogleOAuth, self).get_key_and_secret()
        if key_secret == (None, None):
            key_secret = ('anonymous', 'anonymous')
        return key_secret

class GoogleOpenId(OpenIdAuth):
    name = 'google'
    URL = 'https://www.google.com/accounts/o8/id'

    def get_user_id(self, details, response):
        """
        Return user unique id provided by service. For google user email
        is unique enought to flag a single user. Email comes from schema:
        http://axschema.org/contact/email
        """
        return details['email']
<|endoftext|>


<commit_before># -*- coding: utf-8 -*-
"""Release data for the IPython project."""

#-----------------------------------------------------------------------------
#  Copyright (c) 2008, IPython Development Team.
#  Copyright (c) 2001, Fernando Perez <fernando.perez@colorado.edu>
#  Copyright (c) 2001, Janko Hauser <jhauser@zscout.de>
#  Copyright (c) 2001, Nathaniel Gray <n8gray@caltech.edu>
#
#  Distributed under the terms of the Modified BSD License.
#
#  The full license is in the file COPYING.txt, distributed with this software.
#-----------------------------------------------------------------------------

# Name of the package for release purposes.  This is the name which labels
# the tarballs and RPMs made by distutils, so it's best to lowercase it.
name = 'ipython'

# IPython version information.  An empty _version_extra corresponds to a full
# release.  'dev' as a _version_extra string means this is a development
# version
_version_major = 0
_version_minor = 13
_version_micro = ''  # use '' for first of series, number for 1 and above
#_version_extra = 'dev'
#_version_extra = 'rc1'
_version_extra = ''  # Uncomment this for full releases

# Construct full version string from these.
_ver = [_version_major, _version_minor]
if _version_micro:
    _ver.append(_version_micro)
if _version_extra:
    _ver.append(_version_extra)

__version__ = '.'.join(map(str, _ver))

version = __version__  # backwards compatibility name

description = "IPython: Productive Interactive Computing"

long_description = \
"""
IPython provides a rich toolkit to help you make the most out of using Python
interactively.  Its main components are:

* Powerful interactive Python shells (terminal- and Qt-based).
* A web-based interactive notebook environment with all shell features plus
  support for embedded figures, animations and rich media.
* Support for interactive data visualization and use of GUI toolkits.
* Flexible, embeddable interpreters to load into your own projects.
* A high-performance library for high level and interactive parallel computing
  that works in multicore systems, clusters, supercomputing and cloud scenarios.

The enhanced interactive Python shells have the following main features:

* Comprehensive object introspection.

* Input history, persistent across sessions.

* Caching of output results during a session with automatically generated
  references.

* Extensible tab completion, with support by default for completion of python
  variables and keywords, filenames and function keywords.

* Extensible system of 'magic' commands for controlling the environment and
  performing many tasks related either to IPython or the operating system.

* A rich configuration system with easy switching between different setups
  (simpler than changing $PYTHONSTARTUP environment variables every time).

* Session logging and reloading.

* Extensible syntax processing for special purpose situations.

* Access to the system shell with user-extensible alias system.

* Easily embeddable in other Python programs and GUIs.

* Integrated access to the pdb debugger and the Python profiler.

The parallel computing architecture has the following main features:

* Quickly parallelize Python code from an interactive Python/IPython session.

* A flexible and dynamic process model that be deployed on anything from
  multicore workstations to supercomputers.

* An architecture that supports many different styles of parallelism, from
  message passing to task farming.

* Both blocking and fully asynchronous interfaces.

* High level APIs that enable many things to be parallelized in a few lines
  of code.

* Share live parallel jobs with other users securely.

* Dynamically load balanced task farming system.

* Robust error handling in parallel code.

The latest development version is always available from IPython's `GitHub
site <http://github.com/ipython>`_.
"""

license = 'BSD'

authors = {'Fernando' : ('Fernando Perez','fperez.net@gmail.com'),
           'Janko'    : ('Janko Hauser','jhauser@zscout.de'),
           'Nathan'   : ('Nathaniel Gray','n8gray@caltech.edu'),
           'Ville'    : ('Ville Vainio','vivainio@gmail.com'),
           'Brian'    : ('Brian E Granger', 'ellisonbg@gmail.com'),
           'Min'      : ('Min Ragan-Kelley', 'benjaminrk@gmail.com'),
           'Thomas'   : ('Thomas A. Kluyver', 'takowl@gmail.com'),
           'Jörgen'   : ('Jörgen Stenarson', 'jorgen.stenarson@bostream.nu'),
           'Matthias' : ('Matthias Bussonnier', 'bussonniermatthias@gmail.com'),
           }

author = 'The IPython Development Team'

author_email = 'ipython-dev@scipy.org'

url = 'http://ipython.org'

# This will only be valid for actual releases sent to PyPI, but that's OK since
# those are the ones we want pip/easy_install to be able to find.
download_url = 'http://archive.ipython.org/release/%s' % version

platforms = ['Linux','Mac OSX','Windows XP/2000/NT/Vista/7']

keywords = ['Interactive','Interpreter','Shell','Parallel','Distributed',
            'Web-based computing', 'Qt console', 'Embedding']

classifiers = [
    'Intended Audience :: Developers',
    'Intended Audience :: Science/Research',
    'License :: OSI Approved :: BSD License',
    'Programming Language :: Python',
    'Programming Language :: Python :: 2',
    'Programming Language :: Python :: 2.6',
    'Programming Language :: Python :: 2.7',
    'Programming Language :: Python :: 3',
    'Programming Language :: Python :: 3.1',
    'Programming Language :: Python :: 3.2',
    'Topic :: System :: Distributed Computing',
    'Topic :: System :: Shells'
    ]
<commit_msg>use github for download url<commit_after># -*- coding: utf-8 -*-
"""Release data for the IPython project."""

#-----------------------------------------------------------------------------
#  Copyright (c) 2008, IPython Development Team.
#  Copyright (c) 2001, Fernando Perez <fernando.perez@colorado.edu>
#  Copyright (c) 2001, Janko Hauser <jhauser@zscout.de>
#  Copyright (c) 2001, Nathaniel Gray <n8gray@caltech.edu>
#
#  Distributed under the terms of the Modified BSD License.
#
#  The full license is in the file COPYING.txt, distributed with this software.
#-----------------------------------------------------------------------------

# Name of the package for release purposes.  This is the name which labels
# the tarballs and RPMs made by distutils, so it's best to lowercase it.
name = 'ipython'

# IPython version information.  An empty _version_extra corresponds to a full
# release.  'dev' as a _version_extra string means this is a development
# version
_version_major = 0
_version_minor = 13
_version_micro = ''  # use '' for first of series, number for 1 and above
#_version_extra = 'dev'
#_version_extra = 'rc1'
_version_extra = ''  # Uncomment this for full releases

# Construct full version string from these.
_ver = [_version_major, _version_minor]
if _version_micro:
    _ver.append(_version_micro)
if _version_extra:
    _ver.append(_version_extra)

__version__ = '.'.join(map(str, _ver))

version = __version__  # backwards compatibility name

description = "IPython: Productive Interactive Computing"

long_description = \
"""
IPython provides a rich toolkit to help you make the most out of using Python
interactively.  Its main components are:

* Powerful interactive Python shells (terminal- and Qt-based).
* A web-based interactive notebook environment with all shell features plus
  support for embedded figures, animations and rich media.
* Support for interactive data visualization and use of GUI toolkits.
* Flexible, embeddable interpreters to load into your own projects.
* A high-performance library for high level and interactive parallel computing
  that works in multicore systems, clusters, supercomputing and cloud scenarios.

The enhanced interactive Python shells have the following main features:

* Comprehensive object introspection.

* Input history, persistent across sessions.

* Caching of output results during a session with automatically generated
  references.

* Extensible tab completion, with support by default for completion of python
  variables and keywords, filenames and function keywords.

* Extensible system of 'magic' commands for controlling the environment and
  performing many tasks related either to IPython or the operating system.

* A rich configuration system with easy switching between different setups
  (simpler than changing $PYTHONSTARTUP environment variables every time).

* Session logging and reloading.

* Extensible syntax processing for special purpose situations.

* Access to the system shell with user-extensible alias system.

* Easily embeddable in other Python programs and GUIs.

* Integrated access to the pdb debugger and the Python profiler.

The parallel computing architecture has the following main features:

* Quickly parallelize Python code from an interactive Python/IPython session.

* A flexible and dynamic process model that be deployed on anything from
  multicore workstations to supercomputers.

* An architecture that supports many different styles of parallelism, from
  message passing to task farming.

* Both blocking and fully asynchronous interfaces.

* High level APIs that enable many things to be parallelized in a few lines
  of code.

* Share live parallel jobs with other users securely.

* Dynamically load balanced task farming system.

* Robust error handling in parallel code.

The latest development version is always available from IPython's `GitHub
site <http://github.com/ipython>`_.
"""

license = 'BSD'

authors = {'Fernando' : ('Fernando Perez','fperez.net@gmail.com'),
           'Janko'    : ('Janko Hauser','jhauser@zscout.de'),
           'Nathan'   : ('Nathaniel Gray','n8gray@caltech.edu'),
           'Ville'    : ('Ville Vainio','vivainio@gmail.com'),
           'Brian'    : ('Brian E Granger', 'ellisonbg@gmail.com'),
           'Min'      : ('Min Ragan-Kelley', 'benjaminrk@gmail.com'),
           'Thomas'   : ('Thomas A. Kluyver', 'takowl@gmail.com'),
           'Jörgen'   : ('Jörgen Stenarson', 'jorgen.stenarson@bostream.nu'),
           'Matthias' : ('Matthias Bussonnier', 'bussonniermatthias@gmail.com'),
           }

author = 'The IPython Development Team'

author_email = 'ipython-dev@scipy.org'

url = 'http://ipython.org'

download_url = 'https://github.com/ipython/ipython/downloads'

platforms = ['Linux','Mac OSX','Windows XP/2000/NT/Vista/7']

keywords = ['Interactive','Interpreter','Shell','Parallel','Distributed',
            'Web-based computing', 'Qt console', 'Embedding']

classifiers = [
    'Intended Audience :: Developers',
    'Intended Audience :: Science/Research',
    'License :: OSI Approved :: BSD License',
    'Programming Language :: Python',
    'Programming Language :: Python :: 2',
    'Programming Language :: Python :: 2.6',
    'Programming Language :: Python :: 2.7',
    'Programming Language :: Python :: 3',
    'Programming Language :: Python :: 3.1',
    'Programming Language :: Python :: 3.2',
    'Topic :: System :: Distributed Computing',
    'Topic :: System :: Shells'
    ]
<|endoftext|>


<commit_before># -*- coding: utf-8 -*-
"""Release data for the IPython project."""

#-----------------------------------------------------------------------------
#  Copyright (c) 2008, IPython Development Team.
#  Copyright (c) 2001, Fernando Perez <fernando.perez@colorado.edu>
#  Copyright (c) 2001, Janko Hauser <jhauser@zscout.de>
#  Copyright (c) 2001, Nathaniel Gray <n8gray@caltech.edu>
#
#  Distributed under the terms of the Modified BSD License.
#
#  The full license is in the file COPYING.txt, distributed with this software.
#-----------------------------------------------------------------------------

# Name of the package for release purposes.  This is the name which labels
# the tarballs and RPMs made by distutils, so it's best to lowercase it.
name = 'ipython'

# IPython version information.  An empty _version_extra corresponds to a full
# release.  'dev' as a _version_extra string means this is a development
# version
_version_major = 7
_version_minor = 0
_version_patch = 0
_version_extra = '.dev'
_version_extra = 'rc1'
# _version_extra = ''  # Uncomment this for full releases

# Construct full version string from these.
_ver = [_version_major, _version_minor, _version_patch]

__version__ = '.'.join(map(str, _ver))
if _version_extra:
    __version__ = __version__  + _version_extra

version = __version__  # backwards compatibility name
version_info = (_version_major, _version_minor, _version_patch, _version_extra)

# Change this when incrementing the kernel protocol version
kernel_protocol_version_info = (5, 0)
kernel_protocol_version = "%i.%i" % kernel_protocol_version_info

description = "IPython: Productive Interactive Computing"

long_description = \
"""
IPython provides a rich toolkit to help you make the most out of using Python
interactively.  Its main components are:

* A powerful interactive Python shell
* A `Jupyter <https://jupyter.org/>`_ kernel to work with Python code in Jupyter
  notebooks and other interactive frontends.

The enhanced interactive Python shells have the following main features:

* Comprehensive object introspection.

* Input history, persistent across sessions.

* Caching of output results during a session with automatically generated
  references.

* Extensible tab completion, with support by default for completion of python
  variables and keywords, filenames and function keywords.

* Extensible system of 'magic' commands for controlling the environment and
  performing many tasks related either to IPython or the operating system.

* A rich configuration system with easy switching between different setups
  (simpler than changing $PYTHONSTARTUP environment variables every time).

* Session logging and reloading.

* Extensible syntax processing for special purpose situations.

* Access to the system shell with user-extensible alias system.

* Easily embeddable in other Python programs and GUIs.

* Integrated access to the pdb debugger and the Python profiler.

The latest development version is always available from IPython's `GitHub
site <http://github.com/ipython>`_.
"""

license = 'BSD'

authors = {'Fernando' : ('Fernando Perez','fperez.net@gmail.com'),
           'Janko'    : ('Janko Hauser','jhauser@zscout.de'),
           'Nathan'   : ('Nathaniel Gray','n8gray@caltech.edu'),
           'Ville'    : ('Ville Vainio','vivainio@gmail.com'),
           'Brian'    : ('Brian E Granger', 'ellisonbg@gmail.com'),
           'Min'      : ('Min Ragan-Kelley', 'benjaminrk@gmail.com'),
           'Thomas'   : ('Thomas A. Kluyver', 'takowl@gmail.com'),
           'Jorgen'   : ('Jorgen Stenarson', 'jorgen.stenarson@bostream.nu'),
           'Matthias' : ('Matthias Bussonnier', 'bussonniermatthias@gmail.com'),
           }

author = 'The IPython Development Team'

author_email = 'ipython-dev@python.org'

url = 'https://ipython.org'

platforms = ['Linux','Mac OSX','Windows']

keywords = ['Interactive','Interpreter','Shell', 'Embedding']

classifiers = [
    'Framework :: IPython',
    'Intended Audience :: Developers',
    'Intended Audience :: Science/Research',
    'License :: OSI Approved :: BSD License',
    'Programming Language :: Python',
    'Programming Language :: Python :: 3',
    'Programming Language :: Python :: 3 :: Only',
    'Topic :: System :: Shells'
    ]
<commit_msg>back to development<commit_after># -*- coding: utf-8 -*-
"""Release data for the IPython project."""

#-----------------------------------------------------------------------------
#  Copyright (c) 2008, IPython Development Team.
#  Copyright (c) 2001, Fernando Perez <fernando.perez@colorado.edu>
#  Copyright (c) 2001, Janko Hauser <jhauser@zscout.de>
#  Copyright (c) 2001, Nathaniel Gray <n8gray@caltech.edu>
#
#  Distributed under the terms of the Modified BSD License.
#
#  The full license is in the file COPYING.txt, distributed with this software.
#-----------------------------------------------------------------------------

# Name of the package for release purposes.  This is the name which labels
# the tarballs and RPMs made by distutils, so it's best to lowercase it.
name = 'ipython'

# IPython version information.  An empty _version_extra corresponds to a full
# release.  'dev' as a _version_extra string means this is a development
# version
_version_major = 7
_version_minor = 0
_version_patch = 0
_version_extra = '.dev'
# _version_extra = 'b1'
# _version_extra = ''  # Uncomment this for full releases

# Construct full version string from these.
_ver = [_version_major, _version_minor, _version_patch]

__version__ = '.'.join(map(str, _ver))
if _version_extra:
    __version__ = __version__  + _version_extra

version = __version__  # backwards compatibility name
version_info = (_version_major, _version_minor, _version_patch, _version_extra)

# Change this when incrementing the kernel protocol version
kernel_protocol_version_info = (5, 0)
kernel_protocol_version = "%i.%i" % kernel_protocol_version_info

description = "IPython: Productive Interactive Computing"

long_description = \
"""
IPython provides a rich toolkit to help you make the most out of using Python
interactively.  Its main components are:

* A powerful interactive Python shell
* A `Jupyter <https://jupyter.org/>`_ kernel to work with Python code in Jupyter
  notebooks and other interactive frontends.

The enhanced interactive Python shells have the following main features:

* Comprehensive object introspection.

* Input history, persistent across sessions.

* Caching of output results during a session with automatically generated
  references.

* Extensible tab completion, with support by default for completion of python
  variables and keywords, filenames and function keywords.

* Extensible system of 'magic' commands for controlling the environment and
  performing many tasks related either to IPython or the operating system.

* A rich configuration system with easy switching between different setups
  (simpler than changing $PYTHONSTARTUP environment variables every time).

* Session logging and reloading.

* Extensible syntax processing for special purpose situations.

* Access to the system shell with user-extensible alias system.

* Easily embeddable in other Python programs and GUIs.

* Integrated access to the pdb debugger and the Python profiler.

The latest development version is always available from IPython's `GitHub
site <http://github.com/ipython>`_.
"""

license = 'BSD'

authors = {'Fernando' : ('Fernando Perez','fperez.net@gmail.com'),
           'Janko'    : ('Janko Hauser','jhauser@zscout.de'),
           'Nathan'   : ('Nathaniel Gray','n8gray@caltech.edu'),
           'Ville'    : ('Ville Vainio','vivainio@gmail.com'),
           'Brian'    : ('Brian E Granger', 'ellisonbg@gmail.com'),
           'Min'      : ('Min Ragan-Kelley', 'benjaminrk@gmail.com'),
           'Thomas'   : ('Thomas A. Kluyver', 'takowl@gmail.com'),
           'Jorgen'   : ('Jorgen Stenarson', 'jorgen.stenarson@bostream.nu'),
           'Matthias' : ('Matthias Bussonnier', 'bussonniermatthias@gmail.com'),
           }

author = 'The IPython Development Team'

author_email = 'ipython-dev@python.org'

url = 'https://ipython.org'

platforms = ['Linux','Mac OSX','Windows']

keywords = ['Interactive','Interpreter','Shell', 'Embedding']

classifiers = [
    'Framework :: IPython',
    'Intended Audience :: Developers',
    'Intended Audience :: Science/Research',
    'License :: OSI Approved :: BSD License',
    'Programming Language :: Python',
    'Programming Language :: Python :: 3',
    'Programming Language :: Python :: 3 :: Only',
    'Topic :: System :: Shells'
    ]
<|endoftext|>


<commit_before>from bitmessage_communication.bitmessageclient import BitmessageClient

from oracle_protocol import PROTOCOL_ORACLE_IDENTITY

class OracleCommunication:

  def __init__(self):
    self.client = BitmessageClient()

    # Do we really need it here?
    self.default_address = self.client.default_address

  def broadcast_identity(self):
    subject = PROTOCOL_ORACLE_IDENTITY

    # TODO - what should we add to Identity Broadcast? Maybe public key for verifications?
    # or maybe list of known other oracles?
    message = PROTOCOL_ORACLE_IDENTITY
    self.client.send_broadcast(subject, message)
<commit_msg>why is oracle_communication needed<commit_after># File responsible for sending messages according to protocol

from bitmessage_communication.bitmessageclient import BitmessageClient

from oracle_protocol import PROTOCOL_ORACLE_IDENTITY

class OracleCommunication:

  def __init__(self):
    self.client = BitmessageClient()

    # Do we really need it here?
    self.default_address = self.client.default_address

  def broadcast_identity(self):
    subject = PROTOCOL_ORACLE_IDENTITY

    # TODO - what should we add to Identity Broadcast? Maybe public key for verifications?
    # or maybe list of known other oracles?
    message = PROTOCOL_ORACLE_IDENTITY
    self.client.send_broadcast(subject, message)
<|endoftext|>


<commit_before># Human perceptual average distance to horizon on Earth, in miles; this is
# taken as the unit size of a tile. To provide some reference, a small town of
# 3000 people can easily fit in 2 square miles (that's about 1300 residential
# buildings). So a single tile will provide pleny of space for a small town.
#
# On the other extreme, a large city can be in the neighborhood of 500 square
# miles (e.g., New York City) with a population density of 28,000 people per
# square mile (which would be 84000 people per tile). A city the size of NYC
# would require about 150 tiles, a grid of 10 by 15 tiles.
horizonDistance = 3.1
<commit_msg>Added comments about increases in the order of magnitude for tile grids. Comment now covers town, city, state, continent, and world sizes (each an order of magnitude larger than the previous one).<commit_after># Human perceptual average distance to horizon on Earth, in miles; this is
# taken as the unit size of a tile. To provide some reference, a small town of
# 3000 people can easily fit in 2 square miles (that's about 1300 residential
# buildings). So a single tile of 3.1 miles x 3.1 miles will provide plenty of
# space for a small town.
#
# A large city can be in the neighborhood of 500 square miles (e.g., New York
# City) with a population density of 28,000 people per square mile (which would
# be 84000 people per tile). A city the size of NYC would require about 150
# tiles, a grid of 10 by 15 tiles.
#
# The next step up in order of magnitude, 100 by 100 tiles, would be about the
# size of the state of Michigan (the 11th largest state in the US).
#
# As a further extreme, a continent the size of North America (about 3 times
# larger than the surface area of Australia) would be 1000 by 1000 tiles.

# And finally, the Earth itself has a total of 316944047 square miles (land and
# sea) which would be about 102240015 tiles, or a grid of 10002 by 10222 tiles.
horizonDistance = 3.1
<|endoftext|>


<commit_before>"""
This class is an amalgamation of tiles, edges and vertices to represent the board. Don't ask how it works,
no one knows.
"""

# local imports
from Implementation import Tile
from Implementation import Edge
from Implementation import Vertex

class Board:

    def __init__(self):
        self.tile_array = [
            [Tile.Tile() for _ in range(3)],
            [Tile.Tile() for _ in range(4)],
            [Tile.Tile() for _ in range(5)],
            [Tile.Tile() for _ in range(4)],
            [Tile.Tile() for _ in range(3)],
        ]

        self.connect_tiles()
        self.add_edges_and_vertices()

    def connect_tiles(self):
        for i, row in self.tile_array:
            for j, tile in row:
                if i <= 1:
                    # check if vaild coordinate
                    if self.is_valid_coordinate(i, j+1):
                        # connect tile to neighbor at 90degrees and connect neighbor back
                        tile.t2 = self.tile_array[i][j+1]
                        self.tile_array[i][j+1].t5 = tile
                    # connect tile to neigher at 150degree and connect neighbor back
                    tile.t3 = self.tile_array[i+1][j+1]
                    self.tile_array[i+1][j+1].t6 = tile
                    # connect tile to neighbor at 210degree and connect neighbor back
                    tile.t4 = self.tile_array[i+1][j]
                    self.tile_array[i+1][j].t1 = tile
                if i == 2:
                    # check if valid coordinate
                    if self.is_valid_coordinate(i, j+1):
                        # connect tile at 90degree and connect neighbor back
                        tile.t2 = self.tile_array[i][j+1]
                        self.tile_array[i][j+1].t5 = tile
                if i > 2:
                    # connect neighbor at -30degrees and connect neighbor back
                    tile.t6 = self.tile_array[i-1][j]
                    self.tile_array[i-1][j].t3 = tile
                    # connect neighbor at 30degrees and connect neighbor back
                    tile.t1 = self.tile_array[i-1][j+1]
                    self.tile_array[i-1][j+1].t4 = tile
                    # check if valid coordinate
                    if self.is_valid_coordinate(i, j+1):
                        # connect neighbor at 90 degrees and connect neighbor back
                        tile.t2 = self.tile_array[i][j+1]
                        self.tile_array[i][j+1].t5 = tile

    def add_edges_and_vertices(self):
        """
        Either pure gold or pure garbage. Not sure yet.
        Need to figure out how to set edge's tiles and vertex's tile, but this needs to sit
        for a day for me to think about my first statement.
        """
        for row in self.tile_array:
            for tile in row:
                for index, edge in tile.edge_arr:
                    # initialize edge and vertex attached to current tile
                    edge = Edge.Edge()
                    new_vertex = tile.vertex_arr[index % 6] = Vertex.Vertex()
                    # attach tile to vertex
                    new_vertex.t1 = tile
                    if tile.tile_arr[index] is not None:
                        # for one neighbor (border tiles) attach vertex to neighbor and vice versa
                        tile.tile_arr[index].vertex_arr[(index + 3) % 6] = new_vertex
                        new_vertex.t2 = tile.tile_arr[index]
                        # attach edge to adjacent tile
                        tile.tile_arr[index].edge_arr[(index + 3) % 6] = edge
                        if tile.tile_arr[index-1] is not None:
                            # for two neighbors (center tiles) do the same again for vertices
                            tile.tile_arr[index-1].vertex_arr[(index + 2) % 6] = new_vertex
                            new_vertex.t3 = tile.tile_arr[index-1]

    def is_valid_coordinate(self, x, y):
        try:
            self.tile_array[x][y]
            return True
        except IndexError:
            return False
<commit_msg>Added changes I added last night and forgot to push.<commit_after>"""
This class is an amalgamation of tiles, edges and vertices to represent the board. Don't ask how it works,
no one knows.
"""

# local imports
from Implementation import Tile
from Implementation import Edge
from Implementation import Vertex

class Board:

    def __init__(self):
        self.tile_array = [
            [Tile.Tile() for _ in range(3)],
            [Tile.Tile() for _ in range(4)],
            [Tile.Tile() for _ in range(5)],
            [Tile.Tile() for _ in range(4)],
            [Tile.Tile() for _ in range(3)],
        ]

        self.connect_tiles()
        self.add_edges_and_vertices()

    def connect_tiles(self):
        for i, row in self.tile_array:
            for j, tile in row:
                if i <= 1:
                    # check if vaild coordinate
                    if self.is_valid_coordinate(i, j+1):
                        # connect tile to neighbor at 90degrees and connect neighbor back
                        tile.t2 = self.tile_array[i][j+1]
                        self.tile_array[i][j+1].t5 = tile
                    # connect tile to neigher at 150degree and connect neighbor back
                    tile.t3 = self.tile_array[i+1][j+1]
                    self.tile_array[i+1][j+1].t6 = tile
                    # connect tile to neighbor at 210degree and connect neighbor back
                    tile.t4 = self.tile_array[i+1][j]
                    self.tile_array[i+1][j].t1 = tile
                if i == 2:
                    # check if valid coordinate
                    if self.is_valid_coordinate(i, j+1):
                        # connect tile at 90degree and connect neighbor back
                        tile.t2 = self.tile_array[i][j+1]
                        self.tile_array[i][j+1].t5 = tile
                if i > 2:
                    # connect neighbor at -30degrees and connect neighbor back
                    tile.t6 = self.tile_array[i-1][j]
                    self.tile_array[i-1][j].t3 = tile
                    # connect neighbor at 30degrees and connect neighbor back
                    tile.t1 = self.tile_array[i-1][j+1]
                    self.tile_array[i-1][j+1].t4 = tile
                    # check if valid coordinate
                    if self.is_valid_coordinate(i, j+1):
                        # connect neighbor at 90 degrees and connect neighbor back
                        tile.t2 = self.tile_array[i][j+1]
                        self.tile_array[i][j+1].t5 = tile

    def add_edges_and_vertices(self):
        """
        Either pure gold or pure garbage. Not sure yet.
        Need to figure out how to set edge's tiles and vertex's tile, but this needs to sit
        for a day for me to think about my first statement.
        Instead of creating the edge first, instead grab the pointers together in an array as
        a batch, then iterate through array to initialize the pointers as a group to a single edge.
        e.g. if edge @ index in tile.edge_arr is nil, grab edge pointer at index of tile.edge_arr
        and place in temp_edge_arr
        Then grab the other corresponding edges of corresponding tiles in tile.tile_arr and use logic
        to iterate through temp_edge_arr and link to newly constructed edge.
        I didn't wanna modify the code yet seeing as I've yet to practice more with Python, and I'd
        like you to walk me through the logic of this code when you get a chance before making any
        modifications and possibly derping it up.
        """
        for row in self.tile_array:
            for tile in row:
                for index, edge in tile.edge_arr:
                    # initialize edge and vertex attached to current tile
                    edge = Edge.Edge()
                    new_vertex = tile.vertex_arr[index % 6] = Vertex.Vertex()
                    # attach tile to vertex
                    new_vertex.t1 = tile
                    if tile.tile_arr[index] is not None:
                        # for one neighbor (border tiles) attach vertex to neighbor and vice versa
                        tile.tile_arr[index].vertex_arr[(index + 3) % 6] = new_vertex
                        new_vertex.t2 = tile.tile_arr[index]
                        # attach edge to adjacent tile
                        tile.tile_arr[index].edge_arr[(index + 3) % 6] = edge
                        if tile.tile_arr[index-1] is not None:
                            # for two neighbors (center tiles) do the same again for vertices
                            tile.tile_arr[index-1].vertex_arr[(index + 2) % 6] = new_vertex
                            new_vertex.t3 = tile.tile_arr[index-1]

    def is_valid_coordinate(self, x, y):
        try:
            self.tile_array[x][y]
            return True
        except IndexError:
            return False
<|endoftext|>


<commit_before>Version = "1.8.5.24"
<commit_msg>update to 1.8.5.25<commit_after>Version = "1.8.5.25"
<|endoftext|>


<commit_before>"""
Tests for L{ikdisplay.twitter}.
"""

from twisted.trial import unittest
from ikdisplay import twitter

class TestExtractImage(unittest.TestCase):

    def _testExtractImage(self, inurl, outurl):
        d = twitter.extractImage(inurl)
        d.addCallback(lambda result: self.assertEquals(outurl, result))
        return d

    def testTwitpic(self):
        return self._testExtractImage("http://twitpic.com/3dhy78", "http://twitpic.com/show/large/3dhy78")

    def testMobyPictureFull(self):
        return self._testExtractImage("http://www.mobypicture.com/user/marjolijn/view/90053", "http://img.mobypicture.com/5bd603ae84e09ac10ce15b98f4dd5e7f_full.jpg")

    def testMobyPictureShort(self):
        return self._testExtractImage("http://moby.to/1234", "http://img.mobypicture.com/5d84733aa1dd84f9bb0da21e2413acfa_full.jpg")

    def testFlickr(self):
        return self._testExtractImage("http://www.flickr.com/photos/bees/2341623661/", "http://farm4.static.flickr.com/3123/2341623661_7c99f48bbf.jpg")

    def testYFrog(self):
        return self._testExtractImage("http://yfrog.com/c9vd30j", "http://img441.yfrog.com/img441/3194/vd30.jpg")

    def testImgur(self):
        return self._testExtractImage("http://imgur.com/hPa9B", "http://imgur.com/hPa9B.jpg")

    def testTinypic(self):
        return self._testExtractImage("http://i56.tinypic.com/zoc3o0.jpg", "http://i56.tinypic.com/zoc3o0.jpg")

    def testUnsupported(self):
        return self._testExtractImage("http://some.unsupported/url", None)
<commit_msg>Fix mobypicture tests for changed static URL.<commit_after>"""
Tests for L{ikdisplay.twitter}.
"""

from twisted.trial import unittest
from ikdisplay import twitter

class TestExtractImage(unittest.TestCase):

    def _testExtractImage(self, inurl, outurl):
        d = twitter.extractImage(inurl)
        d.addCallback(lambda result: self.assertEquals(outurl, result))
        return d

    def testTwitpic(self):
        return self._testExtractImage("http://twitpic.com/3dhy78", "http://twitpic.com/show/large/3dhy78")

    def testMobyPictureFull(self):
        return self._testExtractImage("http://www.mobypicture.com/user/marjolijn/view/90053", "http://a3.img.mobypicture.com/5bd603ae84e09ac10ce15b98f4dd5e7f_full.jpg")

    def testMobyPictureShort(self):
        return self._testExtractImage("http://moby.to/1234", "http://a1.img.mobypicture.com/5d84733aa1dd84f9bb0da21e2413acfa_full.jpg")

    def testFlickr(self):
        return self._testExtractImage("http://www.flickr.com/photos/bees/2341623661/", "http://farm4.static.flickr.com/3123/2341623661_7c99f48bbf.jpg")

    def testYFrog(self):
        return self._testExtractImage("http://yfrog.com/c9vd30j", "http://img441.yfrog.com/img441/3194/vd30.jpg")

    def testImgur(self):
        return self._testExtractImage("http://imgur.com/hPa9B", "http://imgur.com/hPa9B.jpg")

    def testTinypic(self):
        return self._testExtractImage("http://i56.tinypic.com/zoc3o0.jpg", "http://i56.tinypic.com/zoc3o0.jpg")

    def testUnsupported(self):
        return self._testExtractImage("http://some.unsupported/url", None)
<|endoftext|>


<commit_before>Version = "1.7.6.2"
<commit_msg>Update to 1.7.7<commit_after>Version = "1.7.7"
<|endoftext|>


<commit_before>Version = "1.8.5.31"
<commit_msg>update to 1.8.5.32<commit_after>Version = "1.8.5.32"
<|endoftext|>


<commit_before>from collections import OrderedDict
import ast

class AstGrapher(object):
    """
    Enhanced visitor that provides parent node mapping and
    keeps track of what Load Varialbes and the line they appear on.

    Note that line refers to the parsed expression/statement found in
    `module.body` and not the source text line.

    self.load_names is keyed by the actual ast.AST. It contains all the
    Name(ctx=Load) found in that line.
    """

    def __init__(self, code):
        self.graph = {}

        if isinstance(code, str):
            code = ast.parse(code)
        self.code = code
        self._processed = False

    def process(self):
        if self._processed:
            raise Exception('Grapher has already processed code')
        self.visit(self.code)
        self._processed = True

    def visit(self, node):
        method = 'visit_' + node.__class__.__name__
        visitor = getattr(self, method, self.generic_visit)
        return visitor(node)

    def generic_visit(self, node):
        for field_name, field in ast.iter_fields(node):
            if isinstance(field, list):
                for i, item in enumerate(field):
                    self.handle_item(node, item, field_name, i)
                continue

            # need to flatten so we don't have special processing
            # for lists vs single values
            item = field
            self.handle_item(node, item, field_name)

    def handle_item(self, parent, node, field_name, i=None):
        """ insert node => (parent, field_name, i) into graph"""
        if not isinstance(node, ast.AST):
            return

        self.graph[node] = ((parent, field_name, i))
        self.visit(node)

    def parent(self, node):
        return self.graph[node]

def is_load_name(node):
    if not isinstance(node, ast.Name):
        return False

    if isinstance(node.ctx, ast.Load):
        return True

class GatherGrapher(AstGrapher):
    """
    Adds the ability to gather nodes based on a certian condition.
    """

    def __init__(self, *args, **kwargs):
        self.gather_check = kwargs.pop('gather_check', is_load_name)
        self.gather_nodes = {}
        self.line = None

        super().__init__(*args, **kwargs)

    def visit_Module(self, node):
        body = node.body
        for line in node.body:
            self.line = line
            self.generic_visit(line)

    def visit(self, node):
        # check for load name. vars that grab from context
        if self.gather_check(node):
            self.gather_nodes.setdefault(self.line, []).append(node)
        super().visit(node)
<commit_msg>Track depth of nodes<commit_after>from collections import OrderedDict
import ast

class AstGrapher(object):
    """
    Enhanced visitor that provides parent node mapping and
    keeps track of what Load Varialbes and the line they appear on.

    Note that line refers to the parsed expression/statement found in
    `module.body` and not the source text line.

    self.load_names is keyed by the actual ast.AST. It contains all the
    Name(ctx=Load) found in that line.
    """

    def __init__(self, code):
        self.graph = {}
        self.depth = {}
        # 0 based depth
        self.current_depth = -1

        if isinstance(code, str):
            code = ast.parse(code)
        self.code = code
        self._processed = False

    def process(self):
        if self._processed:
            raise Exception('Grapher has already processed code')
        self.visit(self.code)
        self._processed = True

    def visit(self, node):
        method = 'visit_' + node.__class__.__name__
        visitor = getattr(self, method, self.generic_visit)
        return visitor(node)

    def generic_visit(self, node):
        self.current_depth += 1
        for field_name, field in ast.iter_fields(node):
            if isinstance(field, list):
                for i, item in enumerate(field):
                    self.handle_item(node, item, field_name, i)
                continue

            # need to flatten so we don't have special processing
            # for lists vs single values
            item = field
            self.handle_item(node, item, field_name)
        self.current_depth -= 1

    def handle_item(self, parent, node, field_name, i=None):
        """ insert node => (parent, field_name, i) into graph"""
        if not isinstance(node, ast.AST):
            return

        self.graph[node] = ((parent, field_name, i))
        self.depth[node] = self.current_depth
        self.visit(node)

    def parent(self, node):
        return self.graph[node]

def is_load_name(node):
    if not isinstance(node, ast.Name):
        return False

    if isinstance(node.ctx, ast.Load):
        return True

class GatherGrapher(AstGrapher):
    """
    Adds the ability to gather nodes based on a certian condition.
    """

    def __init__(self, *args, **kwargs):
        self.gather_check = kwargs.pop('gather_check', is_load_name)
        self.gather_nodes = {}
        self.line = None

        super().__init__(*args, **kwargs)

    def visit_Module(self, node):
        body = node.body
        for line in node.body:
            self.line = line
            self.generic_visit(line)

    def visit(self, node):
        # check for load name. vars that grab from context
        if self.gather_check(node):
            self.gather_nodes.setdefault(self.line, []).append(node)
        super().visit(node)
<|endoftext|>


<commit_before># -*- coding: utf-8 -*-
__version__ = 0.1

def get_version():
    """ Returns the current nago version """
    return __version__<commit_msg>Bumped version number to 0.2<commit_after># -*- coding: utf-8 -*-
__version__ = 0.2

def get_version():
    """ Returns the current nago version """
    return __version__<|endoftext|>