Python humanfriendly.format_timespan() Examples

The following are 27 code examples of humanfriendly.format_timespan(). You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may also want to check out all available functions/classes of the module humanfriendly , or try the search function .
Example #1
Source File: tcp.py    From python-executor with MIT License 6 votes vote down vote up
def wait_until_connected(self):
        """
        Wait until connections are being accepted.

        :raises: :exc:`TimeoutError` when the SSH server isn't fast enough to
                 initialize.
        """
        timer = Timer()
        with Spinner(timer=timer) as spinner:
            while not self.is_connected:
                if timer.elapsed_time > self.wait_timeout:
                    raise TimeoutError(format(
                        "Failed to establish connection to %s within configured timeout of %s!",
                        self.endpoint, format_timespan(self.wait_timeout),
                    ))
                spinner.step(label="Waiting for %s to accept connections" % self.endpoint)
                spinner.sleep()
        logger.debug("Waited %s for %s to accept connections.", timer, self.endpoint) 
Example #2
Source File: run_processor.py    From temci with GNU General Public License v3.0 6 votes vote down vote up
def _can_run_next_block(self) -> bool:
        if not in_standalone_mode:
            estimated_time = self.stats_helper.estimate_time_for_next_round(self.run_block_size,
                                                                            all=self.block_run_count < self.min_runs)
            to_bench_count = len(self.stats_helper.get_program_ids_to_bench())
            if -1 < self.end_time < round(time.time() + estimated_time):
                logging.warning("Ran too long ({}) and is therefore now aborted. "
                                "{} program blocks should've been benchmarked again."
                                .format(humanfriendly.format_timespan(time.time() + estimated_time - self.start_time),
                                        to_bench_count))
                return False
        if self.block_run_count >= self.maximum_of_max_runs() and self.block_run_count >= self.maximum_of_min_runs():
            #print("benchmarked too often, block run count ", self.block_run_count, self.block_run_count + self.run_block_size > self.min_runs)
            logging.warning("Benchmarked program blocks too often and aborted therefore now.")
            return False
        return True 
Example #3
Source File: guild.py    From bot with MIT License 6 votes vote down vote up
def get_info(self, ctx: commands.Context, guild: discord.Guild):
        # This takes both context and guild to allow for showing public
        # guilds in the future
        created = guild.created_at.strftime('%b %-d %Y @ %I:%M %p')
        cdelta = humanfriendly.format_timespan(
            datetime.datetime.utcnow() - guild.created_at,
            max_units=2
        ) + ' ago'
        info = [
            f'**Created by {guild.owner or "Unknown#0000"} {cdelta}**',
            f'**Members:** {guild.member_count:,d}',
            f'**Region:** {region.get(str(guild.region), "❓ Deprecated Region")}'
        ]
        is_cached = len(guild.members) / guild.member_count
        if is_cached > 0.98 and guild.get_member(ctx.author):
            # is_cached should be 1.0 if cached but allow for discrepancies
            joinpos = sorted(
                guild.members,
                key=lambda m: m.joined_at or m.created_at
            ).index(ctx.author) + 1
            info.append(f'**Your Join Position:** {joinpos:,d}')
        return info 
Example #4
Source File: utils.py    From TC-ResNet with Apache License 2.0 6 votes vote down vote up
def __call__(self, name, log_func=None):
        """
        Example.
            timer = Timer(log)
            with timer("Some Routines"):
                routine1()
                routine2()
        """
        if log_func is None:
            log_func = self.log.info

        start = time.clock()
        yield
        end = time.clock()
        duration = end - start
        readable_duration = format_timespan(duration)
        log_func(f"{name} :: {readable_duration}") 
Example #5
Source File: utils.py    From MMNet with Apache License 2.0 6 votes vote down vote up
def __call__(self, name, log_func=None):
        """
        Example.
            timer = Timer(log)
            with timer("Some Routines"):
                routine1()
                routine2()
        """
        if log_func is None:
            log_func = self.log.info

        start = time.clock()
        yield
        end = time.clock()
        duration = end - start
        readable_duration = format_timespan(duration)
        log_func(f"{name} :: {readable_duration}") 
