<commit_before>from typing import Any, Dict, List, Optional, Set, Tuple, Union  # mypy type checking

from .data import Alliance, DisplayType
from .ids.effect_id import EffectId
from .ids.upgrade_id import UpgradeId
from .ids.unit_typeid import UnitTypeId
from .pixel_map import PixelMap
from .position import Point2, Point3
from .power_source import PsionicMatrix
from .score import ScoreDetails
from .units import Units
from .constants import geyser_ids, mineral_ids

class Blip:
    def __init__(self, proto):
        self._proto = proto

    @property
    def is_blip(self) -> bool:
        """Detected by sensor tower."""
        return self._proto.is_blip

    @property
    def is_snapshot(self) -> bool:
        return self._proto.display_type == DisplayType.Snapshot.value

    @property
    def is_visible(self) -> bool:
        return self._proto.display_type == DisplayType.Visible.value

    @property
    def alliance(self) -> Alliance:
        return self._proto.alliance

    @property
    def is_mine(self) -> bool:
        return self._proto.alliance == Alliance.Self.value

    @property
    def is_enemy(self) -> bool:
        return self._proto.alliance == Alliance.Enemy.value

    @property
    def position(self) -> Point2:
        """2d position of the blip."""
        return self.position3d.to2

    @property
    def position3d(self) -> Point3:
        """3d position of the blip."""
        return Point3.from_proto(self._proto.pos)

class Common:
    ATTRIBUTES = [
        "player_id",
        "minerals", "vespene",
        "food_cap", "food_used",
        "food_army", "food_workers",
        "idle_worker_count", "army_count",
        "warp_gate_count", "larva_count"
    ]

    def __init__(self, proto):
        self._proto = proto

    def __getattr__(self, attr):
        assert attr in self.ATTRIBUTES, f"'{attr}' is not a valid attribute"
        return int(getattr(self._proto, attr))

class EffectData:
    def __init__(self, proto):
        self._proto = proto

    @property
    def id(self) -> EffectId:
        return EffectId(self._proto.effect_id)

    @property
    def positions(self) -> List[Point2]:
        return [Point2.from_proto(p) for p in self._proto.pos]

class GameState:
    def __init__(self, response_observation, game_data):
        self.actions = response_observation.actions  # successful actions since last loop
        self.action_errors = response_observation.action_errors  # error actions since last loop
        # https://github.com/Blizzard/s2client-proto/blob/51662231c0965eba47d5183ed0a6336d5ae6b640/s2clientprotocol/sc2api.proto#L575
        self.observation = response_observation.observation
        self.alerts = self.observation.alerts
        self.player_result = response_observation.player_result
        self.chat = response_observation.chat
        self.common: Common = Common(self.observation.player_common)
        self.psionic_matrix: PsionicMatrix = PsionicMatrix.from_proto(
            self.observation.raw_data.player.power_sources
        )  # what area pylon covers
        self.game_loop: int = self.observation.game_loop  # game loop, 22.4 per second on faster game speed

        self.score: ScoreDetails = ScoreDetails(
            self.observation.score
        )  # https://github.com/Blizzard/s2client-proto/blob/33f0ecf615aa06ca845ffe4739ef3133f37265a9/s2clientprotocol/score.proto#L31
        self.abilities = self.observation.abilities  # abilities of selected units

        # Fix for enemy units detected by my sensor tower, as blips have less unit information than normal visible units
        visibleUnits, hiddenUnits, minerals, geysers, destructables, enemy, own = ([] for _ in range(7))

        for unit in self.observation.raw_data.units:
            if unit.is_blip:
                hiddenUnits.append(unit)
            else:
                visibleUnits.append(unit)
                # all destructable rocks except the one below the main base ramps
                if unit.alliance == Alliance.Neutral.value and unit.radius > 1.5:
                    destructables.append(unit)
                elif unit.alliance == Alliance.Neutral.value:
                    # mineral field enums
                    if unit.unit_type in mineral_ids:
                        minerals.append(unit)
                    # geyser enums
                    elif unit.unit_type in geyser_ids:
                        geysers.append(unit)
                elif unit.alliance == Alliance.Self.value:
                    own.append(unit)
                elif unit.alliance == Alliance.Enemy.value:
                    enemy.append(unit)

        self.own_units: Units = Units.from_proto(own, game_data)
        self.enemy_units: Units = Units.from_proto(enemy, game_data)
        self.mineral_field: Units = Units.from_proto(minerals, game_data)
        self.vespene_geyser: Units = Units.from_proto(geysers, game_data)
        self.resources: Units = Units.from_proto(minerals + geysers, game_data)
        self.destructables: Units = Units.from_proto(destructables, game_data)
        self.units: Units = Units.from_proto(visibleUnits, game_data)
        self.upgrades: Set[UpgradeId] = {UpgradeId(upgrade) for upgrade in self.observation.raw_data.player.upgrade_ids}
        self.dead_units: Set[int] = {
            dead_unit_tag for dead_unit_tag in self.observation.raw_data.event.dead_units
        }  # set of unit tags that died this step - sometimes has multiple entries

        self.blips: Set[Blip] = {Blip(unit) for unit in hiddenUnits}
        self.visibility: PixelMap = PixelMap(self.observation.raw_data.map_state.visibility)
        self.creep: PixelMap = PixelMap(self.observation.raw_data.map_state.creep)

        self.effects: Set[EffectData] = {
            EffectData(effect) for effect in self.observation.raw_data.effects
        }  # effects like ravager bile shot, lurker attack, everything in effect_id.py
        """ Usage:
        for effect in self.state.effects:
            if effect.id == EffectId.RAVAGERCORROSIVEBILECP:
                positions = effect.positions
                # dodge the ravager biles
        """

<commit_msg>rollback1<commit_after>from typing import Any, Dict, List, Optional, Set, Tuple, Union  # mypy type checking

from .data import Alliance, DisplayType
from .ids.effect_id import EffectId
from .ids.upgrade_id import UpgradeId
from .ids.unit_typeid import UnitTypeId
from .pixel_map import PixelMap
from .position import Point2, Point3
from .power_source import PsionicMatrix
from .score import ScoreDetails
from .units import Units
from .constants import geyser_ids, mineral_ids

class Blip:
    def __init__(self, proto):
        self._proto = proto

    @property
    def is_blip(self) -> bool:
        """Detected by sensor tower."""
        return self._proto.is_blip

    @property
    def is_snapshot(self) -> bool:
        return self._proto.display_type == DisplayType.Snapshot.value

    @property
    def is_visible(self) -> bool:
        return self._proto.display_type == DisplayType.Visible.value

    @property
    def alliance(self) -> Alliance:
        return self._proto.alliance

    @property
    def is_mine(self) -> bool:
        return self._proto.alliance == Alliance.Self.value

    @property
    def is_enemy(self) -> bool:
        return self._proto.alliance == Alliance.Enemy.value

    @property
    def position(self) -> Point2:
        """2d position of the blip."""
        return self.position3d.to2

    @property
    def position3d(self) -> Point3:
        """3d position of the blip."""
        return Point3.from_proto(self._proto.pos)

class Common:
    ATTRIBUTES = [
        "player_id",
        "minerals", "vespene",
        "food_cap", "food_used",
        "food_army", "food_workers",
        "idle_worker_count", "army_count",
        "warp_gate_count", "larva_count"
    ]

    def __init__(self, proto):
        self._proto = proto

    def __getattr__(self, attr):
        assert attr in self.ATTRIBUTES, f"'{attr}' is not a valid attribute"
        return int(getattr(self._proto, attr))

class EffectData:
    def __init__(self, proto):
        self._proto = proto

    @property
    def id(self) -> EffectId:
        return EffectId(self._proto.effect_id)

    @property
    def positions(self) -> List[Point2]:
        return [Point2.from_proto(p) for p in self._proto.pos]

