def write_to_console(
    ticker: str,
    interval: str,
    data_downloaded: Candles,
    live: Live,
    table: Table,
) -> Table:
    """Write data to console.

    Args:
        ticker (str): Quote + base currency.
        interval (str): Candlestick interval.
        data_downloaded (Candles): Response from the exchange.
        live (Live): Context manager.
        table (Table): Rich table.

    Returns:
        Table: Updated table to be rendered.
    """
    for row_limit, single_candle in enumerate(data_downloaded[::-1]):
        timestamp = pd.to_datetime(single_candle[0], unit='ms')
        add_row_to_table(ticker, interval, table, single_candle, timestamp)
        max_rows = 15
        if row_limit == max_rows:
            live.update(table)
            break
    live.update(table)
    return table
Exemplo n.º 2
0
 def recurse_solve(xw: Crossword,
                   display_context: Live) -> Optional[Crossword]:
     open_words = [w for w in xw.iterwords() if w.is_open()]
     if len(open_words) == 0:
         return xw
     num_matches = np.array(
         [len(word_list.find_matches(w)) for w in open_words])
     noise = np.abs(np.random.normal(scale=num_matches)) * temperature
     word_to_match = open_words[np.argmin(num_matches + noise)]
     matches = word_to_match.find_matches(word_list)
     if len(matches) == 0:
         return
     else:
         noisy_matches = matches.rescore(
             lambda _, s: s * np.random.lognormal(
                 0.0, 0.1 * temperature))
         new_xw = copy.deepcopy(xw)
         for match in noisy_matches.words:
             if timeout and time.time() > start_time + timeout:
                 return
             new_xw[word_to_match.index] = match
             display_context.update(new_xw._text_grid())
             fill = recurse_solve(new_xw, live)
             if fill:
                 return fill
Exemplo n.º 3
0
class Presentation:
    def __init__(self, content):
        self.slides = [
            slide_content.strip() for slide_content in content.split("---\n")
        ]
        print(self.slides)
        for i in range(1, len(self.slides)):
            self.slides[i] = "# " + self.slides[i]
        self.index = 0
        self.live = Live()

    def start(self):
        self.live.start()
        self.update()

    def stop(self):
        self.live.stop()

    def next(self):
        if self.index >= self.__len__() - 1:
            self.stop()
            return
        self.index = self.index + 1
        self.update()

    def update(self):
        self.live.update(
            Layout(Padding(Markdown(self.slides[self.index]), (2, 2))))

    @property
    def started(self):
        return self.live.is_started

    def __len__(self):
        return len(self.slides)
Exemplo n.º 4
0
def write_to_column(
    ticker: str,
    interval: str,
    data_downloaded: Candles,
    live: Live,
) -> Table:
    """Write data to console.

    Args:
        ticker (str): Quote + base currency.
        interval (str): Candlestick interval.
        data_downloaded (Candles): Response from the exchange.
        live (Live): Context manager.

    Returns:
        Table: Updated table to be rendered.
    """
    table = setup_table()
    for row_limit, single_candle in enumerate(data_downloaded[::-1]):
        table.add_row(
            f'[bold white]{single_candle[2]}[/bold white]',  # Open
            f'[bold white]{single_candle[1]}[/bold white]',  # Close
            f'[bold white]{single_candle[3]}[/bold white]',  # High
            f'[bold white]{single_candle[4]}[/bold white]',  # Low
            f'[bold white]{single_candle[5]}[/bold white]',  # Volume
            f'[bold white]{ticker}[/bold white]',
            f'[bold white]{interval}[/bold white]',
            f"[bold white]{pd.to_datetime(single_candle[0], unit='ms')}[/bold white]",
        )
        if row_limit == 15:
            live.update(table)
            break
    live.update(table)
    return table
Exemplo n.º 5
0
def attack(
    target: int,
    client: VBitve,
    profile: Profile,
    live: Live,
    log: Callable[[Any], None],
) -> None:
    attack = client.attack(target)
    if attack:
        profile.update(attack["new_user"])
        live.update(profile.table, refresh=True)
        text = attack["snackbar"]["text"].split("\n")[-1]
        log(f"Напал на id{target}: +{text}")
Exemplo n.º 6
0
def bot(client: VBitve, profile: Profile, live: Live,
        log: Callable[[Any], None]) -> None:
    if ATTACK_MODE and profile.next_attack < time() * 1000:
        if ATTACK_MODE == 2:
            wars = client.clan_me().get("active_wars")
            if wars:
                war = choice(wars)
                try:
                    enemy_clan = war["clan"]
                except KeyError:
                    enemy_clan = war["attackedClan"]
                target_clan = client.clan(enemy_clan["id"])
                if target_clan:
                    army = target_clan["army"]
                    suitable_enemies = [
                        enemy for enemy in army
                        if enemy["power"] < profile.power
                    ]
                    target = (suitable_enemies[0]
                              if suitable_enemies else army[-1])
                    attack(target["id"], client, profile, live, log)
            else:
                attack_random(client, profile, live, log)
        elif ATTACK_MODE == 3:
            attack(choice(ATTACK_TARGETS), client, profile, live, log)
        else:
            attack_random(client, profile, live, log)
    if profile.cooldown < time() * 1000:
        if TRAIN and profile.balance >= profile.train_cost:
            train = client.train()
            if train:
                profile.update(train["new_user"])
                live.update(profile.table, refresh=True)
                log(f"Тренирую армию -{profile.train_cost}$")
        elif CONTRACT:
            contract = client.contract()
            if contract:
                profile.update(contract["new_user"])
                live.update(profile.table, refresh=True)
                log(f"Беру контракт +{profile.contract}$")
    time_to_wait = int(profile.full_cooldown / 1000 - time()) + 1
    if time_to_wait > 0:
        log(f"Жду {time_to_wait} секунд до окончания перезарядки")
        sleep(time_to_wait)
