weathergrabber 0.0.8b6__py3-none-any.whl → 0.0.9__py3-none-any.whl

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.
Files changed (99) hide show
  1. weathergrabber/__init__.py +1 -1
  2. weathergrabber/adapter/repository/forecast_repository.py +135 -0
  3. weathergrabber/adapter/tty/console_tty.py +4 -4
  4. weathergrabber/adapter/tty/json_tty.py +3 -3
  5. weathergrabber/adapter/tty/statistics_tty.py +35 -0
  6. weathergrabber/adapter/tty/waybar_tty.py +4 -4
  7. weathergrabber/{service → application/services}/extract_aqi_service.py +1 -1
  8. weathergrabber/{service → application/services}/extract_current_conditions_service.py +5 -5
  9. weathergrabber/{service → application/services}/extract_daily_forecast_oldstyle_service.py +4 -4
  10. weathergrabber/{service → application/services}/extract_daily_forecast_service.py +6 -6
  11. weathergrabber/{service → application/services}/extract_health_activities_service.py +1 -1
  12. weathergrabber/{service → application/services}/extract_hourly_forecast_oldstyle_service.py +3 -3
  13. weathergrabber/{service → application/services}/extract_hourly_forecast_service.py +5 -5
  14. weathergrabber/{service → application/services}/extract_today_details_service.py +8 -8
  15. weathergrabber/application/services/retrieve_forecast_from_cache_service.py +27 -0
  16. weathergrabber/application/services/retrieve_statistics_service.py +20 -0
  17. weathergrabber/application/services/save_forecast_to_cache_service.py +21 -0
  18. weathergrabber/application/usecases/statistics_uc.py +19 -0
  19. weathergrabber/application/usecases/weather_forecast_uc.py +123 -0
  20. weathergrabber/application/weathergrabber_application.py +92 -0
  21. weathergrabber/cli.py +6 -2
  22. weathergrabber/core.py +7 -3
  23. weathergrabber/domain/adapter/mappers/air_quality_index_mapper.py +25 -0
  24. weathergrabber/domain/adapter/mappers/city_location_mapper.py +15 -0
  25. weathergrabber/domain/adapter/mappers/color_mapper.py +17 -0
  26. weathergrabber/domain/adapter/mappers/current_conditions_mapper.py +32 -0
  27. weathergrabber/domain/adapter/mappers/daily_predictions_mapper.py +30 -0
  28. weathergrabber/domain/adapter/mappers/day_night_mapper.py +23 -0
  29. weathergrabber/domain/adapter/mappers/forecast_mapper.py +38 -0
  30. weathergrabber/domain/adapter/mappers/health_activities_mapper.py +15 -0
  31. weathergrabber/domain/adapter/mappers/hourly_predictions_mapper.py +38 -0
  32. weathergrabber/domain/adapter/mappers/label_value_mapper.py +13 -0
  33. weathergrabber/domain/adapter/mappers/moon_phase_mapper.py +16 -0
  34. weathergrabber/domain/adapter/mappers/precipitation_mapper.py +13 -0
  35. weathergrabber/domain/adapter/mappers/search_mapper.py +13 -0
  36. weathergrabber/domain/adapter/mappers/statistics_mapper.py +25 -0
  37. weathergrabber/domain/adapter/mappers/sunrise_sunset_mapper.py +23 -0
  38. weathergrabber/domain/adapter/mappers/temperature_high_low_mapper.py +15 -0
  39. weathergrabber/domain/adapter/mappers/timestamp_mapper.py +15 -0
  40. weathergrabber/domain/adapter/mappers/today_details_mapper.py +42 -0
  41. weathergrabber/domain/adapter/mappers/uv_index_mapper.py +17 -0
  42. weathergrabber/domain/adapter/mappers/weather_icon_enum_mapper.py +11 -0
  43. weathergrabber/domain/adapter/mappers/wind_mapper.py +16 -0
  44. weathergrabber/domain/adapter/output_enum.py +1 -1
  45. weathergrabber/domain/adapter/params.py +25 -4
  46. weathergrabber/domain/{moon_phase.py → entities/moon_phase.py} +1 -1
  47. weathergrabber/domain/entities/statistics.py +46 -0
  48. weathergrabber/domain/{sunrise_sunset.py → entities/sunrise_sunset.py} +0 -1
  49. weathergrabber/domain/{weather_icon_enum.py → entities/weather_icon_enum.py} +1 -0
  50. {weathergrabber-0.0.8b6.dist-info → weathergrabber-0.0.9.dist-info}/METADATA +32 -7
  51. weathergrabber-0.0.9.dist-info/RECORD +80 -0
  52. {weathergrabber-0.0.8b6.dist-info → weathergrabber-0.0.9.dist-info}/WHEEL +1 -1
  53. weathergrabber/domain/adapter/mapper/air_quality_index_mapper.py +0 -13
  54. weathergrabber/domain/adapter/mapper/city_location_mapper.py +0 -8
  55. weathergrabber/domain/adapter/mapper/color_mapper.py +0 -10
  56. weathergrabber/domain/adapter/mapper/current_conditions_mapper.py +0 -16
  57. weathergrabber/domain/adapter/mapper/daily_predictions_mapper.py +0 -15
  58. weathergrabber/domain/adapter/mapper/day_night_mapper.py +0 -12
  59. weathergrabber/domain/adapter/mapper/forecast_mapper.py +0 -20
  60. weathergrabber/domain/adapter/mapper/health_activities_mapper.py +0 -8
  61. weathergrabber/domain/adapter/mapper/hourly_predictions_mapper.py +0 -19
  62. weathergrabber/domain/adapter/mapper/label_value_mapper.py +0 -7
  63. weathergrabber/domain/adapter/mapper/moon_phase_mapper.py +0 -9
  64. weathergrabber/domain/adapter/mapper/precipitation_mapper.py +0 -7
  65. weathergrabber/domain/adapter/mapper/search_mapper.py +0 -7
  66. weathergrabber/domain/adapter/mapper/sunrise_sunset_mapper.py +0 -13
  67. weathergrabber/domain/adapter/mapper/temperature_high_low_mapper.py +0 -8
  68. weathergrabber/domain/adapter/mapper/timestamp_mapper.py +0 -8
  69. weathergrabber/domain/adapter/mapper/today_details_mapper.py +0 -21
  70. weathergrabber/domain/adapter/mapper/uv_index_mapper.py +0 -9
  71. weathergrabber/domain/adapter/mapper/weather_icon_enum_mapper.py +0 -8
  72. weathergrabber/domain/adapter/mapper/wind_mapper.py +0 -7
  73. weathergrabber/usecase/use_case.py +0 -87
  74. weathergrabber/weathergrabber_application.py +0 -78
  75. weathergrabber-0.0.8b6.dist-info/RECORD +0 -72
  76. /weathergrabber/{service → application/services}/extract_temperature_service.py +0 -0
  77. /weathergrabber/{service → application/services}/read_weather_service.py +0 -0
  78. /weathergrabber/{service → application/services}/search_location_service.py +0 -0
  79. /weathergrabber/domain/{air_quality_index.py → entities/air_quality_index.py} +0 -0
  80. /weathergrabber/domain/{city_location.py → entities/city_location.py} +0 -0
  81. /weathergrabber/domain/{color.py → entities/color.py} +0 -0
  82. /weathergrabber/domain/{current_conditions.py → entities/current_conditions.py} +0 -0
  83. /weathergrabber/domain/{daily_predictions.py → entities/daily_predictions.py} +0 -0
  84. /weathergrabber/domain/{day_night.py → entities/day_night.py} +0 -0
  85. /weathergrabber/domain/{forecast.py → entities/forecast.py} +0 -0
  86. /weathergrabber/domain/{health_activities.py → entities/health_activities.py} +0 -0
  87. /weathergrabber/domain/{hourly_predictions.py → entities/hourly_predictions.py} +0 -0
  88. /weathergrabber/domain/{label_value.py → entities/label_value.py} +0 -0
  89. /weathergrabber/domain/{moon_phase_enum.py → entities/moon_phase_enum.py} +0 -0
  90. /weathergrabber/domain/{precipitation.py → entities/precipitation.py} +0 -0
  91. /weathergrabber/domain/{search.py → entities/search.py} +0 -0
  92. /weathergrabber/domain/{temperature_hight_low.py → entities/temperature_hight_low.py} +0 -0
  93. /weathergrabber/domain/{timestamp.py → entities/timestamp.py} +0 -0
  94. /weathergrabber/domain/{today_details.py → entities/today_details.py} +0 -0
  95. /weathergrabber/domain/{uv_index.py → entities/uv_index.py} +0 -0
  96. /weathergrabber/domain/{wind.py → entities/wind.py} +0 -0
  97. {weathergrabber-0.0.8b6.dist-info → weathergrabber-0.0.9.dist-info}/entry_points.txt +0 -0
  98. {weathergrabber-0.0.8b6.dist-info → weathergrabber-0.0.9.dist-info}/licenses/LICENSE +0 -0
  99. {weathergrabber-0.0.8b6.dist-info → weathergrabber-0.0.9.dist-info}/top_level.txt +0 -0
