示例#1
0
    def start(self):
        if not self.stopped:
            return
        super().start()
        mouse_source, keyboard_source, engagement_source = self.sources

        initial_keyboard_event = keyboard.KeyboardEvent(keyboard.KEY_UP, 0)
        initial_mouse_event = mouse.ButtonEvent(event_type=mouse.UP,
                                                button=0,
                                                time=time.time())
        self.subscriptions = [
            mouse_source.output.pipe(
                operators.start_with(initial_mouse_event)).pipe(
                    operators.combine_latest(
                        keyboard_source.output.pipe(
                            operators.start_with(initial_keyboard_event)),
                        engagement_source.output)).pipe(
                            operators.throttle_first(0.1))  # in seconds
            .subscribe(self.update)
        ]

        if self.window is None:
            self.window = Window(points=self.points_in_buffer,
                                 toggle_callback=self.toggle_recording)

        self.window.show()
        self.window.activateWindow()
        self.window.raise_()
示例#2
0
def main():
    loop = asyncio.get_event_loop()
    io_scheduler = AsyncIOThreadSafeScheduler(loop=loop)
    scheduler = ThreadPoolScheduler(multiprocessing.cpu_count())

    semaphore = Subject()

    semaphore_stream = semaphore.pipe(
        ops.flat_map(lambda _: rx.of(True).pipe(
            ops.delay(ARGS.block_time, scheduler=scheduler),
            ops.start_with(False))), ops.start_with(True))

    video_stream_observable = rx.using(
        lambda: VideoStreamDisposable(),
        lambda d: rx.from_iterable(video_stream_iterable(d.cap)))

    gated_video_stream = video_stream_observable.pipe(
        ops.subscribe_on(scheduler),
        ops.sample(1 / ARGS.fps),  # sample frames based on fps
        ops.combine_latest(semaphore_stream),
        ops.filter(lambda tup: tup[1]),  # proceed only if semaphore allows
        ops.map(lambda tup: tup[0])  # take only frame
    )

    disposable = gated_video_stream.pipe(
        ops.filter(has_face),  # filter frames without faces
        ops.map(lambda frame: Image.fromarray(
            cv2.cvtColor(frame, cv2.COLOR_BGR2RGB))),  # map frame to PIL image
        ops.map(lambda img: img.resize(
            (640, 360))),  # resize image (inference will be faster)
        ops.observe_on(io_scheduler),
        ops.map(lambda img: ImageFacesPair(img, analyse_frame(img))
                ),  # analyse frame for faces
        ops.filter(lambda img_faces_pair: any([
            face.top_prediction.confidence > ARGS.threshold
            for face in img_faces_pair.faces
        ])),  # proceed only if there is a known face in the frame
        ops.throttle_first(1),
        ops.flat_map(unlock_request),  # unlock the door
        ops.do_action(
            on_next=lambda _: semaphore.on_next(True)
        )  # trigger semaphore which will block stream for "block-seconds" seconds (doors are unlocked for that long after unlock request)
    ).subscribe(on_error=lambda e: logger.exception(e))

    try:
        loop.run_forever()
    except Exception as e:
        logger.exception(e)
        logger.info("Smart lock face recognition engine shutdown")
        disposable.dispose()
示例#3
0
文件: reduce.py 项目: wolf937/RxPY
def _reduce(accumulator: Callable[[Any, Any], Any],
            seed: Any = NotSet) -> Callable[[Observable], Observable]:
    """Applies an accumulator function over an observable sequence,
    returning the result of the aggregation as a single element in the
    result sequence. The specified seed value is used as the initial
    accumulator value.

    For aggregation behavior with incremental intermediate results, see
    `scan()`.

    Examples:
        >>> res = reduce(lambda acc, x: acc + x)
        >>> res = reduce(lambda acc, x: acc + x, 0)

    Args:
        accumulator: An accumulator function to be
            invoked on each element.
        seed: Optional initial accumulator value.

    Returns:
        An operator function that takes an observable source and returns
        an observable sequence containing a single element with the
        final accumulator value.
    """

    if seed is not NotSet:
        initial = ops.start_with(seed)
        scanner = ops.scan(accumulator, seed=seed)

        return pipe(scanner, initial, ops.last())

    return pipe(ops.scan(accumulator), ops.last())