Exemplo n.º 7
0
class Dash:
    def __init__(self, *parts):
        self.console = Console(color_system="standard", file=REAL_STDOUT)
        self.lv = Live(
            auto_refresh=False,
            redirect_stdout=False,
            redirect_stderr=False,
            console=self.console,
            screen=True,
        )
        self.stack = StackedTerminalLines(parts, self.lv.console.height - 2)
        self.header = Text("<header>")
        self.footer = Text("<footer>")

    def clear(self):
        self.stack.clear()
        self.header = Text("<header>")
        self.footer = Text("<footer>")

    def shifter(self, n, mode):
        def shift(_=None):
            if mode == "line":
                self.stack.shift(n, mode="line")
            elif mode == "screen":
                self.stack.shift(n, mode="screen")
            elif mode == "whole":
                self.stack.shift(n, mode="whole")
            elif mode == "focus":
                self.stack.move_focus(n)
            else:
                raise Exception(f"Unknown mode: {mode}")
            self.update()

        return shift

    def update(self):
        self.lv.update(Group(self.header, self.stack, self.footer),
                       refresh=True)

    def run(self):
        return self.lv
Exemplo n.º 8
0
class RichUI(UI):
    """
    A UI that uses the rich terminal library
    """
    def __init__(self) -> None:
        self._rich_live: Live

    def __enter__(self) -> 'RichUI':
        self._rich_live = Live(Spinner("bouncingBar", ""),
                               refresh_per_second=16)

        self._rich_live.start()
        return self

    def __exit__(self, *args: Any, **kwargs: Any) -> None:
        self._rich_live.stop()

    def update(self, job: SlurmJobStatus) -> None:
        self._rich_live.update(self._make_table(job))

    def error(self, text: str) -> None:
        self._rich_live.console.print(":cross_mark:",
                                      text,
                                      style="bold red",
                                      emoji=True)

    def info(self, text: str) -> None:
        self._rich_live.console.print(":information_source:",
                                      text,
                                      style="bold blue",
                                      emoji=True)

    def success(self, text: str) -> None:
        self._rich_live.console.print(":heavy_check_mark: ",
                                      text,
                                      style="bold green",
                                      emoji=True)

    def launch(self, text: str) -> None:
        self._rich_live.console.print(":rocket: ",
                                      text,
                                      style="bold yellow",
                                      emoji=True)

    def _make_table(self, job: SlurmJobStatus) -> Table:
        table = Table(style="bold", box=box.MINIMAL)
        table.add_column("ID")
        table.add_column("Name")
        table.add_column("State")

        for task in job.tasks:
            last_column: RenderableType = task.state
            color = "grey42"
            if task.state == "RUNNING":
                color = "blue"
                last_column = Spinner("arc", task.state)
            elif task.state == "COMPLETED":
                color = "green"
                last_column = f":heavy_check_mark: {task.state}"
            elif task.state == "FAILED":
                color = "red"
                last_column = f":cross_mark: {task.state}"

            table.add_row(str(task.id), task.name, last_column, style=color)

        return table