@@ -18,20 +18,25 @@ class Params:
18
18
 
19
19
  def __str__(self):
20
20
  return f"Location(search_name={self.search_name}, id={self.id})"
21
-
21
+
22
22
  def __init__(
23
23
  self,
24
24
  location: Optional["Params.Location"] = None,
25
25
  language: str = "en-US",
26
26
  output_format: OutputEnum = OutputEnum.CONSOLE,
27
27
  keep_open: bool = False,
28
- icons: IconEnum = IconEnum.EMOJI
28
+ icons: IconEnum = IconEnum.EMOJI,
29
+ force_cache: bool = False,
30
+ cache_statistics: bool = False,
31
+
29
32
  ):
30
33
  self._location = location
31
34
  self._language = language
32
35
  self._output_format = output_format
33
36
  self._keep_open = keep_open
34
37
  self._icons = icons
38
+ self._force_cache = force_cache
39
+ self._cache_statistics = cache_statistics
35
40
 
36
41
  @property
37
42
  def location(self) -> Optional["Params.Location"]:
@@ -52,7 +57,23 @@ class Params:
52
57
  @property
53
58
  def icons(self) -> IconEnum:
54
59
  return self._icons
60
+
61
+ @property
62
+ def force_cache(self) -> bool:
63
+ return self._force_cache
55
64
 
65
+ @property
66
+ def cache_statistics(self) -> bool:
67
+ return self._cache_statistics
68
+
56
69
  def __str__(self):
57
- return f"Params(location={self.location}, language={self.language}, output_format={self.output_format}, keep_open={self.keep_open}, icons={self.icons})"
58
-
70
+ return f'''
71
+ Params(
72
+ location={self.location},
73
+ language={self.language},
74
+ output_format={self.output_format},
75
+ keep_open={self.keep_open},
76
+ icons={self.icons},
77
+ force_cache={self.force_cache},
78
+ cache_statistics={self.cache_statistics})
79
+ '''
@@ -1,4 +1,4 @@
1
- from weathergrabber.domain.moon_phase_enum import MoonPhaseEnum
1
+ from weathergrabber.domain.entities.moon_phase_enum import MoonPhaseEnum
2
2
 
3
3
  class MoonPhase:
4
4
  def __init__(self, icon: MoonPhaseEnum, phase: str, label:str = None):
