Exemplo n.º 1
0
def stop_log():
    print("\n End of log session : " +
          TZDT.now().strftime("%b %d %Y %I:%M:%S %p") + "\n")
    sys.stdout = ORIG_STDOUT
    print("Log mode deactivated : " +
          TZDT.now().strftime("%b %d %Y %I:%M:%S %p") + "\n")
    logger.close()
def confirm_shift(confirm_button):
    if confirm_button is None:
        print("shift NOT confirmed, timestamp: " + TZDT.now().strftime("%I:%M:%S %p"))
    else:
        confirm_button.click()  # click to confirm shift
        # print confirmation message when ConfirmShift page is stale
        wait_for_stale_elements(driver, confirm_button)
        print('Shift confirmed at: ' + TZDT.now().strftime("%I:%M:%S %p"))
Exemplo n.º 3
0
def get_desired_shift_dates(schedule_dict, delta):
    # variable to hold output
    shifts_list = []
    # get time now
    timeNow = TZDT.now()
    # add delta weeks to date
    desiredWeekday = timeNow + timedelta(weeks=delta)  # adds delta weeks
    # get year, month and day for desiredWeekday
    dateTuple = date_to_tuple(desiredWeekday)
    desired_year = dateTuple[0]
    desired_month = dateTuple[1]
    desired_day = dateTuple[2]
    # convert desiredWeekday to weekday string format and find shift times in schedule
    weekdayFormat = desiredWeekday.strftime("%a")
    shifts_of_the_day = schedule_dict[
        weekdayFormat]  # this is a list of tuples
    # find start and end times in shift times
    for startTime, endTime in shifts_of_the_day:
        # make shift list in datetime format, include just the startTime
        _shiftStartTime = datetime(desired_year, desired_month, desired_day,
                                   startTime)
        _shiftEndTime = datetime(desired_year, desired_month, desired_day,
                                 endTime)
        tuple_shift_start_end = (_shiftStartTime, _shiftEndTime)
        shifts_list.append(tuple_shift_start_end)

    return shifts_list
def grab_shift(date_and_time_tuple, parsed_table, location_of_shift='Lab Assistance - Lamont'):
        # find shifts in shiftboard
    available_shifts = parsed_table  # shiftboard_parser(tableRowXpath)
    # variable for input_starTime and input_endTime
    inputStartTime = date_and_time_tuple[0]
    inputEndTime = date_and_time_tuple[1]
    # extract just the date from input
    bare_y, bare_m, bare_d = date_to_tuple(inputStartTime)
    plain_date = datetime(bare_y, bare_m, bare_d)
    # extract  just the hour from inputStartTime and inputEndTime and format it
    inputStartHour = inputStartTime.strftime("%I%p").lower().lstrip("0")
    inputEndHour = inputEndTime.strftime("%I%p").lower().lstrip("0")
    # find shift
    if plain_date in available_shifts:
        # get shifts and shifts' info on plain_date
        dictValues = available_shifts[plain_date]
        # Handle empty dictValues
        if dictValues == []:
            print("No shifts to grab today, or all shifts have already been taken")
            return None
        else:
            pass
        for shiftDateRange, shiftLocation, clickElement in dictValues:
            # Name shiftDataRange elements for readability
            shiftStartTime = shiftDateRange[0]
            shiftEndTime = shiftDateRange[1]
            # find shift by comparing shiftStartTime and shiftEndTime to shift hours
            if (shiftStartTime == inputStartHour) and (shiftEndTime == inputEndHour) and (shiftLocation == location_of_shift):
                # indicate that shift has been found
                print(shiftStartTime + "-" + shiftEndTime + " : " + shiftLocation + " : MATCH FOUND, deploying confirm button...")
                clickElement.click()    # click to grab shift
                # find "take this shift button"
                TakeThisShift = patiently_find(driver, element_present, By.XPATH, TakeThisShiftXpath)
                TakeThisShift.click()   # click to take shift
                # find "confirm shift" button
                ConfirmShift = patiently_find(driver, element_present, By.XPATH, ConfirmShiftXpath)
                # Return confirm shift button
                print('Confirm button deployed at: ' + TZDT.now().strftime("%I:%M:%S %p"))
                return ConfirmShift

            elif (shiftStartTime != inputStartHour) and (shiftEndTime != inputEndHour) and (shiftLocation != location_of_shift):
                print(shiftStartTime + "-" + shiftEndTime + " : " + shiftLocation + ": Time and Location mismatch, skipping...")
            elif shiftLocation != location_of_shift:
                print(shiftStartTime + "-" + shiftEndTime + " : " + shiftLocation + ": Location mismatch. Input loaction is unpreferred.")
            elif (shiftStartTime != inputStartHour) and (shiftEndTime != inputEndHour):
                print(shiftStartTime + "-" + shiftEndTime + " : " + shiftLocation + ": Time mismatch. skipping...")
            else:
                print(shiftStartTime + "-" + shiftEndTime + " : " + shiftLocation + ": Error in grab_shift function of browser_handler: None of the conditions match")
    elif plain_date not in available_shifts:
        print("Date mismatch")
        return None  # return None for error handling
    else:
        print("Something went wrong with grab_shift")
        return None  # return non if all do not match
