J'ai créé un système qui décide automatiquement de s'exécuter demain avec Python et l'ajoute à Google Agenda.

introduction

Je cours pratiquement tous les jours en semaine, mais bien sûr, je n'ai pas envie de courir les jours de pluie ou les jours fériés. J'ai donc écrit un programme en Python qui automatise la décision d'exécuter le lendemain et ajoute un rendez-vous à Google Agenda.

environnement

Je suppose macOS ou Linux parce que j'utilise crontab pour l'exécuter régulièrement, mais sous Windows, vous pourrez peut-être faire de même avec AWS.

Paramètres Python

Tout d'abord, configurez Python. Personnellement, je n'aime pas polluer l'environnement, donc je crée un virtualenv pour chaque projet. Veuillez consulter ici pour plus de détails, car il s'écarte du sujet principal.

$ 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

Déterminez la météo de demain

J'ai utilisé OpenWeatherMap pour obtenir les prévisions météorologiques.

C'est très simple à utiliser, récupérez la clé API dans l'onglet "Clés API" après avoir créé le compte et définissez-le sur ʻOPENWEATHER_API_KEY`. Au fait, cette fois, j'ai utilisé le code postal pour spécifier l'emplacement, mais il semble que vous puissiez également spécifier le nom de la ville et la latitude / longitude (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()

Ensuite, un tel résultat sera retourné.

{
    "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"
        },
        ...

Quant au résultat, le résultat est retourné toutes les 3 heures jusqu'à 5 jours plus tard. Le tableau de list contient les prévisions météorologiques pour la date et l'heure de dt_txt.

--temp: température --feels_like: ressent la température --temp_min: température minimale --temp_max: température maximale --pression: pression atmosphérique --sea_level: pression atmosphérique à la surface de la mer --grnd_level: Pression au sol --humidité: humidité

Etc. Il y a beaucoup d'informations et c'est merveilleux. Mais cette fois, je veux juste savoir s'il pleut, donc j'aimerais me concentrer sur le «principal» du «temps».

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

Tout d'abord, utilisez datetime pour calculer la date de demain. Et comme je cours tôt le matin, je mettrai les dates vers 6h et 9h demain sous forme de chaînes dans tommorow_morning_dt. Ensuite, en comparant avec le résultat précédent, si dt_txt est la date souhaitée, elle est ajoutée à tommorow_morning_weather.

Vous pouvez maintenant obtenir la météo pour la période de demain. Cependant, je pense honnêtement que cette implémentation est subtile et qu'il semble absurde de comparer les dates par chaîne, alors faites-moi savoir s'il existe un bon moyen.

Déterminez si c'est un jour férié

En gros, je n'ai pas envie de courir sauf en semaine, donc je veux exclure les vacances. Il est facile de parler si vous excluez simplement les vacances, mais vous devez également considérer les vacances, alors référez-vous à ici et jpholiday J'ai utilisé un package appelé . Vous pouvez également utiliser ʻis_rain () `pour déterminer s'il pleut, ce que vous venez de faire, pour exprimer les conditions de fonctionnement. Au fait, la fonction «jour de la semaine ()» de «date / heure» correspond à 0 à 4 du lundi au vendredi, et correspond à 5,6 le samedi et le dimanche.

import jpholiday

if tommorow.weekday() < 5 and not jpholiday.is_holiday(tommorow) and not is_rain(tommorow_str):
    #Ajouter un événement à Google Agenda
    add_event(tommorow_str)

Ajouter un événement à Google Agenda

Enfin, ajoutez l'événement à Google Agenda. Veuillez consulter ici pour savoir comment activer l'API Google Agenda. Je laisserai les détails à la destination du lien, mais j'expliquerai brièvement la procédure pour utiliser l'API.

  1. Appuyez sur le bouton "Activer l'API Google Agenda" dans Python Quickstart.
  2. Une fois la fenêtre contextuelle affichée, appuyez sur le bouton «TÉLÉCHARGER LA CONFIGURATION CLIENT» pour télécharger «credentials.json».
  3. Déplacez credentials.json dans le même répertoire que votre projet.