class GameState:
    def __init__(self, response_observation, game_data):
        self.actions = response_observation.actions  # successful actions since last loop
        self.action_errors = response_observation.action_errors  # error actions since last loop
        # https://github.com/Blizzard/s2client-proto/blob/51662231c0965eba47d5183ed0a6336d5ae6b640/s2clientprotocol/sc2api.proto#L575
        self.observation = response_observation.observation
        self.player_result = response_observation.player_result
        self.chat = response_observation.chat
        self.common: Common = Common(self.observation.player_common)
        self.psionic_matrix: PsionicMatrix = PsionicMatrix.from_proto(
            self.observation.raw_data.player.power_sources
        )  # what area pylon covers
        self.game_loop: int = self.observation.game_loop  # game loop, 22.4 per second on faster game speed

        self.score: ScoreDetails = ScoreDetails(
            self.observation.score
        )  # https://github.com/Blizzard/s2client-proto/blob/33f0ecf615aa06ca845ffe4739ef3133f37265a9/s2clientprotocol/score.proto#L31
        self.abilities = self.observation.abilities  # abilities of selected units

        # Fix for enemy units detected by my sensor tower, as blips have less unit information than normal visible units
        visibleUnits, hiddenUnits, minerals, geysers, destructables, enemy, own = ([] for _ in range(7))

        for unit in self.observation.raw_data.units:
            if unit.is_blip:
                hiddenUnits.append(unit)
            else:
                visibleUnits.append(unit)
                # all destructable rocks except the one below the main base ramps
                if unit.alliance == Alliance.Neutral.value and unit.radius > 1.5:
                    destructables.append(unit)
                elif unit.alliance == Alliance.Neutral.value:
                    # mineral field enums
                    if unit.unit_type in mineral_ids:
                        minerals.append(unit)
                    # geyser enums
                    elif unit.unit_type in geyser_ids:
                        geysers.append(unit)
                elif unit.alliance == Alliance.Self.value:
                    own.append(unit)
                elif unit.alliance == Alliance.Enemy.value:
                    enemy.append(unit)

        self.own_units: Units = Units.from_proto(own, game_data)
        self.enemy_units: Units = Units.from_proto(enemy, game_data)
        self.mineral_field: Units = Units.from_proto(minerals, game_data)
        self.vespene_geyser: Units = Units.from_proto(geysers, game_data)
        self.resources: Units = Units.from_proto(minerals + geysers, game_data)
        self.destructables: Units = Units.from_proto(destructables, game_data)
        self.units: Units = Units.from_proto(visibleUnits, game_data)
        self.upgrades: Set[UpgradeId] = {UpgradeId(upgrade) for upgrade in self.observation.raw_data.player.upgrade_ids}
        self.dead_units: Set[int] = {
            dead_unit_tag for dead_unit_tag in self.observation.raw_data.event.dead_units
        }  # set of unit tags that died this step - sometimes has multiple entries

        self.blips: Set[Blip] = {Blip(unit) for unit in hiddenUnits}
        self.visibility: PixelMap = PixelMap(self.observation.raw_data.map_state.visibility)
        self.creep: PixelMap = PixelMap(self.observation.raw_data.map_state.creep)

        self.effects: Set[EffectData] = {
            EffectData(effect) for effect in self.observation.raw_data.effects
        }  # effects like ravager bile shot, lurker attack, everything in effect_id.py
        """ Usage:
        for effect in self.state.effects:
            if effect.id == EffectId.RAVAGERCORROSIVEBILECP:
                positions = effect.positions
                # dodge the ravager biles
        """

<|endoftext|>


<commit_before>from blessings import Terminal
from django.core.management.base import BaseCommand
from sphinx.ext.intersphinx import fetch_inventory, INVENTORY_FILENAME

from cbv.models import Klass

t = Terminal()

class Command(BaseCommand):
    args = ''
    help = 'Fetches the docs urls for CBV Classes.'
    django_doc_url = 'http://django.readthedocs.org/en/{version}'
    # these versions need to be obtained manually from RTFD website
    # do not ask me why it is `1.5.x` for Django 1.5..
    django_versions = ['1.3', '1.4', '1.5.x']

    def bless_prints(self, version, msg):
        # wish the blessings lib supports method chaining..
        a = t.blue('Django ' + version + ': ')
        z = t.green(msg)
        print a + z

    def handle(self, *args, **options):
        """
        Docs urls for Classes can differ between Django versions.
        This script sets correct urls for specific Classes using bits from
        `sphinx.ext.intersphinx` to fetch docs inventory data.
        """

        for v in self.django_versions:
            cnt = 1

            ver_url = self.django_doc_url.format(version=v)
            ver_inv_url = ver_url + '/' + INVENTORY_FILENAME

            if '.x' in v:
                v = v.split('.x')[0]
            # get flat list of CBV classes per Django version
            qs_lookups = {'module__project_version__version_number': v}
            ver_classes = Klass.objects.filter(**qs_lookups).values_list(
                'name', flat=True)
            self.bless_prints(v, 'Found {0} classes'.format(len(ver_classes)))
            self.bless_prints(v, 'Getting inventory @ {0}'.format(ver_inv_url))
            # fetch some inventory dataz
            # the arg `None` should be a Sphinx instance object..
            invdata = fetch_inventory(None, ver_url, ver_inv_url)
            for role in invdata:
                # we only want classes..
                if role == 'py:class':
                    for item in invdata[role]:
                        # ..which come from django.views
                        if 'django.views.' in item:
                            # get class name
                            inv_klass = item.split('.')[-1]
                            # save hits to db and update only required classes
                            if inv_klass in ver_classes:
                                url = invdata[role][item][2]
                                Klass.objects.filter(**qs_lookups).update(
                                    docs_url=url)
                                cnt += 1
            self.bless_prints(v, 'Updated {0} classes\n'.format(cnt))
<commit_msg>Update the correct class<commit_after>from blessings import Terminal
from django.core.management.base import BaseCommand
from sphinx.ext.intersphinx import fetch_inventory, INVENTORY_FILENAME

from cbv.models import Klass

t = Terminal()

class Command(BaseCommand):
    args = ''
    help = 'Fetches the docs urls for CBV Classes.'
    django_doc_url = 'http://django.readthedocs.org/en/{version}'
    # these versions need to be obtained manually from RTFD website
    # do not ask me why it is `1.5.x` for Django 1.5..
    django_versions = ['1.3', '1.4', '1.5.x']

    def bless_prints(self, version, msg):
        # wish the blessings lib supports method chaining..
        a = t.blue('Django ' + version + ': ')
        z = t.green(msg)
        print a + z

    def handle(self, *args, **options):
        """
        Docs urls for Classes can differ between Django versions.
        This script sets correct urls for specific Classes using bits from
        `sphinx.ext.intersphinx` to fetch docs inventory data.
        """

        for v in self.django_versions:
            cnt = 1

            ver_url = self.django_doc_url.format(version=v)
            ver_inv_url = ver_url + '/' + INVENTORY_FILENAME

            if '.x' in v:
                v = v.split('.x')[0]
            # get flat list of CBV classes per Django version
            qs_lookups = {'module__project_version__version_number': v}
            ver_classes = Klass.objects.filter(**qs_lookups).values_list(
                'name', flat=True)
            self.bless_prints(v, 'Found {0} classes'.format(len(ver_classes)))
            self.bless_prints(v, 'Getting inventory @ {0}'.format(ver_inv_url))
            # fetch some inventory dataz
            # the arg `None` should be a Sphinx instance object..
            invdata = fetch_inventory(None, ver_url, ver_inv_url)
            for role in invdata:
                # we only want classes..
                if role == 'py:class':
                    for item in invdata[role]:
                        # ..which come from django.views
                        if 'django.views.' in item:
                            # get class name
                            inv_klass = item.split('.')[-1]
                            # save hits to db and update only required classes
                            if inv_klass in ver_classes:
                                url = invdata[role][item][2]
                                qs_lookups.update({
                                    'name': inv_klass
                                })
                                Klass.objects.filter(**qs_lookups).update(
                                    docs_url=url)
                                cnt += 1
            self.bless_prints(v, 'Updated {0} classes\n'.format(cnt))
<|endoftext|>


<commit_before>import json
import pytz
import datetime
import dateutil.parser
from django.utils.six.moves.urllib.parse import quote

from django.db.models import Q, F
from django.core.urlresolvers import reverse
from django.http import HttpResponse
from django.shortcuts import get_object_or_404
from django.utils import timezone
from django.http import HttpResponseRedirect, Http404, HttpResponseBadRequest
from django.views.generic.base import TemplateResponseMixin
from django.views.generic.detail import DetailView
from django.views.generic.edit import (
        UpdateView, CreateView, DeleteView, ModelFormMixin, ProcessFormView)
from django.utils.http import is_safe_url

from schedule.conf.settings import (GET_EVENTS_FUNC, OCCURRENCE_CANCEL_REDIRECT,
                                    EVENT_NAME_PLACEHOLDER, CHECK_EVENT_PERM_FUNC,
                                    CHECK_OCCURRENCE_PERM_FUNC, USE_FULLCALENDAR)
from schedule.forms import EventForm, OccurrenceForm
from schedule.models import Calendar, Occurrence, Event
from schedule.periods import weekday_names
from schedule.utils import (check_event_permissions,
    check_calendar_permissions, coerce_date_dict,
    check_occurrence_permissions)

class CalendarViewPermissionMixin(object):
    @classmethod
    def as_view(cls, **initkwargs):
        view = super(CalendarViewPermissionMixin, cls).as_view(**initkwargs)
        return check_calendar_permissions(view)

class EventEditPermissionMixin(object):
    @classmethod
    def as_view(cls, **initkwargs):
        view = super(EventEditPermissionMixin, cls).as_view(**initkwargs)
        return check_event_permissions(view)

class OccurrenceEditPermissionMixin(object):
    @classmethod
    def as_view(cls, **initkwargs):
        view = super(OccurrenceEditPermissionMixin, cls).as_view(**initkwargs)
        return check_occurrence_permissions(view)

class TemplateKwargMixin(TemplateResponseMixin):
    def get_template_names(self):
        if 'template_name' in self.kwargs:
            return [self.kwargs['template_name']]
        else:
            return super(TemplateKwargMixin, self).get_template_names()

class CancelButtonMixin(object):
    def post(self, request, *args, **kwargs):
        next_url = kwargs.get('next', None)
        self.success_url = get_next_url(request, next_url)
        if "cancel" in request.POST:
            return HttpResponseRedirect(self.success_url)
        else:
            return super(CancelButtonMixin, self).post(request, *args, **kwargs)

class CalendarMixin(CalendarViewPermissionMixin, TemplateKwargMixin):
    model = Calendar
    slug_url_kwarg = 'calendar_slug'

class CalendarView(CalendarMixin, DetailView):
    template_name = 'schedule/calendar.html'

class FullCalendarView(CalendarMixin, DetailView):
    template_name="fullcalendar.html"

    def get(self, request, *args, **kwargs):
        self.object = self.get_object()
        context = self.get_context_data(**kwargs)
        return self.render_to_response(context)

    def get_context_data(self, **kwargs):
        context = super(FullCalendarView, self).get_context_data()
        context = {
            'calendar_slug': kwargs.get('calendar_slug'),
        }
        return context