Exemplo n.º 5
0
def GUI_log(file_name, _data):
    if _data != "\n":
        my_file = open(file_name, "a")
        global FirstTime
        if FirstTime:
            my_file.write('\n\n')
            FirstTime = False
        my_file.write(TZDT.now().strftime("%b %d %Y %I:%M:%S %p") + " - " +
                      str(_data) + "\n")
        my_file.close()
    else:
        pass  # ignore \n
Exemplo n.º 6
0
def check_if_shift_approching(schedule_list_of_tuples, delta, decrease_delta):
    for time in schedule_list_of_tuples:
        shiftStartTime = time[0]
        shiftEndTime = time[1]
        if (TZDT.now() + timedelta(weeks=delta)) >= (
                shiftStartTime - timedelta(seconds=decrease_delta)):
            time_on_this_date = (timedelta(weeks=delta) + TZDT.now())
            print(
                "Grabbing time approaching for " +
                date_to_short_hour(shiftStartTime) + "-" +
                date_to_short_hour(shiftEndTime) + " in " +
                str(timedelta.total_seconds(shiftStartTime -
                                            time_on_this_date)).split(".")[0] +
                " seconds")
            return time
        else:
            # troubleshooting
            if debugMode:
                print("...")
            else:
                pass
    return None
Exemplo n.º 7
0
def main_x():
    try:
        # startup message
        global FirstTimeInitiating
        if (FirstTimeInitiating):
            print("Program initiated on " +
                  TZDT.now().strftime("%b %d %Y %I:%M:%S %p"))
            FirstTimeInitiating = False
        else:
            pass

        # get user input
        try:
            # Update storage file?
            if sys.argv[1].lower().find('yes') != -1:
                print("Clear command received, clearing storage file...")
                FM.clear_data_file(dailyShiftStore)
                print("Storage file cleared successfully")
            else:
                pass
            # specify location
            global LOCATION
            if sys.argv[1].lower().find('lamont') != -1:
                print("Specified location: LAMONT")
                LOCATION = LAMONT
            elif sys.argv[1].lower().find('cabot') != -1:
                print("Specified location: CABOT")
                LOCATION = CABOT
            else:
                print("Location not specified."
                      )  # pass if location not specified

            sys.argv = []  # clear input
        except IndexError:
            pass  # ignore this error
        '''
        # Alternative code for requesting user input

        global FirstTimeInitiating
        if FirstTimeInitiating:
            if askyesno('Verify', 'Update storage data?'):
                print("Clear command received, clearing storage file...")
                FM.clear_data_file(dailyShiftStore)
                print("Storage file cleared successfully")
                FirstTimeInitiating = False
            else:
                pass  # ignore
        else:
            pass  # ignore
        '''

        # variable to hold dersied shifts start times in a list
        shiftsOfTheDay = []
        # check the mode (calendar mode or scheduler mode)
        if calendarMode:

            # check if record of shifts already exists in file, check date timestamp
            timestamp_storedData = None  # variable to hold timestamp from stored file
            try:
                storedData = FM.load_data(dailyShiftStore)
                timestamp_storedData = storedData[
                    0]  # never use index with an empty tuple
            except EOFError:
                pass  # do not alter value of timestamp stored data
            if (timestamp_storedData == SC.today_raw_date()):

                # data already exists thus retrieve shifts of the day ie index 1 of tuple
                print("Valid up-to-date shift data found in storage")
                shiftsOfTheDay = storedData[1]
                print("Storage data retrieved!")

                # Show retrieved data on GUI
                print("Today's available shifts:")
                for each_tuple in shiftsOfTheDay:
                    print(SC.datetime_tuple_to_string_format(each_tuple))
                if shiftsOfTheDay == []:  # print none if no shifts available
                    print(None)

            else:  # get new data and write to file
                GUI.BAR_MODE = "loading"
                # initiation sequence
                print(
                    "Calendar mode active. \nRetrieving data from shiftboard website"
                )
                BH.launch_browser(address)  # go to shiftbaord website
                BH.login(email, password)  # login
                BH.goto_next_week(weekNo)  # go to weekNo weeks ahead
                # extract table data from shiftboard
                parsedShiftboardTable_for_calendar = BH.shiftboard_parser(
                    BH.tableRowXpath)
                # remove taken shifts
                parsedShiftboardTable_for_calendar = BH.remove_taken_shifts(
                    parsedShiftboardTable_for_calendar)
                print("Shift filtering complete")
                # extract day's shifts in a list of tuples
                extractedDayShifts = BH.extract_day_shift_time(
                    parsedShiftboardTable_for_calendar, weekNo)
                # convert shift time ranges to datetimes and get list of tuples of shifts
                tuple_of_date_and_shift_tuples = BH.shift_time_to_datetime_parser(
                    extractedDayShifts)
                list_of_tuples_shift_times_of_day = tuple_of_date_and_shift_tuples[
                    1]  # list of shifts for this day
                # use calendar_manager functions to retrieve day schedule with free periods
                print("Extracting schedule data from calendar")
                search_date = tuple_of_date_and_shift_tuples[
                    0]  # get date on tuple list of extractedDayShifts
                list_free_periods = CLDM.retrieve_schedule_of_the_day(
                    search_date)  # list of free periods for this day
                # use calendar_manager functions to compare shift time to free periods
                for each_shift in list_of_tuples_shift_times_of_day:
                    # check if free at shift times and add start times of shifts that work to shiftsOfTheDay
                    isFree = CLDM.check_if_free_comparator(
                        each_shift, list_free_periods)
                    if isFree:
                        # store start time and end times of each shift to shiftsOfTheDay list.
                        shiftsOfTheDay.append(each_shift)

                    else:
                        pass  # do nothing
                # remove duplicates from shiftsOfTheDay, also changes order of elements ie sets are unordered
                print("List of shifts compiled successfully")
                shiftsOfTheDay = list(set(shiftsOfTheDay))
                # store to file for future sessions, include datestamp stored in dailyShiftStore
                print("Writing list of shifts to storage file...")
                FM.write_data(dailyShiftStore,
                              (SC.today_raw_date(), shiftsOfTheDay))
                print("Stored successfully")

        else:

            # schedule mode
            # get list of dates of desired shifts two weeks from now from scheduler
            shiftsOfTheDay = SC.get_desired_shift_dates(desiredShifts, weekNo)

        # switch to shift listening mode and enter loop
        print("Listening for shifts from " + LOCATION + "...")
        GUI.BAR_MODE = "listening"  # switch display mode

        # Make the program loop forever
        while True:

            # get approaching shift two weeks from now, (30 seconds earlier)
            shiftToTake = SC.check_if_shift_approching(shiftsOfTheDay, weekNo,
                                                       30)

            # if exit button is pressed in GUI
            if GUI.exit_thread:
                break

            # check if its sleeping time
            elif SC.today_time(wakeHour, wakeMinute) > TZDT.now():
                # go to sleep
                print("Sleeping time zzz")
                break

            # check if desired shifts is empty
            elif shiftsOfTheDay == []:
                # exit loop if empty
                if calendarMode:
                    print(
                        "You have no free periods or there are no more shifts available on \n"
                        + shift_check_date.strftime("%b %d %Y"))
                else:
                    print("Your schedule is empty on " +
                          shift_check_date.strftime("%b %d %Y"))
                # exit
                break

            # check if shift is approaching
            elif shiftToTake is None:

                # keep waiting for shift to approach
                pass
                # SPC.spinner()

            # run the code below if approaching
            else:
                # GUI
                GUI.BAR_MODE = "loading"

                # wait for internet connectivity
                print("Checking for internet connectivity at " +
                      TZDT.now().strftime("%b %d %Y %I:%M:%S %p"))
                while (not BH.connected()):
                    # check if program has been aborted
                    if GUI.exit_thread:
                        break
                    else:
                        pass  # keep waiting for internet connectivity

                # connection successful
                print("Internet connection established at " +
                      TZDT.now().strftime("%b %d %Y %I:%M:%S %p"))

                # launch browser
                BH.launch_browser(address)

                # enter username and password and log in
                BH.login(email, password)

                # go to two weeks ahead
                BH.goto_next_week(weekNo)

                # parse shiftboard table
                parsedShiftboardTable = BH.shiftboard_parser(BH.tableRowXpath)

                # remove taken shifts
                parsedShiftboardTable = BH.remove_taken_shifts(
                    parsedShiftboardTable)

                # get shift confirm button
                confirmBtn = BH.grab_shift(shiftToTake, parsedShiftboardTable,
                                           LOCATION)

                # check if get shift confirm button is empty
                if confirmBtn is None:
                    # remove shift time from list and update record to file
                    print("Could NOT find shift on shiftboard")
                    shift_remover(shiftToTake, shiftsOfTheDay)
                    # then call main
                    main_x()
                else:
                    pass  # ignore if shift found

                # create function to abort shift grabbing if need be
                def abort_grabbing():
                    shift_remover(shiftToTake, shiftsOfTheDay)  # remove shift
                    main_x()  # call main to abort

                # abort message
                ABORT_MESSAGE = SC.datetime_tuple_to_string_format(
                    shiftToTake
                ) + '''\nThis shift will be taken in less than 30 seconds. Click below to cancel'''

                # confirm shift, wait until the time reaches
                GUI.BAR_MODE = "flashing"  # change bar GUI

                # ask user if shift grabbing should be aborted
                GUI.final_shift_notification(15000, ABORT_MESSAGE,
                                             abort_grabbing)

                while ((TZDT.now() + timedelta(weeks=weekNo)) <
                       (shiftToTake[0]) + timedelta(milliseconds=1)):
                    # check if program has been aborted
                    if GUI.exit_thread:
                        break
                    else:
                        pass  # ignore

                # confirm
                BH.confirm_shift(confirmBtn)
                GUI.BAR_MODE = "loading"

                # remove confirmed shift from list for this session and record to file
                shift_remover(shiftToTake, shiftsOfTheDay)

                # switch to shift listening mode mode once done
                print("Done.\nListening for shifts from " + LOCATION + "...")
                GUI.BAR_MODE = "listening"
                # BH.delay(5)
                # BH.exit_sequence()
            BH.delay(1)  # delay for 1 second, decrease CPU cycle rate

        # print loop exit message
        timestamp = TZDT.now()
        print("Loop exit at :" + timestamp.strftime("%b %d %Y %I:%M:%S %p"))

        # set arbitrary variable for wakeTime, value will be updated below
        wakeTime = timestamp
        # find wake up time by increasing timestamp by 1 day, fix this with if statements
        if SC.today_time(wakeHour, wakeMinute) < TZDT.now() < SC.today_time(
                23, 59):
            wakeTime = timestamp + timedelta(days=1)
        else:
            pass  # dont add a day ie wake up in the morning the same day

        # extract current date from wakeTime
        wakeTime_year, wakeTime_month, wakeTime_day = SC.date_to_tuple(
            wakeTime)
        # date at 8:45am on the next day
        wakeTime = datetime(wakeTime_year, wakeTime_month, wakeTime_day,
                            wakeHour, wakeMinute)
        # activate sleepmode and wait until 8:45am the next day to wake
        if not GUI.exit_thread:
            print("Sleep mode activated at :" +
                  TZDT.now().strftime("%b %d %Y %I:%M:%S %p"))
            GUI.BAR_MODE = "sleeping"
        # uncomment when ready to commence
        while TZDT.now() < wakeTime:
            # if exit button pressed
            if GUI.exit_thread:
                BH.exit_sequence()
                GUI.exit_success = True  # indicate to GUI that exit was successful
                quit()  # exit all python scripts
                break
            else:
                GUI.gray_fade_in()
                GUI.gray_fade_out()
            BH.delay(3)  # decrease CPU cycle rate by sleeeping
        # if exit button NOT pressed
        if not GUI.exit_thread:
            # wake up sequence
            print("Sleep mode deactivated. Waking up at :" +
                  TZDT.now().strftime("%b %d %Y %I:%M:%S %p"))
            GUI.BAR_MODE = "listening"
            main_x()  # call main to wake the program and listen for shifts
        else:
            pass
    except Exception as e:
        # print the exception raised
        print("PROGRAM ERROR DETECTED: ")
        print(str(e) + "\n")

        # wait for internet connectivity
        print("Checking for internet connectivity at " +
              TZDT.now().strftime("%b %d %Y %I:%M:%S %p"))
        while (not BH.connected()):
            # check if program has been aborted
            if GUI.exit_thread:
                break
            else:
                pass  # keep waiting for internet connectivity

        # connection successful
        print("Internet connection established at " +
              TZDT.now().strftime("%b %d %Y %I:%M:%S %p"))

        # call main to re initiate the program
        main_x()
