<commit_before># Under MIT License, see LICENSE.txt
import math as m
from typing import Dict

import numpy as np

from Util.position import Position

ORIENTATION_ABSOLUTE_TOLERANCE = 0.004

class Pose:

    def __init__(self, position: Position=Position(), orientation: float=0):
        if isinstance(position, np.ndarray):
            raise TypeError("You need to pass a Position to Pose, use Position.from_array() to convert it.")
        self._orientation = orientation
        self._position = position

    @classmethod
    def from_dict(cls, my_dict: Dict[str, float]) -> 'Pose':
        return cls(Position(my_dict['x'], my_dict['y']), my_dict['orientation'])

    @classmethod
    def from_values(cls, x: float, y: float, orientation: float=0) -> 'Pose':
        return cls(Position(x, y), orientation)

    @property
    def x(self) -> float:
        return self._position.x

    @x.setter
    def x(self, new_x: float):
        self.position.x = new_x

    @property
    def y(self) -> float:
        return self._position.y

    @y.setter
    def y(self, new_y: float):
        self.position.y = new_y

    @property
    def position(self) -> Position:
        return self._position

    @position.setter
    def position(self, position: Position):
        self._position = position.copy()

    @property
    def norm(self) -> float:
        return self.position.norm

    @property
    def orientation(self) -> float:
        return self._orientation

    @orientation.setter
    def orientation(self, orientation: float):
        self._orientation = orientation

    def to_array(self) -> np.ndarray:
        return np.array([self.x, self.y, self.orientation])

    def to_dict(self) -> Dict[str, float]:
        return {'x': self.x, 'y': self.y, 'orientation': self.orientation}

    def __add__(self, other: Position) -> 'Pose':
        assert(isinstance(other, Position))
        return Pose(self.position + other, self.orientation)

    def __sub__(self, other: Position) -> 'Pose':
        return self + (-other)

    def __eq__(self, other: 'Pose') -> bool:
        orientation_equal = m.isclose(self.orientation, other.orientation,
                                      abs_tol=ORIENTATION_ABSOLUTE_TOLERANCE, rel_tol=0)
        position_equal = self.position == other.position
        return position_equal and orientation_equal

    def __ne__(self, other: 'Pose') -> bool:
        return not self.__eq__(other)

    def __str__(self) -> str:
        return '{}, orientation = {:5.3f}'.format(self.position, self.orientation)

    def __repr__(self) -> str:
        return 'Pose' + str(self)
<commit_msg>Fix stupid mistake that fail tests<commit_after># Under MIT License, see LICENSE.txt
import math as m
from typing import Dict

import numpy as np

from Util.position import Position

ORIENTATION_ABSOLUTE_TOLERANCE = 0.004

class Pose:

    def __init__(self, position: Position=Position(), orientation: float=0):
        if isinstance(position, np.ndarray):
            raise TypeError("You need to pass a Position to Pose, use Position.from_array() to convert it.")
        self._orientation = orientation
        self._position = position.copy()

    @classmethod
    def from_dict(cls, my_dict: Dict[str, float]) -> 'Pose':
        return cls(Position(my_dict['x'], my_dict['y']), my_dict['orientation'])

    @classmethod
    def from_values(cls, x: float, y: float, orientation: float=0) -> 'Pose':
        return cls(Position(x, y), orientation)

    @property
    def x(self) -> float:
        return self._position.x

    @x.setter
    def x(self, new_x: float):
        self.position.x = new_x

    @property
    def y(self) -> float:
        return self._position.y

    @y.setter
    def y(self, new_y: float):
        self.position.y = new_y

    @property
    def position(self) -> Position:
        return self._position

    @position.setter
    def position(self, position: Position):
        self._position = position.copy()

    @property
    def norm(self) -> float:
        return self.position.norm

    @property
    def orientation(self) -> float:
        return self._orientation

    @orientation.setter
    def orientation(self, orientation: float):
        self._orientation = orientation

    def to_array(self) -> np.ndarray:
        return np.array([self.x, self.y, self.orientation])

    def to_dict(self) -> Dict[str, float]:
        return {'x': self.x, 'y': self.y, 'orientation': self.orientation}

    def __add__(self, other: Position) -> 'Pose':
        assert(isinstance(other, Position))
        return Pose(self.position + other, self.orientation)

    def __sub__(self, other: Position) -> 'Pose':
        return self + (-other)

    def __eq__(self, other: 'Pose') -> bool:
        orientation_equal = m.isclose(self.orientation, other.orientation,
                                      abs_tol=ORIENTATION_ABSOLUTE_TOLERANCE, rel_tol=0)
        position_equal = self.position == other.position
        return position_equal and orientation_equal

    def __ne__(self, other: 'Pose') -> bool:
        return not self.__eq__(other)

    def __str__(self) -> str:
        return '{}, orientation = {:5.3f}'.format(self.position, self.orientation)

    def __repr__(self) -> str:
        return 'Pose' + str(self)
<|endoftext|>


<commit_before>from django.core.cache import cache
from django.db import models

def key_from_slug(slug):
    return 'flatcontent_%s' % (slug)

class FlatContent(models.Model):
    slug = models.SlugField(max_length=255, unique=True, help_text='The name by which the template author retrieves this content.')
    content = models.TextField()

    class Meta:
        verbose_name_plural = 'flat content'

    def __unicode__(self):
        return self.slug

    def save(self):
        super(FlatContent, self).save()
        cache.delete(key_from_slug(self.slug))

    # CLASS METHODS WITH CACHING

    def get(cls, slug):
        """
        Checks if key is in cache, otherwise performs database lookup and
        inserts into cache.
        """
        key = key_from_slug(slug)
        cache_value = cache.get(key)
        if cache_value:
            return cache_value

        try:
            fc = cls.objects.get(slug=slug)
        except cls.DoesNotExist:
            return ''
        cache.set(key, fc.content)
        return fc.content
    get = classmethod(get)

<commit_msg>Moving helper method, key_from_slug, into the model.<commit_after>from django.core.cache import cache
from django.db import models

class FlatContent(models.Model):
    slug = models.SlugField(max_length=255, unique=True, help_text='The name by which the template author retrieves this content.')
    content = models.TextField()

    class Meta:
        verbose_name_plural = 'flat content'

    def __unicode__(self):
        return self.slug

    def save(self):
        super(FlatContent, self).save()
        cache.delete(self.key_from_slug(self.slug))

    # Helper method to get key for caching
    def key_from_slug(slug):
        return 'flatcontent_%s' % (slug)
    key_from_slug = staticmethod(key_from_slug)

    # Class method with caching
    def get(cls, slug):
        """
        Checks if key is in cache, otherwise performs database lookup and
        inserts into cache.
        """
        key = cls.key_from_slug(slug)
        cache_value = cache.get(key)
        if cache_value:
            return cache_value

        try:
            fc = cls.objects.get(slug=slug)
        except cls.DoesNotExist:
            return ''
        cache.set(key, fc.content)
        return fc.content
    get = classmethod(get)

<|endoftext|>


<commit_before>from django.test import TestCase
from unittest import mock
from events.services.EventService import EventService

class HomePageTest(TestCase):
    def test_uses_home_template(self):
        response = self.client.get('/')
        self.assertTemplateUsed(response, 'home.html')

    @mock.patch('events.services.EventService.EventService.events')
    def test_call_event_service(self, mock_event_service_get):
        self.client.get('/')

        self.assertTrue(mock_event_service_get.called)

class EventServiceTest(TestCase):

    @mock.patch('events.services.EventService.requests.get')
    def test_events_with_no_args_api_is_called_with_no_args(
            self, requests_mock):
        # given I call events with no args
        EventService.events()

        # then the api is reached without query parameters
        self.assertIn(
            mock.call(
                'http://thisdayinmusic.icdif.com/api/v0.1/event',
                params=None
            ),
            requests_mock.call_args_list
        )

    @mock.patch('events.services.EventService.requests.get')
    def test_events_with_day_args_api_is_called_with_no_args(
            self, requests_mock):
        # given I call events with day
        EventService.events(day=10)

        # then the api is reached without query parameters
        self.assertIn(
            mock.call(
                'http://thisdayinmusic.icdif.com/api/v0.1/event',
                params=None
            ),
            requests_mock.call_args_list
        )

    @mock.patch('events.services.EventService.requests.get')
    def test_events_with_month_args_api_is_called_with_no_args(
            self, requests_mock):
        # given I call events with month
        EventService.events(month=10)

        # then the api is reached without query parameters
        self.assertIn(
            mock.call(
                'http://thisdayinmusic.icdif.com/api/v0.1/event',
                params=None
            ),
            requests_mock.call_args_list
        )

    @mock.patch('events.services.EventService.requests.get')
    def test_events_with_day_and_month_args_api_is_called_with_day_and_month(
            self, requests_mock):
        # given I call events with day and month
        EventService.events(month=10, day=20)

        # then the api is reached with day and month as query parameters
        self.assertIn(
            mock.call(
                'http://thisdayinmusic.icdif.com/api/v0.1/event',
                params={'day': 20, 'month': 10}
            ),
            requests_mock.call_args_list
        )

    @mock.patch('events.services.EventService.requests.models.Response.json',
                return_value={"response": {"events": [{}]}})
    def test_when_api_returns_results_events_should_return_them(
            self, response_json):
        # given that the api responds with a json
        result = EventService.events()

        # then a dictionary is returned
        self.assertEqual(type(result), dict)

        # with the right keys
        self.assertEqual(result['response'], {"events": [{}]})
<commit_msg>Tests event page calling event service with the right args<commit_after>from django.test import TestCase
from unittest import mock
from events.services.EventService import EventService