示例#4
0
def _reduce(accumulator: Callable[[Any, Any], Any], seed: Any = NotSet) -> Callable[[Observable], Observable]:
    """Applies an accumulator function over an observable sequence,
    returning the result of the aggregation as a single element in the
    result sequence. The specified seed value is used as the initial
    accumulator value.

    For aggregation behavior with incremental intermediate results, see
    `scan()`.

    Examples:
        >>> res = reduce(lambda acc, x: acc + x)
        >>> res = reduce(lambda acc, x: acc + x, 0)

    Args:
        accumulator: An accumulator function to be
            invoked on each element.
        seed: Optional initial accumulator value.

    Returns:
        An operator function that takes an observable source and returns
        an observable sequence containing a single element with the
        final accumulator value.
    """


    if seed is not NotSet:
        initial = ops.start_with(seed)
        scanner = ops.scan(accumulator, seed=seed)

        return pipe(scanner, initial, ops.last())

    return pipe(ops.scan(accumulator), ops.last())
示例#5
0
        def value_for(button: MouseButton) -> Observable:
            code = codes[button]

            return self._activeInputs.pipe(
                ops.start_with({}),
                ops.map(lambda i: code in i and pressed(i[code])),
                ops.map(lambda v: button if v else 0))
示例#6
0
    def __init__(self, error_handler: ErrorHandler) -> None:
        if error_handler is None:
            raise ValueError("Argument 'error_handler' is required.")

        super().__init__()

        self._error_handler = error_handler

        self._added_window = Subject()
        self._removed_window = Subject()

        changed_window = rx.merge(
            self._added_window.pipe(ops.map(lambda v: (v, True))),
            self._removed_window.pipe(ops.map(lambda v: (v, False))))

        def on_window_change(windows: Tuple[Window, ...], event: Tuple[Window, bool]):
            (window, added) = event

            if added and window not in windows:
                return windows + (window,)
            elif not added and window in windows:
                return tuple(c for c in windows if c is not window)

        # noinspection PyTypeChecker
        self.windows = changed_window.pipe(
            ops.scan(on_window_change, ()), ops.start_with(()), ops.distinct_until_changed())
示例#7
0
    def __init__(self, context: BlenderContext) -> None:
        super().__init__(context)

        self._activeInputs = Subject()

        # noinspection PyTypeChecker
        self.pressed = self._activeInputs.pipe(
            ops.start_with({}), ops.map(lambda s: set(s.keys())))
示例#8
0
    def __init__(self, context: Context, visible: bool = True) -> None:
        super().__init__(context, visible)

        # noinspection PyTypeChecker
        self.hover = rx.merge(
            self.on_mouse_over.pipe(ops.map(lambda _: True)),
            self.on_mouse_out.pipe(ops.map(lambda _: False))).pipe(ops.start_with(False))

        mouse = MouseInput.input(self)

        # noinspection PyTypeChecker
        self.active = self.on_mouse_down.pipe(
            ops.filter(lambda e: e.button == MouseButton.LEFT),
            ops.map(lambda _: rx.concat(rx.of(True), mouse.on_button_release(MouseButton.LEFT).pipe(
                ops.take(1),
                ops.map(lambda _: False)))),
            ops.exclusive(),
            ops.start_with(False))
示例#9
0
 def _start_periodic_refresh(self) -> None:
     _LOG.debug("start refresh")
     self._composite_disposable.add(
         rx.interval(timedelta(milliseconds=999),
                     scheduler=self._scheduler).pipe(
                         operators.start_with(0),
                         operators.subscribe_on(self._scheduler),
                         operators.observe_on(GtkScheduler(GLib)),
                     ).subscribe(on_next=self._on_periodic_refresh_tick,
                                 on_error=lambda e: _LOG.exception(
                                     f"Refresh error: {str(e)}")))