class CalendarByPeriodsView(CalendarMixin, DetailView):
    template_name = 'schedule/calendar_by_period.html'

    def get(self, request, *args, **kwargs):
        self.object = self.get_object()
        context = self.get_context_data(request, **kwargs)
        return self.render_to_response(context)

    def get_context_data(self, request, **kwargs):
        context = super(CalendarByPeriodsView, self).get_context_data(**kwargs)
        calendar = self.object
        period_class = kwargs['period']
        try:
            date = coerce_date_dict(request.GET)
        except ValueError:
            raise Http404
        if date:
            try:
                date = datetime.datetime(**date)
            except ValueError:
                raise Http404
        else:
            date = timezone.now()
        event_list = GET_EVENTS_FUNC(request, calendar)

        local_timezone = timezone.get_current_timezone()
        period = period_class(event_list, date, tzinfo=local_timezone)

        context.update({
            'date': date,
            'period': period,
            'calendar': calendar,
            'weekday_names': weekday_names,
            'here': quote(request.get_full_path()),
        })
        return context

class OccurrenceMixin(CalendarViewPermissionMixin, TemplateKwargMixin):
    model = Occurrence
    pk_url_kwarg = 'occurrence_id'
    form_class = OccurrenceForm

class OccurrenceEditMixin(CancelButtonMixin, OccurrenceEditPermissionMixin, OccurrenceMixin):
    def get_initial(self):
        initial_data = super(OccurrenceEditMixin, self).get_initial()
        _, self.object = get_occurrence(**self.kwargs)
        return initial_data

class OccurrenceView(OccurrenceMixin, DetailView):
    template_name = 'schedule/occurrence.html'

class OccurrencePreview(OccurrenceMixin, ModelFormMixin, ProcessFormView):
    template_name = 'schedule/occurrence.html'

    def get_context_data(self, **kwargs):
        context = super(OccurrencePreview, self).get_context_data()
        context = {
            'event': self.object.event,
            'occurrence': self.object,
        }
        return context

class EditOccurrenceView(OccurrenceEditMixin, UpdateView):
    template_name = 'schedule/edit_occurrence.html'

class CreateOccurrenceView(OccurrenceEditMixin, CreateView):
    template_name = 'schedule/edit_occurrence.html'

class CancelOccurrenceView(OccurrenceEditMixin, ModelFormMixin, ProcessFormView):
    template_name = 'schedule/cancel_occurrence.html'

    def post(self, request, *args, **kwargs):
        event, occurrence = get_occurrence(**kwargs)
        self.success_url = kwargs.get('next',
                        get_next_url(request, event.get_absolute_url()))
        if "cancel" not in request.POST:
            occurrence.cancel()
        return HttpResponseRedirect(self.success_url)

class EventMixin(CalendarViewPermissionMixin, TemplateKwargMixin):
    model = Event
    pk_url_kwarg = 'event_id'

class EventEditMixin(CancelButtonMixin, EventEditPermissionMixin, EventMixin):
    pass

class EventView(EventMixin, DetailView):
    template_name = 'schedule/event.html'

class EditEventView(EventEditMixin, UpdateView):
    form_class = EventForm
    template_name = 'schedule/create_event.html'

    def form_valid(self, form):
        event = form.save(commit=False)
        old_event = Event.objects.get(pk=event.pk)
        dts = datetime.timedelta(minutes=int((event.start - old_event.start).total_seconds() / 60))
        dte = datetime.timedelta(minutes=int((event.end - old_event.end).total_seconds() / 60))
        event.occurrence_set.all().update(
            original_start=F('original_start') + dts,
            original_end=F('original_end') + dte,
        )
        event.save()
        return super(EditEventView, self).form_valid(form)

class CreateEventView(EventEditMixin, CreateView):
    form_class = EventForm
    template_name = 'schedule/create_event.html'

    def get_initial(self):
        date = coerce_date_dict(self.request.GET)
        initial_data = None
        if date:
            try:
                start = datetime.datetime(**date)
                initial_data = {
                    "start": start,
                    "end": start + datetime.timedelta(minutes=30)
                }
            except TypeError:
                raise Http404
            except ValueError:
                raise Http404
        return initial_data

    def form_valid(self, form):
        event = form.save(commit=False)
        event.creator = self.request.user
        event.calendar = get_object_or_404(Calendar, slug=self.kwargs['calendar_slug'])
        event.save()
        return HttpResponseRedirect(event.get_absolute_url())

class DeleteEventView(EventEditMixin, DeleteView):
    template_name = 'schedule/delete_event.html'

    def get_context_data(self, **kwargs):
        ctx = super(DeleteEventView, self).get_context_data(**kwargs)
        ctx['next'] = self.get_success_url()
        return ctx

    def get_success_url(self):
        """
        After the event is deleted there are three options for redirect, tried in
        this order:
        # Try to find a 'next' GET variable
        # If the key word argument redirect is set
        # Lastly redirect to the event detail of the recently create event
        """
        url_val = 'fullcalendar' if USE_FULLCALENDAR else 'day_calendar'
        next_url = self.kwargs.get('next') or reverse(url_val, args=[self.object.calendar.slug])
        next_url = get_next_url(self.request, next_url)
        return next_url

def get_occurrence(event_id, occurrence_id=None, year=None, month=None,
                   day=None, hour=None, minute=None, second=None,
                   tzinfo=pytz.utc):
    """
    Because occurrences don't have to be persisted, there must be two ways to
    retrieve them. both need an event, but if its persisted the occurrence can
    be retrieved with an id. If it is not persisted it takes a date to
    retrieve it.  This function returns an event and occurrence regardless of
    which method is used.
    """
    if(occurrence_id):
        occurrence = get_object_or_404(Occurrence, id=occurrence_id)
        event = occurrence.event
    elif(all((year, month, day, hour, minute, second))):
        event = get_object_or_404(Event, id=event_id)
        occurrence = event.get_occurrence(
            datetime.datetime(int(year), int(month), int(day), int(hour),
                              int(minute), int(second), tzinfo=tzinfo))
        if occurrence is None:
            raise Http404
    else:
        raise Http404
    return event, occurrence

def check_next_url(next_url):
    """
    Checks to make sure the next url is not redirecting to another page.
    Basically it is a minimal security check.
    """
    if not next_url or '://' in next_url:
        return None
    return next_url

def get_next_url(request, default):
    next_url = default
    if OCCURRENCE_CANCEL_REDIRECT:
        next_url = OCCURRENCE_CANCEL_REDIRECT
    _next_url = request.GET.get('next') if request.method in ['GET', 'HEAD'] else request.POST.get('next')
    if _next_url and is_safe_url(url=_next_url, host=request.get_host()):
        next_url = _next_url
    return next_url

@check_calendar_permissions
def api_occurrences(request):
    utc=pytz.UTC
    if not request.GET.get('start') or not request.GET.get('end'):
        return HttpResponseBadRequest('Start and end parameters are required')
    # version 2 of full calendar
    # TODO: improve this code with date util package
    if '-' in request.GET.get('start'):
        def convert(ddatetime):
            if ddatetime:
                ddatetime = ddatetime.split(' ')[0]
                return datetime.datetime.strptime(ddatetime, '%Y-%m-%d')
    else:
        def convert(ddatetime):
            return datetime.datetime.utcfromtimestamp(float(ddatetime))

    start = utc.localize(convert(request.GET.get('start')))
    end = utc.localize(convert(request.GET.get('end')))
    calendar_slug = request.GET.get('calendar_slug')
    if calendar_slug:
        calendars = [get_object_or_404(Calendar, slug=calendar_slug)]
    # if no calendar slug is given, get all the calendars
    else:
        calendars = Calendar.objects.all()
    response_data =[]
    if Occurrence.objects.all().count() > 0:
        i = Occurrence.objects.latest('id').id + 1
    else:
        i = 1
    event_list = []
    for calendar in calendars:
        # create flat list of events from each calendar
        event_list += calendar.events.filter(start__lte=end).filter(
                        Q(end_recurring_period__gte=start) | Q(end_recurring_period__isnull=True))
    for event in event_list:
        occurrences = event.get_occurrences(start, end)
        for occurrence in occurrences:
            if occurrence.id:
                occurrence_id = occurrence.id
                existed = True
            else:
                occurrence_id = i + occurrence.event.id
                existed = False
            response_data.append({
                "id": occurrence_id,
                "title": occurrence.title,
                "start": occurrence.start.isoformat(),
                "end": occurrence.end.isoformat(),
                "existed": existed,
                "event_id": occurrence.event.id,
                "color": occurrence.event.color_event,
                "description": occurrence.description,
            })
    return HttpResponse(json.dumps(response_data), content_type="application/json")

@check_calendar_permissions
def api_move_or_resize_by_code(request):
    if request.method == 'POST':
        id = request.POST.get('id')
        existed = (request.POST.get('existed') == 'true')
        dt = datetime.timedelta(minutes=int(request.POST.get('delta')))
        resize = bool(request.POST.get('resize', False))
        resp = {}
        resp['status'] = "PERMISSION DENIED"

        if existed:
            occurrence = Occurrence.objects.get(id=id)
            occurrence.end += dt
            if not resize:
                occurrence.start += dt
            if CHECK_OCCURRENCE_PERM_FUNC(occurrence, request.user):
                occurrence.save()
                resp['status'] = "OK"
        else:
            event_id = request.POST.get('event_id')
            event = Event.objects.get(id=event_id)
            dts = 0
            dte = dt
            if not resize:
                event.start += dt
                dts = dt
            event.end = event.end + dt
            if CHECK_EVENT_PERM_FUNC(event, request.user):
                event.save()
                event.occurrence_set.all().update(
                    original_start=F('original_start') + dts,
                    original_end=F('original_end') + dte,
                )
                resp['status'] = "OK"
    return HttpResponse(json.dumps(resp))