Example #6
Source File: utils.py    From BentoML with Apache License 2.0 5 votes vote down vote up
def humanfriendly_age_from_datetime(dt, detailed=False, max_unit=2):
    return humanfriendly.format_timespan(datetime.utcnow() - dt, detailed, max_unit) 
Example #7
Source File: uploader.py    From zimfarm with GNU General Public License v3.0 5 votes vote down vote up
def display_stats(filesize, started_on, ended_on=None):
    ended_on = ended_on or now()
    duration = (ended_on - started_on).total_seconds()
    if humanfriendly:
        hfilesize = humanfriendly.format_size(filesize, binary=True)
        hduration = humanfriendly.format_timespan(duration, max_units=2)
        speed = humanfriendly.format_size(filesize / duration)
        msg = f"uploaded {hfilesize} in {hduration} ({speed}/s)"
    else:
        hfilesize = filesize / 2 ** 20  # size in MiB
        speed = filesize / 1000000 / duration  # MB/s
        duration = duration / 60  # in mn
        msg = f"uploaded {hfilesize:.3}MiB in {duration:.1}mn ({speed:.3}MBps)"
    logger.info(f"[stats] {msg}") 
Example #8
Source File: run_driver.py    From temci with GNU General Public License v3.0 5 votes vote down vote up
def __init__(self, cmd: str, timeout: float, out: str, err: str, ret_code: int):
        from temci.report.rundata import RecordedProgramError
        super().__init__(RecordedProgramError("The following run command hit a timeout after {}: {}"
                                              .format(humanfriendly.format_timespan(timeout), cmd), out, err,
                                              ret_code)) 
Example #9
Source File: app.py    From mlapp with MIT License 5 votes vote down vote up
def health() -> str:
    """
    Setup root to return application status and serve as health check or readiness endpoint
    Kubernetes or similar resource managers can start service when it replied 200 OK back
    and restart in case of failure
    """
    return {"version": VERSION,
            "uptime": format_timespan(time.time() - start_time)
            } 
Example #10
Source File: utils.py    From TC-ResNet with Apache License 2.0 5 votes vote down vote up
def wait(message, stop_checker_closure):
    assert callable(stop_checker_closure)
    st = time.time()
    while True:
        try:
            time_pass = hf.format_timespan(int(time.time() - st))
            sys.stdout.write(colored((
                f"{message}. Do you wanna wait? If not, then ctrl+c! :: waiting time: {time_pass}\r"
            ), "yellow", attrs=["bold"]))
            sys.stdout.flush()
            time.sleep(1)
            if stop_checker_closure():
                break
        except KeyboardInterrupt:
            break 
Example #11
Source File: utils.py    From TC-ResNet with Apache License 2.0 5 votes vote down vote up
def timer(name):
    st = time.time()
    yield
    print("<Timer> {} : {}".format(name, format_timespan(time.time() - st))) 
Example #12
Source File: utils.py    From TC-ResNet with Apache License 2.0 5 votes vote down vote up
def format_timespan(duration):
    if duration < 10:
        readable_duration = "{:.1f} (ms)".format(duration * 1000)
    else:
        readable_duration = hf.format_timespan(duration)
    return readable_duration 