Exemplo n.º 8
0
import sys  # module to get input from user
import stdout_GUI as GUI  # gui for display
# from tkMessageBox import askyesno  # uncomment if switching to alternative input method
import timezone_datetime as TZDT

# program variables
debugMode = False
weekNo = 2
takenShifts = 'taken_shifts.txt'
wakeHour = 8  # am
wakeMinute = 50  # am
calendarMode = True
dailyShiftStore = 'daily_shift_store.txt'
secret_data = 'secret.data'
FirstTimeInitiating = True
shift_check_date = TZDT.now() + timedelta(weeks=weekNo)

# user variables
email = FM.load_data(secret_data)[0]  # get email from file
password = FM.load_data(secret_data)[1]  # get password from file
address = 'https://www.shiftboard.com/log-in/'  # shiftboard website address

# shift related variables
desiredShifts = SC.desiredShifts  # shifts to grab
LAMONT = 'LAMONT'
CABOT = 'CABOT Studios'
LOCATION = LAMONT  # system default for location

# program functions

Exemplo n.º 9
0
def start_log():
    print("Log mode active. Redirecting ouput to logfile")
    sys.stdout = logger
    print("\n New log session : " +
          TZDT.now().strftime("%b %d %Y %I:%M:%S %p") + "\n")
Exemplo n.º 10
0
def exit_sequence():
    print("Exit sequence initiated at : " + TZDT.now().strftime("%b %d %Y %I:%M:%S %p") + ". Closing browser and exiting program.")
    driver.quit()  # close browser after done
Exemplo n.º 11
0
def today_time(_hour, _minute):
    _year, _month, _day = date_to_tuple(TZDT.now())
    return datetime(_year, _month, _day, _hour, _minute)
Exemplo n.º 12
0
def today_raw_date():
    _y, _m, _d = date_to_tuple(TZDT.now())
    return datetime(_y, _m, _d)