@check_calendar_permissions
def api_select_create(request):
    if request.method == 'POST':
        calendar_slug = request.POST.get('calendar_slug')
        start = dateutil.parser.parse(request.POST.get('start'))
        end = dateutil.parser.parse(request.POST.get('end'))

        calendar = Calendar.objects.get(slug=calendar_slug)
        Event.objects.create(
                                        start=start,
                                        end=end,
                                        title=EVENT_NAME_PLACEHOLDER,
                                        calendar=calendar,
                                    )

        resp = {}
        resp['status'] = "OK"

    return HttpResponse(json.dumps(resp))
<commit_msg>Include most of the event details in the response<commit_after>import json
import pytz
import datetime
import dateutil.parser
from django.utils.six.moves.urllib.parse import quote

from django.db.models import Q, F
from django.core.urlresolvers import reverse
from django.http import HttpResponse
from django.shortcuts import get_object_or_404
from django.utils import timezone
from django.http import HttpResponseRedirect, Http404, HttpResponseBadRequest
from django.views.generic.base import TemplateResponseMixin
from django.views.generic.detail import DetailView
from django.views.generic.edit import (
        UpdateView, CreateView, DeleteView, ModelFormMixin, ProcessFormView)
from django.utils.http import is_safe_url

from schedule.conf.settings import (GET_EVENTS_FUNC, OCCURRENCE_CANCEL_REDIRECT,
                                    EVENT_NAME_PLACEHOLDER, CHECK_EVENT_PERM_FUNC,
                                    CHECK_OCCURRENCE_PERM_FUNC, USE_FULLCALENDAR)
from schedule.forms import EventForm, OccurrenceForm
from schedule.models import Calendar, Occurrence, Event
from schedule.periods import weekday_names
from schedule.utils import (check_event_permissions,
    check_calendar_permissions, coerce_date_dict,
    check_occurrence_permissions)

class CalendarViewPermissionMixin(object):
    @classmethod
    def as_view(cls, **initkwargs):
        view = super(CalendarViewPermissionMixin, cls).as_view(**initkwargs)
        return check_calendar_permissions(view)

class EventEditPermissionMixin(object):
    @classmethod
    def as_view(cls, **initkwargs):
        view = super(EventEditPermissionMixin, cls).as_view(**initkwargs)
        return check_event_permissions(view)

class OccurrenceEditPermissionMixin(object):
    @classmethod
    def as_view(cls, **initkwargs):
        view = super(OccurrenceEditPermissionMixin, cls).as_view(**initkwargs)
        return check_occurrence_permissions(view)

class TemplateKwargMixin(TemplateResponseMixin):
    def get_template_names(self):
        if 'template_name' in self.kwargs:
            return [self.kwargs['template_name']]
        else:
            return super(TemplateKwargMixin, self).get_template_names()

class CancelButtonMixin(object):
    def post(self, request, *args, **kwargs):
        next_url = kwargs.get('next', None)
        self.success_url = get_next_url(request, next_url)
        if "cancel" in request.POST:
            return HttpResponseRedirect(self.success_url)
        else:
            return super(CancelButtonMixin, self).post(request, *args, **kwargs)

class CalendarMixin(CalendarViewPermissionMixin, TemplateKwargMixin):
    model = Calendar
    slug_url_kwarg = 'calendar_slug'

class CalendarView(CalendarMixin, DetailView):
    template_name = 'schedule/calendar.html'

class FullCalendarView(CalendarMixin, DetailView):
    template_name="fullcalendar.html"

    def get(self, request, *args, **kwargs):
        self.object = self.get_object()
        context = self.get_context_data(**kwargs)
        return self.render_to_response(context)

    def get_context_data(self, **kwargs):
        context = super(FullCalendarView, self).get_context_data()
        context = {
            'calendar_slug': kwargs.get('calendar_slug'),
        }
        return context

class CalendarByPeriodsView(CalendarMixin, DetailView):
    template_name = 'schedule/calendar_by_period.html'

    def get(self, request, *args, **kwargs):
        self.object = self.get_object()
        context = self.get_context_data(request, **kwargs)
        return self.render_to_response(context)

    def get_context_data(self, request, **kwargs):
        context = super(CalendarByPeriodsView, self).get_context_data(**kwargs)
        calendar = self.object
        period_class = kwargs['period']
        try:
            date = coerce_date_dict(request.GET)
        except ValueError:
            raise Http404
        if date:
            try:
                date = datetime.datetime(**date)
            except ValueError:
                raise Http404
        else:
            date = timezone.now()
        event_list = GET_EVENTS_FUNC(request, calendar)

        local_timezone = timezone.get_current_timezone()
        period = period_class(event_list, date, tzinfo=local_timezone)

        context.update({
            'date': date,
            'period': period,
            'calendar': calendar,
            'weekday_names': weekday_names,
            'here': quote(request.get_full_path()),
        })
        return context

class OccurrenceMixin(CalendarViewPermissionMixin, TemplateKwargMixin):
    model = Occurrence
    pk_url_kwarg = 'occurrence_id'
    form_class = OccurrenceForm

class OccurrenceEditMixin(CancelButtonMixin, OccurrenceEditPermissionMixin, OccurrenceMixin):
    def get_initial(self):
        initial_data = super(OccurrenceEditMixin, self).get_initial()
        _, self.object = get_occurrence(**self.kwargs)
        return initial_data

class OccurrenceView(OccurrenceMixin, DetailView):
    template_name = 'schedule/occurrence.html'

class OccurrencePreview(OccurrenceMixin, ModelFormMixin, ProcessFormView):
    template_name = 'schedule/occurrence.html'

    def get_context_data(self, **kwargs):
        context = super(OccurrencePreview, self).get_context_data()
        context = {
            'event': self.object.event,
            'occurrence': self.object,
        }
        return context

class EditOccurrenceView(OccurrenceEditMixin, UpdateView):
    template_name = 'schedule/edit_occurrence.html'

class CreateOccurrenceView(OccurrenceEditMixin, CreateView):
    template_name = 'schedule/edit_occurrence.html'

class CancelOccurrenceView(OccurrenceEditMixin, ModelFormMixin, ProcessFormView):
    template_name = 'schedule/cancel_occurrence.html'

    def post(self, request, *args, **kwargs):
        event, occurrence = get_occurrence(**kwargs)
        self.success_url = kwargs.get('next',
                        get_next_url(request, event.get_absolute_url()))
        if "cancel" not in request.POST:
            occurrence.cancel()
        return HttpResponseRedirect(self.success_url)

class EventMixin(CalendarViewPermissionMixin, TemplateKwargMixin):
    model = Event
    pk_url_kwarg = 'event_id'

class EventEditMixin(CancelButtonMixin, EventEditPermissionMixin, EventMixin):
    pass

class EventView(EventMixin, DetailView):
    template_name = 'schedule/event.html'

class EditEventView(EventEditMixin, UpdateView):
    form_class = EventForm
    template_name = 'schedule/create_event.html'

    def form_valid(self, form):
        event = form.save(commit=False)
        old_event = Event.objects.get(pk=event.pk)
        dts = datetime.timedelta(minutes=int((event.start - old_event.start).total_seconds() / 60))
        dte = datetime.timedelta(minutes=int((event.end - old_event.end).total_seconds() / 60))
        event.occurrence_set.all().update(
            original_start=F('original_start') + dts,
            original_end=F('original_end') + dte,
        )
        event.save()
        return super(EditEventView, self).form_valid(form)

class CreateEventView(EventEditMixin, CreateView):
    form_class = EventForm
    template_name = 'schedule/create_event.html'

    def get_initial(self):
        date = coerce_date_dict(self.request.GET)
        initial_data = None
        if date:
            try:
                start = datetime.datetime(**date)
                initial_data = {
                    "start": start,
                    "end": start + datetime.timedelta(minutes=30)
                }
            except TypeError:
                raise Http404
            except ValueError:
                raise Http404
        return initial_data

    def form_valid(self, form):
        event = form.save(commit=False)
        event.creator = self.request.user
        event.calendar = get_object_or_404(Calendar, slug=self.kwargs['calendar_slug'])
        event.save()
        return HttpResponseRedirect(event.get_absolute_url())

class DeleteEventView(EventEditMixin, DeleteView):
    template_name = 'schedule/delete_event.html'

    def get_context_data(self, **kwargs):
        ctx = super(DeleteEventView, self).get_context_data(**kwargs)
        ctx['next'] = self.get_success_url()
        return ctx

    def get_success_url(self):
        """
        After the event is deleted there are three options for redirect, tried in
        this order:
        # Try to find a 'next' GET variable
        # If the key word argument redirect is set
        # Lastly redirect to the event detail of the recently create event
        """
        url_val = 'fullcalendar' if USE_FULLCALENDAR else 'day_calendar'
        next_url = self.kwargs.get('next') or reverse(url_val, args=[self.object.calendar.slug])
        next_url = get_next_url(self.request, next_url)
        return next_url