Pour l'instant, vous êtes prêt à utiliser l'API.

Ensuite, vérifiez l'ID du calendrier que vous souhaitez ajouter. La méthode de vérification d'identité est également expliquée en détail dans le lien précédent, je vais donc montrer brièvement le flux.

  1. Ouvrez Google Agenda.
  2. Dans le menu déroulant de "Mon calendrier" dans la barre latérale gauche, appuyez sur le bouton "Paramètres et partage" du calendrier que vous souhaitez ajouter.
  3. L '"ID de calendrier" est affiché dans l'élément supérieur de "Combiner les calendriers", alors notez-le.

En définissant l'ID d'agenda confirmé sur "CALENDAR_ID", vous pouvez enfin ajouter un événement.

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': 'fonctionnement',
        '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()

La première moitié du code est extraite de Official Sample, il doit donc être modifié en particulier. Ça ne ressemble pas à ça. Après cela, entrez le titre de l'événement que vous voulez ajouter au «résumé» de «événement», et entrez l'heure de début et l'heure de fin dans «dateTime» de «start» et «end», respectivement, et vous avez terminé.

Code d'achèvement

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']

#Définissez n'importe quelle valeur.
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': 'fonctionnement',
        '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()

De plus, ce code

$ python add_calendar.py

Lorsqu'il est exécuté avec, l'écran d'avertissement s'affiche pour la première fois, mais il n'y a pas de problème, donc

  1. Sélectionnez un compte
  2. Cliquez sur le lien "Détails"
  3. Cliquez sur le lien "Aller au démarrage rapide (page non sécurisée)"
  4. Cliquez sur le bouton "Autoriser"
  5. Cliquez sur le bouton "Autoriser"

Veuillez procéder selon la procédure de. Vous n'avez pas besoin d'effectuer cette opération à partir de la deuxième fois.

Maintenant que nous avons confirmé que le temps de demain ne pleut pas, que c'est un jour de semaine, et que nous avons terminé un script pour ajouter un calendrier en cours, nous aimerions automatiser cela.

Exécution périodique d'événements supplémentaires

L'exécution périodique est facile avec crontab, qui est inclus par défaut dans macOS et Linux. Pour plus d'informations, veuillez consulter ici. Premier,

$ crontab -e

Lancez crontab avec. Et écrivez comme ceci:

00 18 * * 0-4 [chemin python] [Répertoire de projets]/add_calendar.py

Le chemin python est

$ which python

Vous pouvez vérifier avec.

«00 18 * * 0-4» signifie courir du dimanche au jeudi à 18h00. De gauche à droite, il représente «minute», «heure», «jour», «mois» et «jour». Je ne pense pas qu'il soit nécessaire de spécifier le jour du jour parce que le programme détermine s'il s'agit d'un jour de semaine, mais je l'ai ajouté pour réduire le traitement inutile.

Résumé

Cette fois, j'ai écrit un script dans le but d'ajouter en cours d'exécution, mais je pense qu'il est assez fréquent que vous vouliez juger les conditions et ajouter un rendez-vous au calendrier, alors veuillez l'utiliser.

référence

Création d'un environnement avec pyenv et pyenv-virtualenv

Un script qui combine datetime et jpholiday pour déterminer s'il s'agit d'un jour de semaine ou d'un week-end / vacances

Obtenez des informations météo d'OpenWeatherMap en utilisant python

Essayez d'utiliser OpenWeatherMap, une API gratuite de prévisions météorologiques

Ajouter des rendez-vous à Google Agenda en Python

Obtenir / ajouter des rendez-vous Google Agenda à l'aide de l'API Google Agenda

Comment écrire crontab

Recommended Posts