示例#10
0
 def _start_refresh(self) -> None:
     _LOG.debug("start refresh")
     refresh_interval = self._settings_interactor.get_int(
         'settings_refresh_interval')
     self._composite_disposable.add(
         rx.interval(refresh_interval, scheduler=self._scheduler).pipe(
             operators.start_with(0),
             operators.subscribe_on(self._scheduler),
             operators.flat_map(lambda _: self._get_status()),
             operators.observe_on(GtkScheduler(GLib)),
         ).subscribe(on_next=self._update_status,
                     on_error=self._handle_refresh_error))
示例#11
0
def sequentialSocket(channel):
    scheduler = rx.scheduler.timeoutscheduler.TimeoutScheduler()
    stream = rx.interval(SOCKET_LIMIT_SEC-10, scheduler).pipe(
        ops.start_with('start'),
        ops.map(lambda _: temporarySocket(channel)),
        ops.switch_latest(),
        ops.filter(lambda res: res[:2] == '42'),
        ops.map(lambda res: json.loads(res[13:-1])),
        ops.map(Response.from_dict),
        ops.map(lambda res: res.message.data),
    )
    return stream
示例#12
0
    def __init__(self, scheduler=None):
        self._observerable = rx.interval(
            ObserveConfig.interval,
            scheduler).pipe(ops.map(lambda dummy: get_merge_requests()),
                            ops.retry(), ops.publish(), ops.ref_count())

        self._ready_to_merge = self._observerable.pipe(
            ops.map(lambda requests: next((request for request in requests if
                                           is_ready_to_merge(request)), None)),
            ops.start_with(None), ops.distinct_until_changed())

        self._ready_to_merge.subscribe(lambda ready_to_merge: logging.info(
            'Ready to merge: ' + str(ready_to_merge)))

        voted_merge_requests = self._observerable.pipe(
            ops.map(_to_voted_merge_requests_set))
        self._new_votes_merge_requests = voted_merge_requests.pipe(
            ops.skip(1), ops.zip(voted_merge_requests),
            ops.map(lambda zipped: zipped[0] - zipped[1]), ops.filter(len),
            ops.map(_to_merge_requests))

        self._new_votes_merge_requests.pipe(
            ops.map(lambda diff_set:
                    [merge_request.get_iid() for merge_request in diff_set])
        ).subscribe(
            lambda ids: logging.info(f'New votes for merge requests: {ids}'))

        awards = self._new_votes_merge_requests.pipe(ops.map(_to_awards_set),
                                                     ops.publish(),
                                                     ops.ref_count(),
                                                     ops.start_with(set()))
        self._new_awards = awards.pipe(
            ops.skip(1), ops.zip(awards),
            ops.map(lambda zipped: zipped[0] - zipped[1]), ops.filter(len),
            ops.flat_map(lambda diff_set: rx.from_iterable(diff_set)),
            ops.map(lambda award_key: award_key.award))

        self._new_awards.subscribe(
            lambda new_award: logging.info('New award: ' + str(new_award)))
示例#13
0
    def observe_ve_property(self,
                            service_name='*',
                            object_path='*') -> rx.Observable:
        # TODO: constants, generics?
        prop = self.observe_signal(service_name, object_path,
                                   'com.victronenergy.BusItem',
                                   'PropertiesChanged')

        # TODO: behaviorSubject? replay?
        # prepend own exported properties, so the subscriber does't have to wait for first property changed
        own = [
            p.to_ve_property()
            for ((sn, path), p) in self._ve_properties.items()
            if matches(sn, service_name) and matches(path, object_path)
        ]

        # TODO: request tree export and prepend matching, maybe this will obsolete the above

        return prop.pipe(
            op.map(VeProperty.parse),
            op.start_with(*own))  # TODO all ve_prop observable, publish
op.catch()
op.retry()

"""Utility"""
op.delay()
op.materialize()
op.time_interval()
op.timeout()
op.timestamp()

"""Conditional and Boolean"""
op.all()
op.contains()
op.default_if_empty()
op.sequence_equal()
op.skip_until()
op.skip_while()
op.take_until()
op.take_while()

"""Connectable"""
op.publish()
op.ref_count()
op.replay()