def get_occurrence(event_id, occurrence_id=None, year=None, month=None,
                   day=None, hour=None, minute=None, second=None,
                   tzinfo=pytz.utc):
    """
    Because occurrences don't have to be persisted, there must be two ways to
    retrieve them. both need an event, but if its persisted the occurrence can
    be retrieved with an id. If it is not persisted it takes a date to
    retrieve it.  This function returns an event and occurrence regardless of
    which method is used.
    """
    if(occurrence_id):
        occurrence = get_object_or_404(Occurrence, id=occurrence_id)
        event = occurrence.event
    elif(all((year, month, day, hour, minute, second))):
        event = get_object_or_404(Event, id=event_id)
        occurrence = event.get_occurrence(
            datetime.datetime(int(year), int(month), int(day), int(hour),
                              int(minute), int(second), tzinfo=tzinfo))
        if occurrence is None:
            raise Http404
    else:
        raise Http404
    return event, occurrence

def check_next_url(next_url):
    """
    Checks to make sure the next url is not redirecting to another page.
    Basically it is a minimal security check.
    """
    if not next_url or '://' in next_url:
        return None
    return next_url

def get_next_url(request, default):
    next_url = default
    if OCCURRENCE_CANCEL_REDIRECT:
        next_url = OCCURRENCE_CANCEL_REDIRECT
    _next_url = request.GET.get('next') if request.method in ['GET', 'HEAD'] else request.POST.get('next')
    if _next_url and is_safe_url(url=_next_url, host=request.get_host()):
        next_url = _next_url
    return next_url

@check_calendar_permissions
def api_occurrences(request):
    utc=pytz.UTC
    if not request.GET.get('start') or not request.GET.get('end'):
        return HttpResponseBadRequest('Start and end parameters are required')
    # version 2 of full calendar
    # TODO: improve this code with date util package
    if '-' in request.GET.get('start'):
        def convert(ddatetime):
            if ddatetime:
                ddatetime = ddatetime.split(' ')[0]
                return datetime.datetime.strptime(ddatetime, '%Y-%m-%d')
    else:
        def convert(ddatetime):
            return datetime.datetime.utcfromtimestamp(float(ddatetime))

    start = utc.localize(convert(request.GET.get('start')))
    end = utc.localize(convert(request.GET.get('end')))
    calendar_slug = request.GET.get('calendar_slug')
    if calendar_slug:
        calendars = [get_object_or_404(Calendar, slug=calendar_slug)]
    # if no calendar slug is given, get all the calendars
    else:
        calendars = Calendar.objects.all()
    response_data =[]
    if Occurrence.objects.all().count() > 0:
        i = Occurrence.objects.latest('id').id + 1
    else:
        i = 1
    event_list = []
    for calendar in calendars:
        # create flat list of events from each calendar
        event_list += calendar.events.filter(start__lte=end).filter(
                        Q(end_recurring_period__gte=start) | Q(end_recurring_period__isnull=True))
    for event in event_list:
        occurrences = event.get_occurrences(start, end)
        for occurrence in occurrences:
            if occurrence.id:
                occurrence_id = occurrence.id
                existed = True
            else:
                occurrence_id = i + occurrence.event.id
                existed = False
            recur_rule = occurrence.event.rule.name \
                if occurrence.event.rule else None
            recur_period_end = \
                occurrence.event.end_recurring_period.isoformat() \
                if occurrence.event.end_recurring_period else None
            response_data.append({
                "id": occurrence_id,
                "title": occurrence.title,
                "start": occurrence.start.isoformat(),
                "end": occurrence.end.isoformat(),
                "existed": existed,
                "event_id": occurrence.event.id,
                "color": occurrence.event.color_event,
                "description": occurrence.description,
                "rule": recur_rule,
                "end_recurring_period": recur_period_end,
                "creator": str(occurrence.event.creator),
                "calendar": occurrence.event.calendar.slug,
                "cancelled": occurrence.cancelled,
            })
    return HttpResponse(json.dumps(response_data), content_type="application/json")

@check_calendar_permissions
def api_move_or_resize_by_code(request):
    if request.method == 'POST':
        id = request.POST.get('id')
        existed = (request.POST.get('existed') == 'true')
        dt = datetime.timedelta(minutes=int(request.POST.get('delta')))
        resize = bool(request.POST.get('resize', False))
        resp = {}
        resp['status'] = "PERMISSION DENIED"

        if existed:
            occurrence = Occurrence.objects.get(id=id)
            occurrence.end += dt
            if not resize:
                occurrence.start += dt
            if CHECK_OCCURRENCE_PERM_FUNC(occurrence, request.user):
                occurrence.save()
                resp['status'] = "OK"
        else:
            event_id = request.POST.get('event_id')
            event = Event.objects.get(id=event_id)
            dts = 0
            dte = dt
            if not resize:
                event.start += dt
                dts = dt
            event.end = event.end + dt
            if CHECK_EVENT_PERM_FUNC(event, request.user):
                event.save()
                event.occurrence_set.all().update(
                    original_start=F('original_start') + dts,
                    original_end=F('original_end') + dte,
                )
                resp['status'] = "OK"
    return HttpResponse(json.dumps(resp))

@check_calendar_permissions
def api_select_create(request):
    if request.method == 'POST':
        calendar_slug = request.POST.get('calendar_slug')
        start = dateutil.parser.parse(request.POST.get('start'))
        end = dateutil.parser.parse(request.POST.get('end'))

        calendar = Calendar.objects.get(slug=calendar_slug)
        Event.objects.create(
                                        start=start,
                                        end=end,
                                        title=EVENT_NAME_PLACEHOLDER,
                                        calendar=calendar,
                                    )

        resp = {}
        resp['status'] = "OK"

    return HttpResponse(json.dumps(resp))
<|endoftext|>


<commit_before>import logging
import luigi
import os
import random
import string
import time
from collections import namedtuple

# ==============================================================================

log = logging.getLogger('sciluigi-interface')

# ==============================================================================

class AuditTrailHelpers():
    '''
    Mixin for luigi.Task:s, with functionality for writing audit logs of running tasks
    '''
    def add_auditinfo(self, infotype, infoval):
        return self._add_auditinfo(self.instance_name, infotype, infoval)

    def _add_auditinfo(self, instance_name, infotype, infoval):
        dirpath = self.workflow_task.get_auditdirpath()
        if not os.path.exists(dirpath):
            os.makedirs(dirpath)

        auditfile = os.path.join(dirpath, instance_name)
        if not os.path.exists(auditfile):
            with open(auditfile, 'w') as afile:
                afile.write('[%s]\n' % self.instance_name)
        with open(auditfile, 'a') as afile:
            afile.write('%s: %s\n' % (infotype, infoval))

    def get_instance_name(self):
        instance_name = None
        if self.instance_name is not None:
            instance_name = self.instance_name
        else:
            instance_name = self.task_id
        return instance_name

    def get_timestamp(self):
        return timelog()

    @luigi.Task.event_handler(luigi.Event.START)
    def save_start_time(self):
        if hasattr(self, 'workflow_task') and self.workflow_task is not None:
            msg = 'Task {task} started'.format(
                    task = self.get_instance_name())
            log.info(msg)

    @luigi.Task.event_handler(luigi.Event.PROCESSING_TIME)
    def save_end_time(self, task_exectime_sec):
        if hasattr(self, 'workflow_task') and self.workflow_task is not None:
            msg = 'Task {task} finished after {proctime:.3f}s'.format(
                    task = self.get_instance_name(),
                    proctime = task_exectime_sec)
            log.info(msg)
            self.add_auditinfo('task_exectime_sec', '%.3f' % task_exectime_sec)
            for paramname, paramval in self.param_kwargs.iteritems():
                if paramname not in ['workflow_task']:
                    self.add_auditinfo(paramname, paramval)
<commit_msg>Handle problem with multiple jobs checking the same folder at the same time, by sleeping randomly up to 1 sec<commit_after>import logging
import luigi
import os
import random
import string
import time
from collections import namedtuple

# ==============================================================================

log = logging.getLogger('sciluigi-interface')

# ==============================================================================

class AuditTrailHelpers():
    '''
    Mixin for luigi.Task:s, with functionality for writing audit logs of running tasks
    '''
    def add_auditinfo(self, infotype, infoval):
        return self._add_auditinfo(self.instance_name, infotype, infoval)

    def _add_auditinfo(self, instance_name, infotype, infoval):
        dirpath = self.workflow_task.get_auditdirpath()
        if not os.path.isdir(dirpath):
            time.sleep(random.random())
            if not os.path.isdir(dirpath):
                os.makedirs(dirpath)

        auditfile = os.path.join(dirpath, instance_name)
        if not os.path.exists(auditfile):
            with open(auditfile, 'w') as afile:
                afile.write('[%s]\n' % self.instance_name)
        with open(auditfile, 'a') as afile:
            afile.write('%s: %s\n' % (infotype, infoval))

    def get_instance_name(self):
        instance_name = None
        if self.instance_name is not None:
            instance_name = self.instance_name
        else:
            instance_name = self.task_id
        return instance_name

    def get_timestamp(self):
        return timelog()

    @luigi.Task.event_handler(luigi.Event.START)
    def save_start_time(self):
        if hasattr(self, 'workflow_task') and self.workflow_task is not None:
            msg = 'Task {task} started'.format(
                    task = self.get_instance_name())
            log.info(msg)

    @luigi.Task.event_handler(luigi.Event.PROCESSING_TIME)
    def save_end_time(self, task_exectime_sec):
        if hasattr(self, 'workflow_task') and self.workflow_task is not None:
            msg = 'Task {task} finished after {proctime:.3f}s'.format(
                    task = self.get_instance_name(),
                    proctime = task_exectime_sec)
            log.info(msg)
            self.add_auditinfo('task_exectime_sec', '%.3f' % task_exectime_sec)
            for paramname, paramval in self.param_kwargs.iteritems():
                if paramname not in ['workflow_task']:
                    self.add_auditinfo(paramname, paramval)
