Skip to content

feat: add flags for get-status subcommand#37

Open
slate5 wants to merge 8 commits into
ProtossGP32:mainfrom
slate5:feature/get-status-period
Open

feat: add flags for get-status subcommand#37
slate5 wants to merge 8 commits into
ProtossGP32:mainfrom
slate5:feature/get-status-period

Conversation

@slate5
Copy link
Copy Markdown

@slate5 slate5 commented Oct 13, 2025

Closes #33

Copy link
Copy Markdown
Owner

@ProtossGP32 ProtossGP32 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changes reviewed, please address what's commented in the review.

"""Return the total amount of worked hours and current sign status."""
# Retrieve info for the period flags, e.g., --week, --month, --year
if period != "today":
return self._get_status_period(period), None
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

get_status returns a tuple[timedelta, bool] but you're returning tuple[timedelta, None]. Pylance is complaining about this, so we should fix this. Maybe we should invoke a new method that only returns self._get_status_period(period) if you only want the total time... Or make the bool return value optional.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would rather use Optional[bool] to avoid dispersing subcommands and their flags. Ideally, we would execute one function from cli.py that represents a subcommand and pass any flags as arguments.

Another option is to return the sign-in status also for each variation of get-status, which would imply 2 REST API calls for period flags (e.g., --week, --month, --year).

What do you think?

Copy link
Copy Markdown
Owner

@ProtossGP32 ProtossGP32 Oct 16, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's go with the Optional[bool] option for now. I'll let you know if Pylance complains about any other thing then (it hates types inconsistencies during unit tests).

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Additionally, the get-status command in woffu-cli ends with error when defining different time windows due to the status not being available:

(.venv) mpalacin@bsc-84885021:~/GitHub/personal_projects/woffu-client$ woffu-cli get-status
[2025-10-17 10:04:53] INFO woffu_api_client: Hours worked today: 00:42:22
[2025-10-17 10:04:53] INFO woffu_api_client: You're currently signed in.
(.venv) mpalacin@bsc-84885021:~/GitHub/personal_projects/woffu-client$ woffu-cli get-status --week
[2025-10-17 10:05:02] INFO woffu_api_client: Hours worked this week: 14:25
❌ Error retrieving status: not enough values to unpack (expected 2, got 1)

Please try to secure this.

@slate5 slate5 requested a review from ProtossGP32 October 17, 2025 13:04
@slate5 slate5 force-pushed the feature/get-status-period branch from d764480 to f69c0c0 Compare October 20, 2025 22:08
from_date = today.replace(month=1, day=1)
to_date = today.replace(month=12, day=31)