Example #13
Source File: ImageBuilder.py    From ue4-docker with MIT License 5 votes vote down vote up
def _processImage(self, image, command, actionPresentTense, actionPastTense):
		'''
		Processes the specified image by running the supplied command if it doesn't exist (use rebuild=True to force processing)
		'''
		
		# Determine if we are processing the image
		if self._willProcess(image) == False:
			self.logger.info('Image "{}" exists and rebuild not requested, skipping {}.'.format(image, actionPresentTense))
			return
		
		# Determine if we are running in "dry run" mode
		self.logger.action('{}ing image "{}"...'.format(actionPresentTense.capitalize(), image))
		if self.dryRun == True:
			print(command)
			self.logger.action('Completed dry run for image "{}".'.format(image), newline=False)
			return
		
		# Attempt to process the image using the supplied command
		startTime = time.time()
		exitCode = subprocess.call(command)
		endTime = time.time()
		
		# Determine if processing succeeded
		if exitCode == 0:
			self.logger.action('{} image "{}" in {}'.format(
				actionPastTense.capitalize(),
				image,
				humanfriendly.format_timespan(endTime - startTime)
			), newline=False)
		else:
			raise RuntimeError('failed to {} image "{}".'.format(actionPresentTense, image)) 
Example #14
Source File: cli.py    From apt-smart with MIT License 5 votes vote down vote up
def report_available_mirrors(updater):
    """Print the available mirrors to the terminal (in a human friendly format)."""
    if connected_to_terminal() or os.getenv('TRAVIS') == 'true':  # make Travis CI test this code
        # https://docs.travis-ci.com/user/environment-variables/#default-environment-variables
        have_bandwidth = any(c.bandwidth for c in updater.ranked_mirrors)
        have_last_updated = any(c.last_updated is not None for c in updater.ranked_mirrors)
        column_names = ["Rank", "Mirror URL", "Available?", "Updating?"]
        if have_last_updated:
            column_names.append("Last updated")
        if have_bandwidth:
            column_names.append("Bandwidth")
        data = []
        long_mirror_urls = {}
        if os.getenv('TRAVIS') == 'true' and updater.url_char_len < 50:
            updater.url_char_len = 50
        for i, candidate in enumerate(updater.ranked_mirrors, start=1):
            if len(candidate.mirror_url) <= updater.url_char_len:
                stripped_mirror_url = candidate.mirror_url
            else:  # the mirror_url is too long, strip it
                stripped_mirror_url = candidate.mirror_url[:updater.url_char_len - 3]
                stripped_mirror_url = stripped_mirror_url + "..."
                long_mirror_urls[i] = candidate.mirror_url  # store it, output as full afterwards
            row = [i, stripped_mirror_url,
                   "Yes" if candidate.is_available else "No",
                   "Yes" if candidate.is_updating else "No"]
            if have_last_updated:
                row.append("Up to date" if candidate.last_updated == 0 else (
                    "%s behind" % format_timespan(candidate.last_updated, max_units=1)
                    if candidate.last_updated else "Unknown"
                ))
            if have_bandwidth:
                row.append("%s/s" % format_size(round(candidate.bandwidth, 0))
                           if candidate.bandwidth else "Unknown")
            data.append(row)
        output(format_table(data, column_names=column_names))
        if long_mirror_urls:
            output(u"Full URLs which are too long to be shown in above table:")
            for key in long_mirror_urls:
                output(u"%i: %s", key, long_mirror_urls[key])
    else:
        output(u"\n".join(
            candidate.mirror_url for candidate in updater.ranked_mirrors
            if candidate.is_available and not candidate.is_updating
        )) 
Example #15
Source File: remindme_ext.py    From SML-Cogs with MIT License 5 votes vote down vote up
def futureme(self, ctx):
        """Return list of future events set by remindme."""
        author = ctx.message.author
        author_reminders = []
        for r in self.reminders:
            if r["ID"] == author.id:
                if r["FUTURE"] >= int(time.time()):
                    author_reminders.append(r)
        if len(author_reminders) == 0:
            await self.bot.say("You have no future evnets.")
            return

        author_reminders = sorted(author_reminders, key=lambda x: x["FUTURE"])
        out = ["Here are your list of reminders:"]
        for i, r in enumerate(author_reminders, 1):
            out.append("**{}. {}**\n{}".format(
                i,
                humanfriendly.format_timespan(r["FUTURE"] - time.time()),
                r["TEXT"]
            ))
        try:
            await self.bot.send_message(
                author,
                "\n".join(out))
            await self.bot.say("Check your DM for all your future events.")
        except (discord.errors.Forbidden, discord.errors.NotFound):
            await self.bot.say("\n".join(out))
        except discord.errors.HTTPException:
            pass 