"""Combining"""
op.combine_latest()
op.merge()
op.start_with()
op.zip()
示例#15
0
tickerSocket = sequentialSocket(ch.ticker)
transactionsSocket = sequentialSocket(ch.transactions)
depthDiffSocket = sequentialSocket(ch.depth_diff)
depthWholeSocket = sequentialSocket(ch.depth_whole)

tickerStream = tickerSocket.pipe(ops.map(Ticker.from_dict))
transactionsStream = transactionsSocket.pipe(
    ops.map(TransactionsData.from_dict))
depthDiffStream = depthDiffSocket.pipe(ops.map(DepthDiff.from_dict))
depthWholeStream = depthWholeSocket.pipe(ops.map(DepthWhole.from_dict))


# API

clockStream = rx.interval(10).pipe(ops.start_with('start'))

# Public

tickerAPI = clockStream.pipe(ops.map(bitbank.ticker))
depthAPI = clockStream.pipe(ops.map(bitbank.depth))
transactionsAPI = clockStream.pipe(ops.map(bitbank.transactions))
candlestickAPI = clockStream.pipe(ops.map(bitbank.candlestick))
statusesAPI = clockStream.pipe(ops.map(bitbank.statuses))
pairsAPI = clockStream.pipe(ops.map(bitbank.pairs))

# Private

assetsAPI = clockStream.pipe(ops.map(bitbank.assets))
orderAPI = clockStream.pipe(ops.map(bitbank.order))
cancelOrderAPI = clockStream.pipe(ops.map(bitbank.cancel_order))
示例#16
0
class Component(Drawable, StyleResolver, MouseEventHandler, EventDispatcher,
                ContextAware, ReactiveObject):
    visible: RP[bool] = rv.new_property()

    parent: RP[Maybe[Container]] = rv.from_value(Nothing)

    offset: RV[Point] = parent.as_view().map(lambda _, parent: parent.map(
        lambda p: rx.combine_latest(p.observe("offset"), p.observe("location"))
        .pipe(ops.map(lambda v: v[0] + v[1]))).or_else_call(lambda: rx.of(
            Point(0, 0)))).pipe(lambda _: (ops.exclusive(), ))

    _minimum_size: RP[Dimension] = rv.from_value(Dimension(0, 0))

    _preferred_size: RP[Dimension] = rv.from_value(Dimension(0, 0))

    minimum_size_override: RP[Maybe[Dimension]] = rv.from_value(Nothing)

    minimum_size: RV[Dimension] = rv.combine_latest(
        _minimum_size,
        minimum_size_override)(ops.pipe(ops.map(lambda v: v[1].value_or(v[0])),
                                        ops.distinct_until_changed()))

    preferred_size_override: RP[Maybe[Dimension]] = rv.from_value(
        Nothing).pipe(lambda o:
                      (ops.combine_latest(o.observe("minimum_size")),
                       ops.map(lambda t: t[0].map(lambda v: t[1].copy(
                           width=max(v.width, t[1].width),
                           height=max(v.height, t[1].height)))),
                       ops.distinct_until_changed()))

    preferred_size: RV[Dimension] = rv.combine_latest(
        _preferred_size, preferred_size_override, minimum_size)(ops.pipe(
            ops.map(lambda v: (v[1].value_or(v[0]), v[2])),
            ops.map(lambda v: v[0].copy(width=max(v[0].width, v[1].width),
                                        height=max(v[0].height, v[1].height))),
            ops.distinct_until_changed()))

    bounds: RP[Bounds] = Bounded.bounds.pipe(lambda o: (
        ops.combine_latest(o.observe("minimum_size")),
        ops.map(lambda v: v[0].copy(width=max(v[0].width, v[1].width),
                                    height=max(v[0].height, v[1].height))),
        ops.start_with(o.preferred_size)))

    def __init__(self, context: Context, visible: bool = True) -> None:
        if context is None:
            raise ValueError("Argument 'context' is required.")

        # noinspection PyTypeChecker
        self.visible = visible

        self._context = context
        self._valid = False
        self._ui = self.create_ui()

        assert self._ui is not None

        super().__init__()

        self.validate()

        self.ui \
            .on_invalidate(self) \
            .pipe(ops.take_until(self.on_dispose)) \
            .subscribe(lambda _: self.invalidate(), on_error=self.error_handler)

    @property
    def context(self) -> Context:
        return self._context

    @property
    def ui(self) -> ComponentUI:
        return self._ui

    @property
    def look_and_feel(self) -> LookAndFeel:
        return self.context.look_and_feel

    def create_ui(self) -> ComponentUI:
        return self.context.look_and_feel.create_ui(self)

    def show(self) -> None:
        # noinspection PyTypeChecker
        self.visible = True

    def hide(self) -> None:
        # noinspection PyTypeChecker
        self.visible = False

    @property
    def valid(self) -> bool:
        return self._valid

    # noinspection PyTypeChecker
    def validate(self, force: bool = False) -> None:
        if self.visible and (not self.valid or force):
            self._minimum_size = self.ui.minimum_size(self)
            self._preferred_size = self.ui.preferred_size(self)

            self._valid = True

            self.parent.map(lambda p: p.request_layout())

    def invalidate(self) -> None:
        self._valid = False

        self.parent.map(lambda p: p.invalidate())

    def draw(self, g: Graphics) -> None:
        if self.visible:
            g.save()

            (dx,
             dy) = self.parent.map(lambda p: p.location).value_or(Point(0, 0))
            (cx, cy, cw, ch) = self.ui.clip_bounds(self).tuple

            g.translate(dx, dy)
            g.rectangle(cx, cy, cw, ch)

            g.clip()

            try:
                self.draw_component(g)
            except BaseException as e:
                self.error_handler(e)

            g.restore()

    def draw_component(self, g: Graphics) -> None:
        self.ui.draw(g, self)

    def position_of(self, event: PositionalEvent) -> Point:
        if event is None:
            raise ValueError("Argument 'event' is required.")

        return event.position - self.offset

    @property
    def inputs(self) -> Mapping[str, Input]:
        return self.context.inputs

    @property
    def parent_dispatcher(self) -> Maybe[EventDispatcher]:
        # noinspection PyTypeChecker
        return self.parent

    def __repr__(self) -> Any:
        return str({"id": id(self), "type": type(self).__name__})
