aboutsummaryrefslogtreecommitdiffstats
path: root/harvester_submit_week_for_approval.py
blob: 77e06657414b23a5e03f1713c4cbd624bccddf60 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
#!/usr/bin/env python

import argparse
from datetime import datetime, timedelta
import subprocess

from selenium.webdriver import Firefox
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.firefox.options import Options
from selenium.webdriver.support import expected_conditions as expected
from selenium.webdriver.support.wait import WebDriverWait

email = ''
password = ''
subdomain = ''


def login(driver, wait):
    driver.get('https://id.getharvest.com/harvest/sign_in')

    wait.until(
        expected.visibility_of_element_located((By.NAME, 'email'))
    ).send_keys(email)
    driver.find_element_by_name('password').send_keys(password + Keys.ENTER)

    wait.until(
        expected.visibility_of_element_located((By.ID, 'user-dropdown-toggle'))
    )

    return driver

def most_recent_friday():
    friday = 4
    now = datetime.now()

    if now.weekday() >= friday:
        return now - timedelta(days=now.weekday() - friday)
    else:
        return now - timedelta(weeks=1) + timedelta(days=friday - now.weekday())

def submit_week_for_approval(driver, wait):
    # friday = most_recent_friday()
    friday = datetime(2018, 1, 15)

    url = 'https://{subdomain}.harvestapp.com/time/week/{year}/{month}/{day}/'.format(
        subdomain=subdomain,
        year=friday.year,
        month=friday.month,
        day=friday.day)

    driver.get(url)

    # Wait for page to load
    wait.until(expected.text_to_be_present_in_element(
        (By.CLASS_NAME, 'timesheet-header'),
        str(friday.year)))
    wait.until(expected.text_to_be_present_in_element(
        (By.CSS_SELECTOR, '.day .js-day'),
        friday.strftime('%d %b')))

    # Click "Submit Week for Approval" button
    driver.find_element_by_css_selector(
        '.approval-button .submit-link'
    ).click()

    # Click "Yes, Submit Timesheet" button
    wait.until(
        expected.visibility_of_element_located(
            (
                By.CSS_SELECTOR,
                '.approval-confirmation .js-submit-for-approval',
            )
        )
    ).click()

    # Wait for success message
    wait.until(expected.text_to_be_present_in_element(
        (By.ID, 'status_message'),
        'Timesheet has been submitted for approval.'))

    return driver

def get_password(command):
    result = subprocess.run(['sh', '-c', command], stdout=subprocess.PIPE)

    return str(result.stdout, 'utf-8').rstrip()


if __name__ == "__main__":
    parser = argparse.ArgumentParser(
        description='Submit the most recent Harvest timesheet for approval.')
    parser.add_argument(
        '--email',
        required=True,
        help='Harvest email address')
    parser.add_argument(
        '--password-command',
        required=True,
        help='Shell command to get Harvest password')
    parser.add_argument(
        '--subdomain',
        required=True,
        help='Harvest subdomain (acme in acme.harvestapp.com)')

    args = parser.parse_args()

    options = Options()
    options.add_argument('-headless')
    driver = Firefox(
        executable_path='./geckodriver',
        firefox_binary='/Applications/FirefoxDeveloperEdition.app/Contents/MacOS/firefox-bin',
        firefox_options=options)

    wait = WebDriverWait(driver, timeout=10)

    driver = login(driver, wait)
    driver = submit_week_for_approval(driver, wait)

    driver.quit()