Example #16
Source File: clans.py    From SML-Cogs with MIT License 5 votes vote down vote up
def format_timespan(seconds, short=False, pad=False):
    """Wrapper for human friendly, shorten words."""
    h = humanfriendly.format_timespan(int(seconds))
    if short:
        h = h.replace(' weeks', 'w')
        h = h.replace(' week', 'w')
        h = h.replace(' days', 'd')
        h = h.replace(' day', 'd')
        h = h.replace(' hours', 'h')
        h = h.replace(' hour', 'h')
        h = h.replace(' minutes', 'm')
        h = h.replace(' minute', 'm')
        h = h.replace(' seconds', 's')
        h = h.replace(' second', 's')
        h = h.replace(',', '')
        h = h.replace(' and', '')
        h = h.replace('  ', ' ')
    else:
        h = h.replace('week', 'wk')
        h = h.replace('hour', 'hr')
        h = h.replace('minute', 'min')
        h = h.replace('second', 'sec')
    if pad:
        h = ' ' + h
        h = re.sub('(\D)(\d)(\D)', r'\g<1>0\2\3', h)
        h = h.strip()
    return h 
Example #17
Source File: utils.py    From MMNet with Apache License 2.0 5 votes vote down vote up
def wait(message, stop_checker_closure):
    assert callable(stop_checker_closure)
    st = time.time()
    while True:
        try:
            time_pass = hf.format_timespan(int(time.time() - st))
            sys.stdout.write(colored((
                f"{message}. Do you wanna wait? If not, then ctrl+c! :: waiting time: {time_pass}\r"
            ), "yellow", attrs=["bold"]))
            sys.stdout.flush()
            time.sleep(1)
            if stop_checker_closure():
                break
        except KeyboardInterrupt:
            break 
Example #18
Source File: utils.py    From MMNet with Apache License 2.0 5 votes vote down vote up
def timer(name):
    st = time.time()
    yield
    print("<Timer> {} : {}".format(name, format_timespan(time.time() - st))) 
Example #19
Source File: utils.py    From MMNet with Apache License 2.0 5 votes vote down vote up
def format_timespan(duration):
    if duration < 10:
        readable_duration = "{:.1f} (ms)".format(duration * 1000)
    else:
        readable_duration = hf.format_timespan(duration)
    return readable_duration 
Example #20
Source File: utils.py    From bot with MIT License 5 votes vote down vote up
def delremind(self, ctx, i: int = None):
		mine = sorted(self.reminders.get(ctx.author.id, []), key=lambda r: r['for'])
		if not mine:
			return await ctx.error('You have no reminders.')
		if not i:
			return await ctx.error(f'You must specify the reminder to delete. Use the [number] from `{ctx.prefix}reminders` to select a reminder')
		i -= 1  # Arrays start at 0
		if i >= len(mine):
			return await ctx.error(f'You don\'t have that many reminders. Use the [number] from `{ctx.prefix}reminders` to select a reminder')
		r = mine[i]
		forwhen = datetime.datetime.fromtimestamp(r['for'], datetime.timezone.utc).strftime('%b %-d %Y @ %I:%M %p')
		delta = humanfriendly.format_timespan(datetime.datetime.fromtimestamp(r['for'], datetime.timezone.utc) - datetime.datetime.now(datetime.timezone.utc), max_units=2)
		await self.deleteremind(ctx.author.id, r['for'])
		return await ctx.success(f'Your reminder, "{r["reminder"]}" for {forwhen} ({delta} from now), has been deleted!') 