示例#17
0
        def _fetch_margin_accounts(_):
            group = Group.load(context)
            return MarginAccount.load_all_for_group_with_open_orders(
                context, context.program_id, group)

        return _fetch_margin_accounts

    liquidation_processor = LiquidationProcessor(default_context,
                                                 NullAccountLiquidator(),
                                                 NullWalletBalancer())

    print("Starting margin account fetcher subscription")
    margin_account_interval = 60
    margin_account_subscription = rx.interval(margin_account_interval).pipe(
        ops.subscribe_on(pool_scheduler),
        ops.start_with(-1),
        ops.map(fetch_margin_accounts(default_context)),
    ).subscribe(
        create_backpressure_skipping_observer(
            on_next=liquidation_processor.update_margin_accounts,
            on_error=log_subscription_error))

    print("Starting price fetcher subscription")
    price_interval = 2
    price_subscription = rx.interval(price_interval).pipe(
        ops.subscribe_on(pool_scheduler),
        ops.map(fetch_prices(default_context))).subscribe(
            create_backpressure_skipping_observer(
                on_next=liquidation_processor.update_prices,
                on_error=log_subscription_error))
 def create():
     return xs.pipe(_.start_with(42))
示例#19
0
import rx
from rx.operators import map, start_with
from .streams import *


