Ich habe ein System erstellt, das automatisch entscheidet, ob es morgen mit Python ausgeführt wird, und es zu Google Kalender hinzufügt.

Einführung

Grundsätzlich laufe ich jeden Tag an Wochentagen, aber natürlich habe ich keine Lust, an Regentagen oder Feiertagen zu laufen. Also habe ich in Python ein Programm geschrieben, das die Entscheidung, ob es am nächsten Tag ausgeführt werden soll, automatisiert und Google Kalender einen Termin hinzufügt.

Umgebung

Ich gehe von MacOS oder Linux aus, weil ich "crontab" verwende, um es regelmäßig auszuführen, aber unter Windows können Sie möglicherweise dasselbe mit AWS tun.

Python-Einstellungen

Richten Sie zuerst Python ein. Persönlich mag ich es nicht, die Umwelt zu verschmutzen, deshalb mache ich für jedes Projekt eine "virtuelle Umgebung". Weitere Informationen finden Sie unter hier, da dies vom Hauptthema abweicht.

$ pyenv virtualenv 3.8.1 develop_3.8.1
$ pyenv activate develop_3.8.1
$ pip install --upgrade google-api-python-client google-auth-httplib2 google-auth-oauthlib

Bestimmen Sie das Wetter von morgen

Ich habe OpenWeatherMap verwendet, um die Wettervorhersage zu erhalten.