Example #21
Source File: utils.py    From bot with MIT License 5 votes vote down vote up
def reminders(self, ctx):
		mine = sorted(self.reminders.get(ctx.author.id, []), key=lambda r: r['for'])
		if not mine:
			return await ctx.error('You have no reminders.')
		paginator = WrappedPaginator(prefix='', suffix='', max_size=1980)
		for i, r in enumerate(mine):
			forwhen = datetime.datetime.fromtimestamp(r['for'], datetime.timezone.utc).strftime('%b %-d %Y @ %I:%M %p')
			delta = humanfriendly.format_timespan(datetime.datetime.fromtimestamp(r['for'], datetime.timezone.utc) - datetime.datetime.now(datetime.timezone.utc), max_units=2)
			paginator.add_line(f'[{i + 1}] {r["reminder"]} - {forwhen} ({delta})')
		interface = PaginatorEmbedInterface(ctx.bot, paginator, owner=ctx.author)
		return await interface.send_to(ctx) 
Example #22
Source File: utils.py    From bot with MIT License 5 votes vote down vote up
def remindme(self, ctx, *, reminder: str):
		if parseTime(reminder):
			days, hours, minutes, seconds = parseTime(reminder)
			reminder = parseTime(reminder, True)
			if not reminder.replace(' ', '') or not reminder:
				return await ctx.error('Invalid format. Please provide a reminder along with the time')
		else:
			return await ctx.error('Invalid format. Please use the format "DAYSd HOURSh MINUTESm SECONDSs" along with your reminder')
		if not days and not hours and not minutes and not seconds:
			return await ctx.error('Invalid format. Please provide a time')
		if not days and not hours and not minutes and seconds < 120:
			return await ctx.error('If you need a bot to remind you about something in less than two minutes you should *probably* be worried...')
		try:
			forwhen = datetime.datetime.now(datetime.timezone.utc) + datetime.timedelta(days=days, seconds=seconds, minutes=minutes, hours=hours)
		except OverflowError:
			return await ctx.error(f'Somehow I don\'t think Discord is gonna be around for that long. Reminders are limited to 3 months anyways')
		limit = datetime.datetime.now(datetime.timezone.utc) + datetime.timedelta(days=90)
		if forwhen > limit and not await self.bot.is_owner(ctx.author):
			return await ctx.error('Reminders currently cannot be set for more than 3 months (90 days)')
		if ctx.author.id not in self.reminders:
			try:
				await ctx.author.send('Hey, I\'m just checking to see if I can DM you as this is where I will send your reminder :)')
			except discord.Forbidden:
				return await ctx.error('I was unable to DM you.\nI send reminders in DMs so you must make sure "Allow direct messages from server members." is enabled in at least one mutual server')
		reminder = reminder.strip()
		con = await self.bot.db.acquire()
		async with con.transaction():
			query = 'INSERT INTO remind (\"uid\", \"forwhen\", \"reminder\") VALUES ($1, $2, $3);'
			await self.bot.db.execute(query, ctx.author.id, forwhen.timestamp(), reminder)
		await self.bot.db.release(con)
		await self.loadremind()
		return await ctx.success(f'Reminder set for {humanfriendly.format_timespan(datetime.timedelta(days=days, seconds=seconds, minutes=minutes, hours=hours))} from now') 
Example #23
Source File: user.py    From bot with MIT License 5 votes vote down vote up
def get_info(self, ctx: commands.Context, user: typing.Union[discord.User, discord.Member]):
        created = user.created_at.strftime('%b %-d %Y @ %I:%M %p')
        cdelta = humanfriendly.format_timespan(
            datetime.datetime.utcnow() - user.created_at,
            max_units=2
        ) + ' ago'
        info = [
            f'**Mention:** {user.mention}',
            f'**Created:** {created} ({cdelta})'
        ]
        if isinstance(user, discord.Member):
            joined = user.joined_at.strftime('%b %-d %Y @ %I:%M %p')
            jdelta = humanfriendly.format_timespan(
                datetime.datetime.utcnow() - user.joined_at,
                max_units=2
            ) + ' ago'
            if ctx.guild and ctx.guild.owner == user:
                info.append(f'**Created Guild:** {joined} ({jdelta})')
            else:
                info.append(f'**Joined:** {joined} ({jdelta})')
            is_cached = len(ctx.guild.members) / ctx.guild.member_count
            if is_cached > 0.98:  # is_cached should be 1.0 if cached but allow for discrepancies
                joinpos = sorted(
                    ctx.guild.members,
                    key=lambda m: m.joined_at or m.created_at
                ).index(user) + 1
                info.append(f'**Join Position:** {joinpos:,d}')
            if user.nick and user.nick != user.name:
                info.append(f'**Nickname:** {user.nick}')
        return info 
