-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathcherrywatch.py
More file actions
157 lines (126 loc) · 4.42 KB
/
cherrywatch.py
File metadata and controls
157 lines (126 loc) · 4.42 KB
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
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
import requests
import html
import os
import logging
import sys
from enum import Enum
from datetime import date
from collections import defaultdict
import re
import json
from bs4 import BeautifulSoup
from twilio.rest import Client
from logging.config import dictConfig
dictConfig(
{
"version": 1,
"disable_existing_loggers": True,
"formatters": {
# the default formatter
"default": {
# for more formatting see https://docs.python.org/3/library/logging.html#logrecord-attributes # noqa: E501
"format": "%(asctime)s [%(name)s] [%(levelname)s] [%(filename)s:%(lineno)d - %(funcName)s()] - %(message)s", # noqa: E501
}
},
"handlers": {
# log to the console
"console": {
"level": "INFO",
"class": "logging.StreamHandler",
"formatter": "default",
"stream": "ext://sys.stdout",
},
},
"loggers": {
# set the fast api logger
"fastapi": {
# set handlers based on the config name
"handlers": ["console"],
"level": "INFO",
# don't propagate to the root logger
"propagate": False,
},
},
# set the root logger
"root": {"level": "INFO", "handlers": ["console"]},
}
)
ACCOUNT_SID = os.environ.get("ACCOUNT_SID")
AUTH_TOKEN = os.environ.get("AUTH_TOKEN")
TWILIO_NUMBER = os.environ.get("TWILIO_NUMBER")
RECIPIENTS = os.environ.get("RECIPIENTS")
account_sid = ACCOUNT_SID
auth_token = AUTH_TOKEN
client = Client(account_sid, auth_token)
class BloomStage(Enum):
prebloom = "Prebloom"
first_bloom = "First Bloom"
peak_bloom = "Peak Bloom"
post_peak_bloom = "Post-Peak Bloom"
def get_scraped_tree_data():
URL = "https://www.bbg.org/collections/cherries"
page = requests.get(URL)
soup = BeautifulSoup(page.text, "html.parser")
script_with_tree_data = soup.find_all("script")[3].string.strip()
pattern = re.compile("var prunuses = ([\s\S]*);", re.MULTILINE)
prunuses = re.match(pattern, script_with_tree_data)
prunuses = prunuses.group(1)
# remove trailing comma
prunuses = re.sub(",[ \t\r\n]+\]", "]", prunuses)
prunuses = json.loads(prunuses)
return prunuses
prunuses = get_scraped_tree_data()
update_message = "Welcome to Jen's Cherry Blossom Watch! \n\n"
update_message += "Today, at the Brooklyn Botanic Garden, "
kanzan_bloom_counts = defaultdict(int)
combined_other_bloom_counts = defaultdict(int)
total_kanzan = 0
total_others = 0
tree_types = set()
# Process the tree data
for tree in prunuses:
tree_type = tree[3]
tree_types.add(tree_type)
bloom_stage = tree[7]
if tree_type == "kanzan":
kanzan_bloom_counts[bloom_stage] += 1
total_kanzan += 1
else:
combined_other_bloom_counts[bloom_stage] += 1
total_others += 1
# Remove 'kanzan' from the set and count the remaining types
tree_types.discard("kanzan")
non_kanzan_species_count = len(tree_types)
# Calculating percentages
kanzan_percentages = {
stage: round((count / total_kanzan) * 100, 2)
for stage, count in kanzan_bloom_counts.items()
}
other_percentages = {
stage: round((count / total_others) * 100, 2)
for stage, count in combined_other_bloom_counts.items()
}
update_message += "the double-blossom Kanzan trees on Cherry Esplanade and Cherry Walk are at peak bloom! 🚨\n"
desired_order = ['Prebloom', 'First Bloom', 'Peak Bloom', 'Post-Peak Bloom']
for stage in desired_order:
if stage in kanzan_percentages:
update_message += f"'{stage}': {kanzan_percentages[stage]}%\n"
update_message += f"\nThe remaining {non_kanzan_species_count} species are at the following bloom stages:\n"
for stage in desired_order:
if stage in other_percentages:
update_message += f"'{stage}': {other_percentages[stage]}%\n"
today = date.today()
today = today.strftime("%-m-%-d-%Y")
recipients = RECIPIENTS.split(",")
print(f"Message: {update_message}")
try:
for recipient in recipients:
message = client.messages.create(
to=recipient,
from_=TWILIO_NUMBER,
body=update_message,
media_url=f"https://raw.githubusercontent.com/jennyckaplan/cherrywatch/main/images/{today}.png",
)
except Exception as error:
logging.info(f"ERROR: {error}")
sys.exit(1)