Exemplo n.º 9
0
class Log:
    STATUS_WIDTH = 11

    def __init__(self) -> None:
        self.console = Console(highlight=False)

        self._crawl_progress = Progress(
            TextColumn("{task.description}", table_column=Column(ratio=1)),
            BarColumn(),
            TimeRemainingColumn(),
            expand=True,
        )
        self._download_progress = Progress(
            TextColumn("{task.description}", table_column=Column(ratio=1)),
            TransferSpeedColumn(),
            DownloadColumn(),
            BarColumn(),
            TimeRemainingColumn(),
            expand=True,
        )

        self._live = Live(console=self.console, transient=True)
        self._update_live()

        self._showing_progress = False
        self._progress_suspended = False
        self._lock = asyncio.Lock()
        self._lines: List[str] = []

        # Whether different parts of the output are enabled or disabled
        self.output_explain = False
        self.output_status = True
        self.output_report = True

    def _update_live(self) -> None:
        elements = []
        if self._crawl_progress.task_ids:
            elements.append(self._crawl_progress)
        if self._download_progress.task_ids:
            elements.append(self._download_progress)

        group = Group(*elements)
        self._live.update(group)

    @contextmanager
    def show_progress(self) -> Iterator[None]:
        if self._showing_progress:
            raise RuntimeError(
                "Calling 'show_progress' while already showing progress")

        self._showing_progress = True
        try:
            with self._live:
                yield
        finally:
            self._showing_progress = False

    @asynccontextmanager
    async def exclusive_output(self) -> AsyncIterator[None]:
        if not self._showing_progress:
            raise RuntimeError(
                "Calling 'exclusive_output' while not showing progress")

        async with self._lock:
            self._progress_suspended = True
            self._live.stop()
            try:
                yield
            finally:
                self._live.start()
                self._progress_suspended = False
                for line in self._lines:
                    self.print(line)
                self._lines = []

    def unlock(self) -> None:
        """
        Get rid of an exclusive output state.

        This function is meant to let PFERD print log messages after the event
        loop was forcibly stopped and if it will not be started up again. After
        this is called, it is not safe to use any functions except the logging
        functions (print, warn, ...).
        """

        self._progress_suspended = False
        for line in self._lines:
            self.print(line)

    def print(self, text: str) -> None:
        """
        Print a normal message. Allows markup.
        """

        if self._progress_suspended:
            self._lines.append(text)
        else:
            self.console.print(text)

    # TODO Print errors (and warnings?) to stderr

    def warn(self, text: str) -> None:
        """
        Print a warning message. Allows no markup.
        """

        self.print(f"[bold bright_red]Warning[/] {escape(text)}")

    def warn_contd(self, text: str) -> None:
        """
        Print further lines of a warning message. Allows no markup.
        """

        self.print(f"{escape(text)}")

    def error(self, text: str) -> None:
        """
        Print an error message. Allows no markup.
        """

        self.print(f"[bold bright_red]Error[/] [red]{escape(text)}")

    def error_contd(self, text: str) -> None:
        """
        Print further lines of an error message. Allows no markup.
        """

        self.print(f"[red]{escape(text)}")

    def unexpected_exception(self) -> None:
        """
        Call this in an "except" clause to log an unexpected exception.
        """

        t, v, tb = sys.exc_info()
        if t is None or v is None or tb is None:
            # We're not currently handling an exception, so somebody probably
            # called this function where they shouldn't.
            self.error("Something unexpected happened")
            self.error_contd("")
            for line in traceback.format_stack():
                self.error_contd(line[:-1])  # Without the newline
            self.error_contd("")
        else:
            self.error("An unexpected exception occurred")
            self.error_contd("")
            self.error_contd(traceback.format_exc())

        # Our print function doesn't take types other than strings, but the
        # underlying rich.print function does. This call is a special case
        # anyways, and we're calling it internally, so this should be fine.
        self.print(
            Panel.fit("""
Please copy your program output and send it to the PFERD maintainers, either
directly or as a GitHub issue: https://github.com/Garmelon/PFERD/issues/new
        """.strip()))  # type: ignore

    def explain_topic(self, text: str) -> None:
        """
        Print a top-level explain text. Allows no markup.
        """

        if self.output_explain:
            self.print(f"[yellow]{escape(text)}")

    def explain(self, text: str) -> None:
        """
        Print an indented explain text. Allows no markup.
        """

        if self.output_explain:
            self.print(f"  {escape(text)}")

    def status(self,
               style: str,
               action: str,
               text: str,
               suffix: str = "") -> None:
        """
        Print a status update while crawling. Allows markup in the "style"
        argument which will be applied to the "action" string.
        """

        if self.output_status:
            action = escape(f"{action:<{self.STATUS_WIDTH}}")
            self.print(f"{style}{action}[/] {escape(text)} {suffix}")

    def report(self, text: str) -> None:
        """
        Print a report after crawling. Allows markup.
        """

        if self.output_report:
            self.print(text)

    @contextmanager
    def _bar(
        self,
        progress: Progress,
        description: str,
        total: Optional[float],
    ) -> Iterator[ProgressBar]:
        if total is None:
            # Indeterminate progress bar
            taskid = progress.add_task(description, start=False)
        else:
            taskid = progress.add_task(description, total=total)
        self._update_live()

        try:
            yield ProgressBar(progress, taskid)
        finally:
            progress.remove_task(taskid)
            self._update_live()

    def crawl_bar(
        self,
        style: str,
        action: str,
        text: str,
        total: Optional[float] = None,
    ) -> ContextManager[ProgressBar]:
        """
        Allows markup in the "style" argument which will be applied to the
        "action" string.
        """

        action = escape(f"{action:<{self.STATUS_WIDTH}}")
        description = f"{style}{action}[/] {text}"
        return self._bar(self._crawl_progress, description, total)

    def download_bar(
        self,
        style: str,
        action: str,
        text: str,
        total: Optional[float] = None,
    ) -> ContextManager[ProgressBar]:
        """
        Allows markup in the "style" argument which will be applied to the
        "action" string.
        """

        action = escape(f"{action:<{self.STATUS_WIDTH}}")
        description = f"{style}{action}[/] {text}"
        return self._bar(self._download_progress, description, total)