Example #24
Source File: reporter.py    From espnet with Apache License 2.0 5 votes vote down vote up
def log_message(self, epoch: int = None) -> str:
        if epoch is None:
            epoch = self.get_epoch()

        message = ""
        for key, d in self.stats[epoch].items():
            _message = ""
            for key2, v in d.items():
                if v is not None:
                    if len(_message) != 0:
                        _message += ", "
                    if isinstance(v, float):
                        if abs(v) > 1.0e3:
                            _message += f"{key2}={v:.3e}"
                        elif abs(v) > 1.0e-3:
                            _message += f"{key2}={v:.3f}"
                        else:
                            _message += f"{key2}={v:.3e}"
                    elif isinstance(v, datetime.timedelta):
                        _v = humanfriendly.format_timespan(v)
                        _message += f"{key2}={_v}"
                    else:
                        _message += f"{key2}={v}"
            if len(_message) != 0:
                if len(message) == 0:
                    message += f"{epoch}epoch results: "
                else:
                    message += ", "
                message += f"[{key}] {_message}"
        return message 
Example #25
Source File: status.py    From clusterman with Apache License 2.0 4 votes vote down vote up
def _write_agent_details(node_metadata: ClusterNodeMetadata) -> None:
    agent_aws_state = color_conditions(
        node_metadata.instance.state,
        green=any_of('running',),
        blue=any_of('pending',),
        red=any_of('shutting-down', 'terminated', 'stopping', 'stopped'),
    )
    print(
        f'\t - {node_metadata.instance.instance_id} {node_metadata.instance.market} '
        f'({node_metadata.instance.ip_address}): {agent_aws_state}, up for '
        f'{format_timespan(node_metadata.instance.uptime.total_seconds(), max_units=1)}'
    )

    agent_mesos_state = color_conditions(
        node_metadata.agent.state,
        green=any_of(AgentState.RUNNING,),
        blue=any_of(AgentState.IDLE,),
        red=any_of(AgentState.ORPHANED, AgentState.UNKNOWN),
    )
    sys.stdout.write(f'\t   {agent_mesos_state} ')

    if node_metadata.agent.state == AgentState.RUNNING:
        colored_resources = [
            (
                color_conditions(
                    int(allocated / total * 100),
                    postfix='%',
                    green=lambda x: x <= 90,
                    yellow=lambda x: x <= 95,
                    red=lambda x: x > 95,
                )
                if total
                else 'None'
            )
            for (allocated, total) in zip(node_metadata.agent.allocated_resources, node_metadata.agent.total_resources)
        ]

        sys.stdout.write(
            f'{node_metadata.agent.task_count} tasks; '
            f'CPUs: {colored_resources[0]}, '
            f'Mem: {colored_resources[1]}, '
            f'Disk: {colored_resources[2]}, '
            f'GPUs: {colored_resources[3]}'
        )
    sys.stdout.write('\n') 
