aboutsummaryrefslogtreecommitdiffstats
path: root/harvester_submit_week_for_approval.py
diff options
context:
space:
mode:
authorTeddy Wing2018-02-04 06:38:18 +0100
committerTeddy Wing2018-02-04 06:38:18 +0100
commit3245850eaa8f290a1307730b391bea42b6cb6e76 (patch)
treef6b5507ee34e12b36f1f9bb240bc3d2513b8cb43 /harvester_submit_week_for_approval.py
parent84e7104af041307cd4c11237fcdf2898132c7cd9 (diff)
downloadharvester-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.py71
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(