diff options
| author | Teddy Wing | 2018-02-04 06:38:18 +0100 |
|---|---|---|
| committer | Teddy Wing | 2018-02-04 06:38:18 +0100 |
| commit | 3245850eaa8f290a1307730b391bea42b6cb6e76 (patch) | |
| tree | f6b5507ee34e12b36f1f9bb240bc3d2513b8cb43 /harvester_submit_week_for_approval.py | |
| parent | 84e7104af041307cd4c11237fcdf2898132c7cd9 (diff) | |
| download | harvester-submit-week-for-approval-3245850eaa8f290a1307730b391bea42b6cb6e76.tar.bz2 | |
Check that there are time entries for every day in the week
Before submitting the time sheet for approval (and before doing anything
with Selenium), ensure that there's at least one time entry logged for
each day in the week.
To do this, we query the Harvest API with newly-required account ID and
API token values. This gives us a bunch of time entries. We check them
to see if they fell in the last week. If all weekdays from the last week
have at least one time entry, then the rest of the program executes and
we run Selenium to submit the time sheet.
If any day had missing entries, an exception is raised and the program
exits.
Diffstat (limited to 'harvester_submit_week_for_approval.py')
| -rw-r--r-- | harvester_submit_week_for_approval.py | 71 |
1 files changed, 71 insertions, 0 deletions
diff --git a/harvester_submit_week_for_approval.py b/harvester_submit_week_for_approval.py index 6f9e047..b52f6c9 100644 --- a/harvester_submit_week_for_approval.py +++ b/harvester_submit_week_for_approval.py @@ -3,6 +3,7 @@ import argparse from datetime import datetime, timedelta import subprocess +import sys from selenium.webdriver import Firefox from selenium.webdriver.common.by import By @@ -11,6 +12,8 @@ from selenium.webdriver.firefox.options import Options from selenium.webdriver.support import expected_conditions as expected from selenium.webdriver.support.wait import WebDriverWait +import requests + def login(driver, wait, email, password): driver.get('https://id.getharvest.com/harvest/sign_in') @@ -89,6 +92,61 @@ def get_password(command): return str(result.stdout, 'utf-8').rstrip() +class WeekIsComplete(object): + + def __init__(self, account_id, api_token, friday): + self.account_id = account_id + self.api_token = api_token + self.friday = friday + self._monday = None + self.days = {} + + # Add `self.days['2018-01-31'] = 0` for all weekdays + for i in range(5): + self.days[(self.monday + timedelta(days=i)).strftime('%F')] = 0 + + def check(self): + time_entries = self._fetch_week() + days = self.days.keys() + + for entry in time_entries['time_entries']: + if entry['spent_date'] in days: + self.days[entry['spent_date']] += 1 + + for _, count in self.days.items(): + if count == 0: + raise IncompleteWeekError + + return True + + def _fetch_week(self): + r = requests.get( + 'https://api.harvestapp.com/api/v2/time_entries', + headers={ + 'Harvest-Account-ID': self.account_id, + 'Authorization': 'Bearer {}'.format(self.api_token), + 'User-Agent': 'harvester-submit-week-for-approval (TODO email address or link to app)', + 'Content-Type': 'application/json', + }, + params={ + 'from': self.monday.strftime('%F'), + 'to': self.friday.strftime('%F'), + }) + + return r.json() + + @property + def monday(self): + if not self._monday: + self._monday = self.friday - timedelta(days=4) + + return self._monday + + +class IncompleteWeekError(RuntimeError): + pass + + if __name__ == "__main__": parser = argparse.ArgumentParser( description='Submit the most recent Harvest timesheet for approval.') @@ -107,6 +165,19 @@ if __name__ == "__main__": args = parser.parse_args() + # Don't submit unless there is at least 1 time sheet logged for each day + # that week + try: + WeekIsComplete( + account_id='', + api_token='', + friday=most_recent_friday() + ).check() + except IncompleteWeekError: + print('Week was incomplete') + + sys.exit(1) + options = Options() options.add_argument('-headless') driver = Firefox( |
