weathergrabber 0.0.7a4__tar.gz → 0.0.8a2__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {weathergrabber-0.0.7a4/weathergrabber.egg-info → weathergrabber-0.0.8a2}/PKG-INFO +1 -1
- {weathergrabber-0.0.7a4 → weathergrabber-0.0.8a2}/pyproject.toml +1 -1
- {weathergrabber-0.0.7a4 → weathergrabber-0.0.8a2}/weathergrabber/__init__.py +1 -1
- {weathergrabber-0.0.7a4 → weathergrabber-0.0.8a2}/weathergrabber/adapter/tty/console_tty.py +41 -10
- {weathergrabber-0.0.7a4 → weathergrabber-0.0.8a2}/weathergrabber/adapter/tty/waybar_tty.py +38 -11
- weathergrabber-0.0.8a2/weathergrabber/domain/city_location.py +71 -0
- {weathergrabber-0.0.7a4 → weathergrabber-0.0.8a2}/weathergrabber/domain/moon_phase_enum.py +3 -3
- {weathergrabber-0.0.7a4 → weathergrabber-0.0.8a2}/weathergrabber/domain/weather_icon_enum.py +1 -0
- weathergrabber-0.0.8a2/weathergrabber/service/extract_current_conditions_service.py +42 -0
- {weathergrabber-0.0.7a4 → weathergrabber-0.0.8a2/weathergrabber.egg-info}/PKG-INFO +1 -1
- weathergrabber-0.0.7a4/weathergrabber/domain/city_location.py +0 -37
- weathergrabber-0.0.7a4/weathergrabber/service/extract_current_conditions_service.py +0 -47
- {weathergrabber-0.0.7a4 → weathergrabber-0.0.8a2}/LICENSE +0 -0
- {weathergrabber-0.0.7a4 → weathergrabber-0.0.8a2}/README.md +0 -0
- {weathergrabber-0.0.7a4 → weathergrabber-0.0.8a2}/setup.cfg +0 -0
- {weathergrabber-0.0.7a4 → weathergrabber-0.0.8a2}/tests/test_cli.py +0 -0
- {weathergrabber-0.0.7a4 → weathergrabber-0.0.8a2}/tests/test_core.py +0 -0
- {weathergrabber-0.0.7a4 → weathergrabber-0.0.8a2}/weathergrabber/__main__.py +0 -0
- {weathergrabber-0.0.7a4 → weathergrabber-0.0.8a2}/weathergrabber/adapter/client/weather_api.py +0 -0
- {weathergrabber-0.0.7a4 → weathergrabber-0.0.8a2}/weathergrabber/adapter/client/weather_search_api.py +0 -0
- {weathergrabber-0.0.7a4 → weathergrabber-0.0.8a2}/weathergrabber/adapter/tty/json_tty.py +0 -0
- {weathergrabber-0.0.7a4 → weathergrabber-0.0.8a2}/weathergrabber/cli.py +0 -0
- {weathergrabber-0.0.7a4 → weathergrabber-0.0.8a2}/weathergrabber/core.py +0 -0
- {weathergrabber-0.0.7a4 → weathergrabber-0.0.8a2}/weathergrabber/domain/adapter/icon_enum.py +0 -0
- {weathergrabber-0.0.7a4 → weathergrabber-0.0.8a2}/weathergrabber/domain/adapter/mapper/air_quality_index_mapper.py +0 -0
- {weathergrabber-0.0.7a4 → weathergrabber-0.0.8a2}/weathergrabber/domain/adapter/mapper/city_location_mapper.py +0 -0
- {weathergrabber-0.0.7a4 → weathergrabber-0.0.8a2}/weathergrabber/domain/adapter/mapper/color_mapper.py +0 -0
- {weathergrabber-0.0.7a4 → weathergrabber-0.0.8a2}/weathergrabber/domain/adapter/mapper/current_conditions_mapper.py +0 -0
- {weathergrabber-0.0.7a4 → weathergrabber-0.0.8a2}/weathergrabber/domain/adapter/mapper/daily_predictions_mapper.py +0 -0
- {weathergrabber-0.0.7a4 → weathergrabber-0.0.8a2}/weathergrabber/domain/adapter/mapper/day_night_mapper.py +0 -0
- {weathergrabber-0.0.7a4 → weathergrabber-0.0.8a2}/weathergrabber/domain/adapter/mapper/forecast_mapper.py +0 -0
- {weathergrabber-0.0.7a4 → weathergrabber-0.0.8a2}/weathergrabber/domain/adapter/mapper/health_activities_mapper.py +0 -0
- {weathergrabber-0.0.7a4 → weathergrabber-0.0.8a2}/weathergrabber/domain/adapter/mapper/hourly_predictions_mapper.py +0 -0
- {weathergrabber-0.0.7a4 → weathergrabber-0.0.8a2}/weathergrabber/domain/adapter/mapper/label_value_mapper.py +0 -0
- {weathergrabber-0.0.7a4 → weathergrabber-0.0.8a2}/weathergrabber/domain/adapter/mapper/moon_phase_mapper.py +0 -0
- {weathergrabber-0.0.7a4 → weathergrabber-0.0.8a2}/weathergrabber/domain/adapter/mapper/precipitation_mapper.py +0 -0
- {weathergrabber-0.0.7a4 → weathergrabber-0.0.8a2}/weathergrabber/domain/adapter/mapper/search_mapper.py +0 -0
- {weathergrabber-0.0.7a4 → weathergrabber-0.0.8a2}/weathergrabber/domain/adapter/mapper/sunrise_sunset_mapper.py +0 -0
- {weathergrabber-0.0.7a4 → weathergrabber-0.0.8a2}/weathergrabber/domain/adapter/mapper/temperature_high_low_mapper.py +0 -0
- {weathergrabber-0.0.7a4 → weathergrabber-0.0.8a2}/weathergrabber/domain/adapter/mapper/timestamp_mapper.py +0 -0
- {weathergrabber-0.0.7a4 → weathergrabber-0.0.8a2}/weathergrabber/domain/adapter/mapper/today_details_mapper.py +0 -0
- {weathergrabber-0.0.7a4 → weathergrabber-0.0.8a2}/weathergrabber/domain/adapter/mapper/uv_index_mapper.py +0 -0
- {weathergrabber-0.0.7a4 → weathergrabber-0.0.8a2}/weathergrabber/domain/adapter/mapper/weather_icon_enum_mapper.py +0 -0
- {weathergrabber-0.0.7a4 → weathergrabber-0.0.8a2}/weathergrabber/domain/adapter/mapper/wind_mapper.py +0 -0
- {weathergrabber-0.0.7a4 → weathergrabber-0.0.8a2}/weathergrabber/domain/adapter/output_enum.py +0 -0
- {weathergrabber-0.0.7a4 → weathergrabber-0.0.8a2}/weathergrabber/domain/adapter/params.py +0 -0
- {weathergrabber-0.0.7a4 → weathergrabber-0.0.8a2}/weathergrabber/domain/air_quality_index.py +0 -0
- {weathergrabber-0.0.7a4 → weathergrabber-0.0.8a2}/weathergrabber/domain/color.py +0 -0
- {weathergrabber-0.0.7a4 → weathergrabber-0.0.8a2}/weathergrabber/domain/current_conditions.py +0 -0
- {weathergrabber-0.0.7a4 → weathergrabber-0.0.8a2}/weathergrabber/domain/daily_predictions.py +0 -0
- {weathergrabber-0.0.7a4 → weathergrabber-0.0.8a2}/weathergrabber/domain/day_night.py +0 -0
- {weathergrabber-0.0.7a4 → weathergrabber-0.0.8a2}/weathergrabber/domain/forecast.py +0 -0
- {weathergrabber-0.0.7a4 → weathergrabber-0.0.8a2}/weathergrabber/domain/health_activities.py +0 -0
- {weathergrabber-0.0.7a4 → weathergrabber-0.0.8a2}/weathergrabber/domain/hourly_predictions.py +0 -0
- {weathergrabber-0.0.7a4 → weathergrabber-0.0.8a2}/weathergrabber/domain/label_value.py +0 -0
- {weathergrabber-0.0.7a4 → weathergrabber-0.0.8a2}/weathergrabber/domain/moon_phase.py +0 -0
- {weathergrabber-0.0.7a4 → weathergrabber-0.0.8a2}/weathergrabber/domain/precipitation.py +0 -0
- {weathergrabber-0.0.7a4 → weathergrabber-0.0.8a2}/weathergrabber/domain/search.py +0 -0
- {weathergrabber-0.0.7a4 → weathergrabber-0.0.8a2}/weathergrabber/domain/sunrise_sunset.py +0 -0
- {weathergrabber-0.0.7a4 → weathergrabber-0.0.8a2}/weathergrabber/domain/temperature_hight_low.py +0 -0
- {weathergrabber-0.0.7a4 → weathergrabber-0.0.8a2}/weathergrabber/domain/timestamp.py +0 -0
- {weathergrabber-0.0.7a4 → weathergrabber-0.0.8a2}/weathergrabber/domain/today_details.py +0 -0
- {weathergrabber-0.0.7a4 → weathergrabber-0.0.8a2}/weathergrabber/domain/uv_index.py +0 -0
- {weathergrabber-0.0.7a4 → weathergrabber-0.0.8a2}/weathergrabber/domain/wind.py +0 -0
- {weathergrabber-0.0.7a4 → weathergrabber-0.0.8a2}/weathergrabber/service/extract_aqi_service.py +0 -0
- {weathergrabber-0.0.7a4 → weathergrabber-0.0.8a2}/weathergrabber/service/extract_daily_forecast_oldstyle_service.py +0 -0
- {weathergrabber-0.0.7a4 → weathergrabber-0.0.8a2}/weathergrabber/service/extract_daily_forecast_service.py +0 -0
- {weathergrabber-0.0.7a4 → weathergrabber-0.0.8a2}/weathergrabber/service/extract_health_activities_service.py +0 -0
- {weathergrabber-0.0.7a4 → weathergrabber-0.0.8a2}/weathergrabber/service/extract_hourly_forecast_oldstyle_service.py +0 -0
- {weathergrabber-0.0.7a4 → weathergrabber-0.0.8a2}/weathergrabber/service/extract_hourly_forecast_service.py +0 -0
- {weathergrabber-0.0.7a4 → weathergrabber-0.0.8a2}/weathergrabber/service/extract_temperature_service.py +0 -0
- {weathergrabber-0.0.7a4 → weathergrabber-0.0.8a2}/weathergrabber/service/extract_today_details_service.py +0 -0
- {weathergrabber-0.0.7a4 → weathergrabber-0.0.8a2}/weathergrabber/service/read_weather_service.py +0 -0
- {weathergrabber-0.0.7a4 → weathergrabber-0.0.8a2}/weathergrabber/service/search_location_service.py +0 -0
- {weathergrabber-0.0.7a4 → weathergrabber-0.0.8a2}/weathergrabber/usecase/use_case.py +0 -0
- {weathergrabber-0.0.7a4 → weathergrabber-0.0.8a2}/weathergrabber/weathergrabber_application.py +0 -0
- {weathergrabber-0.0.7a4 → weathergrabber-0.0.8a2}/weathergrabber.egg-info/SOURCES.txt +0 -0
- {weathergrabber-0.0.7a4 → weathergrabber-0.0.8a2}/weathergrabber.egg-info/dependency_links.txt +0 -0
- {weathergrabber-0.0.7a4 → weathergrabber-0.0.8a2}/weathergrabber.egg-info/entry_points.txt +0 -0
- {weathergrabber-0.0.7a4 → weathergrabber-0.0.8a2}/weathergrabber.egg-info/requires.txt +0 -0
- {weathergrabber-0.0.7a4 → weathergrabber-0.0.8a2}/weathergrabber.egg-info/top_level.txt +0 -0
|
@@ -21,8 +21,7 @@ class ConsoleTTY:
|
|
|
21
21
|
|
|
22
22
|
rain_icon = WeatherIconEnum.RAIN.fa_icon if is_fa else WeatherIconEnum.RAIN.emoji_icon
|
|
23
23
|
|
|
24
|
-
|
|
25
|
-
state_province = forecast.current_conditions.location.state_province
|
|
24
|
+
city_location = forecast.current_conditions.location
|
|
26
25
|
icon = forecast.current_conditions.icon.fa_icon if is_fa else forecast.current_conditions.icon.emoji_icon
|
|
27
26
|
temperature = forecast.current_conditions.temperature
|
|
28
27
|
|
|
@@ -62,18 +61,48 @@ class ConsoleTTY:
|
|
|
62
61
|
aqi_acronym = forecast.air_quality_index.acronym
|
|
63
62
|
aqi_value = forecast.air_quality_index.value
|
|
64
63
|
|
|
64
|
+
hourly_predictions_format = [
|
|
65
|
+
{
|
|
66
|
+
'title': h.title if len(h.title) < 8 else h.title[:6] + '.',
|
|
67
|
+
'temperature' : h.temperature,
|
|
68
|
+
'icon': h.icon.fa_icon if is_fa else h.icon.emoji_icon,
|
|
69
|
+
'precipitation': f"{h.precipitation.percentage if h.precipitation.percentage else ''}"
|
|
70
|
+
} for h in forecast.hourly_predictions
|
|
71
|
+
]
|
|
72
|
+
|
|
73
|
+
daily_predictions_format = [
|
|
74
|
+
{
|
|
75
|
+
'title': d.title if len(d.title) < 8 else d.title[:6] + '.',
|
|
76
|
+
'high_low': f"{d.high_low}",
|
|
77
|
+
'icon': d.icon.fa_icon if is_fa else d.icon.emoji_icon,
|
|
78
|
+
'precipitation': f"{d.precipitation.percentage}"
|
|
79
|
+
} for d in forecast.daily_predictions
|
|
80
|
+
]
|
|
81
|
+
|
|
82
|
+
# Hourly predictions and daily predictions
|
|
65
83
|
hourly_predictions = [
|
|
66
|
-
|
|
67
|
-
|
|
84
|
+
f"{h['title']}"
|
|
85
|
+
f"{'\t' if len(h['title']) < 3 else ''}\t"
|
|
86
|
+
f"{h['temperature']}"
|
|
87
|
+
"\t"
|
|
88
|
+
f"{h['icon']}\t"
|
|
89
|
+
f"{rain_icon} {h['precipitation']}"
|
|
90
|
+
for h in hourly_predictions_format
|
|
68
91
|
]
|
|
92
|
+
|
|
69
93
|
daily_predictions = [
|
|
70
|
-
|
|
71
|
-
|
|
94
|
+
f"{d['title']}"
|
|
95
|
+
f"{'\t' if len(d['title']) < 3 else ''}\t"
|
|
96
|
+
f"{d['high_low']}"
|
|
97
|
+
f"\t"
|
|
98
|
+
f"{d['icon']}\t"
|
|
99
|
+
f"{rain_icon} {d['precipitation']}"
|
|
100
|
+
for d in daily_predictions_format
|
|
72
101
|
]
|
|
73
102
|
|
|
74
103
|
print_value = (
|
|
75
104
|
"\n"
|
|
76
|
-
f"{
|
|
105
|
+
f"{city_location}\n"
|
|
77
106
|
"\n"
|
|
78
107
|
f"{icon} {temperature}\n"
|
|
79
108
|
"\n"
|
|
@@ -84,9 +113,11 @@ class ConsoleTTY:
|
|
|
84
113
|
"\n"
|
|
85
114
|
f"{moon_icon} {moon_phase}\n"
|
|
86
115
|
"\n"
|
|
87
|
-
f"{wind_icon} {wind}\t
|
|
88
|
-
f"{humidity_icon} {humidity}\t\t
|
|
89
|
-
f"{visibility_icon} {visibility}
|
|
116
|
+
f"{wind_icon} {wind}\t{uv_index}\n"
|
|
117
|
+
f"{humidity_icon} {humidity}\t\t{pressure}\n"
|
|
118
|
+
f"{visibility_icon} {visibility}"
|
|
119
|
+
f"\t{'\t' if len(visibility) < 6 else ''}"
|
|
120
|
+
f"{aqi_acronym} {aqi_category} {aqi_value}\n"
|
|
90
121
|
"\n"
|
|
91
122
|
f"{'\n'.join(hourly_predictions)}\n"
|
|
92
123
|
"\n"
|
|
@@ -21,10 +21,11 @@ class WaybarTTY:
|
|
|
21
21
|
# Forecast icon and temperature
|
|
22
22
|
icon = forecast.current_conditions.icon.fa_icon if is_fa else forecast.current_conditions.icon.emoji_icon
|
|
23
23
|
temperature = forecast.current_conditions.temperature
|
|
24
|
+
rain_icon = WeatherIconEnum.RAIN.fa_icon if is_fa else WeatherIconEnum.RAIN.emoji_icon
|
|
25
|
+
|
|
24
26
|
|
|
25
27
|
# City and state/province
|
|
26
|
-
|
|
27
|
-
state_province = forecast.current_conditions.location.state_province
|
|
28
|
+
city_location = forecast.current_conditions.location
|
|
28
29
|
|
|
29
30
|
# Summary
|
|
30
31
|
summary = forecast.current_conditions.summary
|
|
@@ -65,19 +66,45 @@ class WaybarTTY:
|
|
|
65
66
|
aqi_acronym = forecast.air_quality_index.acronym
|
|
66
67
|
aqi_value = forecast.air_quality_index.value
|
|
67
68
|
|
|
69
|
+
hourly_predictions_format = [{
|
|
70
|
+
'title': h.title if len(h.title) < 10 else h.title[:9] + '.',
|
|
71
|
+
'temperature' : h.temperature,
|
|
72
|
+
'icon': h.icon.fa_icon if is_fa else h.icon.emoji_icon,
|
|
73
|
+
'precipitation': f"{h.precipitation.percentage if h.precipitation.percentage else ''}"
|
|
74
|
+
} for h in forecast.hourly_predictions]
|
|
75
|
+
|
|
76
|
+
daily_predictions_format = [
|
|
77
|
+
{
|
|
78
|
+
'title': d.title if len(d.title) < 10 else d.title[:9] + '.',
|
|
79
|
+
'high_low': f"{d.high_low.high}/<span size='small'>{d.high_low.low}</span>",
|
|
80
|
+
'icon': d.icon.fa_icon if is_fa else d.icon.emoji_icon,
|
|
81
|
+
'precipitation': f"{d.precipitation.percentage}"
|
|
82
|
+
} for d in forecast.daily_predictions
|
|
83
|
+
]
|
|
84
|
+
|
|
68
85
|
# Hourly predictions and daily predictions
|
|
69
|
-
rain_icon = WeatherIconEnum.RAIN.fa_icon if is_fa else WeatherIconEnum.RAIN.emoji_icon
|
|
70
86
|
hourly_predictions = [
|
|
71
|
-
|
|
72
|
-
|
|
87
|
+
f"{h['title']}"
|
|
88
|
+
f"{'\t\t' if len(h['title']) < 4 else '\t'}"
|
|
89
|
+
f"{h['temperature']}"
|
|
90
|
+
"\t\t"
|
|
91
|
+
f"{h['icon']}\t"
|
|
92
|
+
f"{rain_icon} {h['precipitation']}"
|
|
93
|
+
for h in hourly_predictions_format
|
|
73
94
|
]
|
|
95
|
+
|
|
74
96
|
daily_predictions = [
|
|
75
|
-
|
|
76
|
-
|
|
97
|
+
f"{d['title']}"
|
|
98
|
+
f"\t{'\t' if len(d['title']) < 6 else ' '}"
|
|
99
|
+
f"{d['high_low']}"
|
|
100
|
+
f"\t{'\t' if len(d['high_low']) < 6 else ''}"
|
|
101
|
+
f"{d['icon']}\t"
|
|
102
|
+
f"{rain_icon} {d['precipitation']}"
|
|
103
|
+
for d in daily_predictions_format
|
|
77
104
|
]
|
|
78
105
|
|
|
79
106
|
tooltip = (
|
|
80
|
-
f"{
|
|
107
|
+
f"{city_location}\n"
|
|
81
108
|
"\n"
|
|
82
109
|
f"<span size='xx-large'>{icon}\t\t{temperature}</span>\n"
|
|
83
110
|
"\n"
|
|
@@ -89,9 +116,9 @@ class WaybarTTY:
|
|
|
89
116
|
"\n"
|
|
90
117
|
f"{moon_icon} {moon_phase}\n"
|
|
91
118
|
"\n"
|
|
92
|
-
f"{wind_icon} {wind}\t
|
|
93
|
-
f"{humidity_icon} {humidity}\t\t
|
|
94
|
-
f"{visibility_icon} {visibility}\t
|
|
119
|
+
f"{wind_icon} {wind}\t\t{uv_index}\n"
|
|
120
|
+
f"{humidity_icon} {humidity}\t\t{pressure}\n"
|
|
121
|
+
f"{visibility_icon} {visibility}\t{aqi_acronym} {aqi_category} {aqi_value}\n"
|
|
95
122
|
"\n"
|
|
96
123
|
f"{'\n'.join(hourly_predictions)}\n"
|
|
97
124
|
"\n"
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
class CityLocation:
|
|
2
|
+
|
|
3
|
+
def __init__(self, city: str, state_province: str = None, country: str = None, location = None):
|
|
4
|
+
self._city = city
|
|
5
|
+
self._state_province = state_province
|
|
6
|
+
self._country = country
|
|
7
|
+
self._location = location
|
|
8
|
+
|
|
9
|
+
@property
|
|
10
|
+
def city(self) -> str:
|
|
11
|
+
return self._city
|
|
12
|
+
|
|
13
|
+
@property
|
|
14
|
+
def state_province(self) -> str:
|
|
15
|
+
return self._state_province
|
|
16
|
+
|
|
17
|
+
@property
|
|
18
|
+
def country(self) -> str:
|
|
19
|
+
return self._country
|
|
20
|
+
|
|
21
|
+
@property
|
|
22
|
+
def location(self):
|
|
23
|
+
return self._location
|
|
24
|
+
|
|
25
|
+
def __repr__(self):
|
|
26
|
+
return f"CityLocation(city={self.city}, state_province={self.state_province}, country={self.country}, location={self.location})"
|
|
27
|
+
|
|
28
|
+
def __str__(self):
|
|
29
|
+
parts = []
|
|
30
|
+
if self.location:
|
|
31
|
+
parts.append(self.location)
|
|
32
|
+
if self.city:
|
|
33
|
+
parts.append(self.city)
|
|
34
|
+
if self.state_province:
|
|
35
|
+
parts.append(self.state_province)
|
|
36
|
+
if self.country:
|
|
37
|
+
parts.append(self.country)
|
|
38
|
+
return ", ".join(parts) if parts else "Unknown Location"
|
|
39
|
+
|
|
40
|
+
@classmethod
|
|
41
|
+
def from_string(cls, data: str) -> "CityLocation":
|
|
42
|
+
#'Nova Friburgo, Rio de Janeiro, Brazil'
|
|
43
|
+
#'Macuco, Santos, São Paulo, Brésil'
|
|
44
|
+
#'New York, NY, USA'
|
|
45
|
+
#'Tokyo, Tokyo Prefecture, Japan'
|
|
46
|
+
country, state_province, city, location = None, None, None, None
|
|
47
|
+
parts = data.split(", ")
|
|
48
|
+
|
|
49
|
+
if len(parts) > 2:
|
|
50
|
+
i = len(parts) - 1
|
|
51
|
+
while i > 0:
|
|
52
|
+
if not country:
|
|
53
|
+
country = parts[i]
|
|
54
|
+
elif not state_province:
|
|
55
|
+
state_province = parts[i]
|
|
56
|
+
elif not city:
|
|
57
|
+
city = parts[i]
|
|
58
|
+
i -= 1
|
|
59
|
+
# Location is the first registry. If it's different from city, use it.
|
|
60
|
+
if city != parts[0]:
|
|
61
|
+
location = parts[0]
|
|
62
|
+
return cls(city=city, state_province=state_province, country=country, location=location)
|
|
63
|
+
|
|
64
|
+
if len(parts) == 2:
|
|
65
|
+
city, state_province = parts
|
|
66
|
+
return cls(city=city, state_province=state_province)
|
|
67
|
+
elif len(parts) == 1:
|
|
68
|
+
city = parts[0]
|
|
69
|
+
return cls(city=city)
|
|
70
|
+
else:
|
|
71
|
+
raise ValueError("Invalid city location string format")
|
|
@@ -18,12 +18,12 @@ class MoonPhaseEnum(Enum):
|
|
|
18
18
|
PHASE_10 = ("phase-10", "\uf186", "🌔")
|
|
19
19
|
PHASE_11 = ("phase-11", "\uf186", "🌔")
|
|
20
20
|
PHASE_12 = ("phase-12", "\uf186", "🌔")
|
|
21
|
-
PHASE_13 = ("phase-13", "\uf186", "
|
|
21
|
+
PHASE_13 = ("phase-13", "\uf186", "🌕")
|
|
22
22
|
# Full Moon
|
|
23
23
|
PHASE_14 = ("phase-14", "\uf186", "🌕")
|
|
24
24
|
# Waning Gibbous
|
|
25
|
-
PHASE_15 = ("phase-15", "\uf186", "
|
|
26
|
-
PHASE_16 = ("phase-16", "\uf186", "
|
|
25
|
+
PHASE_15 = ("phase-15", "\uf186", "🌕")
|
|
26
|
+
PHASE_16 = ("phase-16", "\uf186", "🌕")
|
|
27
27
|
PHASE_17 = ("phase-17", "\uf186", "🌖")
|
|
28
28
|
PHASE_18 = ("phase-18", "\uf186", "🌖")
|
|
29
29
|
PHASE_19 = ("phase-19", "\uf186", "🌖")
|
{weathergrabber-0.0.7a4 → weathergrabber-0.0.8a2}/weathergrabber/domain/weather_icon_enum.py
RENAMED
|
@@ -11,6 +11,7 @@ class WeatherIconEnum(Enum):
|
|
|
11
11
|
FEEL = ('feel', '\uf2c9', '🥵')
|
|
12
12
|
FOGGY = ('foggy', '\uf74e', '🌫️')
|
|
13
13
|
HUMIDITY = ('humidity', '\uf043', '💧')
|
|
14
|
+
ISOLATED_THUNDERSTORMS = ('isolated-thunderstorms', chr(0x26C8), '⛈️')
|
|
14
15
|
MOSTLY_CLEAR_DAY = ('mostly-clear-day', chr(0xF0599), '☀️')
|
|
15
16
|
MOSTLY_CLEAR_NIGHT = ('mostly-clear-night', chr(0xF0594), '🌙')
|
|
16
17
|
MOSTLY_CLOUDY_DAY = ('mostly-cloudy-day', chr(0xf013), '☁️')
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import logging
|
|
2
|
+
from pyquery import PyQuery
|
|
3
|
+
from weathergrabber.domain.weather_icon_enum import WeatherIconEnum
|
|
4
|
+
from weathergrabber.domain.city_location import CityLocation
|
|
5
|
+
from weathergrabber.domain.timestamp import Timestamp
|
|
6
|
+
from weathergrabber.domain.day_night import DayNight
|
|
7
|
+
from weathergrabber.domain.current_conditions import CurrentConditions
|
|
8
|
+
|
|
9
|
+
class ExtractCurrentConditionsService:
|
|
10
|
+
def __init__(self):
|
|
11
|
+
self.logger = logging.getLogger(__name__)
|
|
12
|
+
pass
|
|
13
|
+
|
|
14
|
+
def execute(self, weather_data: PyQuery) -> dict:
|
|
15
|
+
self.logger.debug("Extracting Current Conditions")
|
|
16
|
+
|
|
17
|
+
data = PyQuery(weather_data('div[data-testid="CurrentConditionsContainer"]'))
|
|
18
|
+
|
|
19
|
+
city_location_data = data.find('h1').text() #'Nova Friburgo, Rio de Janeiro, Brazil'
|
|
20
|
+
timestamp_data = data.find('span[class*="timestamp"]').text() # 'As of 8:01 pm GMT-03:00'
|
|
21
|
+
icon_data = data.find('svg[class*="wxIcon"]').attr('name') # 'partly-cloudy-night'
|
|
22
|
+
temp_day_night = data.find('div[class*="tempHiLoValue"]').text() #'Day\xa063°\xa0•\xa0Night\xa046°'
|
|
23
|
+
|
|
24
|
+
city_location = CityLocation.from_string(city_location_data)
|
|
25
|
+
timestamp = Timestamp.from_string(timestamp_data)
|
|
26
|
+
temperature = data.find('span[class*="tempValue"]').text() # '48°'
|
|
27
|
+
icon = WeatherIconEnum.from_name(icon_data)
|
|
28
|
+
phrase = data.find('div[data-testid*="wxPhrase"]').text() # 'Partly Cloudy'
|
|
29
|
+
day_night = DayNight.from_string(temp_day_night)
|
|
30
|
+
|
|
31
|
+
current_conditions = CurrentConditions(
|
|
32
|
+
location=city_location,
|
|
33
|
+
timestamp=timestamp,
|
|
34
|
+
temperature=temperature,
|
|
35
|
+
icon=icon,
|
|
36
|
+
summary=phrase,
|
|
37
|
+
day_night=day_night
|
|
38
|
+
)
|
|
39
|
+
|
|
40
|
+
self.logger.debug(f"Extracted current conditions: {current_conditions}")
|
|
41
|
+
|
|
42
|
+
return current_conditions
|
|
@@ -1,37 +0,0 @@
|
|
|
1
|
-
class CityLocation:
|
|
2
|
-
|
|
3
|
-
def __init__(self, city: str, state_province: str = None, country: str = None):
|
|
4
|
-
self._city = city
|
|
5
|
-
self._state_province = state_province
|
|
6
|
-
self._country = country
|
|
7
|
-
|
|
8
|
-
@property
|
|
9
|
-
def city(self) -> str:
|
|
10
|
-
return self._city
|
|
11
|
-
|
|
12
|
-
@property
|
|
13
|
-
def state_province(self) -> str:
|
|
14
|
-
return self._state_province
|
|
15
|
-
|
|
16
|
-
@property
|
|
17
|
-
def country(self) -> str:
|
|
18
|
-
return self._country
|
|
19
|
-
|
|
20
|
-
def __repr__(self):
|
|
21
|
-
return f"CityLocation(city={self.city}, state_province={self.state_province}, country={self.country})"
|
|
22
|
-
|
|
23
|
-
@classmethod
|
|
24
|
-
def from_string(cls, data: str) -> "CityLocation":
|
|
25
|
-
#'Nova Friburgo, Rio de Janeiro, Brazil'
|
|
26
|
-
parts = data.split(", ")
|
|
27
|
-
if len(parts) == 3:
|
|
28
|
-
city, state_province, country = parts
|
|
29
|
-
return cls(city=city, state_province=state_province, country=country)
|
|
30
|
-
if len(parts) == 2:
|
|
31
|
-
city, state_province = parts
|
|
32
|
-
return cls(city=city, state_province=state_province)
|
|
33
|
-
elif len(parts) == 1:
|
|
34
|
-
city = parts[0]
|
|
35
|
-
return cls(city=city)
|
|
36
|
-
else:
|
|
37
|
-
raise ValueError("Invalid city location string format")
|
|
@@ -1,47 +0,0 @@
|
|
|
1
|
-
import logging
|
|
2
|
-
from pyquery import PyQuery
|
|
3
|
-
from weathergrabber.domain.weather_icon_enum import WeatherIconEnum
|
|
4
|
-
from weathergrabber.domain.city_location import CityLocation
|
|
5
|
-
from weathergrabber.domain.timestamp import Timestamp
|
|
6
|
-
from weathergrabber.domain.day_night import DayNight
|
|
7
|
-
from weathergrabber.domain.current_conditions import CurrentConditions
|
|
8
|
-
|
|
9
|
-
class ExtractCurrentConditionsService:
|
|
10
|
-
def __init__(self):
|
|
11
|
-
self.logger = logging.getLogger(__name__)
|
|
12
|
-
pass
|
|
13
|
-
|
|
14
|
-
def execute(self, weather_data: PyQuery) -> dict:
|
|
15
|
-
try:
|
|
16
|
-
self.logger.debug("Extracting Current Conditions")
|
|
17
|
-
|
|
18
|
-
data = PyQuery(weather_data('div[data-testid="CurrentConditionsContainer"]'))
|
|
19
|
-
|
|
20
|
-
city_location_data = data.find('h1').text() #'Nova Friburgo, Rio de Janeiro, Brazil'
|
|
21
|
-
timestamp_data = data.find('span[class*="timestamp"]').text() # 'As of 8:01 pm GMT-03:00'
|
|
22
|
-
icon_data = data.find('svg[class*="wxIcon"]').attr('name') # 'partly-cloudy-night'
|
|
23
|
-
temp_day_night = data.find('div[class*="tempHiLoValue"]').text() #'Day\xa063°\xa0•\xa0Night\xa046°'
|
|
24
|
-
|
|
25
|
-
city_location = CityLocation.from_string(city_location_data)
|
|
26
|
-
timestamp = Timestamp.from_string(timestamp_data)
|
|
27
|
-
temperature = data.find('span[class*="tempValue"]').text() # '48°'
|
|
28
|
-
icon = WeatherIconEnum.from_name(icon_data)
|
|
29
|
-
phrase = data.find('div[data-testid*="wxPhrase"]').text() # 'Partly Cloudy'
|
|
30
|
-
day_night = DayNight.from_string(temp_day_night)
|
|
31
|
-
|
|
32
|
-
current_conditions = CurrentConditions(
|
|
33
|
-
location=city_location,
|
|
34
|
-
timestamp=timestamp,
|
|
35
|
-
temperature=temperature,
|
|
36
|
-
icon=icon,
|
|
37
|
-
summary=phrase,
|
|
38
|
-
day_night=day_night
|
|
39
|
-
)
|
|
40
|
-
|
|
41
|
-
self.logger.debug(f"Extracted current conditions: {current_conditions}")
|
|
42
|
-
|
|
43
|
-
return current_conditions
|
|
44
|
-
|
|
45
|
-
except Exception as e:
|
|
46
|
-
self.logger.error(f"Error extracting current conditions: {e}")
|
|
47
|
-
raise ValueError("Could not extract current conditions") from e
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{weathergrabber-0.0.7a4 → weathergrabber-0.0.8a2}/weathergrabber/adapter/client/weather_api.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{weathergrabber-0.0.7a4 → weathergrabber-0.0.8a2}/weathergrabber/domain/adapter/icon_enum.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{weathergrabber-0.0.7a4 → weathergrabber-0.0.8a2}/weathergrabber/domain/adapter/output_enum.py
RENAMED
|
File without changes
|
|
File without changes
|
{weathergrabber-0.0.7a4 → weathergrabber-0.0.8a2}/weathergrabber/domain/air_quality_index.py
RENAMED
|
File without changes
|
|
File without changes
|
{weathergrabber-0.0.7a4 → weathergrabber-0.0.8a2}/weathergrabber/domain/current_conditions.py
RENAMED
|
File without changes
|
{weathergrabber-0.0.7a4 → weathergrabber-0.0.8a2}/weathergrabber/domain/daily_predictions.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{weathergrabber-0.0.7a4 → weathergrabber-0.0.8a2}/weathergrabber/domain/health_activities.py
RENAMED
|
File without changes
|
{weathergrabber-0.0.7a4 → weathergrabber-0.0.8a2}/weathergrabber/domain/hourly_predictions.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{weathergrabber-0.0.7a4 → weathergrabber-0.0.8a2}/weathergrabber/domain/temperature_hight_low.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{weathergrabber-0.0.7a4 → weathergrabber-0.0.8a2}/weathergrabber/service/extract_aqi_service.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{weathergrabber-0.0.7a4 → weathergrabber-0.0.8a2}/weathergrabber/service/read_weather_service.py
RENAMED
|
File without changes
|
{weathergrabber-0.0.7a4 → weathergrabber-0.0.8a2}/weathergrabber/service/search_location_service.py
RENAMED
|
File without changes
|
|
File without changes
|
{weathergrabber-0.0.7a4 → weathergrabber-0.0.8a2}/weathergrabber/weathergrabber_application.py
RENAMED
|
File without changes
|
|
File without changes
|
{weathergrabber-0.0.7a4 → weathergrabber-0.0.8a2}/weathergrabber.egg-info/dependency_links.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|