class HomePageTest(TestCase):
    def test_uses_home_template(self):
        response = self.client.get('/')
        self.assertTemplateUsed(response, 'home.html')

    @mock.patch('events.services.EventService.EventService.events')
    def test_home_page_today_calls_event_service(self, mock_event_service_get):
        self.client.get('/')

        self.assertTrue(mock_event_service_get.called)

    @mock.patch('events.services.EventService.EventService.events')
    def test_events_page_calls_event_service(self, mock_event_service_get):
        # when I access a random events page day
        self.client.get('/events/April/25')

        # then the service is called with the right arguments
        self.assertIn(
            mock.call(
                'April',
                '25'
            ),
            mock_event_service_get.call_args_list
        )

class EventServiceTest(TestCase):

    @mock.patch('events.services.EventService.requests.get')
    def test_events_with_no_args_api_is_called_with_no_args(
            self, requests_mock):
        # given I call events with no args
        EventService.events()

        # then the api is reached without query parameters
        self.assertIn(
            mock.call(
                'http://thisdayinmusic.icdif.com/api/v0.1/event',
                params=None
            ),
            requests_mock.call_args_list
        )

    @mock.patch('events.services.EventService.requests.get')
    def test_events_with_day_args_api_is_called_with_no_args(
            self, requests_mock):
        # given I call events with day
        EventService.events(day=10)

        # then the api is reached without query parameters
        self.assertIn(
            mock.call(
                'http://thisdayinmusic.icdif.com/api/v0.1/event',
                params=None
            ),
            requests_mock.call_args_list
        )

    @mock.patch('events.services.EventService.requests.get')
    def test_events_with_month_args_api_is_called_with_no_args(
            self, requests_mock):
        # given I call events with month
        EventService.events(month=10)

        # then the api is reached without query parameters
        self.assertIn(
            mock.call(
                'http://thisdayinmusic.icdif.com/api/v0.1/event',
                params=None
            ),
            requests_mock.call_args_list
        )

    @mock.patch('events.services.EventService.requests.get')
    def test_events_with_day_and_month_args_api_is_called_with_day_and_month(
            self, requests_mock):
        # given I call events with day and month
        EventService.events(month=10, day=20)

        # then the api is reached with day and month as query parameters
        self.assertIn(
            mock.call(
                'http://thisdayinmusic.icdif.com/api/v0.1/event',
                params={'day': 20, 'month': 10}
            ),
            requests_mock.call_args_list
        )

    @mock.patch('events.services.EventService.requests.models.Response.json',
                return_value={"response": {"events": [{}]}})
    def test_when_api_returns_results_events_should_return_them(
            self, response_json):
        # given that the api responds with a json
        result = EventService.events()

        # then a dictionary is returned
        self.assertEqual(type(result), dict)

        # with the right keys
        self.assertEqual(result['response'], {"events": [{}]})
<|endoftext|>


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

"""Copies a Kokoro-built CT4E release to a permenant location and makes it
publicly available.

The GCS location of a Kokoro-built repo is not suitable for direct release or
repo management. An example location:

    gs://kokoro-ct4e-release/prod/google-cloud-eclipse/ubuntu/jar_signing/34/20180323-215548

As a final step, we need to copy such a repo to a permanent location such as:

    gs://cloud-tools-for-eclipse/1.6.1
"""

import re
import subprocess
import sys

def _AskRepoOrigin():
  print
  print "#"
  print "# Enter the GCS URL of the Kokoro-built repo."
  print '# ("Artifact location" in the "jar_signing" success email.)'
  url = raw_input("URL? ")

  gcs_url = _FormatGcsUrl(url)
  if gcs_url:
    return gcs_url
  else:
    print "Wrong URL. Try again."
    return _AskRepoOrigin()

def _FormatGcsUrl(url):
  match_obj = re.search(
      r'kokoro-ct4e-release/prod/google-cloud-eclipse/ubuntu/jar_signing/\d+/[\d-]+$',
      url)
  if match_obj:
    return "gs://" + match_obj.group()
  else:
    return False

def _AskVersion():
  print
  print "#"
  print "# Enter the CT4E version (e.g., 9.9.9)."
  version = raw_input("Version? ")

  if _IsVersionString(version):
    return version
  else:
    print "Wrong format. Try again."
    return _AskVersion()

def _IsVersionString(string):
  return re.search(r'^\d+\.\d+\.\d+$', string)

def _GcsLocationExists(gcs_location):
  try:
    subprocess.check_output(
        ["gsutil", "ls", gcs_location], stderr=subprocess.STDOUT)
    return True
  except subprocess.CalledProcessError:
    return False

def _GetCopyCommand(origin, destination):
  return ["gsutil", "-m", "cp", "-R", origin, destination]

def _GetPublicAccessCommand(target):
  return ["gsutil", "-m", "acl", "ch", "-R", "-u", "AllUsers:R", target]

def main(argv):
  gcs_origin = _AskRepoOrigin()
  version = _AskVersion()
  gcs_destination = "gs://cloud-tools-for-eclipse/" + version

  if _GcsLocationExists(gcs_destination):
    print
    print "#"
    print "# The destination directory already exists. If the version you"
    print "# entered is correct, delete it first and try again."
    print "#"
    print "# Command to delete:"
    print "# gsutil -m rm " + gcs_destination + "/**"
    exit(1)

  # Copy the repo
  copy_command = _GetCopyCommand(gcs_origin, gcs_destination)
  subprocess.check_call(copy_command)

  # Make it publicly available
  acl_command = _GetPublicAccessCommand(gcs_destination)
  subprocess.check_call(acl_command)

  print
  print "#"
  print "# Copy done! The repo URL for installation:"
  print "#"
  print "# https://storage.googleapis.com/cloud-tools-for-eclipse/" + version

if __name__ == "__main__":
   main(sys.argv[1:])