diary_json = self.get(
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here you're calling the same HTTP endpoint as in _get_presence() private method. Maybe we can create a base method for presence retrieving to avoid duplicated code? And then this new method can be used for both the current _get_presence() and the new _get_status_period().

"""Return the total amount of worked hours and current sign status."""
# Retrieve info for the period flags, e.g., --week, --month, --year
if period != "today":
return self._get_status_period(period), None
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Additionally, the get-status command in woffu-cli ends with error when defining different time windows due to the status not being available:

(.venv) mpalacin@bsc-84885021:~/GitHub/personal_projects/woffu-client$ woffu-cli get-status
[2025-10-17 10:04:53] INFO woffu_api_client: Hours worked today: 00:42:22
[2025-10-17 10:04:53] INFO woffu_api_client: You're currently signed in.
(.venv) mpalacin@bsc-84885021:~/GitHub/personal_projects/woffu-client$ woffu-cli get-status --week
[2025-10-17 10:05:02] INFO woffu_api_client: Hours worked this week: 14:25
❌ Error retrieving status: not enough values to unpack (expected 2, got 1)

Please try to secure this.


h, m = map(int, diary_json["totalWorkedTimeFormatted"]["values"])
logger.info(
"Hours worked this {}: {:02d}:{:02d}".format(period, h, m),
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For consistency's sake with the default results, we should use the same time format, including hours, minutes and seconds. This way we ease the job of any external parser that might want to extract this value:

"Hours worked today: {:02d}:{:02d}:{:02d}".format(
                int(hours), int(minutes), int(seconds),
            ),

Comment thread src/woffu_client/cli.py
const="year",
help="Get current year's total hours",
)
st_parser.set_defaults(period="today")
Copy link
Copy Markdown
Owner

@ProtossGP32 ProtossGP32 Oct 21, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it would be good to also define a subparser argument for --today even though it's the default value, so users using some kind of automated script to invoke woffu-cli can easily swap between any of the options and not worry about having to leave it empty. What do you think?

"""
from __future__ import annotations

import calendar
Copy link
Copy Markdown
Owner

@ProtossGP32 ProtossGP32 Nov 21, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

calendar package is deprecated (https://pypi.org/project/Calendar/). Please use any alternative actively maintained to avoid technical debt in the future.

Also, when importing new modules, please add them to the corresponding pyproject.toml section.

@ProtossGP32 ProtossGP32 force-pushed the feature/get-status-period branch 2 times, most recently from 13be18b to e244231 Compare December 19, 2025 13:57
@ProtossGP32
Copy link
Copy Markdown
Owner

ProtossGP32 commented Dec 19, 2025

I've rebased this branch with fix #41 to prevent tests from failing. Please update your local branch (git pull --rebase) before committing any new change, thanks!

@ProtossGP32 ProtossGP32 force-pushed the feature/get-status-period branch from e244231 to a9c8ab7 Compare January 5, 2026 11:02
@ProtossGP32
Copy link
Copy Markdown
Owner

ProtossGP32 commented Feb 2, 2026

I've found out that we can use lighter HTTP requests to retrieve the same weekly, monthly and yearly information:

Summary and Presence

ℹ️ This section contains queries related to summary and presence.

Time formats can vary depending on the values precision, and its format is defined in the resource key:

  • For instance, values that are rounded to the hour and only return a single item in the values array will have _HoursFormatted as the resource type
  • If values array contains more than one item, then the resource type will be _HoursMinutesFormatted
  • TODO: check if there are other resource types

The query is the same for all except the start and end dates and the diaryPresenceType value:

  • 1 is for weekly summary
  • 2 is for monthly summary
  • 3 is for yearly summary
  • Weekly summary:

    • Query:

      https://bsc.woffu.com/api/svc/core/diariesquery/users/<user_id>/diarysummary/presence/summary?fromDate=<current_week_monday>&toDate=<current_week_sunday>&diaryPresenceType=1
    • JSON response:

      {
          'detailEndDate': '2026-02-08T00:00:00',
          'detailStartDate': '2026-02-02T00:00:00',
          'hasAlert': False,
          'percentWorked': 50,
          'title': '_ThisWeek',
          'totalWorkedTimeFormatted': {'resource': '_HoursFormatted', 'values': ['0']},
          'totalWorkingTimeFormatted': {'resource': '_HoursMinutesFormatted',
                                      'values': ['37', '30']},
          'totalWorkingTimeUntilTodayFormatted': {'resource': '_HoursFormatted',
                                                  'values': ['0']},
          'userId': <user_id>
      }
  • Monthly summary:

    • Query:

      https://bsc.woffu.com/api/svc/core/diariesquery/users/<user_id>/diarysummary/presence/summary?fromDate=<current_month_first_day>&toDate=<current_month_last_day>&diaryPresenceType=2
    • JSON response:

      {
          'detailEndDate': '2026-02-01T00:00:00+00:00',
          'detailStartDate': '2026-02-01T00:00:00',
          'hasAlert': False,
          'percentWorked': 50,
          'title': '_February',
          'totalWorkedTimeFormatted': {'resource': '_HoursFormatted', 'values': ['0']},
          'totalWorkingTimeFormatted': {'resource': '_HoursFormatted',
                                      'values': ['150']},
          'totalWorkingTimeUntilTodayFormatted': {'resource': '_HoursFormatted',
                                                  'values': ['0']},
          'userId': <user_id>
      }
  • Yearly summary:

    • Query:

      https://bsc.woffu.com/api/svc/core/diariesquery/users/<user_id>/diarysummary/presence/summary?fromDate=<year>-01-01&toDate=<year>-12-31&diaryPresenceType=3
    • JSON response:

      {
          'detailEndDate': '2026-02-01T00:00:00+00:00',
          'detailStartDate': '2026-01-01T00:00:00',
          'hasAlert': False,
          'percentWorked': 52,
          'title': '2026',
          'totalWorkedTimeFormatted': {'resource': '_HoursMinutesFormatted',
                                      'values': ['156', '24']},
          'totalWorkingTimeFormatted': {'resource': '_HoursFormatted',
                                      'values': ['1642']},
          'totalWorkingTimeUntilTodayFormatted': {'resource': '_HoursFormatted',
                                                  'values': ['150']},
          'userId': <user_id>
      }
      • It automatically clamps the time window between the start of the current year and the day before the current day
        • So it doesn't take into account the already worked hours in the current day
  • Current approach: reusing presence query

    • Query:

      https://bsc.woffu.com/api/svc/core/diariesquery/users/<user_id>/diaries/summary/presence?fromDate=<start_date>&toDate=<end_date>
    • JSON response:

      {
          'diaries: [ "..." ],
          'dynamicColumns': None,
          'isUserAcceptable': True,
          'totalDifferenceTime': 0,
          'totalDifferenceTimeFormatted': {'resource': '_HoursFormatted',
                                          'values': ['0']},
          'totalDynamicColumnsFormatted': {},
          'totalNotRecognizedTimeFormatted': {'resource': '_HoursFormatted',
                                              'values': ['0']},
          'totalRecords': 365,
          'totalScheduleTimeFormatted': {'resource': '_HoursMinutesFormatted',
                                          'values': ['2737', '30']},
          'totalWorkedTimeFormatted': {'resource': '_HoursMinutesFormatted',
                                      'values': ['156', '24']},
          'totalWorkingTimeFormatted': {'resource': '_HoursMinutesFormatted',
                                      'values': ['1852', '30']}
      }

      This is a lot heavier than the previous one (we get info of all the days within that time period) and we only use the totalWorkedTimeFormatted key, which returns the same for both queries. Also, totalWorkingTimeFormatted value doesn't match the previous query for diaryPresenceType=3, so we should verify which one of these is the right one.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Total number of hours for the current month

2 participants