Es ist sehr einfach zu verwenden. Rufen Sie den API-Schlüssel nach dem Erstellen des Kontos von der Registerkarte "API-Schlüssel" ab und setzen Sie ihn auf "OPENWEATHER_API_KEY". Übrigens habe ich diesmal die Postleitzahl verwendet, um den Ort anzugeben, aber anscheinend können Sie auch den Namen der Stadt sowie den Breiten- und Längengrad angeben (https://qiita.com/nownabe/items/aeac1ce0977be963a740).

import requests

BASE_URL = 'http://api.openweathermap.org/data/2.5/forecast'
OPENWEATHER_API_KEY = 'Your OpenWeather Api key'
ZIP_CODE = 'Zip code of your area'

url = '{}?units=metric&zip={zip},JP&APPID={key}'.format(BASE_URL, zip=ZIP_CODE, key=OPENWEATHER_API_KEY)

res = requests.get(url).json()

Dann wird ein solches Ergebnis zurückgegeben.

{
    "cod": "200",
    "message": 0,
    "cnt": 40,
    "list": [
        {
            "dt": 1582956000,
            "main": {
                "temp": 13.03,
                "feels_like": 9.94,
                "temp_min": 12.61,
                "temp_max": 13.03,
                "pressure": 1016,
                "sea_level": 1016,
                "grnd_level": 1010,
                "humidity": 40,
                "temp_kf": 0.42
            },
            "weather": [
                {
                    "id": 803,
                    "main": "Clouds",
                    "description": "broken clouds",
                    "icon": "04d"
                }
            ],
            "clouds": {
                "all": 60
            },
            "wind": {
                "speed": 1.52,
                "deg": 150
            },
            "sys": {
                "pod": "d"
            },
            "dt_txt": "2020-02-29 06:00:00"
        },
        ...

Das Ergebnis wird alle 3 Stunden bis 5 Tage später zurückgegeben. Das Array "Liste" enthält die Wettervorhersage für Datum und Uhrzeit von "dt_txt".

--temp: Temperatur --feels_like: Fühlt Temperatur --temp_min: Mindesttemperatur --temp_max: Maximale Temperatur

Und so weiter. Es gibt viele Informationen und es ist wunderbar. Aber dieses Mal möchte ich nur wissen, ob es regnet, also möchte ich mich auf das "Haupt" des "Wetters" konzentrieren.

import datetime

tommorow = datetime.datetime.now() + datetime.timedelta(days=1)
tommorow_str = tommorow.strftime('%Y-%m-%d')

def is_rain(tommorow_str):
    tommorow_morning_dt = [tommorow_str + ' 06:00:00', tommorow_str + ' 09:00:00']
    tommorow_morning_weather = []

    weather_preds = res['list']

    for pred in weather_preds:
        if pred['dt_txt'] in tommorow_morning_dt:
            for weather in pred['weather']:
                tommorow_morning_weather.append(weather['main'])

    return 'Rain' in tommorow_morning_weather

Verwenden Sie zuerst "datetime", um das Datum von morgen zu berechnen. Und da ich früh morgens renne, werde ich die Daten morgen um 6 Uhr morgens und 9 Uhr morgens als Zeichenfolgen in tommorow_morning_dt einfügen. Und im Vergleich zum vorherigen Ergebnis wird "dt_txt", wenn das gewünschte Datum ist, zu "tommorow_morning_weather" hinzugefügt.

Jetzt können Sie das Wetter für die morgige Laufzeit abrufen. Ich denke jedoch ehrlich, dass diese Implementierung subtil ist und es unsinnig erscheint, Daten nach Zeichenfolge zu vergleichen. Lassen Sie mich also bitte wissen, ob es einen guten Weg gibt.

Bestimmen Sie, ob es ein Feiertag ist

Grundsätzlich habe ich keine Lust zu laufen, außer an Wochentagen, also möchte ich Feiertage ausschließen. Es ist einfach zu sprechen, wenn Sie nur Feiertage ausschließen, aber Sie müssen auch Feiertage berücksichtigen. Lesen Sie daher hier und jpholiday Ich habe ein Paket namens verwendet. Sie können auch is_rain () verwenden, um festzustellen, ob es regnet, was Sie zuvor erstellt haben, um die Bedingungen für das Ausführen auszudrücken. Übrigens entspricht die Funktion "Wochentag ()" von "Datum / Uhrzeit" von Montag bis Freitag 0 bis 4 und am Samstag und Sonntag 5,6.

import jpholiday

if tommorow.weekday() < 5 and not jpholiday.is_holiday(tommorow) and not is_rain(tommorow_str):
    #Ereignis zum Google Kalender hinzufügen
    add_event(tommorow_str)

Fügen Sie ein Ereignis zu Google Kalender hinzu

Fügen Sie das Ereignis schließlich zu Google Kalender hinzu. Unter hier finden Sie leicht verständliche Anweisungen zum Aktivieren der Google Kalender-API. Ich überlasse die Details dem Linkziel, erkläre jedoch kurz die Vorgehensweise zur Verwendung der API.

  1. Klicken Sie in [Python Quickstart] auf die Schaltfläche "Google Kalender-API aktivieren" (https://developers.google.com/calendar/quickstart/python?hl=ja).
  2. Nachdem das Popup angezeigt wurde, drücken Sie die Taste "CLIENT CONFIGURATION HERUNTERLADEN", um "credentials.json" herunterzuladen.
  3. Verschieben Sie credentials.json in dasselbe Verzeichnis wie Ihr Projekt.

Im Moment können Sie die API verwenden.

Überprüfen Sie als Nächstes die ID des Kalenders, den Sie hinzufügen möchten. Die ID-Überprüfungsmethode wird auch im vorherigen Link ausführlich erläutert, sodass ich den Ablauf kurz zeigen werde.

  1. Öffnen Sie Google Kalender.
  2. Klicken Sie im Überlaufmenü von "Mein Kalender" in der linken Seitenleiste auf die Schaltfläche "Einstellungen und Freigabe" des Kalenders, den Sie hinzufügen möchten.
  3. Die "Kalender-ID" wird im oberen Bereich von "Kalender kombinieren" angezeigt. Notieren Sie sich dies.

Durch Setzen der bestätigten Kalender-ID auf "CALENDAR_ID" können Sie schließlich ein Ereignis hinzufügen.

import os.path
import pickle

from googleapiclient.discovery import build
from google_auth_oauthlib.flow import InstalledAppFlow
from google.auth.transport.requests import Request

CALENDAR_ID = 'Your Google Calendar ID'
DIR = os.path.dirname(os.path.abspath(__file__))

def add_event(tommorow):
    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.
    token_pickle_path = os.path.join(DIR, 'token.pickle')
    credentials_path = os.path.join(DIR, 'credentials.json')

    if os.path.exists(token_pickle_path):
        with open(token_pickle_path, '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_path, SCOPES)
            creds = flow.run_local_server(port=0)
        # Save the credentials for the next run
        with open(token_pickle_path, 'wb') as token:
            pickle.dump(creds, token)

    service = build('calendar', 'v3', credentials=creds)

    # Call the Calndar API
    event = {
        'summary': 'Laufen',
        'location': 'Your running location',
        'start': {
            'dateTime': '{}T07:30:00'.format(tommorow),
            'timeZone': 'Japan',
        },
        'end': {
            'dateTime': '{}T09:00:00'.format(tommorow),
            'timeZone': 'Japan',
        },
    }

    service.events().insert(calendarId=CALENDAR_ID, body=event).execute()

Die erste Hälfte des Codes stammt aus dem offiziellen Beispiel und muss daher insbesondere geändert werden. Es sieht nicht so aus. Geben Sie danach den Titel des Ereignisses ein, das Sie zur "Zusammenfassung" des "Ereignisses" hinzufügen möchten, und geben Sie die Start- und Endzeit in "dateTime" von "start" bzw. "end" ein.

Abschlusscode

add_calendar.py


import datetime
import os.path
import pickle
import requests

import jpholiday
from googleapiclient.discovery import build
from google_auth_oauthlib.flow import InstalledAppFlow
from google.auth.transport.requests import Request

# If modifying these scopes, delete the file token.pickle.
SCOPES = ['https://www.googleapis.com/auth/calendar']

#Stellen Sie einen beliebigen Wert ein.
CALENDAR_ID = 'Your Google Calendar ID'
OPENWEATHER_API_KEY = 'You Openweather API key'
ZIP_CODE = 'Zip code of your area'
DIR = os.path.dirname(os.path.abspath(__file__))


def add_event(tommorow):
    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.
    token_pickle_path = os.path.join(DIR, 'token.pickle')
    credentials_path = os.path.join(DIR, 'credentials.json')

    if os.path.exists(token_pickle_path):
        with open(token_pickle_path, '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_path, SCOPES)
            creds = flow.run_local_server(port=0)
        # Save the credentials for the next run
        with open(token_pickle_path, 'wb') as token:
            pickle.dump(creds, token)

    service = build('calendar', 'v3', credentials=creds)

    event = {
        'summary': 'Laufen',
        'location': 'Your running location',
        'start': {
            'dateTime': '{}T07:30:00'.format(tommorow),
            'timeZone': 'Japan',
        },
        'end': {
            'dateTime': '{}T09:00:00'.format(tommorow),
            'timeZone': 'Japan',
        },
    }

    service.events().insert(calendarId=CALENDAR_ID, body=event).execute()


def is_rain(tommorow):
    BASE_URL = 'http://api.openweathermap.org/data/2.5/forecast'
    url = '{}?units=metric&zip={zip},JP&APPID={key}'.format(BASE_URL, zip=ZIP_CODE, key=OPENWEATHER_API_KEY)

    res = requests.get(url).json()
    weather_preds = res['list']

    tommow_morning_dt = [tommorow + ' 06:00:00', tommorow + ' 09:00:00']
    tommow_morning_weather = []

    for pred in weather_preds:
        if pred['dt_txt'] in tommow_morning_dt:
            for weather in pred['weather']:
                tommow_morning_weather.append(weather['main'])

    return 'Rain' in tommow_morning_weather


def main():
    tommorow = datetime.datetime.now() + datetime.timedelta(days=1)
    tommorow_str = tommorow.strftime('%Y-%m-%d')

    # weekday: 0 ~ 4
    if tommorow.weekday() < 5 and not jpholiday.is_holiday(tommorow) and not is_rain(tommorow_str):
        add_event(tommorow_str)


if __name__ == '__main__':
    main()

Außerdem dieser Code

$ python add_calendar.py

Bei der Ausführung mit wird der Warnbildschirm zum ersten Mal angezeigt, es gibt jedoch kein Problem

  1. Wählen Sie ein Konto aus
  2. Klicken Sie auf den Link "Details"
  3. Klicken Sie auf den Link "Zum Schnellstart (unsichere Seite)"
  4. Klicken Sie auf die Schaltfläche "Zulassen"
  5. Klicken Sie auf die Schaltfläche "Zulassen"

Bitte verfahren Sie nach dem Verfahren von. Sie müssen diesen Vorgang nicht ab dem zweiten Mal ausführen.

Nachdem wir bestätigt haben, dass das Wetter von morgen nicht regnerisch ist, sondern an einem Wochentag, haben wir ein Skript erstellt, um einen laufenden Zeitplan hinzuzufügen, und wir möchten dies automatisieren.

Regelmäßige Ausführung zusätzlicher Ereignisse

Die regelmäßige Ausführung ist mit der "crontab", die standardmäßig unter macOS und Linux verfügbar ist, einfach. Weitere Informationen finden Sie unter hier. Zuerst,

$ crontab -e

Starten Sie crontab mit. Und schreibe so:

00 18 * * 0-4 [Python-Pfad] [Projektverzeichnis]/add_calendar.py

Der Python-Pfad ist

$ which python

Sie können mit überprüfen.

"00 18 * * 0-4" bedeutet, von Sonntag bis Donnerstag um 18:00 Uhr zu laufen. Von links nach rechts steht es für "Minute", "Stunde", "Tag", "Monat" und "Tag". Ich denke nicht, dass es notwendig ist, den Tag des Tages anzugeben, da das Programm bestimmt, ob es ein Wochentag ist, aber ich habe ihn hinzugefügt, um unnötige Verarbeitung zu reduzieren.

Zusammenfassung

Dieses Mal habe ich ein Skript geschrieben, um das Laufen hinzuzufügen, aber ich denke, dass es ziemlich häufig ist, dass Sie die Bedingungen beurteilen und dem Kalender einen Termin hinzufügen möchten.

Referenz

Erstellen einer Umgebung mit pyenv und pyenv-virtualenv

Ein Skript, das Datum / Uhrzeit und Feiertag kombiniert, um festzustellen, ob es sich um einen Wochentag oder ein Wochenende / einen Feiertag handelt

Wetterinformationen von OpenWeatherMap mit Python abrufen

Versuchen Sie es mit OpenWeatherMap, einer kostenlosen Wettervorhersage-API

Hinzufügen von Terminen zu Google Kalender in Python

Abrufen / Hinzufügen von Google Kalender-Terminen mithilfe der Google Kalender-API

Wie man Crontab schreibt

Recommended Posts

Ich habe ein System erstellt, das automatisch entscheidet, ob es morgen mit Python ausgeführt wird, und es zu Google Kalender hinzufügt.
[Einführung in den Systemhandel] Ich habe einen Stochastic Oscillator mit Python gezeichnet und damit gespielt ♬
Ich habe einen Server mit Python-Socket und SSL erstellt und versucht, über den Browser darauf zuzugreifen
Ich habe ein Tool zum automatischen Durchsuchen mehrerer Websites mit Selenium (Python) erstellt.
Eine Geschichte, der ich nach der SFTP-Kommunikation mit Python verfallen war
Ich habe versucht, LINE BOT mit Python und Heroku zu machen
Ich habe versucht, mit Python viele Bilder wie das Favicon des Google-Kalenders zu generieren und in Vues Projekt zu integrieren
[Python] Ich habe ein Skript erstellt, das Dateien auf dem lokalen PC automatisch ausschneidet und auf eine externe SSD einfügt.
Ich möchte einen Quantencomputer mit Python betreiben
Ich habe ein Programm erstellt, um Bilder mit Python und OpenCV in ASCII-Grafik umzuwandeln
Ich habe ein Docker-Image erstellt, das RSS liest und automatisch regelmäßig twittert, und es veröffentlicht.
Erstellt eine Web-App, die IT-Ereignisinformationen mit Vue und Flask abbildet
Ich habe einen Kalender erstellt, der den Verteilungsplan von Vtuber automatisch aktualisiert (Google Kalender Edition).
Ich habe ein Paket erstellt, um Zeitreihen mit Python zu filtern
[Python] Ich habe eine Funktion erstellt, die AES entschlüsselt und entschlüsselt, indem ich sie einfach mit pycrypto geworfen habe.
Erstellt einen Toolsver, der Betriebssystem, Python, Module und Toolversionen an Markdown ausspuckt
Ich habe ein Tool erstellt, mit dem das Erstellen und Installieren eines öffentlichen Schlüssels etwas einfacher ist.
Beim Schreiben in eine CSV-Datei mit Python habe ich einen kleinen Fehler gemacht und den Liefertermin nicht eingehalten
Ich habe mit Python eine Lotterie gemacht.
Ich habe mit Python einen Daemon erstellt
Ich habe eine einfache Schaltung mit Python gemacht (AND, OR, NOR, etc.)
Ich habe eine Bibliothek erstellt, die Konfigurationsdateien mit Python einfach lesen kann
Ich habe ein Paket erstellt, das morphologische Analysegeräte mit Python vergleichen kann
Ich möchte einen Platzhalter verwenden, den ich mit Python entfernen möchte
Ein Memorandum beim automatischen Erwerb mit Selen
Ich habe mit Python, Flask und Heroku ein Nyanko-Tweet-Formular erstellt
Ich habe versucht, mit Selenium und Python einen regelmäßigen Ausführungsprozess durchzuführen
Ich habe ein Shuffle gemacht, das mit Python zurückgesetzt (zurückgesetzt) werden kann
Ich habe ein Programm erstellt, das den Tierkreis mit tkinter automatisch berechnet
Ich habe einen Chat-Chat-Bot mit Tensor2Tensor erstellt und diesmal hat es funktioniert
[Python] Ich habe einen Dekorateur gemacht, der keinen Nutzen zu haben scheint.
Ich habe versucht, ein System zu erstellen, um den Programmführer automatisch zu erfassen → ihn an einem Tag im Kalender zu registrieren
Ich habe einen Musik-Bot mit discord.py und der Google Drive-API erstellt (getestet mit Docker → bereitgestellt für Heroku).
Ich habe eine Webanwendung in Python erstellt, die Markdown in HTML konvertiert
Ich habe in Python einen Discord-Bot erstellt, der übersetzt, wenn er reagiert
Ich habe mit Python eine Hex-Map erstellt
[Outlook] Ich habe versucht, mit Python automatisch eine tägliche Berichtsmail zu erstellen
Ich habe ein Tool erstellt, das die Dekomprimierung mit CLI (Python3) etwas erleichtert.
Ich habe mit Python ein schurkenhaftes Spiel gemacht
Ich habe mit Python einen einfachen Blackjack gemacht
Ich habe versucht, den Google-Kalender mit CSV-Terminen mithilfe von Python und Google API zu aktualisieren
Ich habe mit Python eine Einstellungsdatei erstellt
Ich habe mit Python einen Neuronensimulator erstellt
Ich habe ein Modul PyNanaco erstellt, das Nanaco-Guthaben mit Python belasten kann
[Python] Ich habe einen Web-Scraping-Code erstellt, der automatisch den Nachrichtentitel und die URL von Nihon Keizai Shimbun erfasst.
Ich habe versucht, einen periodischen Prozess mit CentOS7, Selenium, Python und Chrome durchzuführen
Machen Sie aus einem Python-Programm einen Daemon und führen Sie es automatisch aus, wenn das Betriebssystem gestartet wird
Ich habe einen Zeilenbot erstellt, der Python verwendet, um ungelesene E-Mails aus Google Mail abzurufen!
Ich habe ein Tool erstellt, um Slack über Connpass-Ereignisse zu informieren, und es zu Terraform gemacht
Ich möchte ein Element mit numpy in eine Datei schreiben und es überprüfen.
[Python] Ich habe einen LINE-Bot erstellt, der Gesichter erkennt und Mosaikverarbeitungen durchführt.