J'ai créé un système qui décide automatiquement de s'exécuter demain avec Python et l'ajoute à Google Agenda.
[Introduction au trading système] J'ai dessiné un oscillateur stochastique avec python et joué avec ♬
J'ai créé un serveur avec socket Python et ssl et j'ai essayé d'y accéder depuis le navigateur
J'ai créé un outil pour parcourir automatiquement plusieurs sites avec Selenium (Python)
Une histoire à laquelle j'étais accro après la communication SFTP avec python
J'ai essayé de faire LINE BOT avec Python et Heroku
J'ai généré beaucoup d'images comme le favicon du calendrier Google avec Python et je l'ai incorporé dans le projet de Vue
[Python] J'ai créé un script qui coupe et colle automatiquement les fichiers du PC local sur un SSD externe.
Je veux faire fonctionner un ordinateur quantique avec Python
J'ai créé un programme pour convertir des images en art ASCII avec Python et OpenCV
J'ai créé et publié une image Docker qui lit RSS et tweete automatiquement régulièrement.
Création d'une application Web qui mappe les informations sur les événements informatiques avec Vue et Flask
J'ai fait un calendrier qui met à jour automatiquement le calendrier de distribution de Vtuber (édition Google Calendar)
J'ai créé un package pour filtrer les séries chronologiques avec python
[Python] J'ai créé une fonction qui déchiffre et décrypte AES simplement en le lançant avec pycrypto.
Création d'un toolver qui crache le système d'exploitation, Python, les modules et les versions d'outils à Markdown
J'ai créé un outil qui facilite un peu la création et l'installation d'une clé publique.
Lors de l'écriture dans un fichier csv avec python, une histoire que j'ai fait une légère erreur et n'a pas respecté la date de livraison
J'ai fait une loterie avec Python.
J'ai créé un démon avec Python
J'ai fait un circuit simple avec Python (AND, OR, NOR, etc.)
J'ai créé une bibliothèque qui lit facilement les fichiers de configuration avec Python
J'ai fait un package qui peut comparer des analyseurs morphologiques avec Python
Je souhaite utiliser un caractère générique que je souhaite décortiquer avec Python remove
Un mémorandum lors de l'acquisition automatique avec du sélénium
J'ai créé un formulaire de tweet Nyanko avec Python, Flask et Heroku
J'ai essayé de faire un processus d'exécution périodique avec Selenium et Python
J'ai fait un shuffle qui peut être réinitialisé (inversé) avec Python
J'ai fait un programme qui calcule automatiquement le zodiaque avec tkinter
J'ai créé un chat chat bot avec Tensor2Tensor et cette fois cela a fonctionné
[Python] J'ai fait un décorateur qui ne semble pas avoir d'utilité.
J'ai essayé de créer un système pour acquérir automatiquement le guide des programmes → l'enregistrer dans le calendrier en un jour
J'ai créé un robot musical en utilisant discord.py et l'API Google Drive (testé avec Docker → déployé sur Heroku)
J'ai créé une application Web en Python qui convertit Markdown en HTML
J'ai créé un bot Discord en Python qui se traduit quand il réagit
J'ai fait une carte hexadécimale avec Python
[Outlook] J'ai essayé de créer automatiquement un e-mail de rapport quotidien avec Python
J'ai créé un outil qui facilite un peu la décompression avec CLI (Python3)
J'ai fait un jeu rogue-like avec Python
J'ai fait un simple blackjack avec Python
J'ai essayé de mettre à jour le calendrier Google avec des rendez-vous CSV à l'aide de Python et de l'API Google
J'ai créé un fichier de configuration avec Python
J'ai fait un simulateur de neurones avec Python
J'ai fait un module PyNanaco qui peut charger des crédits nanaco avec python
[Python] J'ai créé un code de scraping web qui acquiert automatiquement le titre de l'actualité et l'URL de Nihon Keizai Shimbun.
J'ai essayé de faire un processus périodique avec CentOS7, Selenium, Python et Chrome
Transformez un programme Python en démon et exécutez-le automatiquement au démarrage du système d'exploitation
J'ai créé un Line Bot qui utilise Python pour récupérer les e-mails non lus de Gmail!
J'ai créé un outil pour informer Slack des événements Connpass et en ai fait Terraform
Je veux écrire un élément dans un fichier avec numpy et le vérifier.
[Python] J'ai créé un LINE Bot qui détecte les visages et effectue le traitement de la mosaïque.