myTradeStream = rx.combine_latest(
    rx.interval(0.01).pipe(
    map(lambda _: datetime.now().strftime('%Y-%m-%d %H:%M:%S')),
),
    PriceLastBuyStream.pipe(map(lambda res: 'last buy: ' + str(res)), start_with('waiting...')),
    PriceLastSellStream.pipe(map(lambda res: 'last sell: ' + str(res)), start_with('waiting...')),
    PriceMinAskStream.pipe(map(lambda res: 'min ask: ' + str(res)), start_with('waiting...')),
    PriceMaxBidStream.pipe(map(lambda res: 'max bid: ' + str(res)), start_with('waiting...')),
)
def audio_encoder(sources):
    # Parse configuration
    parser = create_arg_parser()

    parsed_argv = sources.argv.argv.pipe(
        ops.skip(1),
        argparse.parse(parser),
        ops.filter(lambda i: i.key == 'config'),
        ops.subscribe_on(aio_scheduler),
        ops.share(),
    )

    # monitor and parse config file
    monitor_init = parsed_argv.pipe(
        ops.flat_map(lambda i: rx.from_([
            inotify.AddWatch(
                id='config', path=i.value, flags=aionotify.Flags.MODIFY),
            inotify.Start(),
        ])))

    config_update = sources.inotify.response.pipe(
        ops.debounce(5.0, scheduler=aio_scheduler),
        ops.map(lambda i: True),
        ops.start_with(True),
    )

    read_request, read_response = rx.combine_latest(
        parsed_argv, config_update).pipe(
            ops.starmap(
                lambda config, _: file.Read(id='config', path=config.value)),
            file.read(sources.file.response),
        )

    config = read_response.pipe(
        ops.filter(lambda i: i.id == "config"),
        ops.flat_map(lambda i: i.data),
        parse_config,
    )

    # Transcode request handling
    encode_init = config.pipe(
        ops.map(lambda i: i.encode),
        ops.distinct_until_changed(),
        ops.map(lambda i: encoder.Configure(samplerate=i.samplerate,
                                            bitdepth=i.bitdepth)),
    )

    encode_request = sources.httpd.route.pipe(
        ops.filter(lambda i: i.id == 'flac_transcode'),
        ops.flat_map(lambda i: i.request),
        ops.flat_map(lambda i: rx.just(i, encode_scheduler)),
        ops.map(lambda i: encoder.EncodeMp3(
            id=i.context, data=i.data, key=i.match_info['key'])),
    )
    encoder_request = rx.merge(encode_init, encode_request)

    # store encoded file
    store_requests = sources.encoder.response.pipe(
        ops.observe_on(s3_scheduler),
        ops.map(lambda i: s3.UploadObject(
            key=i.key + '.flac',
            data=i.data,
            id=i.id,
        )),
    )

    # acknowledge http request
    http_response = sources.s3.response.pipe(
        ops.map(lambda i: httpd.Response(
            data='ok'.encode('utf-8'),
            context=i.id,
        )))

    # http server
    http_init = config.pipe(
        ops.take(1),
        ops.flat_map(lambda i: rx.from_([
            httpd.Initialize(request_max_size=0),
            httpd.AddRoute(
                methods=['POST'],
                path='/api/transcode/v1/flac/{key:[a-zA-Z0-9-\._]*}',
                id='flac_transcode',
            ),
            httpd.StartServer(host=i.server.http.host, port=i.server.http.port
                              ),
        ])),
    )
    http = rx.merge(http_init, http_response)

    # s3 database
    s3_init = config.pipe(
        ops.take(1),
        ops.map(lambda i: s3.Configure(
            access_key=i.s3.access_key,
            secret_key=i.s3.secret_key,
            bucket=i.s3.bucket,
            endpoint_url=i.s3.endpoint_url,
            region_name=i.s3.region_name,
        )),
    )

    # merge sink requests
    file_requests = read_request
    s3_requests = rx.merge(s3_init, store_requests)

    return Sink(
        encoder=encoder.Sink(request=encoder_request),
        s3=s3.Sink(request=s3_requests),
        file=file.Sink(request=file_requests),
        httpd=httpd.Sink(control=http),
        inotify=inotify.Sink(request=monitor_init),
    )
示例#21
0
def test_tuple_with_previous_using_scan():
    rx.from_iterable(range(10)).pipe(ops.start_with((-1, -1)),
                                     ops.scan(lambda tup, y: (y, tup[0])),
                                     ops.skip(2)).subscribe(lambda x: print(x))
示例#22
0
 def prepend_current_list(
         scheduler: Scheduler = None) -> Observable[List[str]]:
     return service_added.pipe(op.start_with(self.current_services))