diff options
| author | Jan Tuomi <jans.tuomi@gmail.com> | 2021-02-12 14:52:00 +0200 |
|---|---|---|
| committer | Jan Tuomi <jans.tuomi@gmail.com> | 2021-02-12 14:52:00 +0200 |
| commit | 6d69d7f19c3014318734e618baff5ba958fe2344 (patch) | |
| tree | 82051fd081b976d4c78829d343cc7cec93db7616 /hommaexceli_py | |
| parent | af5b4941705fd08be5e72ad5c06e8a3ab8b50da7 (diff) | |
Implement Sheets and Telegram clients
Diffstat (limited to 'hommaexceli_py')
| -rw-r--r-- | hommaexceli_py/main.py | 48 | ||||
| -rw-r--r-- | hommaexceli_py/sheets_client.py | 71 | ||||
| -rw-r--r-- | hommaexceli_py/telegram_client.py | 57 |
3 files changed, 136 insertions, 40 deletions
diff --git a/hommaexceli_py/main.py b/hommaexceli_py/main.py index 202606d..46d6acb 100644 --- a/hommaexceli_py/main.py +++ b/hommaexceli_py/main.py @@ -1,47 +1,13 @@ -import pickle -import os.path -from googleapiclient.discovery import build -from google_auth_oauthlib.flow import InstalledAppFlow -from google.auth.transport.requests import Request +from dotenv import load_dotenv -# If modifying these scopes, delete the file token.pickle. -SCOPES = ["https://www.googleapis.com/auth/spreadsheets.readonly"] +load_dotenv() -# The ID and range of a sample spreadsheet. -SPREADSHEET_ID = "1eKEcFRQBdM2b-pPxnSUEilAKdHnMUNXZljO_I6iqwBw" -RANGE_NAME = "A4:C7" +from sheets_client import authenticate_and_fetch_sheets_data +from telegram_client import run_telegram def main(): - """Shows basic usage of the Sheets API. - Prints values from a sample spreadsheet. - """ - creds = None - # The file token.pickle stores the user's access and refresh tokens, and is - # created automatically when the authorization flow completes for the first - # time. - if os.path.exists("token.pickle"): - with open("token.pickle", "rb") as token: - creds = pickle.load(token) - # If there are no (valid) credentials available, let the user log in. - if not creds or not creds.valid: - if creds and creds.expired and creds.refresh_token: - creds.refresh(Request()) - else: - flow = InstalledAppFlow.from_client_secrets_file("credentials.json", SCOPES) - creds = flow.run_local_server(port=0) - # Save the credentials for the next run - with open("token.pickle", "wb") as token: - pickle.dump(creds, token) - - service = build("sheets", "v4", credentials=creds) - - # Call the Sheets API - sheet = service.spreadsheets() - result = ( - sheet.values().get(spreadsheetId=SPREADSHEET_ID, range=RANGE_NAME).execute() - ) - values = result.get("values", []) + values = authenticate_and_fetch_sheets_data() if not values: print("No data found.") @@ -49,7 +15,9 @@ def main(): print("Toistumisväli, Homma, Viimeksi tehty") print("===") for row in values: - print(", ".join(row)) + print(row) + + run_telegram() if __name__ == "__main__": diff --git a/hommaexceli_py/sheets_client.py b/hommaexceli_py/sheets_client.py new file mode 100644 index 0000000..1dd741c --- /dev/null +++ b/hommaexceli_py/sheets_client.py @@ -0,0 +1,71 @@ +import pickle +import os.path +from os import getenv +from datetime import date +from dataclasses import dataclass +from googleapiclient.discovery import build +from google_auth_oauthlib.flow import InstalledAppFlow +from google.auth.transport.requests import Request + + +@dataclass +class SheetsRow: + interval: str + name: str + last_done: str + + +# If modifying these scopes, delete the file token.pickle. +SCOPES = ["https://www.googleapis.com/auth/spreadsheets.readonly"] + + +def _get_or_default(list, index, default=""): + try: + return list[index] + except IndexError: + return default + + +def _row_to_dataclass(values): + interval = _get_or_default(values, 0, "") + name = _get_or_default(values, 1, "") + + today = date.today() + last_done = _get_or_default(values, 2, today.strftime("%Y-%m-%d")) + return SheetsRow(interval, name, last_done) + + +def authenticate_and_fetch_sheets_data(): + creds = None + # The file token.pickle stores the user's access and refresh tokens, and is + # created automatically when the authorization flow completes for the first + # time. + if os.path.exists("token.pickle"): + with open("token.pickle", "rb") as token: + creds = pickle.load(token) + # If there are no (valid) credentials available, let the user log in. + if not creds or not creds.valid: + if creds and creds.expired and creds.refresh_token: + creds.refresh(Request()) + else: + flow = InstalledAppFlow.from_client_secrets_file("credentials.json", SCOPES) + creds = flow.run_local_server(port=0) + # Save the credentials for the next run + with open("token.pickle", "wb") as token: + pickle.dump(creds, token) + + service = build("sheets", "v4", credentials=creds) + + # Call the Sheets API + sheet = service.spreadsheets() + result = ( + sheet.values() + .get( + spreadsheetId=getenv("SHEETS_SPREADSHEET_ID"), + range=getenv("SHEETS_RANGE"), + ) + .execute() + ) + + rows = result.get("values", []) + return map(_row_to_dataclass, rows) diff --git a/hommaexceli_py/telegram_client.py b/hommaexceli_py/telegram_client.py new file mode 100644 index 0000000..0c7fcf2 --- /dev/null +++ b/hommaexceli_py/telegram_client.py @@ -0,0 +1,57 @@ +import datetime +import signal +import sys +from os import getenv +from telegram.ext import Updater, CommandHandler, Job +from telegram import Update + +chats_mem_cache = set() + + +def _signal_handler(sig, frame): + print("You pressed Ctrl+C!") + updater = frame.f_locals["updater"] + for chat_id in chats_mem_cache: + updater.bot.send_message(chat_id=chat_id, text="HommaBot-palvelin sammutettu!") + + updater.stop() + sys.exit(0) + + +def _callback_alarm(context): + context.bot.send_message(chat_id=context.job.context, text="Alarm") + + +def _callback_timer(update: Update, context): + update.message.reply_text( + "HommaBot startattu. Uusia hommapäivityksiä viikon välein." + ) + chats_mem_cache.add(update.message.chat_id) + context.job_queue.run_repeating( + _callback_alarm, + datetime.timedelta(seconds=1), + context=update.message.chat_id, + ) + + +def _stop_timer(update: Update, context): + update.message.reply_text("HommaBot pysäytetty!") + chats_mem_cache.remove(update.message.chat_id) + context.job_queue.stop() + + +def run_telegram(): + updater = Updater(getenv("TELEGRAM_TOKEN")) + updater.dispatcher.add_handler( + CommandHandler("start", _callback_timer, pass_job_queue=True) + ) + updater.dispatcher.add_handler( + CommandHandler("stop", _stop_timer, pass_job_queue=True) + ) + + updater.start_polling() + + signal.signal(signal.SIGINT, _signal_handler) + # while true: + # time.sleep(1) + signal.pause() |