@@ -0,0 +1,46 @@
1
+ from typing import Optional
2
+
3
+
4
+ class Statistics:
5
+ def __init__(
6
+ self,
7
+ total_forecasts: int,
8
+ unique_locations: int,
9
+ unique_search_names: int,
10
+ database_path: str,
11
+ error: Optional[str] = None
12
+ ):
13
+ self._total_forecasts = total_forecasts
14
+ self._unique_locations = unique_locations
15
+ self._unique_search_names = unique_search_names
16
+ self._database_path = database_path
17
+ self._error = error
18
+
19
+ @property
20
+ def total_forecasts(self) -> int:
21
+ return self._total_forecasts
22
+
23
+ @property
24
+ def unique_locations(self) -> int:
25
+ return self._unique_locations
26
+
27
+ @property
28
+ def unique_search_names(self) -> int:
29
+ return self._unique_search_names
30
+
31
+ @property
32
+ def database_path(self) -> str:
33
+ return self._database_path
34
+
35
+ @property
36
+ def error(self) -> Optional[str]:
37
+ return self._error
38
+
39
+ def __repr__(self):
40
+ return (
41
+ f"Statistics(total_forecasts={self.total_forecasts!r}, "
42
+ f"unique_locations={self.unique_locations!r}, "
43
+ f"unique_search_names={self.unique_search_names!r}, "
44
+ f"database_path={self.database_path!r}, "
45
+ f"error={self.error!r})"
46
+ )
@@ -20,7 +20,6 @@ class SunriseSunset:
20
20
  def __repr__(self):
21
21
  return f"IconValue(icon={self._icon}, value='{self._value}')"
22
22
 
23
-
24
23
  def __init__(self, sunrise: str, sunset: str):
25
24
  self._sunrise = SunriseSunset.IconValue(WeatherIconEnum.SUNRISE, sunrise)
26
25
  self._sunset = SunriseSunset.IconValue(WeatherIconEnum.SUNSET, sunset)
@@ -49,6 +49,7 @@ class WeatherIconEnum(Enum):
49
49
  DUST = ('dust', '\uf063', '🌪️')
50
50
  FLURRIES = ('flurries', '\u2744', '🌨️')
51
51
  FREEZING_DRIZZLE = ('freezing-drizzle', '\uf0e9', '🌧️')
52
+ FREEZING_DRIZZLE_RAIN = ('freezing-drizzle-rain', '\uf0e9', '🌧️')
52
53
  FREEZING_RAIN = ('freezing-rain', '\uf0e9', '🌧️')
53
54
  HAIL = ('hail', '\uf015', '🌨️')
54
55
  HAZE = ('haze', '\uf0b6', '🌫️')
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: weathergrabber
3
- Version: 0.0.8b6
3
+ Version: 0.0.9
4
4
  Summary: A grabber for weather.com data with various output formats.
5
5
  Author-email: Carlos Anselmo Mendes Junior <cjuniorfox@gmail.com>
6
6
  License: MIT
@@ -11,6 +11,9 @@ Description-Content-Type: text/markdown
11
11
  License-File: LICENSE
12
12
  Requires-Dist: pyquery>=1.4.3
13
13
  Requires-Dist: requests>=2.32.4
14
+ Provides-Extra: dev
15
+ Requires-Dist: pytest>=8.0.0; extra == "dev"
16
+ Requires-Dist: pytest-cov>=4.1.0; extra == "dev"
14
17
  Dynamic: license-file
15
18
 
16
19
  # Weather Forecast CLI Script
@@ -34,6 +37,8 @@ This script fetches and parses weather forecast data from Weather.com and format
34
37
  - **Console output**: Richly formatted weather data with icons.
35
38
  - **Waybar JSON**: For integration with Waybar.
36
39
  - Supports multiple languages for Weather.com data.
40
+ - **Offline support**: Automatically retrieves cached weather data when internet connection is unavailable.
41
+ - **Cache management**: SQLite-based caching system for storing weather forecasts and enabling offline access.
37
42
  - Includes data such as:
38
43
  - Current temperature and "feels-like" temperature.
39
44
  - Wind speed, humidity, visibility, and air quality.
@@ -163,24 +168,42 @@ weathergrabber.main_cli()
163
168
 
164
169
  ### Options
165
170
 
166
- - `--location-id`, `-l` : 64-character-hex code for location (from Weather.com)
167
- - `--lang`, `-L` : Language (e.g., `pt-BR`, `fr-FR`). Defaults to system locale if not set.
168
- - `--output`, `-o` : Output format. One of `console`, `json`, or `waybar`. Default: `console`.
169
- - `--keep-open`, `-k` : Keep open and refresh every 5 minutes (only makes sense for `console` output).
170
- - `--icons`, `-i` : Icon set. `fa` for Font-Awesome, `emoji` for emoji icons. Default: `emoji`.
171
- - `--log` : Set logging level. One of `debug`, `info`, `warning`, `error`, `critical`. Default: `critical`.
171
+ - `--location-id`, `-l` : 64-character-hex code for location (from Weather.com)
172
+ - `--lang`, `-L` : Language (e.g., `pt-BR`, `fr-FR`). Defaults to system locale if not set.
173
+ - `--output`, `-o` : Output format. One of `console`, `json`, `waybar`, or `statistics`. Default: `console`.
174
+ - `--keep-open`, `-k` : Keep open and refresh every 5 minutes (only makes sense for `console` output).
175
+ - `--force-cache` : Retrieve weather data from cache regardless of internet connection availability. Useful for offline mode.
176
+ - `--cache-statistics` : Display cache database statistics including total forecasts, unique locations, unique search names, and database file path.
177
+ - `--icons`, `-i` : Icon set. `fa` for Font-Awesome, `emoji` for emoji icons. Default: `emoji`.
178
+ - `--log` : Set logging level. One of `debug`, `info`, `warning`, `error`, `critical`. Default: `critical`.
172
179
 
173
180
  ### Environment Variables
174
181
 
175
182
  - `LANG` : Used as default language if `--lang` is not set.