<|endoftext|>


<commit_before>from __future__ import unicode_literals

try:
    # Django 1.4+
    from django.conf.urls import patterns, url
except ImportError: # pragma: no cover
    # Django 1.3
    from django.conf.urls.defaults import patterns, url

from scribbler import views

urlpatterns = patterns('',
    url('^preview/$', views.preview_scribble, name='preview-scribble'),
    url('^create/$', views.create_edit_scribble, name='create-scribble'),
    url('^edit/(?P<scribble_id>(\d+))/$', views.create_edit_scribble, name='edit-scribble'),
    url('^delete/(?P<scribble_id>(\d+))/$', views.delete_scribble, name='delete-scribble'),
    url('^edit-field/(?P<ct_pk>(\d+))/(?P<instance_pk>(\d+))/(?P<field_name>(\w+))/$',
       views.edit_scribble_field, name='edit-scribble-field'),
)
<commit_msg>remove patterns() from urls.py<commit_after>from __future__ import unicode_literals

try:
    # Django 1.4+
    from django.conf.urls import url
except ImportError: # pragma: no cover
    # Django 1.3
    from django.conf.urls.defaults import url

from scribbler import views

urlpatterns = (
    url('^preview/$', views.preview_scribble, name='preview-scribble'),
    url('^create/$', views.create_edit_scribble, name='create-scribble'),
    url('^edit/(?P<scribble_id>(\d+))/$', views.create_edit_scribble, name='edit-scribble'),
    url('^delete/(?P<scribble_id>(\d+))/$', views.delete_scribble, name='delete-scribble'),
    url('^edit-field/(?P<ct_pk>(\d+))/(?P<instance_pk>(\d+))/(?P<field_name>(\w+))/$',
       views.edit_scribble_field, name='edit-scribble-field'),
)
<|endoftext|>


<commit_before>from __future__ import division

import numpy as np

import chainer
import chainer.functions as F

def _elementwise_softmax_cross_entropy(x, t):
    assert x.shape[:-1] == t.shape
    shape = t.shape
    x = F.reshape(x, (-1, x.shape[-1]))
    t = F.flatten(t)
    return F.reshape(
        F.softmax_cross_entropy(x, t, reduce='no'), shape)

def _hard_negative(x, positive, k):
    rank = (x * (positive - 1)).argsort(axis=1).argsort(axis=1)
    hard_negative = rank < (positive.sum(axis=1) * k)[:, np.newaxis]
    return hard_negative

def multibox_loss(mb_locs, mb_confs, gt_mb_locs, gt_mb_labels, k):
    """Computes multibox losses.

    This is a loss function used in [#]_.
    This function returns :obj:`loc_loss` and :obj:`conf_loss`.
    :obj:`loc_loss` is a loss for localization and
    :obj:`conf_loss` is a loss for classification.
    The formulas of these losses can be found in
    the equation (2) and (3) in the original paper.

    .. [#] Wei Liu, Dragomir Anguelov, Dumitru Erhan,
       Christian Szegedy, Scott Reed, Cheng-Yang Fu, Alexander C. Berg.
       SSD: Single Shot MultiBox Detector. ECCV 2016.

    Args:
        mb_locs (chainer.Variable or array): The offsets and scales
            for predicted bounding boxes.
            Its shape is :math:`(B, K, 4)`,
            where :math:`B` is the number of samples in the batch and
            :math:`K` is the number of default bounding boxes.
        mb_confs (chainer.Variable or array): The classes of predicted
            bounding boxes.
            Its shape is :math:`(B, K, n\_class)`.
            This function assumes the first class is background (negative).
        gt_mb_locs (chainer.Variable or array): The offsets and scales
            for ground truth bounding boxes.
            Its shape is :math:`(B, K, 4)`.
        gt_mb_labels (chainer.Variable or array): The classes of ground truth
            bounding boxes.
            Its shape is :math:`(B, K)`.
        k (float): A coefficient which is used for hard negative mining.
            This value determines the ratio between the number of positives
            and that of mined negatives. The value used in the original paper
            is :obj:`3`.

    Returns:
        tuple of chainer.Variable:
        This function returns two :obj:`chainer.Variable`: :obj:`loc_loss` and
        :obj:`conf_loss`.
    """
    mb_locs = chainer.as_variable(mb_locs)
    mb_confs = chainer.as_variable(mb_confs)
    gt_mb_locs = chainer.as_variable(gt_mb_locs)
    gt_mb_labels = chainer.as_variable(gt_mb_labels)

    xp = chainer.cuda.get_array_module(gt_mb_labels.array)

    positive = gt_mb_labels.array > 0
    n_positive = positive.sum()
    if n_positive == 0:
        z = chainer.Variable(xp.zeros((), dtype=np.float32))
        return z, z

    loc_loss = F.huber_loss(mb_locs, gt_mb_locs, 1, reduce='no')
    loc_loss = F.sum(loc_loss, axis=-1)
    loc_loss *= positive.astype(loc_loss.dtype)
    loc_loss = F.sum(loc_loss) / n_positive

    conf_loss = _elementwise_softmax_cross_entropy(mb_confs, gt_mb_labels)
    hard_negative = _hard_negative(conf_loss.array, positive, k)
    conf_loss *= xp.logical_or(positive, hard_negative).astype(conf_loss.dtype)
    conf_loss = F.sum(conf_loss) / n_positive

    return loc_loss, conf_loss
<commit_msg>add n_positive option<commit_after>from __future__ import division

import numpy as np

import chainer
import chainer.functions as F

def _elementwise_softmax_cross_entropy(x, t):
    assert x.shape[:-1] == t.shape
    shape = t.shape
    x = F.reshape(x, (-1, x.shape[-1]))
    t = F.flatten(t)
    return F.reshape(
        F.softmax_cross_entropy(x, t, reduce='no'), shape)

def _hard_negative(x, positive, k):
    rank = (x * (positive - 1)).argsort(axis=1).argsort(axis=1)
    hard_negative = rank < (positive.sum(axis=1) * k)[:, np.newaxis]
    return hard_negative

def multibox_loss(mb_locs, mb_confs, gt_mb_locs, gt_mb_labels, k,
                  n_positive=None):
    """Computes multibox losses.

    This is a loss function used in [#]_.
    This function returns :obj:`loc_loss` and :obj:`conf_loss`.
    :obj:`loc_loss` is a loss for localization and
    :obj:`conf_loss` is a loss for classification.
    The formulas of these losses can be found in
    the equation (2) and (3) in the original paper.

    .. [#] Wei Liu, Dragomir Anguelov, Dumitru Erhan,
       Christian Szegedy, Scott Reed, Cheng-Yang Fu, Alexander C. Berg.
       SSD: Single Shot MultiBox Detector. ECCV 2016.

    Args:
        mb_locs (chainer.Variable or array): The offsets and scales
            for predicted bounding boxes.
            Its shape is :math:`(B, K, 4)`,
            where :math:`B` is the number of samples in the batch and
            :math:`K` is the number of default bounding boxes.
        mb_confs (chainer.Variable or array): The classes of predicted
            bounding boxes.
            Its shape is :math:`(B, K, n\_class)`.
            This function assumes the first class is background (negative).
        gt_mb_locs (chainer.Variable or array): The offsets and scales
            for ground truth bounding boxes.
            Its shape is :math:`(B, K, 4)`.
        gt_mb_labels (chainer.Variable or array): The classes of ground truth
            bounding boxes.
            Its shape is :math:`(B, K)`.
        k (float): A coefficient which is used for hard negative mining.
            This value determines the ratio between the number of positives
            and that of mined negatives. The value used in the original paper
            is :obj:`3`.
        n_positive (int): The number of positive examples in the batch.
            If this value is not specified, it is computed from
            :obj:`gt_mb_labels`.

    Returns:
        tuple of chainer.Variable:
        This function returns two :obj:`chainer.Variable`: :obj:`loc_loss` and
        :obj:`conf_loss`.
    """
    mb_locs = chainer.as_variable(mb_locs)
    mb_confs = chainer.as_variable(mb_confs)
    gt_mb_locs = chainer.as_variable(gt_mb_locs)
    gt_mb_labels = chainer.as_variable(gt_mb_labels)

    xp = chainer.cuda.get_array_module(gt_mb_labels.array)

    positive = gt_mb_labels.array > 0
    if n_positive is None:
        n_positive = positive.sum()
    if n_positive == 0:
        z = chainer.Variable(xp.zeros((), dtype=np.float32))
        return z, z

    loc_loss = F.huber_loss(mb_locs, gt_mb_locs, 1, reduce='no')
    loc_loss = F.sum(loc_loss, axis=-1)
    loc_loss *= positive.astype(loc_loss.dtype)
    loc_loss = F.sum(loc_loss) / n_positive

    conf_loss = _elementwise_softmax_cross_entropy(mb_confs, gt_mb_labels)
    hard_negative = _hard_negative(conf_loss.array, positive, k)
    conf_loss *= xp.logical_or(positive, hard_negative).astype(conf_loss.dtype)
    conf_loss = F.sum(conf_loss) / n_positive

    return loc_loss, conf_loss
<|endoftext|>


<commit_before>import logging

import sanic

import raven
import raven_aiohttp
from raven.handlers.logging import SentryHandler