<commit_msg>Update release script to use Python3 (#3653)<commit_after>#!/usr/bin/env python

"""Copies a Kokoro-built CT4E release to a permenant location and makes it
publicly available.

The GCS location of a Kokoro-built repo is not suitable for direct release or
repo management. An example location:

    gs://kokoro-ct4e-release/prod/google-cloud-eclipse/ubuntu/jar_signing/34/20180323-215548

As a final step, we need to copy such a repo to a permanent location such as:

    gs://cloud-tools-for-eclipse/1.6.1
"""

import re
import subprocess
import sys

def _AskRepoOrigin():
  print()
  print("#")
  print("# Enter the GCS URL of the Kokoro-built repo.")
  print('# ("Artifact location" in the "jar_signing" success email.)')
  url = input("URL? ")

  gcs_url = _FormatGcsUrl(url)
  if gcs_url:
    return gcs_url
  else:
    print("Wrong URL. Try again.")
    return _AskRepoOrigin()

def _FormatGcsUrl(url):
  match_obj = re.search(
      r'kokoro-ct4e-release/prod/google-cloud-eclipse/ubuntu/jar_signing/\d+/[\d-]+$',
      url)
  if match_obj:
    return "gs://" + match_obj.group()
  else:
    return False

def _AskVersion():
  print()
  print("#")
  print("# Enter the CT4E version (e.g., 9.9.9).")
  version = input("Version? ")

  if _IsVersionString(version):
    return version
  else:
    print("Wrong format. Try again.")
    return _AskVersion()

def _IsVersionString(string):
  return re.search(r'^\d+\.\d+\.\d+$', string)

def _GcsLocationExists(gcs_location):
  try:
    subprocess.check_output(
        ["gsutil", "ls", gcs_location], stderr=subprocess.STDOUT)
    return True
  except subprocess.CalledProcessError:
    return False

def _GetCopyCommand(origin, destination):
  return ["gsutil", "-m", "cp", "-R", origin, destination]

def _GetPublicAccessCommand(target):
  return ["gsutil", "-m", "acl", "ch", "-R", "-u", "AllUsers:R", target]

def main(argv):
  gcs_origin = _AskRepoOrigin()
  version = _AskVersion()
  gcs_destination = "gs://cloud-tools-for-eclipse/" + version

  if _GcsLocationExists(gcs_destination):
    print()
    print("#")
    print("# The destination directory already exists. If the version you")
    print("# entered is correct, delete it first and try again.")
    print("#")
    print("# Command to delete:")
    print("# gsutil -m rm " + gcs_destination + "/**")
    exit(1)

  # Copy the repo
  copy_command = _GetCopyCommand(gcs_origin, gcs_destination)
  subprocess.check_call(copy_command)

  # Make it publicly available
  acl_command = _GetPublicAccessCommand(gcs_destination)
  subprocess.check_call(acl_command)

  print()
  print("#")
  print("# Copy done! The repo URL for installation:")
  print("#")
  print("# https://storage.googleapis.com/cloud-tools-for-eclipse/" + version)

if __name__ == "__main__":
   main(sys.argv[1:])
<|endoftext|>


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

from __future__ import unicode_literals

import binascii
import os
from io import BytesIO
from operator import attrgetter

import click
from PIL import Image

from indico.modules.events.layout import layout_settings
from indico.modules.events.models.events import Event
from indico.util.console import cformat, verbose_iterator
from indico.util.fs import secure_filename
from indico.util.struct.iterables import committing_iterator
from indico_zodbimport import Importer, convert_to_unicode
from indico_zodbimport.util import get_archived_file

ALLOWED_THEMES = {'orange.css', 'brown.css', 'right_menu.css'}

class EventLayoutImporter(Importer):
    def __init__(self, **kwargs):
        self.archive_dirs = kwargs.pop('archive_dir')
        super(EventLayoutImporter, self).__init__(**kwargs)

    @staticmethod
    def decorate_command(command):
        command = click.option('--archive-dir', required=True, multiple=True,
                               help="The base path where resources are stored (ArchiveDir in indico.conf). "
                                    "When used multiple times, the dirs are checked in order until a file is "
                                    "found.")(command)
        return command

    def has_data(self):
        return bool(layout_settings.query.filter_by(name='is_searchable').count())

    def migrate(self):
        self.migrate_layout_settings()

    def migrate_layout_settings(self):
        print cformat('%{white!}migrating layout settings, event logos and custom CSS templates')

        default_styles = self.zodb_root['MaKaCInfo']['main']._styleMgr._defaultEventStylesheet
        for event, event_type, dmgr, logo, custom_css in committing_iterator(self._iter_event_layout_data()):
            if event_type != 'conference':
                theme = dmgr._defaultstyle
                if not theme or theme == default_styles[event_type]:
                    continue
                layout_settings.set(event, 'timetable_theme', theme)
                if not self.quiet:
                    self.print_success(cformat('- %{cyan}Default timetable theme: {}').format(theme), event_id=event.id)
                continue

            settings = self._get_event_settings(event, dmgr)
            layout_settings.set_multi(event, settings)
            if not self.quiet:
                self.print_success(cformat('- %{cyan}Layout settings'), event_id=event.id)
            if logo or custom_css:
                e = Event.get(event.id)
                if not e:
                    self.print_warning('Event does not exist (anymore)! Logo and/or CSS file not saved!',
                                       event_id=event.id)
                    continue
            if logo:
                path = get_archived_file(logo, self.archive_dirs)[1]
                if path is None:
                    self.print_error(cformat('%{red!}{} logo not found on disk; skipping it').format(event),
                                     event_id=event.id)
                    continue
                try:
                    logo_image = Image.open(path)
                except IOError as e:
                    self.print_warning('Cannot open the file. The file probably is not an image.')
                    self.print_warning("Cannot open {}: {}".format(path, e))
                    logo_image = None

                if logo_image:
                    logo_bytes = BytesIO()
                    logo_image.save(logo_bytes, 'PNG')
                    logo_bytes.seek(0)
                    logo_content = logo_bytes.read()
                    logo_filename = secure_filename(convert_to_unicode(logo.fileName), 'logo')
                    logo_filename = os.path.splitext(logo_filename)[0] + '.png'
                    logo_metadata = {
                        'size': len(logo_content),
                        'hash': binascii.crc32(logo_content) & 0xffffffff,
                        'filename': logo_filename,
                        'content_type': 'image/png'
                    }
                    e.logo = logo_content
                    e.logo_metadata = logo_metadata
                    if not self.quiet:
                        self.print_success(cformat('- %{cyan}[Logo] {}').format(logo.fileName), event_id=event.id)
            if custom_css:
                stylesheet = custom_css._localFile
                path = get_archived_file(stylesheet, self.archive_dirs)[1]
                if path is None:
                    self.print_error(cformat('%{red!}{} CSS file not found on disk; skipping it').format(event),
                                     event_id=event.id)
                    continue
                with open(path, 'rb') as f:
                    stylesheet_content = convert_to_unicode(f.read())
                e.stylesheet_metadata = {
                    'size': len(stylesheet_content),
                    'hash': binascii.crc32(stylesheet_content) & 0xffffffff,
                    'filename': secure_filename(convert_to_unicode(stylesheet.fileName), 'stylesheet.css'),
                    'content_type': 'text/css'
                }
                e.stylesheet = stylesheet_content
                if not self.quiet:
                    self.print_success(cformat('- %{cyan}[CSS] {}').format(stylesheet.fileName), event_id=event.id)

    def _iter_event_layout_data(self):
        it = self.zodb_root['conferences'].itervalues()
        if self.quiet:
            it = verbose_iterator(it, len(self.zodb_root['conferences']), attrgetter('id'), attrgetter('title'))
        wfr = self.zodb_root['webfactoryregistry']
        dmr = self.zodb_root['displayRegistery']
        for event in self.flushing_iterator(it):
            wf = wfr.get(event.id)
            event_type = 'conference' if wf is None else wf.id
            try:
                dmgr = dmr[event.id]
            except KeyError:
                self.print_error('Skipping event with no displaymgr', event_id=event.id)
                continue
            style_mgr = getattr(dmgr, '_styleMngr', None) if event_type == 'conference' else None
            custom_css = getattr(style_mgr, '_css', None) if event_type == 'conference' else None
            yield event, event_type, dmgr, event._logo, custom_css

    def _get_event_settings(self, event, dmgr):
        format_opts = getattr(dmgr, '_format', None)
        tt = getattr(dmgr, '_tickerTape', None)
        style_mgr = getattr(dmgr, '_styleMngr', None)
        event_id = event.id
        menu = getattr(dmgr, '_menu', None)

        settings = {
            'is_searchable': getattr(dmgr, '_searchEnabled', None),
            'show_nav_bar': getattr(dmgr, '_displayNavigationBar', None),
            'show_social_badges': getattr(dmgr, '_showSocialApps', None),
        }
        if format_opts:
            settings['header_text_color'] = format_opts._data.get('titleTextColor')
            settings['header_background_color'] = format_opts._data.get('titleBgColor')
        else:
            self.print_error(cformat('%{red!} Skipping some settings, missing _format attribute'), event_id=event_id)
        if tt:
            settings['show_banner'] = getattr(tt, '_enabledNowPlaying', None)
            settings['announcement'] = getattr(tt, '_text', None)
            settings['show_announcement'] = getattr(tt, '_enabledSimpleText', None)
        else:
            self.print_error(cformat('%{red!} Skipping some settings, missing _tickerTape attribute'),
                             event_id=event_id)
        if style_mgr:
            template = getattr(style_mgr, '_usingTemplate', None)
            theme = getattr(template, 'templateId', None)
            settings['theme'] = theme if theme in ALLOWED_THEMES else None
            settings['use_custom_css'] = getattr(style_mgr, '_css', None) is not None
        else:
            self.print_error(cformat('%{red!} Skipping some settings, missing _styleMngr attribute'), event_id=event_id)
        if menu:
            settings['timetable_by_room'] = getattr(menu, '_timetable_layout', None) == 'room'
            settings['timetable_detailed'] = getattr(menu, '_timetable_detailed_view', False)
        else:
            self.print_error(cformat('%{red!} Skipping some settings, missing _menu attribute'), event_id=event_id)

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

from __future__ import unicode_literals

import binascii
import os
from io import BytesIO
from operator import attrgetter

import click
from PIL import Image

from indico.modules.events.layout import layout_settings
from indico.modules.events.models.events import Event
from indico.util.console import cformat, verbose_iterator
from indico.util.fs import secure_filename
from indico.util.struct.iterables import committing_iterator
from indico_zodbimport import Importer, convert_to_unicode
from indico_zodbimport.util import get_archived_file

ALLOWED_THEMES = {'orange.css', 'brown.css', 'right_menu.css'}

class EventLayoutImporter(Importer):
    def __init__(self, **kwargs):
        self.archive_dirs = kwargs.pop('archive_dir')
        super(EventLayoutImporter, self).__init__(**kwargs)

    @staticmethod
    def decorate_command(command):
        command = click.option('--archive-dir', required=True, multiple=True,
                               help="The base path where resources are stored (ArchiveDir in indico.conf). "
                                    "When used multiple times, the dirs are checked in order until a file is "
                                    "found.")(command)
        return command

    def has_data(self):
        return bool(layout_settings.query.filter_by(name='is_searchable').count())

    def migrate(self):
        self.migrate_layout_settings()

    def migrate_layout_settings(self):
        print cformat('%{white!}migrating layout settings, event logos and custom CSS templates')

        default_styles = self.zodb_root['MaKaCInfo']['main']._styleMgr._defaultEventStylesheet
        for event, event_type, dmgr, logo, custom_css in committing_iterator(self._iter_event_layout_data()):
            if event_type != 'conference':
                theme = dmgr._defaultstyle
                if not theme or theme == default_styles[event_type]:
                    continue
                layout_settings.set(event, 'timetable_theme', theme)
                if not self.quiet:
                    self.print_success(cformat('- %{cyan}Default timetable theme: {}').format(theme), event_id=event.id)
                continue

            settings = self._get_event_settings(event, dmgr)
            layout_settings.set_multi(event, settings)
            if not self.quiet:
                self.print_success(cformat('- %{cyan}Layout settings'), event_id=event.id)
            if logo or custom_css:
                e = Event.get(event.id)
                if not e:
                    self.print_warning('Event does not exist (anymore)! Logo and/or CSS file not saved!',
                                       event_id=event.id)
                    continue
            if logo:
                path = get_archived_file(logo, self.archive_dirs)[1]
                if path is None:
                    self.print_error(cformat('%{red!}{} logo not found on disk; skipping it').format(event),
                                     event_id=event.id)
                    continue
                try:
                    logo_image = Image.open(path)
                except IOError as e:
                    self.print_warning("Cannot open {}: {}".format(path, e), event_id=event.id)
                    logo_image = None

                if logo_image:
                    logo_bytes = BytesIO()
                    logo_image.save(logo_bytes, 'PNG')
                    logo_bytes.seek(0)
                    logo_content = logo_bytes.read()
                    logo_filename = secure_filename(convert_to_unicode(logo.fileName), 'logo')
                    logo_filename = os.path.splitext(logo_filename)[0] + '.png'
                    logo_metadata = {
                        'size': len(logo_content),
                        'hash': binascii.crc32(logo_content) & 0xffffffff,
                        'filename': logo_filename,
                        'content_type': 'image/png'
                    }
                    e.logo = logo_content
                    e.logo_metadata = logo_metadata
                    if not self.quiet:
                        self.print_success(cformat('- %{cyan}[Logo] {}').format(logo.fileName), event_id=event.id)
            if custom_css:
                stylesheet = custom_css._localFile
                path = get_archived_file(stylesheet, self.archive_dirs)[1]
                if path is None:
                    self.print_error(cformat('%{red!}{} CSS file not found on disk; skipping it').format(event),
                                     event_id=event.id)
                    continue
                with open(path, 'rb') as f:
                    stylesheet_content = convert_to_unicode(f.read())
                e.stylesheet_metadata = {
                    'size': len(stylesheet_content),
                    'hash': binascii.crc32(stylesheet_content) & 0xffffffff,
                    'filename': secure_filename(convert_to_unicode(stylesheet.fileName), 'stylesheet.css'),
                    'content_type': 'text/css'
                }
                e.stylesheet = stylesheet_content
                if not self.quiet:
                    self.print_success(cformat('- %{cyan}[CSS] {}').format(stylesheet.fileName), event_id=event.id)

    def _iter_event_layout_data(self):
        it = self.zodb_root['conferences'].itervalues()
        if self.quiet:
            it = verbose_iterator(it, len(self.zodb_root['conferences']), attrgetter('id'), attrgetter('title'))
        wfr = self.zodb_root['webfactoryregistry']
        dmr = self.zodb_root['displayRegistery']
        for event in self.flushing_iterator(it):
            wf = wfr.get(event.id)
            event_type = 'conference' if wf is None else wf.id
            try:
                dmgr = dmr[event.id]
            except KeyError:
                self.print_error('Skipping event with no displaymgr', event_id=event.id)
                continue
            style_mgr = getattr(dmgr, '_styleMngr', None) if event_type == 'conference' else None
            custom_css = getattr(style_mgr, '_css', None) if event_type == 'conference' else None
            yield event, event_type, dmgr, event._logo, custom_css

    def _get_event_settings(self, event, dmgr):
        format_opts = getattr(dmgr, '_format', None)
        tt = getattr(dmgr, '_tickerTape', None)
        style_mgr = getattr(dmgr, '_styleMngr', None)
        event_id = event.id
        menu = getattr(dmgr, '_menu', None)

        settings = {
            'is_searchable': getattr(dmgr, '_searchEnabled', None),
            'show_nav_bar': getattr(dmgr, '_displayNavigationBar', None),
            'show_social_badges': getattr(dmgr, '_showSocialApps', None),
        }
        if format_opts:
            settings['header_text_color'] = format_opts._data.get('titleTextColor')
            settings['header_background_color'] = format_opts._data.get('titleBgColor')
        else:
            self.print_error(cformat('%{red!} Skipping some settings, missing _format attribute'), event_id=event_id)
        if tt:
            settings['show_banner'] = getattr(tt, '_enabledNowPlaying', None)
            settings['announcement'] = getattr(tt, '_text', None)
            settings['show_announcement'] = getattr(tt, '_enabledSimpleText', None)
        else:
            self.print_error(cformat('%{red!} Skipping some settings, missing _tickerTape attribute'),
                             event_id=event_id)
        if style_mgr:
            template = getattr(style_mgr, '_usingTemplate', None)
            theme = getattr(template, 'templateId', None)
            settings['theme'] = theme if theme in ALLOWED_THEMES else None
            settings['use_custom_css'] = getattr(style_mgr, '_css', None) is not None
        else:
            self.print_error(cformat('%{red!} Skipping some settings, missing _styleMngr attribute'), event_id=event_id)
        if menu:
            settings['timetable_by_room'] = getattr(menu, '_timetable_layout', None) == 'room'
            settings['timetable_detailed'] = getattr(menu, '_timetable_detailed_view', False)
        else:
            self.print_error(cformat('%{red!} Skipping some settings, missing _menu attribute'), event_id=event_id)

        return {k: v for k, v in settings.iteritems() if v is not None}
<|endoftext|>


<commit_before># Copyright (c) 2009, Willow Garage, Inc.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#
#     * Redistributions of source code must retain the above copyright
#       notice, this list of conditions and the following disclaimer.
#     * Redistributions in binary form must reproduce the above copyright
#       notice, this list of conditions and the following disclaimer in the
#       documentation and/or other materials provided with the distribution.
#     * Neither the name of the Willow Garage, Inc. nor the names of its
#       contributors may be used to endorse or promote products derived from
#       this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.

# Author Tully Foote/tfoote@willowgarage.com, Ken Conley/kwc@willowgarage.com

"""
rosdep library and command-line tool
"""

from __future__ import print_function

__version__ = '0.7.1'

from .installers import InstallerContext, Installer, PackageManagerInstaller

from .core import RosdepInternalError, InstallFailed, UnsupportedOs, InvalidData, DownloadFailure
from .model import RosdepDatabase, RosdepDatabaseEntry
from .lookup import RosdepDefinition, RosdepView, RosdepLookup, ResolutionError
from .loader import RosdepLoader
from .rospkg_loader import RosPkgLoader

def create_default_installer_context(verbose=False):
    from .platforms import arch
    from .platforms import cygwin
    from .platforms import debian
    from .platforms import gentoo
    from .platforms import opensuse
    from .platforms import osx
    from .platforms import pip
    from .platforms import redhat
    from .platforms import source

    platform_mods = [arch, cygwin, debian, gentoo, opensuse, osx, redhat]
    installer_mods = [source, pip] + platform_mods

    context = InstallerContext()
    context.set_verbose(verbose)

    # setup installers
    for m in installer_mods:
        if verbose:
            print("registering installers for %s"%(m.__name__))
        m.register_installers(context)

    # setup platforms
    for m in platform_mods:
        if verbose:
            print("registering platforms for %s"%(m.__name__))
        m.register_platforms(context)

    return context

#TODO: this was partially abstracted from main() for another library,
# but it turned out to be unnecessary. Not sure it's worth maintaining
# separately, especially in the top-level module.
def get_default_installer(installer_context=None, verbose=False):
    """
    Based on the active OS and installer context configuration, get
    the installer to use and the necessary configuration state
    (installer keys, OS name/version).

    :returns: installer, installer_keys, default_key, os_name, os_version.
    """
    if installer_context is None:
        installer_context = create_default_installer_context(verbose=verbose)

    os_name, os_version = installer_context.get_os_name_and_version()
    try:
        installer_keys = installer_context.get_os_installer_keys(os_name)
        default_key = installer_context.get_default_os_installer_key(os_name)
    except KeyError:
        raise UnsupportedOs(os_name, installer_context.get_os_keys())
    installer = installer_context.get_installer(default_key)
    return installer, installer_keys, default_key, os_name, os_version

<commit_msg>0.7.2. marker<commit_after># Copyright (c) 2009, Willow Garage, Inc.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#
#     * Redistributions of source code must retain the above copyright
#       notice, this list of conditions and the following disclaimer.
#     * Redistributions in binary form must reproduce the above copyright
#       notice, this list of conditions and the following disclaimer in the
#       documentation and/or other materials provided with the distribution.
#     * Neither the name of the Willow Garage, Inc. nor the names of its
#       contributors may be used to endorse or promote products derived from
#       this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.

# Author Tully Foote/tfoote@willowgarage.com, Ken Conley/kwc@willowgarage.com

"""
rosdep library and command-line tool
"""

from __future__ import print_function

__version__ = '0.7.2'

from .installers import InstallerContext, Installer, PackageManagerInstaller

from .core import RosdepInternalError, InstallFailed, UnsupportedOs, InvalidData, DownloadFailure
from .model import RosdepDatabase, RosdepDatabaseEntry
from .lookup import RosdepDefinition, RosdepView, RosdepLookup, ResolutionError
from .loader import RosdepLoader
from .rospkg_loader import RosPkgLoader

def create_default_installer_context(verbose=False):
    from .platforms import arch
    from .platforms import cygwin
    from .platforms import debian
    from .platforms import gentoo
    from .platforms import opensuse
    from .platforms import osx
    from .platforms import pip
    from .platforms import redhat
    from .platforms import source

    platform_mods = [arch, cygwin, debian, gentoo, opensuse, osx, redhat]
    installer_mods = [source, pip] + platform_mods

    context = InstallerContext()
    context.set_verbose(verbose)

    # setup installers
    for m in installer_mods:
        if verbose:
            print("registering installers for %s"%(m.__name__))
        m.register_installers(context)

    # setup platforms
    for m in platform_mods:
        if verbose:
            print("registering platforms for %s"%(m.__name__))
        m.register_platforms(context)

    return context

#TODO: this was partially abstracted from main() for another library,
# but it turned out to be unnecessary. Not sure it's worth maintaining
# separately, especially in the top-level module.
def get_default_installer(installer_context=None, verbose=False):
    """
    Based on the active OS and installer context configuration, get
    the installer to use and the necessary configuration state
    (installer keys, OS name/version).

    :returns: installer, installer_keys, default_key, os_name, os_version.
    """
    if installer_context is None:
        installer_context = create_default_installer_context(verbose=verbose)

    os_name, os_version = installer_context.get_os_name_and_version()
    try:
        installer_keys = installer_context.get_os_installer_keys(os_name)
        default_key = installer_context.get_default_os_installer_key(os_name)
    except KeyError:
        raise UnsupportedOs(os_name, installer_context.get_os_keys())
    installer = installer_context.get_installer(default_key)
    return installer, installer_keys, default_key, os_name, os_version

<|endoftext|>


<commit_before>from django import forms

from floppyforms.widgets import (TextInput, HiddenInput, CheckboxInput, Select,
                                 ClearableFileInput, SelectMultiple,
                                 DateInput, DateTimeInput, TimeInput, URLInput,
                                 NumberInput, EmailInput, NullBooleanSelect,
                                 SlugInput, IPAddressInput,
                                 SplitDateTimeWidget,
                                 SplitHiddenDateTimeWidget)

__all__ = (
    'Field', 'CharField', 'IntegerField', 'DateField', 'TimeField',
    'DateTimeField', 'EmailField', 'FileField', 'ImageField', 'URLField',
    'BooleanField', 'NullBooleanField', 'ChoiceField', 'MultipleChoiceField',
    'FloatField', 'DecimalField', 'SlugField', 'RegexField', 'IPAddressField',
    'TypedChoiceField', 'FilePathField', 'TypedMultipleChoiceField',
    'ComboField', 'MultiValueField', 'SplitDateTimeField',
)

class Field(forms.Field):
    widget = TextInput
    hidden_widget = HiddenInput

    def __init__(self, *args, **kwargs):
        super(Field, self).__init__(*args, **kwargs)
        self.widget.is_required = self.required  # fallback to support
                                                 # is_required with
                                                 # Django < 1.3

class CharField(Field, forms.CharField):
    widget = TextInput

class BooleanField(Field, forms.BooleanField):
    widget = CheckboxInput

class NullBooleanField(Field, forms.NullBooleanField):
    widget = NullBooleanSelect

class ChoiceField(Field, forms.ChoiceField):
    widget = Select

class TypedChoiceField(ChoiceField, forms.TypedChoiceField):
    widget = Select

class FilePathField(ChoiceField, forms.FilePathField):
    widget = Select

class FileField(Field, forms.FileField):
    widget = ClearableFileInput

class ImageField(Field, forms.ImageField):
    widget = ClearableFileInput

class MultipleChoiceField(forms.MultipleChoiceField):
    widget = SelectMultiple

try:
    Parent = forms.TypedMultipleChoiceField
except AttributeError:  # Django < 1.3
    class Parent(forms.MultipleChoiceField):
        """No-op class for older Django versions"""
        def __init__(self, *args, **kwargs):
            kwargs.pop('coerce', None)
            kwargs.pop('empty_value', None)
            super(Parent, self).__init__(*args, **kwargs)

class TypedMultipleChoiceField(MultipleChoiceField, Parent):
    pass

class DateField(Field, forms.DateField):
    widget = DateInput

class DateTimeField(Field, forms.DateTimeField):
    widget = DateTimeInput

class TimeField(Field, forms.TimeField):
    widget = TimeInput

class DecimalField(Field, forms.DecimalField):
    widget = NumberInput

class FloatField(Field, forms.FloatField):
    widget = NumberInput

class IntegerField(FloatField, forms.IntegerField):
    widget = NumberInput

class EmailField(Field, forms.EmailField):
    widget = EmailInput

class URLField(Field, forms.URLField):
    widget = URLInput

class SlugField(Field, forms.SlugField):
    widget = SlugInput

class RegexField(Field, forms.RegexField):
    widget = TextInput

    def __init__(self, regex, js_regex=None, max_length=None, min_length=None,
                 error_message=None, *args, **kwargs):
        self.js_regex = js_regex
        super(RegexField, self).__init__(regex, max_length, min_length,
                                         *args, **kwargs)

    def widget_attrs(self, widget):
        attrs = super(RegexField, self).widget_attrs(widget) or {}
        if self.js_regex is not None:
            attrs['pattern'] = self.js_regex
        return attrs

class IPAddressField(Field, forms.IPAddressField):
    widget = IPAddressInput

class ComboField(Field, forms.ComboField):
    pass

class MultiValueField(Field, forms.MultiValueField):
    pass

class SplitDateTimeField(forms.SplitDateTimeField):
    widget = SplitDateTimeWidget
    hidden_widget = SplitHiddenDateTimeWidget

    def __init__(self, *args, **kwargs):
        super(SplitDateTimeField, self).__init__(*args, **kwargs)
        for widget in self.widget.widgets:
            widget.is_required = self.required
<commit_msg>Fixed a test failure with Django 1.2<commit_after>from django import forms

from floppyforms.widgets import (TextInput, HiddenInput, CheckboxInput, Select,
                                 ClearableFileInput, SelectMultiple,
                                 DateInput, DateTimeInput, TimeInput, URLInput,
                                 NumberInput, EmailInput, NullBooleanSelect,
                                 SlugInput, IPAddressInput,
                                 SplitDateTimeWidget,
                                 SplitHiddenDateTimeWidget)

__all__ = (
    'Field', 'CharField', 'IntegerField', 'DateField', 'TimeField',
    'DateTimeField', 'EmailField', 'FileField', 'ImageField', 'URLField',
    'BooleanField', 'NullBooleanField', 'ChoiceField', 'MultipleChoiceField',
    'FloatField', 'DecimalField', 'SlugField', 'RegexField', 'IPAddressField',
    'TypedChoiceField', 'FilePathField', 'TypedMultipleChoiceField',
    'ComboField', 'MultiValueField', 'SplitDateTimeField',
)

class Field(forms.Field):
    widget = TextInput
    hidden_widget = HiddenInput

    def __init__(self, *args, **kwargs):
        super(Field, self).__init__(*args, **kwargs)
        self.widget.is_required = self.required  # fallback to support
                                                 # is_required with
                                                 # Django < 1.3

class CharField(Field, forms.CharField):
    widget = TextInput

class BooleanField(Field, forms.BooleanField):
    widget = CheckboxInput

class NullBooleanField(Field, forms.NullBooleanField):
    widget = NullBooleanSelect

class ChoiceField(Field, forms.ChoiceField):
    widget = Select

class TypedChoiceField(ChoiceField, forms.TypedChoiceField):
    widget = Select

class FilePathField(ChoiceField, forms.FilePathField):
    widget = Select

class FileField(Field, forms.FileField):
    widget = ClearableFileInput

class ImageField(Field, forms.ImageField):
    widget = ClearableFileInput

class MultipleChoiceField(Field, forms.MultipleChoiceField):
    widget = SelectMultiple

try:
    Parent = forms.TypedMultipleChoiceField
except AttributeError:  # Django < 1.3
    class Parent(forms.MultipleChoiceField):
        """No-op class for older Django versions"""
        def __init__(self, *args, **kwargs):
            kwargs.pop('coerce', None)
            kwargs.pop('empty_value', None)
            super(Parent, self).__init__(*args, **kwargs)

class TypedMultipleChoiceField(MultipleChoiceField, Parent):
    pass

class DateField(Field, forms.DateField):
    widget = DateInput

class DateTimeField(Field, forms.DateTimeField):
    widget = DateTimeInput

class TimeField(Field, forms.TimeField):
    widget = TimeInput

class DecimalField(Field, forms.DecimalField):
    widget = NumberInput

class FloatField(Field, forms.FloatField):
    widget = NumberInput

class IntegerField(FloatField, forms.IntegerField):
    widget = NumberInput

class EmailField(Field, forms.EmailField):
    widget = EmailInput

class URLField(Field, forms.URLField):
    widget = URLInput

class SlugField(Field, forms.SlugField):
    widget = SlugInput

class RegexField(Field, forms.RegexField):
    widget = TextInput

    def __init__(self, regex, js_regex=None, max_length=None, min_length=None,
                 error_message=None, *args, **kwargs):
        self.js_regex = js_regex
        super(RegexField, self).__init__(regex, max_length, min_length,
                                         *args, **kwargs)

    def widget_attrs(self, widget):
        attrs = super(RegexField, self).widget_attrs(widget) or {}
        if self.js_regex is not None:
            attrs['pattern'] = self.js_regex
        return attrs

class IPAddressField(Field, forms.IPAddressField):
    widget = IPAddressInput

class ComboField(Field, forms.ComboField):
    pass

class MultiValueField(Field, forms.MultiValueField):
    pass

class SplitDateTimeField(forms.SplitDateTimeField):
    widget = SplitDateTimeWidget
    hidden_widget = SplitHiddenDateTimeWidget

    def __init__(self, *args, **kwargs):
        super(SplitDateTimeField, self).__init__(*args, **kwargs)
        for widget in self.widget.widgets:
            widget.is_required = self.required
<|endoftext|>


<commit_before># Copyright (c) 2009, Willow Garage, Inc.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#
#     * Redistributions of source code must retain the above copyright
#       notice, this list of conditions and the following disclaimer.
#     * Redistributions in binary form must reproduce the above copyright
#       notice, this list of conditions and the following disclaimer in the
#       documentation and/or other materials provided with the distribution.
#     * Neither the name of the Willow Garage, Inc. nor the names of its
#       contributors may be used to endorse or promote products derived from
#       this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.

# Author Tully Foote/tfoote@willowgarage.com, Ken Conley/kwc@willowgarage.com

"""
rosdep library and command-line tool
"""

from __future__ import print_function

__version__ = '0.10.20'

import sys

try:
    from .installers import InstallerContext, Installer, \
            PackageManagerInstaller
    from .core import RosdepInternalError, InstallFailed, UnsupportedOs, \
            InvalidData, DownloadFailure
    from .model import RosdepDatabase, RosdepDatabaseEntry
    from .lookup import RosdepDefinition, RosdepView, RosdepLookup, \
            ResolutionError
    from .loader import RosdepLoader
except ImportError:
    # soft-fail if rospkg not available.  Need this backoff behavior
    # in order to support setting __version__ in the module.
    print("failed to load symbols, rosdep will not function properly",
            file=sys.stderr)

# don't let import error take down code as when attempting to compute version number
try:
    from .rospkg_loader import RosPkgLoader
except ImportError:
    print("Cannot import rospkg, rosdep will not function properly",
            file=sys.stderr)

def create_default_installer_context(verbose=False):
    from .platforms import arch
    from .platforms import cygwin
    from .platforms import debian
    from .platforms import gentoo
    from .platforms import opensuse
    from .platforms import osx
    from .platforms import pip
    from .platforms import gem
    from .platforms import redhat
    from .platforms import source

    platform_mods = [arch, cygwin, debian, gentoo, opensuse, osx, redhat]
    installer_mods = [source, pip, gem] + platform_mods

    context = InstallerContext()
    context.set_verbose(verbose)

    # setup installers
    for m in installer_mods:
        if verbose:
            print("registering installers for %s"%(m.__name__))
        m.register_installers(context)

    # setup platforms
    for m in platform_mods:
        if verbose:
            print("registering platforms for %s"%(m.__name__))
        m.register_platforms(context)

    return context

#TODO: this was partially abstracted from main() for another library,
# but it turned out to be unnecessary. Not sure it's worth maintaining
# separately, especially in the top-level module.
def get_default_installer(installer_context=None, verbose=False):
    """
    Based on the active OS and installer context configuration, get
    the installer to use and the necessary configuration state
    (installer keys, OS name/version).

    :returns: installer, installer_keys, default_key, os_name, os_version.
    """
    if installer_context is None:
        installer_context = create_default_installer_context(verbose=verbose)

    os_name, os_version = installer_context.get_os_name_and_version()
    try:
        installer_keys = installer_context.get_os_installer_keys(os_name)
        default_key = installer_context.get_default_os_installer_key(os_name)
    except KeyError:
        raise UnsupportedOs(os_name, installer_context.get_os_keys())
    installer = installer_context.get_installer(default_key)
    return installer, installer_keys, default_key, os_name, os_version

__all__ = ['InstallerContext', 'Installer', 'PackageManagerInstaller',
        'RosdepInternalError', 'InstallFailed', 'UnsupportedOs', 'InvalidData',
        'DownloadFailure',
        'RosdepDatabase', 'RosdepDatabaseEntry',
        'RosdepDefinition', 'RosdepView', 'RosdepLookup', 'ResolutionError',
        'RosdepLoader', 'RosPkgLoader',
        'get_default_installer',
        'create_default_installer_context',
        ]
<commit_msg>0.10.21<commit_after># Copyright (c) 2009, Willow Garage, Inc.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#
#     * Redistributions of source code must retain the above copyright
#       notice, this list of conditions and the following disclaimer.
#     * Redistributions in binary form must reproduce the above copyright
#       notice, this list of conditions and the following disclaimer in the
#       documentation and/or other materials provided with the distribution.
#     * Neither the name of the Willow Garage, Inc. nor the names of its
#       contributors may be used to endorse or promote products derived from
#       this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.

# Author Tully Foote/tfoote@willowgarage.com, Ken Conley/kwc@willowgarage.com

"""
rosdep library and command-line tool
"""

from __future__ import print_function

__version__ = '0.10.21'

import sys

try:
    from .installers import InstallerContext, Installer, \
            PackageManagerInstaller
    from .core import RosdepInternalError, InstallFailed, UnsupportedOs, \
            InvalidData, DownloadFailure
    from .model import RosdepDatabase, RosdepDatabaseEntry
    from .lookup import RosdepDefinition, RosdepView, RosdepLookup, \
            ResolutionError
    from .loader import RosdepLoader
except ImportError:
    # soft-fail if rospkg not available.  Need this backoff behavior
    # in order to support setting __version__ in the module.
    print("failed to load symbols, rosdep will not function properly",
            file=sys.stderr)

# don't let import error take down code as when attempting to compute version number
try:
    from .rospkg_loader import RosPkgLoader
except ImportError:
    print("Cannot import rospkg, rosdep will not function properly",
            file=sys.stderr)

def create_default_installer_context(verbose=False):
    from .platforms import arch
    from .platforms import cygwin
    from .platforms import debian
    from .platforms import gentoo
    from .platforms import opensuse
    from .platforms import osx
    from .platforms import pip
    from .platforms import gem
    from .platforms import redhat
    from .platforms import source

    platform_mods = [arch, cygwin, debian, gentoo, opensuse, osx, redhat]
    installer_mods = [source, pip, gem] + platform_mods

    context = InstallerContext()
    context.set_verbose(verbose)

    # setup installers
    for m in installer_mods:
        if verbose:
            print("registering installers for %s"%(m.__name__))
        m.register_installers(context)

    # setup platforms
    for m in platform_mods:
        if verbose:
            print("registering platforms for %s"%(m.__name__))
        m.register_platforms(context)

    return context

#TODO: this was partially abstracted from main() for another library,
# but it turned out to be unnecessary. Not sure it's worth maintaining
# separately, especially in the top-level module.
def get_default_installer(installer_context=None, verbose=False):
    """
    Based on the active OS and installer context configuration, get
    the installer to use and the necessary configuration state
    (installer keys, OS name/version).

    :returns: installer, installer_keys, default_key, os_name, os_version.
    """
    if installer_context is None:
        installer_context = create_default_installer_context(verbose=verbose)

    os_name, os_version = installer_context.get_os_name_and_version()
    try:
        installer_keys = installer_context.get_os_installer_keys(os_name)
        default_key = installer_context.get_default_os_installer_key(os_name)
    except KeyError:
        raise UnsupportedOs(os_name, installer_context.get_os_keys())
    installer = installer_context.get_installer(default_key)
    return installer, installer_keys, default_key, os_name, os_version

__all__ = ['InstallerContext', 'Installer', 'PackageManagerInstaller',
        'RosdepInternalError', 'InstallFailed', 'UnsupportedOs', 'InvalidData',
        'DownloadFailure',
        'RosdepDatabase', 'RosdepDatabaseEntry',
        'RosdepDefinition', 'RosdepView', 'RosdepLookup', 'ResolutionError',
        'RosdepLoader', 'RosPkgLoader',
        'get_default_installer',
        'create_default_installer_context',
        ]
<|endoftext|>


<commit_before>from __future__ import print_function
import numpy as np
from matplotlib import pyplot as plt

from graphs.generators.swiss_roll import swiss_roll
from graphs.construction import neighbor_graph

def main():
  np.random.seed(1234)
  X, theta = swiss_roll(8, 300, return_theta=True, radius=0.5)
  GT = np.column_stack((theta, X[:,1]))
  g = neighbor_graph(X, k=6)
  g = g.from_adj_matrix(g.matrix('dense'))
  ct = 12

  _, axes = plt.subplots(nrows=4, figsize=(8, 10))
  _plot_diff(axes[0], GT, g, g.minimum_spanning_subtree(), title='MST')
  _plot_diff(axes[1], GT, g, g.circle_tear(cycle_len_thresh=ct),
             title='Circle Tear (%d)' % ct)
  _plot_diff(axes[2], GT, g, g.cycle_cut(cycle_len_thresh=ct),
             title='Cycle Cut (%d)' % ct)
  _plot_diff(axes[3], GT, g, g.isograph(), title='Isograph')
  plt.show()

def _plot_diff(ax, x, g1, g2, title=''):
  g1.plot(x, ax=ax, edge_style='y-')
  g2.plot(x, ax=ax, edge_style='b-')
  ax.set_title(title)

if __name__ == '__main__':
  main()
<commit_msg>Fixing import path<commit_after>from __future__ import print_function
import numpy as np
from matplotlib import pyplot as plt

from graphs.datasets import swiss_roll
from graphs.construction import neighbor_graph

def main():
  np.random.seed(1234)
  X, theta = swiss_roll(8, 300, return_theta=True, radius=0.5)
  GT = np.column_stack((theta, X[:,1]))
  g = neighbor_graph(X, k=6)
  g = g.from_adj_matrix(g.matrix('dense'))
  ct = 12

  _, axes = plt.subplots(nrows=4, figsize=(8, 10))
  _plot_diff(axes[0], GT, g, g.minimum_spanning_subtree(), title='MST')
  _plot_diff(axes[1], GT, g, g.circle_tear(cycle_len_thresh=ct),
             title='Circle Tear (%d)' % ct)
  _plot_diff(axes[2], GT, g, g.cycle_cut(cycle_len_thresh=ct),
             title='Cycle Cut (%d)' % ct)
  _plot_diff(axes[3], GT, g, g.isograph(), title='Isograph')
  plt.show()

def _plot_diff(ax, x, g1, g2, title=''):
  g1.plot(x, ax=ax, edge_style='y-')
  g2.plot(x, ax=ax, edge_style='b-')
  ax.set_title(title)

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


<commit_before><commit_msg>OVS-1855 - Don't trigger the StorageDriver to reload the config file when it's not running yet<commit_after><|endoftext|>


<commit_before>import django
from django import forms
import decimal

from .widgets import (TextInput, HiddenInput, CheckboxInput, Select,
                      ClearableFileInput, SelectMultiple, DateInput,
                      DateTimeInput, TimeInput, URLInput, NumberInput,
                      EmailInput, NullBooleanSelect, SlugInput, IPAddressInput,
                      SplitDateTimeWidget, SplitHiddenDateTimeWidget,
                      MultipleHiddenInput)
if django.VERSION < (1, 9):
    from .widgets import IPAddressInput

__all__ = (
    'Field', 'CharField', 'IntegerField', 'DateField', 'TimeField',
    'DateTimeField', 'EmailField', 'FileField', 'ImageField', 'URLField',
    'BooleanField', 'NullBooleanField', 'ChoiceField', 'MultipleChoiceField',
    'FloatField', 'DecimalField', 'SlugField', 'RegexField',
    'GenericIPAddressField', 'TypedChoiceField', 'FilePathField',
    'TypedMultipleChoiceField', 'ComboField', 'MultiValueField',
    'SplitDateTimeField',
)
if django.VERSION < (1, 9):
    __all__ += ('IPAddressField',)

class Field(forms.Field):
    widget = TextInput
    hidden_widget = HiddenInput

class CharField(Field, forms.CharField):
    widget = TextInput

    def widget_attrs(self, widget):
        attrs = super(CharField, self).widget_attrs(widget)
        if attrs is None:
            attrs = {}
        if self.max_length is not None and isinstance(widget, (TextInput, HiddenInput)):
            # The HTML attribute is maxlength, not max_length.
            attrs.update({'maxlength': str(self.max_length)})
        return attrs

class BooleanField(Field, forms.BooleanField):
    widget = CheckboxInput

class NullBooleanField(Field, forms.NullBooleanField):
    widget = NullBooleanSelect

class ChoiceField(Field, forms.ChoiceField):
    widget = Select

class TypedChoiceField(ChoiceField, forms.TypedChoiceField):
    widget = Select

class FilePathField(ChoiceField, forms.FilePathField):
    widget = Select

class FileField(Field, forms.FileField):
    widget = ClearableFileInput

class ImageField(Field, forms.ImageField):
    widget = ClearableFileInput

class MultipleChoiceField(Field, forms.MultipleChoiceField):
    widget = SelectMultiple
    hidden_widget = MultipleHiddenInput

class TypedMultipleChoiceField(MultipleChoiceField,
                               forms.TypedMultipleChoiceField):
    pass

class DateField(Field, forms.DateField):
    widget = DateInput

class DateTimeField(Field, forms.DateTimeField):
    widget = DateTimeInput

class TimeField(Field, forms.TimeField):
    widget = TimeInput

class FloatField(Field, forms.FloatField):
    widget = NumberInput

    def widget_attrs(self, widget):
        attrs = super(FloatField, self).widget_attrs(widget) or {}
        if self.min_value is not None:
            attrs['min'] = self.min_value
        if self.max_value is not None:
            attrs['max'] = self.max_value
        if 'step' not in widget.attrs:
            attrs.setdefault('step', 'any')
        return attrs

class IntegerField(Field, forms.IntegerField):
    widget = NumberInput

    def __init__(self, *args, **kwargs):
        kwargs.setdefault('widget', NumberInput if not kwargs.get('localize') else self.widget)
        super(IntegerField, self).__init__(*args, **kwargs)

    def widget_attrs(self, widget):
        attrs = super(IntegerField, self).widget_attrs(widget) or {}
        if self.min_value is not None:
            attrs['min'] = self.min_value
        if self.max_value is not None:
            attrs['max'] = self.max_value
        return attrs

class DecimalField(Field, forms.DecimalField):
    widget = NumberInput

    def __init__(self, *args, **kwargs):
        kwargs.setdefault('widget', NumberInput if not kwargs.get('localize') else self.widget)
        super(DecimalField, self).__init__(*args, **kwargs)

    def widget_attrs(self, widget):
        attrs = super(DecimalField, self).widget_attrs(widget) or {}
        if self.min_value is not None:
            attrs['min'] = self.min_value
        if self.max_value is not None:
            attrs['max'] = self.max_value
        if self.decimal_places is not None:
            attrs['step'] = decimal.Decimal('0.1') ** self.decimal_places
        return attrs

class EmailField(Field, forms.EmailField):
    widget = EmailInput

class URLField(Field, forms.URLField):
    widget = URLInput

class SlugField(Field, forms.SlugField):
    widget = SlugInput

class RegexField(Field, forms.RegexField):
    widget = TextInput

    def __init__(self, regex, js_regex=None, max_length=None, min_length=None,
                 error_message=None, *args, **kwargs):
        self.js_regex = js_regex
        super(RegexField, self).__init__(regex, max_length, min_length,
                                         *args, **kwargs)

    def widget_attrs(self, widget):
        attrs = super(RegexField, self).widget_attrs(widget) or {}
        if self.js_regex is not None:
            attrs['pattern'] = self.js_regex
        return attrs

if django.VERSION < (1, 9):
    class IPAddressField(Field, forms.IPAddressField):
        widget = IPAddressInput

class GenericIPAddressField(Field, forms.GenericIPAddressField):
    pass

class ComboField(Field, forms.ComboField):
    pass

class MultiValueField(Field, forms.MultiValueField):
    pass

class SplitDateTimeField(forms.SplitDateTimeField):
    widget = SplitDateTimeWidget
    hidden_widget = SplitHiddenDateTimeWidget

    def __init__(self, *args, **kwargs):
        super(SplitDateTimeField, self).__init__(*args, **kwargs)
        for widget in self.widget.widgets:
            widget.is_required = self.required
<commit_msg>Remove unused conditional import<commit_after>import django
from django import forms
import decimal

from .widgets import (TextInput, HiddenInput, CheckboxInput, Select,
                      ClearableFileInput, SelectMultiple, DateInput,
                      DateTimeInput, TimeInput, URLInput, NumberInput,
                      EmailInput, NullBooleanSelect, SlugInput, IPAddressInput,
                      SplitDateTimeWidget, SplitHiddenDateTimeWidget,
                      MultipleHiddenInput)

__all__ = (
    'Field', 'CharField', 'IntegerField', 'DateField', 'TimeField',
    'DateTimeField', 'EmailField', 'FileField', 'ImageField', 'URLField',
    'BooleanField', 'NullBooleanField', 'ChoiceField', 'MultipleChoiceField',
    'FloatField', 'DecimalField', 'SlugField', 'RegexField',
    'GenericIPAddressField', 'TypedChoiceField', 'FilePathField',
    'TypedMultipleChoiceField', 'ComboField', 'MultiValueField',
    'SplitDateTimeField',
)
if django.VERSION < (1, 9):
    __all__ += ('IPAddressField',)

class Field(forms.Field):
    widget = TextInput
    hidden_widget = HiddenInput

class CharField(Field, forms.CharField):
    widget = TextInput

    def widget_attrs(self, widget):
        attrs = super(CharField, self).widget_attrs(widget)
        if attrs is None:
            attrs = {}
        if self.max_length is not None and isinstance(widget, (TextInput, HiddenInput)):
            # The HTML attribute is maxlength, not max_length.
            attrs.update({'maxlength': str(self.max_length)})
        return attrs

class BooleanField(Field, forms.BooleanField):
    widget = CheckboxInput

class NullBooleanField(Field, forms.NullBooleanField):
    widget = NullBooleanSelect

class ChoiceField(Field, forms.ChoiceField):
    widget = Select

class TypedChoiceField(ChoiceField, forms.TypedChoiceField):
    widget = Select

class FilePathField(ChoiceField, forms.FilePathField):
    widget = Select

class FileField(Field, forms.FileField):
    widget = ClearableFileInput

class ImageField(Field, forms.ImageField):
    widget = ClearableFileInput

class MultipleChoiceField(Field, forms.MultipleChoiceField):
    widget = SelectMultiple
    hidden_widget = MultipleHiddenInput

class TypedMultipleChoiceField(MultipleChoiceField,
                               forms.TypedMultipleChoiceField):
    pass

class DateField(Field, forms.DateField):
    widget = DateInput

class DateTimeField(Field, forms.DateTimeField):
    widget = DateTimeInput

class TimeField(Field, forms.TimeField):
    widget = TimeInput

class FloatField(Field, forms.FloatField):
    widget = NumberInput

    def widget_attrs(self, widget):
        attrs = super(FloatField, self).widget_attrs(widget) or {}
        if self.min_value is not None:
            attrs['min'] = self.min_value
        if self.max_value is not None:
            attrs['max'] = self.max_value
        if 'step' not in widget.attrs:
            attrs.setdefault('step', 'any')
        return attrs

class IntegerField(Field, forms.IntegerField):
    widget = NumberInput

    def __init__(self, *args, **kwargs):
        kwargs.setdefault('widget', NumberInput if not kwargs.get('localize') else self.widget)
        super(IntegerField, self).__init__(*args, **kwargs)

    def widget_attrs(self, widget):
        attrs = super(IntegerField, self).widget_attrs(widget) or {}
        if self.min_value is not None:
            attrs['min'] = self.min_value
        if self.max_value is not None:
            attrs['max'] = self.max_value
        return attrs

class DecimalField(Field, forms.DecimalField):
    widget = NumberInput

    def __init__(self, *args, **kwargs):
        kwargs.setdefault('widget', NumberInput if not kwargs.get('localize') else self.widget)
        super(DecimalField, self).__init__(*args, **kwargs)

    def widget_attrs(self, widget):
        attrs = super(DecimalField, self).widget_attrs(widget) or {}
        if self.min_value is not None:
            attrs['min'] = self.min_value
        if self.max_value is not None:
            attrs['max'] = self.max_value
        if self.decimal_places is not None:
            attrs['step'] = decimal.Decimal('0.1') ** self.decimal_places
        return attrs

class EmailField(Field, forms.EmailField):
    widget = EmailInput

class URLField(Field, forms.URLField):
    widget = URLInput

class SlugField(Field, forms.SlugField):
    widget = SlugInput

class RegexField(Field, forms.RegexField):
    widget = TextInput

    def __init__(self, regex, js_regex=None, max_length=None, min_length=None,
                 error_message=None, *args, **kwargs):
        self.js_regex = js_regex
        super(RegexField, self).__init__(regex, max_length, min_length,
                                         *args, **kwargs)

    def widget_attrs(self, widget):
        attrs = super(RegexField, self).widget_attrs(widget) or {}
        if self.js_regex is not None:
            attrs['pattern'] = self.js_regex
        return attrs

if django.VERSION < (1, 9):
    class IPAddressField(Field, forms.IPAddressField):
        widget = IPAddressInput

class GenericIPAddressField(Field, forms.GenericIPAddressField):
    pass

class ComboField(Field, forms.ComboField):
    pass

class MultiValueField(Field, forms.MultiValueField):
    pass

class SplitDateTimeField(forms.SplitDateTimeField):
    widget = SplitDateTimeWidget
    hidden_widget = SplitHiddenDateTimeWidget

    def __init__(self, *args, **kwargs):
        super(SplitDateTimeField, self).__init__(*args, **kwargs)
        for widget in self.widget.widgets:
            widget.is_required = self.required
<|endoftext|>


<commit_before>#!/usr/bin/env python3
# -*- coding: utf-8 -*-
#
# @mail: sensor.wen@gmail.com
# @date: Mar 3, 2016
# @reference: http://www.oschina.net/code/snippet_90475_9224
#

import sys
import time
import json
import gzip
import urllib.request
import urllib.parse

class BaiduMap:
    """ get baidu map infomation.
    """
    def __init__(self, keyword):
        self.keyword = keyword
        self.query = [
                ('newmap', '1'),
                ('from', 'webmap'),
                ('qt', 's'),
                ('wd', keyword),
                ('wd2', ''),
                ('c', '1'),
                ('b', '(-1599062.039999999,811604.75;24779177.96,8168020.75)'),
                ('tn', 'B_NORMAL_MAP'),
                ('ie', 'utf-8'),
                ('t', time.time().__int__()),
                 ]
        self.mapurl = 'http://map.baidu.com/'
        self.file = open('{}.txt'.format(keyword), 'w')
        self.count = 0
        self.count_c = 0
        self.total_num = 0
        self._get_city()

    def _fetch(self, query=None, json=True):
        data = urllib.parse.urlencode(query)
        url = self.mapurl + '?' + data
        header = {'Accept-Encoding': 'gzip'}
        req = urllib.request.Request(url=url, headers=header)
        resp = urllib.request.urlopen(req).read()
        data = gzip.decompress(resp)

        if json:
            return self._tojson(data.decode())
        else:
            return data.decode()

    def _tojson(self, data):
        try:
            js = json.loads(data, 'utf-8')
        except:
            js = None

        return js

    def _get_city(self):
        data = self._fetch(self.query)

        if type(data['content']) is not list:
            print('keyworld error.')
            sys.exit()

        self.city = data['content']

        if 'more_city' in data:
            for c in data['more_city']:
                self.city.extend(c['city'])

        for city in self.city:
            self.total_num += city['num']

    def _get_data(self, city, page=0):
        query = [
                ('newmap', '1'),
                ('from', 'webmap'),
                ('qt', 'con'),
                ('wd', self.keyword),
                ('wd2', ''),
                ('c', city['code']),
                ('pn', page),
                ('b', '(%s)' % city['geo'].split('|')[1]),
                ('tn', 'B_NORMAL_MAP'),
                ('ie', 'utf-8'),
                ('t', time.time().__int__()),
                 ]

        data = self._fetch(query)
        return data

    def _save(self, content, city):
        for c in content:
            self.count += 1
            self.count_c += 1
            if 'tel' in c:
                tel = c['tel']
            else:
                tel = ''

            _data = '{},{},{},{}\n'.format(city['name'], c['name'], c['addr'], tel)
            self.file.write(_data)
            print('({}/{}) {}[{}/{}]'.format(self.count, self.total_num, city['name'], self.count_c, city['num']))

    def get(self, city):
        self.count_c = 0
        pages = abs(-city['num'] // 10)
        for page in range(0, pages):
            data = self._get_data(city, page)
            if 'content' in data:
                self._save(data['content'], city)

    def get_all(self):
        for city in self.city:
            self.get(city)

        self.file.close()

if __name__ == '__main__':
    if sys.argv.__len__() > 1:
        keyword = sys.argv[1]
    else:
        keyword = '酒店'

    baidumap = BaiduMap(keyword)
    print('_' * 20)
    print('City: {}'.format(baidumap.city.__len__()))
    print('Data: {}'.format(baidumap.total_num))
    print('(当前/总数) 城市 [当前/总数(城市)]')
    baidumap.get_all()

<commit_msg>bmap.py use asyncio<commit_after>#!/usr/bin/env python3
# -*- coding: utf-8 -*-
#
# @mail: sensor.wen@gmail.com
# @date: Mar 3, 2016
# @reference: http://www.oschina.net/code/snippet_90475_9224
#

import sys
import time
import json
import gzip
import urllib.request
import urllib.parse
import asyncio, aiohttp

class BaiduMap:
    """ get baidu map infomation.
    """
    def __init__(self, keyword):
        self.keyword = keyword
        self.query = [
                ('newmap', '1'),
                ('from', 'webmap'),
                ('qt', 's'),
                ('wd', keyword),
                ('wd2', ''),
                ('c', '1'),
                ('b', '(-1599062.039999999,811604.75;24779177.96,8168020.75)'),
                ('tn', 'B_NORMAL_MAP'),
                ('ie', 'utf-8'),
                ('t', time.time().__int__()),
                 ]
        self.mapurl = 'http://map.baidu.com/'
        self.file = open('{}.txt'.format(keyword), 'w')
        self.count = 0
        self.count_c = 0
        self.total_num = 0
        self._get_city()

    async def _fetch(self, query=None, json=True):
        data = urllib.parse.urlencode(query)
        url = self.mapurl + '?' + data
        header = {'Accept-Encoding': 'gzip'}
        with (await semaphore):
            resp = await aiohttp.request('GET', url=url, headers=header)
            data = await resp.read()

        if json:
            return self._tojson(data.decode())
        else:
            return data.decode()

    def _get(self, query=None, json=True):
        data = urllib.parse.urlencode(query)
        url = self.mapurl + '?' + data
        header = {'Accept-Encoding': 'gzip'}
        req = urllib.request.Request(url=url, headers=header)
        resp = urllib.request.urlopen(req).read()
        data = gzip.decompress(resp)

        if json:
            return self._tojson(data.decode())
        else:
            return data.decode()

    def _tojson(self, data):
        try:
            js = json.loads(data, 'utf-8')
        except:
            js = None

        return js

    def _get_city(self):
        data = self._get(self.query)

        if type(data['content']) is not list:
            print('keyworld error.')
            sys.exit()

        self.city = data['content']

        if 'more_city' in data:
            for c in data['more_city']:
                self.city.extend(c['city'])

        for city in self.city:
            self.total_num += city['num']

    async def _get_data(self, city, page=0):
        query = [
                ('newmap', '1'),
                ('from', 'webmap'),
                ('qt', 'con'),
                ('wd', self.keyword),
                ('wd2', ''),
                ('c', city['code']),
                ('pn', page),
                ('b', '(%s)' % city['geo'].split('|')[1]),
                ('tn', 'B_NORMAL_MAP'),
                ('ie', 'utf-8'),
                ('t', time.time().__int__()),
                 ]

        data = await self._fetch(query)
        return data

    def _save(self, content, city):
        for c in content:
            self.count += 1
            self.count_c += 1
            if 'tel' in c:
                tel = c['tel']
            else:
                tel = ''

            _data = '{},{},{},{}\n'.format(city['name'], c['name'], c['addr'], tel)
            self.file.write(_data)
            print('({}/{}) {}[{}/{}]'.format(self.count, self.total_num, city['name'], self.count_c, city['num']))

    async def get(self, city):
        self.count_c = 0
        pages = abs(-city['num'] // 10)
        for page in range(0, pages):
            data = await self._get_data(city, page)
            if 'content' in data:
                self._save(data['content'], city)

if __name__ == '__main__':
    if sys.argv.__len__() > 1:
        keyword = sys.argv[1]
    else:
        keyword = '如家'

    baidumap = BaiduMap(keyword)
    print('_' * 20)
    print('City: {}'.format(baidumap.city.__len__()))
    print('Data: {}'.format(baidumap.total_num))
    print('(当前/总数) 城市 [当前/总数(城市)]')

    global semaphore
    semaphore = asyncio.Semaphore(100)
    loop = asyncio.get_event_loop()
    tasks = asyncio.wait([baidumap.get(i) for i in baidumap.city])
    loop.run_until_complete(tasks)
    baidumap.file.close()
<|endoftext|>


<commit_before># coding=utf-8
#
# ROSREPO
# Manage ROS workspaces with multiple Gitlab repositories
#
# Author: Timo Röhling
#
# Copyright 2016 Fraunhofer FKIE
#
# 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.
#
#
__author__ = "Timo Röhling <timo.roehling@fkie.fraunhofer.de>"
__copyright__ = "Copyright (c) 2016 Fraunhofer FKIE"
__license__ = "Apache-2.0"
__version__ = "3.0.51"
<commit_msg>3.0.52<commit_after># coding=utf-8
#
# ROSREPO
# Manage ROS workspaces with multiple Gitlab repositories
#
# Author: Timo Röhling
#
# Copyright 2016 Fraunhofer FKIE
#
# 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.
#
#
__author__ = "Timo Röhling <timo.roehling@fkie.fraunhofer.de>"
__copyright__ = "Copyright (c) 2016 Fraunhofer FKIE"
__license__ = "Apache-2.0"
__version__ = "3.0.52"
<|endoftext|>