176
183
  - `WEATHER_LOCATION_ID` : Used as default location if neither `location_name` nor `--location-id` is set.
177
184
 
185
+ ## Cache & Offline Support
186
+
187
+ The script maintains a SQLite cache database for storing weather forecasts. This enables several key features:
188
+
189
+ - **Automatic offline fallback**: When internet connection is unavailable, the script automatically retrieves the most recent cached weather data for the requested location.
190
+ - **Forced cache retrieval**: Use `--force-cache` to retrieve data exclusively from the cache, regardless of internet availability. This is useful for offline scenarios or reducing API calls.
191
+ - **Cache statistics**: Use `--cache-statistics` to display information about the cache database, including:
192
+ - Total number of cached forecasts
193
+ - Number of unique locations searched
194
+ - Number of unique search names used
195
+ - Database file path
196
+
197
+ By default, the cache database is stored in the system's temporary directory (`/tmp` on Linux/macOS).
198
+
178
199
  ### Example Usage
179
200
 
180
201
  ```sh
181
202
  weathergrabber "London" --output console --lang en-GB
182
203
  weathergrabber --location-id 1234567890abcdef... --output json
183
204
  weathergrabber "Paris" -o waybar -i fa
205
+ weathergrabber "New York" --force-cache
206
+ weathergrabber --cache-statistics
184
207
  ```
185
208
 
186
209
  Or as a Python module:
@@ -189,4 +212,6 @@ Or as a Python module:
189
212
  python -m weathergrabber "London" --output console --lang en-GB
190
213
  python -m weathergrabber --location-id 1234567890abcdef... --output json
191
214
  python -m weathergrabber "Paris" -o waybar -i fa