class SanicSentry:
    def __init__(self, app=None):
        self.app = None
        self.handler = None
        self.client = None
        if app is not None:
            self.init_app(app)

    def init_app(self, app: sanic.Sanic):
        self.client = raven.Client(
            dsn=app.config['SENTRY_DSN'],
            transport=raven_aiohttp.AioHttpTransport,
        )
        self.handler = SentryHandler(client=self.client, level=app.config.get('SENTRY_LEVEL', logging.ERROR))
        logger = logging.getLogger('sanic')
        logger.addHandler(self.handler)
        self.app = app
        self.app.sentry = self
<commit_msg>Fix to work on Sanic 0.7<commit_after>import logging

import sanic
from sanic.log import logger

import raven
import raven_aiohttp
from raven.handlers.logging import SentryHandler

class SanicSentry:
    def __init__(self, app=None):
        self.app = None
        self.handler = None
        self.client = None
        if app is not None:
            self.init_app(app)

    def init_app(self, app: sanic.Sanic):
        self.client = raven.Client(
            dsn=app.config['SENTRY_DSN'],
            transport=raven_aiohttp.AioHttpTransport,
        )
        self.handler = SentryHandler(client=self.client, level=app.config.get('SENTRY_LEVEL', logging.ERROR))
        logger.addHandler(self.handler)
        self.app = app
        self.app.sentry = self
<|endoftext|>


<commit_before>'''
Created on Apr 2, 2014

Top level module that is responsible for initializing everything

@author: theoklitos
'''

import sys
import urllib2
from util import configuration, misc_utils
from hardware import temperature
from database import mysql_adapter
import time
from threading import Thread

def checkImports():
    try:
        __import__('RPi')
        try:
            import RPi.GPIO  # @UnusedImport
        except RuntimeError:
            raise ImportError()
    except ImportError:
        sys.exit('Either you are not using a raspberry pi or you don\'t have RPi installed.\nTry visiting https://pypi.python.org/pypi/RPi.GPIO')
    try:
        __import__('api')
    except ImportError:
        sys.exit('You need to install api.py. Try visiting http://webpy.org/install')
    print 'Installed libraries and modules are all place.'

def do_sound_check(gpio):
    """ asks the user if he heard 4 clicks, returns the boolean result"""
    print 'Did you hear the four distinct noises (enter \'y\' or \'n\' or any other key to repeat)?'
    response = misc_utils.get_single_char().lower()
    if response == 'y':
        return True
    elif response == 'n':
        gpio.cleanup()
        sys.exit('There seems to be a pin connectivity problem, check your wiring. Terminating.')
    else:
        return False

def checkHardware():
    # first the GPIO pins
    import hardware.chestfreezer_gpio as gpio
    sound_check_passed = True;
    while not sound_check_passed:
        print 'Checking device control - you should hear four clicking noises...'
        time.sleep(1)
        try:
            gpio.output_pin_for_time(configuration.heater_pin(), False, 1)
            time.sleep(1)
            gpio.output_pin_for_time(configuration.freezer_pin(), False, 1)
        except ValueError as e:
            sys.exit('Pins could not be activated, reason:\n' + str(e) + '\nTerminating.')
        sound_check_passed = do_sound_check(gpio)
    print 'GPIO pins #' + configuration.heater_pin() + ' and #' + configuration.freezer_pin() + ' connected correctly.'

    # then the temperature sensor(s)
    temperature.initialize_probes()
    probes = temperature.probe_ids
    if probes is None:
        sys.exit('No temperature probes were detected, check your wiring. Terminating.')
    else:
        print 'Found ' + str(len(probes)) + ' functional temperature sensor(s).'
        mysql_adapter.determine_master_probe()

def checkInternetConnectivity():
    print 'Checking internet connectivity...',
    try:
        urllib2.urlopen('http://74.125.228.100', timeout=5)  # ping google
        do_we_have_internet = True
    except urllib2.URLError:
        do_we_have_internet = False
    if do_we_have_internet:
        print 'connection is good.'
    else:
        print '\nCould not reach the internet. If you want to proceed regardless then press \'y\', otherwise press any other key to exit.'
        response = misc_utils.get_single_char().lower()
        if response != 'y':
            sys.exit('Terminating.')

def checkAndInitDatabase():
    try:
        mysql_adapter.connect()
        print 'Successfully connected to the database.'
    except Exception as e:
        sys.exit('Could not connect to database. Error:\n' + str(e) + '\nTerminating.')

def startTemperatureRecordingThread():
    """ starts a thread that stored the temperature readings every second """
    def record_temperatures():
        while True:
            try:
                mysql_adapter.store_temperatures(temperature.get_temperature_readings())
            except Exception as e:
                print 'Could not log temperature. Error:\n' + str(e)
            time.sleep(configuration.store_temperature_interval_seconds())
    temperature_recording_thread = Thread(target=record_temperatures, args=())
    temperature_recording_thread.start()

def startControllerThread():
    pass

def startWebInterface():
    import api.chestfreezer_api as api
    print 'Starting web interface...\n'
    api.run()

if __name__ == "__main__":
    # check if everything is in place
    checkImports()
    checkAndInitDatabase()
    checkHardware()
    checkInternetConnectivity()

    # start threads that do all the work
    startTemperatureRecordingThread()
    startControllerThread()

    # finally, the api interface
    startWebInterface()

<commit_msg>reverted removed HW check<commit_after>'''
Created on Apr 2, 2014

Top level module that is responsible for initializing everything

@author: theoklitos
'''

import sys
import urllib2
from util import configuration, misc_utils
from hardware import temperature
from database import mysql_adapter
import time
from threading import Thread

def checkImports():
    try:
        __import__('RPi')
        try:
            import RPi.GPIO  # @UnusedImport
        except RuntimeError:
            raise ImportError()
    except ImportError:
        sys.exit('Either you are not using a raspberry pi or you don\'t have RPi installed.\nTry visiting https://pypi.python.org/pypi/RPi.GPIO')
    try:
        __import__('api')
    except ImportError:
        sys.exit('You need to install api.py. Try visiting http://webpy.org/install')
    print 'Installed libraries and modules are all place.'

def do_sound_check(gpio):
    """ asks the user if he heard 4 clicks, returns the boolean result"""
    print 'Did you hear the four distinct noises (enter \'y\' or \'n\' or any other key to repeat)?'
    response = misc_utils.get_single_char().lower()
    if response == 'y':
        return True
    elif response == 'n':
        gpio.cleanup()
        sys.exit('There seems to be a pin connectivity problem, check your wiring. Terminating.')
    else:
        return False

def checkHardware():
    # first the GPIO pins
    import hardware.chestfreezer_gpio as gpio
    sound_check_passed = False;
    while not sound_check_passed:
        print 'Checking device control - you should hear four clicking noises...'
        time.sleep(1)
        try:
            gpio.output_pin_for_time(configuration.heater_pin(), False, 1)
            time.sleep(1)
            gpio.output_pin_for_time(configuration.freezer_pin(), False, 1)
        except ValueError as e:
            sys.exit('Pins could not be activated, reason:\n' + str(e) + '\nTerminating.')
        sound_check_passed = do_sound_check(gpio)
    print 'GPIO pins #' + configuration.heater_pin() + ' and #' + configuration.freezer_pin() + ' connected correctly.'

    # then the temperature sensor(s)
    temperature.initialize_probes()
    probes = temperature.probe_ids
    if probes is None:
        sys.exit('No temperature probes were detected, check your wiring. Terminating.')
    else:
        print 'Found ' + str(len(probes)) + ' functional temperature sensor(s).'
        mysql_adapter.determine_master_probe()

def checkInternetConnectivity():
    print 'Checking internet connectivity...',
    try:
        urllib2.urlopen('http://74.125.228.100', timeout=5)  # ping google
        do_we_have_internet = True
    except urllib2.URLError:
        do_we_have_internet = False
    if do_we_have_internet:
        print 'connection is good.'
    else:
        print '\nCould not reach the internet. If you want to proceed regardless then press \'y\', otherwise press any other key to exit.'
        response = misc_utils.get_single_char().lower()
        if response != 'y':
            sys.exit('Terminating.')

def checkAndInitDatabase():
    try:
        mysql_adapter.connect()
        print 'Successfully connected to the database.'
    except Exception as e:
        sys.exit('Could not connect to database. Error:\n' + str(e) + '\nTerminating.')

def startTemperatureRecordingThread():
    """ starts a thread that stored the temperature readings every second """
    def record_temperatures():
        while True:
            try:
                mysql_adapter.store_temperatures(temperature.get_temperature_readings())
            except Exception as e:
                print 'Could not log temperature. Error:\n' + str(e)
            time.sleep(configuration.store_temperature_interval_seconds())
    temperature_recording_thread = Thread(target=record_temperatures, args=())
    temperature_recording_thread.start()

def startControllerThread():
    pass

def startWebInterface():
    import api.chestfreezer_api as api
    print 'Starting web interface...\n'
    api.run()

if __name__ == "__main__":
    # check if everything is in place
    checkImports()
    checkAndInitDatabase()
    checkHardware()
    checkInternetConnectivity()

    # start threads that do all the work
    startTemperatureRecordingThread()
    startControllerThread()

    # finally, the api interface
    startWebInterface()

<|endoftext|>


<commit_before>class Provider(object):
    """Base provider class"""
    regions = {}

    def __init__(self, key=''):
        self.key = key

    def create(self):
        raise NotImplemented()

    def start(self):
        raise NotImplemented()

    def stop():
        raise NotImplemented()

    def dstroy():
        raise NotImplemented()

    def list_servers():
        raise NotImplemented()

    def status():
        raise NotImplemented()