Example #26
Source File: game.py    From temci with GNU General Public License v3.0 4 votes vote down vote up
def get_full_html(self, base_dir: str, html_func: t.Callable[[str, int, bool], str] = None) -> str:
        resources_path = os.path.abspath(os.path.join(os.path.dirname(report.__file__), "report_resources"))
        shutil.copytree(resources_path, os.path.join(base_dir, "resources"))
        html = """<html lang="en">
    <head>
        <title>Implementation comparison for {lang}</title>
        <link rel="stylesheet" src="http://gregfranko.com/jquery.tocify.js/css/jquery.ui.all.css">
        <link rel="stylesheet" src="http://gregfranko.com/jquery.tocify.js/css/jquery.tocify.css">
        <link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" rel="stylesheet">
        <link rel="stylesheet" href="{srv}resources/style.css">
        <script src="https://code.jquery.com/jquery-2.1.4.min.js"></script>
        <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js"></script>
        <script src="http://gregfranko.com/jquery.tocify.js/js/jquery-ui-1.9.1.custom.min.js"></script>
        <script src="http://gregfranko.com/jquery.tocify.js/js/jquery.tocify.js"></script>
        <script type="text/javascript" src="https://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_SVG"></script>
        <script src="{srv}resources/script.js"></script>
    </head>
    <body style="font-family: sans-serif;">
        <div id="toc"></div>
        <div class="container">
          <div class="row">
             <div class="col-sm-3">
                <div id="toc"></div>
            </div>
             <!-- sidebar, which will move to the top on a small screen -->
             <!-- main content area -->
             <div class="col-sm-9">
                <div class="page-header">
                    <h1>Implementation comparison for {lang}</h1>
                    <p class="lead">A comparison of {comparing_str}</p>
                  </div>
                {inner_html}
                <footer class="footer">
                    Generated by <a href="https://github.com/parttimenerd/temci">temci</a>'s game.py in {timespan}<br/>
                    The benchmarked algorithms and their inputs come from the
                    <a href="http://benchmarksgame.alioth.debian.org/">benchmarksgame</a>
                </footer>
             </div>
          </div>
        </div>
    </body>
</html>
        """
        lang = self.name
        comparing_str = util.join_strs(self.get_scores_per_impl().keys())
        html_func = html_func or self.get_html
        inner_html = html_func(base_dir + "/fig", 2, with_header=False)
        import humanfriendly
        timespan = humanfriendly.format_timespan(time.time() - START_TIME)
        srv = "" if USABLE_WITH_SERVER else "file:"
        return html.format(**locals()) 
Example #27
Source File: uploader.py    From zimfarm with GNU General Public License v3.0 4 votes vote down vote up
def watched_upload(delay, method, **kwargs):
    str_delay = humanfriendly.format_timespan(delay) if humanfriendly else f"{delay}s"
    logger.info(f"... watching file until {str_delay} after last modification")

    class ExitCatcher:
        def __init__(self):
            self.requested = False
            for name in ["TERM", "INT", "QUIT"]:
                signal.signal(getattr(signal, f"SIG{name}"), self.on_exit)

        def on_exit(self, signum, frame):
            self.requested = True
            logger.info(f"received signal {signal.strsignal(signum)}, graceful exit.")

    exit_catcher = ExitCatcher()
    last_change = datetime.datetime.fromtimestamp(kwargs["src_path"].stat().st_mtime)
    last_upload, retries = None, 10

    while (
        # make sure we upload it at least once
        not last_upload
        # delay without change has not expired
        or datetime.datetime.now() - datetime.timedelta(seconds=delay) < last_change
    ):

        # file has changed (or initial), we need to upload
        if not last_upload or last_upload < last_change:
            started_on = datetime.datetime.now()
            kwargs["filesize"] = kwargs["src_path"].stat().st_size
            returncode = method(**kwargs)
            if returncode != 0:
                retries -= 1
                if retries <= 0:
                    return returncode
            else:
                if not last_upload:  # this was first run
                    kwargs["resume"] = True
                last_upload = started_on

        if exit_catcher.requested:
            break

        # nb of seconds to sleep between modtime checks
        time.sleep(1)

        # refresh modification time
        last_change = datetime.datetime.fromtimestamp(
            kwargs["src_path"].stat().st_mtime
        )
    if not exit_catcher.requested:
        logger.info(f"File last modified on {last_change}. Delay expired.")