215
+ python -m weathergrabber "Toronto" --force-cache
216
+ python -m weathergrabber --cache-statistics
192
217
  ```
@@ -0,0 +1,80 @@
1
+ weathergrabber/__init__.py,sha256=z_8SVcvgPHVKWJg57APMX_xsh9hDcvZYhnsrGmiN9_E,216
2
+ weathergrabber/__main__.py,sha256=yYL-jc4kVHqaYVADzjKZfmCN2mziRofsXgnzrECbGDo,68
3
+ weathergrabber/cli.py,sha256=o5CgYggCGNzLpTj8Ynuy_QqoloGYGcnPCgm9RN8iO_c,2480
4
+ weathergrabber/core.py,sha256=76xkBPJluuQkhfEEWLrMp7ash03MZLnwl0kHzOKJseY,1376
5
+ weathergrabber/adapter/client/weather_api.py,sha256=9S7JmXaAVvvPY60dz6rC3lx7X68BcqyvNzvSVM1-af8,963
6
+ weathergrabber/adapter/client/weather_search_api.py,sha256=1oy7JitHcmwkkhFlD0eIt5A7a4cGbf7LMNi26tR8z5o,1724
7
+ weathergrabber/adapter/repository/forecast_repository.py,sha256=kuQWG6e-cNzFpS7BxqbHJUKw6OLH59zYUD6sOTtEO2o,5814
8
+ weathergrabber/adapter/tty/console_tty.py,sha256=YMe1xaOdBkMil4KidvAJWh3Qwbyg9dzHNJHAO9DjYnI,6022
9
+ weathergrabber/adapter/tty/json_tty.py,sha256=sZEUxsNKrCr6U3rAtn9dAtDJNdsnCAupWac_tmSnL3w,682
10
+ weathergrabber/adapter/tty/statistics_tty.py,sha256=6ES5AsnCAnXl6Bp_8tyqz2_C2j92nbf6ahHQj3UkTAI,1525
11
+ weathergrabber/adapter/tty/waybar_tty.py,sha256=vGErv9NshqPVzP2eh-O3govZRumUM-VXiwWRBsiRGzo,6191
12
+ weathergrabber/application/weathergrabber_application.py,sha256=yFbo920vGLi6TreDMw6n1bZ-wy1lcBJewKurP0qKfCA,5190
13
+ weathergrabber/application/services/extract_aqi_service.py,sha256=OIDbdXankKCn3LrxUsZkAlpf0tIgniFxuGiSDviL5UM,1099
14
+ weathergrabber/application/services/extract_current_conditions_service.py,sha256=lUo7meqt5SMCuZTKEjVW-iWYpxsYksvsDOGZdHD57ac,1883
15
+ weathergrabber/application/services/extract_daily_forecast_oldstyle_service.py,sha256=HPODxFKinUIhZrE6O-1PyaKavWtp1go4Xp5yY2KnC10,2226
16
+ weathergrabber/application/services/extract_daily_forecast_service.py,sha256=tJ7Lvi3bEiAT1cN6byoq4nx00BG91fG16iXEhwT0MDc,2762
17
+ weathergrabber/application/services/extract_health_activities_service.py,sha256=efrJMsVXEGTURGqOTmlbD973eF00vrX53tQqwbtytmo,1023
18
+ weathergrabber/application/services/extract_hourly_forecast_oldstyle_service.py,sha256=yVNhcMF0kYvwhofalv4z3GKqF33SBC41c2j4QU65nCA,2127
19
+ weathergrabber/application/services/extract_hourly_forecast_service.py,sha256=4y2xntFyXsorBUng5_KndNIvBZQCnTQ6ig6QDZsCT6E,2802
20
+ weathergrabber/application/services/extract_temperature_service.py,sha256=46nRO3Izj1QmG4BNTh8flsODsovHyWPzZzOnkl1Gbj4,634
21
+ weathergrabber/application/services/extract_today_details_service.py,sha256=lUt0D3SZy7NlPvDRjnIRhvZgSRm_WTBMtOhk7CUte3o,3814
22
+ weathergrabber/application/services/read_weather_service.py,sha256=7_B8E9IN1KCwOhpuS5PfWazI1sCrDyYrZhkV2R38bhc,649
23
+ weathergrabber/application/services/retrieve_forecast_from_cache_service.py,sha256=7fY6pJ_2qahbFNzhnxJ7taG1cb9-ExFEV7tYnLlMCAs,1314
24
+ weathergrabber/application/services/retrieve_statistics_service.py,sha256=XjDGbjZNlaaV1eT3hgVq_Pm012b6JHMQ66xT9DdVnPI,838
25
+ weathergrabber/application/services/save_forecast_to_cache_service.py,sha256=a64D2_JIpFHiQodltlWJ4Us3MtTcDff_xVwSJZmwZ0c,747
26
+ weathergrabber/application/services/search_location_service.py,sha256=tZmVgO45hjwoa4cl5bKPjMBmYlGxJiH_I9Ymb5pwEwU,1422
27
+ weathergrabber/application/usecases/statistics_uc.py,sha256=ycr0dH9Ddy5S8kdzjdk5Munk01RUfY1JNPXEriH2dE0,836
28
+ weathergrabber/application/usecases/weather_forecast_uc.py,sha256=zD77byoQx3YOJeKqgp1LgyRZU15OAzXfErt-7LMRqvo,6968
29
+ weathergrabber/domain/adapter/icon_enum.py,sha256=YxGYS5vBRV2AiAfeuPOdqaQOHixAssiMbOzQnTmdSBg,84
30
+ weathergrabber/domain/adapter/output_enum.py,sha256=KwR3mpIrW9T3b6mV3vEHjv4ff8BAxQM-58UTtX5EVZ0,116
31
+ weathergrabber/domain/adapter/params.py,sha256=TBhF1H2esDG16HuME43yUwm7OZivgHHnanzRpjVfj-M,2220
32
+ weathergrabber/domain/adapter/mappers/air_quality_index_mapper.py,sha256=uEAVVvuib64lASvJosZXt3KmwmYl8CklHEPxIE3uXa4,889
33
+ weathergrabber/domain/adapter/mappers/city_location_mapper.py,sha256=1OLftve-uZ2APUv9lTWabHt-yxrop7R17IWgJE7fn9g,454
34
+ weathergrabber/domain/adapter/mappers/color_mapper.py,sha256=9B4Eas4VU5khnLhqtL_9zpX9TsHIYeoZLxI-Qg-Tsoo,398
35
+ weathergrabber/domain/adapter/mappers/current_conditions_mapper.py,sha256=MYRci1NZTjk7op0zxbMfEA71Qmi4n17FtkvKPI3FAOU,1852
36
+ weathergrabber/domain/adapter/mappers/daily_predictions_mapper.py,sha256=cFfBIfIkXj9DcxOugYW_sQ9qmpdJZ-3KmbMwy7ukqPs,1921
37
+ weathergrabber/domain/adapter/mappers/day_night_mapper.py,sha256=Qileog_XlKzdaSvubEzxVQNcx-jGfZt-tfpoiWNd3Jw,770
38
+ weathergrabber/domain/adapter/mappers/forecast_mapper.py,sha256=KNifHlqnPtQiHuB92ENBRY2YFhqkxtpgcLsaUQan9mY,3149
39
+ weathergrabber/domain/adapter/mappers/health_activities_mapper.py,sha256=f-H8uzy-d3ZH46KZRcoIE07UMT_buPsG6JVZRrMkQwU,482
40
+ weathergrabber/domain/adapter/mappers/hourly_predictions_mapper.py,sha256=EWyzfaFDUub04IgMAVNLW2QIzRiOzLjx3BXimohfEE4,2080
41
+ weathergrabber/domain/adapter/mappers/label_value_mapper.py,sha256=rHftbEvAGHXIZWgRuoLR8VWYsUcjjA1MTHzU2M1pCgc,328
42
+ weathergrabber/domain/adapter/mappers/moon_phase_mapper.py,sha256=KXoM_0vdb5fE9RR6bhiI0nkf8xfUEF7wjziYcxdQYaA,535
43
+ weathergrabber/domain/adapter/mappers/precipitation_mapper.py,sha256=Y-JmjtM3HjQSzLFPFmLbDwdaB5CpJ4Lcj6h0Igrk3lw,367
44
+ weathergrabber/domain/adapter/mappers/search_mapper.py,sha256=bRXzqGlonVZj-PeeJb4ptVfiLhagC51Mcuv3KUSu50E,321
45
+ weathergrabber/domain/adapter/mappers/statistics_mapper.py,sha256=B2rTkujzfQQT4SW6nq_RPAh9azLEPp30UzTOXjRrNLw,904
46
+ weathergrabber/domain/adapter/mappers/sunrise_sunset_mapper.py,sha256=c7RvsOzwVB7g4akKN7QnyIDk7Q41U40eQPYmpzXYMzU,975
47
+ weathergrabber/domain/adapter/mappers/temperature_high_low_mapper.py,sha256=EIH-ALc2iU5AzR66sjIREhdvuJmgnvrv7bMvtP71OPs,448
48
+ weathergrabber/domain/adapter/mappers/timestamp_mapper.py,sha256=0TvnW8RLcRuZHaf3gH74PKvrojPorQA0-CYXmbL1hSQ,370
49
+ weathergrabber/domain/adapter/mappers/today_details_mapper.py,sha256=PkoD6mF6uGi41EDj61uqutPSsiIe-fMEsroUr1-RvwQ,2949
50
+ weathergrabber/domain/adapter/mappers/uv_index_mapper.py,sha256=KnmZjHta2GLFg4xzSED7dFMZ1CF0z46UksugV1-pBDw,451
51
+ weathergrabber/domain/adapter/mappers/weather_icon_enum_mapper.py,sha256=Wtr-DgGwlTIWav4GxlruOW0E3nFO0CGBp38OLfJc80k,375
52
+ weathergrabber/domain/adapter/mappers/wind_mapper.py,sha256=U8KKhRi8ZcgDyKzIp0fywVpKpctxEg1o085uf8GYlUQ,366
53
+ weathergrabber/domain/entities/air_quality_index.py,sha256=8uBqxVIKCYIvrHuP-XbCHjYZhq7Z0RmqkgAAdCw6Tp4,2680
54
+ weathergrabber/domain/entities/city_location.py,sha256=p-11c7AwA8t-nNdvTjl9-Oc5Kw4D2XP7tI4WrATVYpQ,2382
55
+ weathergrabber/domain/entities/color.py,sha256=HfgB5CwxrSHT05TIXCqVCy0GoRpuEl99aUrUSJhaqcE,1601
56
+ weathergrabber/domain/entities/current_conditions.py,sha256=S14j2lL_gc2pds0wbl5M4_72PbVdubOuX8lnE_tZVTg,1477
57
+ weathergrabber/domain/entities/daily_predictions.py,sha256=8pzmaU-yugS2Hx_6MBWAk24wlSISe1OQIRrCK_lfvbw,1618
58
+ weathergrabber/domain/entities/day_night.py,sha256=7geOuVH9xDb1ecLKnZmj6eqp3H3kp9G0YY497cEyPtg,1442
59
+ weathergrabber/domain/entities/forecast.py,sha256=CO0VTdMI0kjuwbpwwDNRCf_82oNtw5QkN-9GgobPet8,2399
60
+ weathergrabber/domain/entities/health_activities.py,sha256=oaIF_nI-iaN4OIHWTL-L7QZUQxCemdmNvzprDXysK-g,1481
61
+ weathergrabber/domain/entities/hourly_predictions.py,sha256=PFiGuo7mBoQHLR-bDirV--R126YAOzkwIHgaeRGFQSA,2179
62
+ weathergrabber/domain/entities/label_value.py,sha256=LvrvZbSrcEUUpxvKAmYkFnpDFWsa6LFmGA9O8i6HB84,446
63
+ weathergrabber/domain/entities/moon_phase.py,sha256=UltNeGfFYO7tQ0IGD3pLV9xvo9nO-5iDZRwk0KGST4E,596
64
+ weathergrabber/domain/entities/moon_phase_enum.py,sha256=U4h4s5xDQfX37nkmt5ppkk6uJdamngeE-hQx3E44HHk,2185
65
+ weathergrabber/domain/entities/precipitation.py,sha256=eXrpwMOsEJWGqV4bEBhN9niWYXalgdZRLG4-I39JZ2A,466
66
+ weathergrabber/domain/entities/search.py,sha256=j3BzskyPl0hDWV02XTOC4tJonV5RHxr5Rop_rYMKUtA,387
67
+ weathergrabber/domain/entities/statistics.py,sha256=yOZm7Z2osePE3nvU7trQx3F7_d_gJoJKSOo__wGUAEQ,1280
68
+ weathergrabber/domain/entities/sunrise_sunset.py,sha256=i2FxwrCmgGEYV56Rq8Hvlf-mIcFcxn2Aw7S81gSTFcg,1206
69
+ weathergrabber/domain/entities/temperature_hight_low.py,sha256=PQOJ5uDtfMRBR5yMxXA46xuorJC08jva2C0-WAV5yxs,909
70
+ weathergrabber/domain/entities/timestamp.py,sha256=Bk6f8Tx0-yNitYmEKIWHnqh_ALDwxEHrhoCRSrfvYTU,1222
71
+ weathergrabber/domain/entities/today_details.py,sha256=EUlV7xerYw5QhEsBfvO5m6-9Ghm4nPkXJz9zCmSYTbA,2398
72
+ weathergrabber/domain/entities/uv_index.py,sha256=7XalamfjJdVSqo4x7G4JVf_HJtrPJxO1BpbvmAfBhnw,1481
73
+ weathergrabber/domain/entities/weather_icon_enum.py,sha256=4mbTtZjyYaX7hNlKh1LLQdVNAEjZkmFGPijARxilZLs,4088
74
+ weathergrabber/domain/entities/wind.py,sha256=wTDz3X1rYsnw_eNoDi1miwaomxwhiJkY_q6xrdZtLak,789
75
+ weathergrabber-0.0.9.dist-info/licenses/LICENSE,sha256=X5JFljoqN43yFwpMLudQ9rtty4K_FeZfnz3v8Yhw23Q,1067
76
+ weathergrabber-0.0.9.dist-info/METADATA,sha256=4FKucUYm98q6YWNOfDI3Glq990k3_XWwzNLbMwVGy6I,7473
77
+ weathergrabber-0.0.9.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
78
+ weathergrabber-0.0.9.dist-info/entry_points.txt,sha256=m2P9a4mrJDTzuNaiTU438NA60GxCfaw7VKvruWw43N8,63
79
+ weathergrabber-0.0.9.dist-info/top_level.txt,sha256=P3NMDJJYRIvQujf994Vb4gZrobkKWkL2gh3NF_ajQWM,15
80
+ weathergrabber-0.0.9.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (80.9.0)
2
+ Generator: setuptools (80.10.2)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5
 
@@ -1,13 +0,0 @@
1
-
2
- from weathergrabber.domain.air_quality_index import AirQualityIndex
3
- from weathergrabber.domain.adapter.mapper.color_mapper import color_to_dict
4
-
5
- def air_quality_index_to_dict(aqi: AirQualityIndex) -> dict:
6
- return {
7
- "title": aqi.title,
8
- "value": aqi.value,
9
- "category": aqi.category,
10
- "description": aqi.description,
11
- "acronym": aqi.acronym,
12
- "color": color_to_dict(aqi.color) if aqi.color else None,
13
- }
@@ -1,8 +0,0 @@
1
- from weathergrabber.domain.city_location import CityLocation
2
-
3
- def city_location_to_dict(loc: CityLocation) -> dict:
4
- return {
5
- "city": loc.city,
6
- "state_province": loc.state_province,
7
- "country": loc.country,
8
- }
@@ -1,10 +0,0 @@
1
- from weathergrabber.domain.color import Color
2
-
3
- def color_to_dict(color: Color) -> dict:
4
- return {
5
- "red": color.red,
6
- "green": color.green,
7
- "blue": color.blue,
8
- "hex": color.hex,
9
- "rgb": color.rgb,
10
- }
@@ -1,16 +0,0 @@
1
-
2
- from weathergrabber.domain.current_conditions import CurrentConditions
3
- from weathergrabber.domain.adapter.mapper.city_location_mapper import city_location_to_dict
4
- from weathergrabber.domain.adapter.mapper.timestamp_mapper import timestamp_to_dict
5
- from weathergrabber.domain.adapter.mapper.weather_icon_enum_mapper import weather_icon_enum_to_dict
6
- from weathergrabber.domain.adapter.mapper.day_night_mapper import day_night_to_dict
7
-
8
- def current_conditions_to_dict(cc: CurrentConditions) -> dict:
9
- return {
10
- "location": city_location_to_dict(cc.location) if cc.location else None,
11
- "timestamp": timestamp_to_dict(cc.timestamp) if cc.timestamp else None,
12
- "temperature": cc.temperature,
13
- "icon": weather_icon_enum_to_dict(cc.icon) if cc.icon else None,
14
- "summary": cc.summary,
15
- "day_night": day_night_to_dict(cc.day_night) if cc.day_night else None,
16
- }
@@ -1,15 +0,0 @@
1
- from weathergrabber.domain.daily_predictions import DailyPredictions
2
- from weathergrabber.domain.adapter.mapper.temperature_high_low_mapper import temperature_high_low_to_dict
3
- from weathergrabber.domain.adapter.mapper.weather_icon_enum_mapper import weather_icon_enum_to_dict
4
- from weathergrabber.domain.adapter.mapper.precipitation_mapper import precipitation_to_dict
5
- from weathergrabber.domain.adapter.mapper.moon_phase_mapper import moon_phase_to_dict
6
-
7
- def daily_predictions_to_dict(dp: DailyPredictions) -> dict:
8
- return {
9
- "title": dp.title,
10
- "high_low": temperature_high_low_to_dict(dp.high_low) if dp.high_low else None,
11
- "icon": weather_icon_enum_to_dict(dp.icon) if dp.icon else None,
12
- "summary": dp.summary,
13
- "precipitation": precipitation_to_dict(dp.precipitation) if dp.precipitation else None,
14
- "moon_phase": moon_phase_to_dict(dp.moon_phase) if dp.moon_phase else None,
15
- }
@@ -1,12 +0,0 @@
1
- from weathergrabber.domain.day_night import DayNight
2
-
3
- def day_night_to_dict(dn: DayNight) -> dict:
4
- def temp_to_dict(temp):
5
- return {
6
- "label": temp.label,
7
- "value": temp.value,
8
- } if temp else None
9
- return {
10
- "day": temp_to_dict(dn.day) if dn.day else None,
11
- "night": temp_to_dict(dn.night) if dn.night else None,
12
- }
@@ -1,20 +0,0 @@
1
- from weathergrabber.domain.forecast import Forecast
2
-
3
- from weathergrabber.domain.adapter.mapper.search_mapper import search_to_dict
4
- from weathergrabber.domain.adapter.mapper.current_conditions_mapper import current_conditions_to_dict
5
- from weathergrabber.domain.adapter.mapper.today_details_mapper import today_details_to_dict
6
- from weathergrabber.domain.adapter.mapper.air_quality_index_mapper import air_quality_index_to_dict
7
- from weathergrabber.domain.adapter.mapper.health_activities_mapper import health_activities_to_dict
8
- from weathergrabber.domain.adapter.mapper.hourly_predictions_mapper import hourly_predictions_to_dict
9
- from weathergrabber.domain.adapter.mapper.daily_predictions_mapper import daily_predictions_to_dict
10
-
11
- def forecast_to_dict(forecast: Forecast) -> dict:
12
- return {
13
- "search": search_to_dict(forecast.search) if forecast.search else None,
14
- "current_conditions": current_conditions_to_dict(forecast.current_conditions) if forecast.current_conditions else None,
15
- "today_details": today_details_to_dict(forecast.today_details) if forecast.today_details else None,
16
- "air_quality_index": air_quality_index_to_dict(forecast.air_quality_index) if forecast.air_quality_index else None,
17
- "health_activities": health_activities_to_dict(forecast.health_activities) if forecast.health_activities else None,
18
- "hourly_predictions": [hourly_predictions_to_dict(h) for h in forecast.hourly_predictions],
19
- "daily_predictions": [daily_predictions_to_dict(d) for d in forecast.daily_predictions],
20
- }
@@ -1,8 +0,0 @@
1
- from weathergrabber.domain.health_activities import HealthActivities
2
-
3
- def health_activities_to_dict(ha: HealthActivities) -> dict:
4
- return {
5
- "category_name": ha.category_name,
6
- "title": ha.title,
7
- "description": ha.description,
8
- }
@@ -1,19 +0,0 @@
1
- from weathergrabber.domain.hourly_predictions import HourlyPredictions
2
- from weathergrabber.domain.adapter.mapper.weather_icon_enum_mapper import weather_icon_enum_to_dict
3
- from weathergrabber.domain.adapter.mapper.precipitation_mapper import precipitation_to_dict
4
- from weathergrabber.domain.adapter.mapper.wind_mapper import wind_to_dict
5
- from weathergrabber.domain.adapter.mapper.uv_index_mapper import uv_index_to_dict
6
-
7
- def hourly_predictions_to_dict(hp: HourlyPredictions) -> dict:
8
- return {
9
- "title": hp.title,
10
- "temperature": hp.temperature,
11
- "icon": weather_icon_enum_to_dict(hp.icon) if hp.icon else None,
12
- "summary": hp.summary,
13
- "precipitation": precipitation_to_dict(hp.precipitation) if hp.precipitation else None,
14
- "wind": wind_to_dict(hp.wind) if hp.wind else None,
15
- "feels_like": hp.feels_like,
16
- "humidity": hp.humidity,
17
- "uv_index": uv_index_to_dict(hp.uv_index) if hp.uv_index else None,
18
- "cloud_cover": hp.cloud_cover,
19
- }
@@ -1,7 +0,0 @@
1
- from weathergrabber.domain.label_value import LabelValue
2
-
3
- def label_value_to_dict(lv: LabelValue) -> dict:
4
- return {
5
- "label": lv.label,
6
- "value": lv.value,
7
- }
@@ -1,9 +0,0 @@
1
- from weathergrabber.domain.moon_phase import MoonPhase
2
- from weathergrabber.domain.moon_phase_enum import MoonPhaseEnum
3
-
4
- def moon_phase_to_dict(mp: MoonPhase) -> dict:
5
- return {
6
- "icon": mp.icon.name if mp.icon else None,
7
- "phase": mp.phase,
8
- "label": mp.label,
9
- }
@@ -1,7 +0,0 @@
1
- from weathergrabber.domain.precipitation import Precipitation
2
-
3
- def precipitation_to_dict(p: Precipitation) -> dict:
4
- return {
5
- "percentage": p.percentage,
6
- "amount": p.amount,
7
- }
@@ -1,7 +0,0 @@
1
- from weathergrabber.domain.search import Search
2
-
3
- def search_to_dict(search: Search) -> dict:
4
- return {
5
- "id": search.id,
6
- "search_name": search.search_name,
7
- }
@@ -1,13 +0,0 @@
1
- from weathergrabber.domain.sunrise_sunset import SunriseSunset
2
- from weathergrabber.domain.adapter.mapper.weather_icon_enum_mapper import weather_icon_enum_to_dict
3
-
4
- def sunrise_sunset_to_dict(ss: SunriseSunset) -> dict:
5
- def icon_value_to_dict(iv):
6
- return {
7
- "icon": weather_icon_enum_to_dict(iv.icon) if iv.icon else None,
8
- "value": iv.value,
9
- } if iv else None
10
- return {
11
- "sunrise": icon_value_to_dict(ss.sunrise) if ss.sunrise else None,
12
- "sunset": icon_value_to_dict(ss.sunset) if ss.sunset else None,
13
- }
@@ -1,8 +0,0 @@
1
- from weathergrabber.domain.temperature_hight_low import TemperatureHighLow
2
-
3
- def temperature_high_low_to_dict(thl: TemperatureHighLow) -> dict:
4
- return {
5
- "high": thl.high,
6
- "low": thl.low,
7
- "label": thl.label,
8
- }
@@ -1,8 +0,0 @@
1
- from weathergrabber.domain.timestamp import Timestamp
2
-
3
- def timestamp_to_dict(ts: Timestamp) -> dict:
4
- return {
5
- "time": ts.time,
6
- "gmt": ts.gmt,
7
- "text": ts.text,
8
- }
@@ -1,21 +0,0 @@
1
-
2
- from weathergrabber.domain.today_details import TodayDetails
3
- from weathergrabber.domain.adapter.mapper.label_value_mapper import label_value_to_dict
4
- from weathergrabber.domain.adapter.mapper.sunrise_sunset_mapper import sunrise_sunset_to_dict
5
- from weathergrabber.domain.adapter.mapper.temperature_high_low_mapper import temperature_high_low_to_dict
6
- from weathergrabber.domain.adapter.mapper.uv_index_mapper import uv_index_to_dict
7
- from weathergrabber.domain.adapter.mapper.moon_phase_mapper import moon_phase_to_dict
8
-
9
- def today_details_to_dict(td: TodayDetails) -> dict:
10
- return {
11
- "feelslike": label_value_to_dict(td.feelslike) if td.feelslike else None,
12
- "sunrise_sunset": sunrise_sunset_to_dict(td.sunrise_sunset) if td.sunrise_sunset else None,
13
- "high_low": temperature_high_low_to_dict(td.high_low) if td.high_low else None,
14
- "wind": label_value_to_dict(td.wind) if td.wind else None,
15
- "humidity": label_value_to_dict(td.humidity) if td.humidity else None,
16
- "dew_point": label_value_to_dict(td.dew_point) if td.dew_point else None,
17
- "pressure": label_value_to_dict(td.pressure) if td.pressure else None,
18
- "uv_index": uv_index_to_dict(td.uv_index) if td.uv_index else None,
19
- "visibility": label_value_to_dict(td.visibility) if td.visibility else None,
20
- "moon_phase": moon_phase_to_dict(td.moon_phase) if td.moon_phase else None,
21
- }
@@ -1,9 +0,0 @@
1
- from weathergrabber.domain.uv_index import UVIndex
2
-
3
- def uv_index_to_dict(uv: UVIndex) -> dict:
4
- return {
5
- "string_value": uv.string_value,
6
- "index": uv.index,
7
- "of": uv.of,
8
- "label": uv.label,
9
- }
@@ -1,8 +0,0 @@
1
- from weathergrabber.domain.weather_icon_enum import WeatherIconEnum
2
-
3
- def weather_icon_enum_to_dict(icon: WeatherIconEnum) -> dict:
4
- return {
5
- "name": icon.name,
6
- "fa_icon": icon.fa_icon,
7
- "emoji_icon": icon.emoji_icon,
8
- }
@@ -1,7 +0,0 @@
1
- def wind_to_dict(wind):
2
- if wind is None:
3
- return None
4
- return {
5
- "direction": wind.direction,
6
- "speed": wind.speed
7
- }