<commit_msg>Add parameters to base provider methods<commit_after>class Provider(object):
    """Base provider class"""
    regions = {}

    def __init__(self, key=''):
        self.key = key

    def create(self, region, name='hello'):
        raise NotImplemented()

    def start(self):
        raise NotImplemented()

    def stop(self):
        raise NotImplemented()

    def dstroy(self):
        raise NotImplemented()

    def list_servers(self):
        raise NotImplemented()

    def status(self):
        raise NotImplemented()
<|endoftext|>


<commit_before>"""
Configurable Pipeline for the Analysis of Connectomes
=====================================================

CPAC is a configurable, open-source, Nipype-based, automated processing pipeline for resting state functional MRI (R-fMRI) data, for use by both novice and expert users.
"""

from numpy.testing import nosetester
test = nosetester.NoseTester.test

class _NoseTester(nosetester.NoseTester):
    def test(self, label='fast', verbose=1, extra_argv=['--exe'], doctests = False, coverage=False):
        return super(_NoseTester, self).test(label=label, verbose=verbose, extra_argv=extra_argv, doctests=doctests, coverage=coverage)

test = _NoseTester().test

import anat_preproc, \
       func_preproc, \
       reho, \
       seg_preproc, \
       registration, \
       sca, \
       basc, \
       nuisance, \
       generate_motion_statistics, \
       alff, \
       qc, \
       seg_preproc, \
       vmhc, \
       median_angle, \
       timeseries, \
       network_centrality, \
       scrubbing, \
       group_analysis, \
       easy_thresh,\
       utils, \
       pipeline, \
       cwas, \
       GUI

__all__ = ['GUI', 'pipeline', 'anat_preproc', 'func_preproc', 'registration', 'seg_preproc', 'reho', 'sca', 'basc', 'nuisance', 'alff', 'vmhc', 'median_angle', 'generate_motion_statistics', 'timeseries', 'network_centrality', 'scrubbing', 'utils', 'group_analysis', 'easy_thresh', 'qc', 'cwas']

#__version__ = '0.1-git'

from subprocess import Popen, PIPE
import re

try:
    version = '0.3.1'
#    gitproc = Popen(['git', 'log', '--oneline'], stdout = PIPE)
#    (stdout, stderr) = gitproc.communicate()
#    rows = stdout.split("\n")
#    v_num = re.search( r'(?<=(version_|release_))(.)*', rows[0])
#    if v_num:
#        version = v_num.group(0).strip("'")
#    else:
#        version = 'unknown_version'
except OSError:
    version = 'unknown_version'

__version__ =  str(version)
<commit_msg>Update __init__.py<commit_after>"""
Configurable Pipeline for the Analysis of Connectomes
=====================================================

CPAC is a configurable, open-source, Nipype-based, automated processing pipeline for resting state functional MRI (R-fMRI) data, for use by both novice and expert users.
"""

from numpy.testing import nosetester
test = nosetester.NoseTester.test

class _NoseTester(nosetester.NoseTester):
    def test(self, label='fast', verbose=1, extra_argv=['--exe'], doctests = False, coverage=False):
        return super(_NoseTester, self).test(label=label, verbose=verbose, extra_argv=extra_argv, doctests=doctests, coverage=coverage)

test = _NoseTester().test

import anat_preproc, \
       func_preproc, \
       reho, \
       seg_preproc, \
       registration, \
       sca, \
       basc, \
       nuisance, \
       generate_motion_statistics, \
       alff, \
       qc, \
       seg_preproc, \
       vmhc, \
       median_angle, \
       timeseries, \
       network_centrality, \
       scrubbing, \
       group_analysis, \
       easy_thresh,\
       utils, \
       pipeline, \
       cwas, \
       GUI

__all__ = ['GUI', 'pipeline', 'anat_preproc', 'func_preproc', 'registration', 'seg_preproc', 'reho', 'sca', 'basc', 'nuisance', 'alff', 'vmhc', 'median_angle', 'generate_motion_statistics', 'timeseries', 'network_centrality', 'scrubbing', 'utils', 'group_analysis', 'easy_thresh', 'qc', 'cwas']

#__version__ = '0.1-git'

from subprocess import Popen, PIPE
import re

try:
    version = '0.3.2'
#    gitproc = Popen(['git', 'log', '--oneline'], stdout = PIPE)
#    (stdout, stderr) = gitproc.communicate()
#    rows = stdout.split("\n")
#    v_num = re.search( r'(?<=(version_|release_))(.)*', rows[0])
#    if v_num:
#        version = v_num.group(0).strip("'")
#    else:
#        version = 'unknown_version'
except OSError:
    version = 'unknown_version'

__version__ =  str(version)
<|endoftext|>


<commit_before>if __name__ == '__main__':
    from NeuroIO import NeuroIO
    from PreProcess import PreProcess
    from Cluster import Cluster

    neuroread = NeuroIO(r"C:\Users\USERNAME\Downloads\Brainbow-demo.tif")
    img_data = neuroread.img_data_return()[0]
    img_path = neuroread.img_data_return()[1]
    pre_processed_data = PreProcess(im_data=img_data, filepath=img_path, snapshotpath=r"C:\UROP\\", multiprocess=True,
                                    cores="auto")
    pre_processed_data.blur(blur_sigma=0.5, xyz_scale=(1, 1, 1))
    pre_processed_data.find_threshold(method="isodata", snapshot=True)
    refined_mask = pre_processed_data.sobel_watershed(threshold="last", snapshot=True)
    pre_processed_data.lab_mode()
    img_lab = pre_processed_data.return_data()
    segment = Cluster(img_data=img_lab, mask=refined_mask)
    cluster_results = segment.DBSCAN(start_frame=0, end_frame=100, size_threshold=75, max_dist=19, min_samp=10,
                                     dist_weight=3.0,
                                     color_weight=18.0, metric="euclidean", algo="ball_tree")
    neuroread.img_data_write(cluster_results, "C:\Users\USERNAME\Desktop\\")
<commit_msg>Enable support for the parallel dbscan.<commit_after>if __name__ == '__main__':
    from NeuroIO import NeuroIO
    from PreProcess import PreProcess
    from Cluster import Cluster

    neuroread = NeuroIO(r"C:\Users\USERNAME\Downloads\Brainbow-demo.tif")
    img_data = neuroread.img_data_return()[0]
    img_path = neuroread.img_data_return()[1]
    pre_processed_data = PreProcess(im_data=img_data, filepath=img_path, snapshotpath=r"C:\UROP\\",
                                    multiprocess=True, cores="auto")
    pre_processed_data.blur(blur_sigma=0.5, xyz_scale=(1, 1, 1))
    pre_processed_data.find_threshold(method="isodata", snapshot=True)
    refined_mask = pre_processed_data.sobel_watershed(threshold="last", snapshot=True)
    pre_processed_data.lab_mode()
    img_lab = pre_processed_data.return_data()
    segment = Cluster(img_data=img_lab, mask=refined_mask)
    cluster_results = segment.super_pixel(start_frame=0, end_frame=100, size_threshold=75, max_dist=19, min_samp=10,
                                          dist_weight=3.0, color_weight=18.0, metric="euclidean", algo="auto",
                                          multiprocess=True, num_cores="auto", num_slices=4)
    neuroread.img_data_write(cluster_results, "C:\Users\USERNAME\Desktop\\")
<|endoftext|>


<commit_before>from miflora.miflora_poller import MiFloraPoller, \
    MI_CONDUCTIVITY, MI_MOISTURE, MI_LIGHT, MI_TEMPERATURE, MI_BATTERY

poller = MiFloraPoller("C4:7C:8D:60:8F:E6")
print("Getting data from Mi Flora")
print("FW: {}".format(poller.firmware_version()))
print("Name: {}".format(poller.name()))
print("Temperature: {}".format(poller.parameter_value("temperature")))
print("Moisture: {}".format(poller.parameter_value(MI_MOISTURE)))
print("Light: {}".format(poller.parameter_value(MI_LIGHT)))
print("Conductivity: {}".format(poller.parameter_value(MI_CONDUCTIVITY)))
print("Battery: {}".format(poller.parameter_value(MI_BATTERY)))

<commit_msg>Added MAC address as command line parameter for demo.py.  (#38)<commit_after>#!/usr/bin/env python3

import argparse
import re
from miflora.miflora_poller import MiFloraPoller, \
    MI_CONDUCTIVITY, MI_MOISTURE, MI_LIGHT, MI_TEMPERATURE, MI_BATTERY

def valid_miflora_mac(mac, pat=re.compile(r"C4:7C:8D:[0-9A-F]{2}:[0-9A-F]{2}:[0-9A-F]{2}")):
    if not pat.match(mac):
        raise argparse.ArgumentTypeError('The MAC address "{}" seems to be in the wrong format'.format(mac))
    return mac

parser = argparse.ArgumentParser()
parser.add_argument('mac',type=valid_miflora_mac)
args = parser.parse_args()

poller = MiFloraPoller(args.mac)
print("Getting data from Mi Flora")
print("FW: {}".format(poller.firmware_version()))
print("Name: {}".format(poller.name()))
print("Temperature: {}".format(poller.parameter_value(MI_TEMPERATURE)))
print("Moisture: {}".format(poller.parameter_value(MI_MOISTURE)))
print("Light: {}".format(poller.parameter_value(MI_LIGHT)))
print("Conductivity: {}".format(poller.parameter_value(MI_CONDUCTIVITY)))
print("Battery: {}".format(poller.parameter_value(MI_BATTERY)))

<|endoftext|>