├── .gitignore ├── COPYING ├── DEBIAN ├── README.Debian ├── changelog ├── control ├── copyright ├── patches │ └── series ├── postinst ├── postrm ├── rules ├── source │ ├── format │ └── local-options └── watch ├── Forecast ├── App.py ├── data.py ├── maps.py ├── page.py ├── start.py ├── style.py └── weatherInfo ├── README.md ├── __init__.py ├── data ├── dependencies │ └── python3-requests.json ├── dev.salaniLeo.forecast.appdata.xml.in ├── dev.salaniLeo.forecast.desktop.in ├── dev.salaniLeo.forecast.gschema.xml ├── forecast.gresource.xml ├── gschemas.compiled ├── images │ ├── app1-dark.png │ ├── app1-light.png │ ├── app2-dark.png │ ├── app2-light.png │ ├── app3-dark.png │ ├── app3-light.png │ ├── app4-dark.png │ └── app4-light.png ├── meson.build ├── status │ ├── humidity.svg │ ├── info-symbolic.svg │ ├── temperature-symbolic.svg │ ├── weather-clear-large.svg │ ├── weather-clear-night-large.svg │ ├── weather-clear-night-small.svg │ ├── weather-clear-small.svg │ ├── weather-few-clouds-large.svg │ ├── weather-few-clouds-night-large.svg │ ├── weather-few-clouds-night-small.svg │ ├── weather-few-clouds-small.svg │ ├── weather-fog-large.svg │ ├── weather-fog-small.svg │ ├── weather-hourly-symbolic.svg │ ├── weather-overcast-large.svg │ ├── weather-overcast-small.svg │ ├── weather-severe-alert-large.svg │ ├── weather-severe-alert-small.svg │ ├── weather-showers-large.svg │ ├── weather-showers-scattered-large.svg │ ├── weather-showers-scattered-small.svg │ ├── weather-showers-small.svg │ ├── weather-snow-large.svg │ ├── weather-snow-small.svg │ ├── weather-storm-large.svg │ ├── weather-storm-small.svg │ ├── weather-tornado-large.svg │ ├── weather-tornado-small.svg │ ├── weather-windy-large.svg │ └── weather-windy-small.svg └── style.css ├── dev.salaniLeo.forecast.json ├── forecast.in ├── meson.build ├── po ├── Forecast.pot ├── LINGUAS ├── POTFILES.in ├── de.po ├── hi.po ├── meson.build ├── pt.po └── tr.po └── share └── icons ├── hicolor ├── scalable │ └── apps │ │ ├── dev.salaniLeo.forecast.Devel.svg │ │ └── dev.salaniLeo.forecast.svg └── symbolic │ └── apps │ └── dev.salaniLeo.forecast-symbolic.svg └── meson.build /.gitignore: -------------------------------------------------------------------------------- 1 | .flatpak-builder 2 | .flatpak 3 | .venv 4 | .vscode 5 | Forecast/__pycache__ 6 | .env 7 | dist 8 | weatherInfo.spec 9 | build 10 | Forecast/weatherInfo.py 11 | -------------------------------------------------------------------------------- /DEBIAN/README.Debian: -------------------------------------------------------------------------------- 1 | forecast for Debian 2 | 3 | -- Himadri Sekhar Basu Wed, 21 Jun 2023 15:39:46 +0530 4 | -------------------------------------------------------------------------------- /DEBIAN/changelog: -------------------------------------------------------------------------------- 1 | forecast (0.2.2-1) stable; urgency=medium 2 | 3 | * Removed window border 4 | * Updated appdata and added option to gschemas 5 | * Modified night css 6 | * Added smooth transitions and reloads, 7 | also added options to manage saved locations 8 | * Updated css and screenshots 9 | * Added new version to appdata 10 | * Updated app 11 | * Complete redesign of the app 12 | * Updated potfile 13 | * Updated screenshots and style 14 | * Added v0.2.2 15 | 16 | -- Himadri Sekhar Basu Tue, 04 Jul 2023 12:41:58 +0530 17 | 18 | forecast (0.2.1-1) stable; urgency=medium 19 | 20 | * Initial release. 21 | * Added release 0.2.1 22 | * Added support for an AppImage build 23 | * Added __init__.py 24 | * Updated screenshots 25 | * Updated release 0.2.1 26 | 27 | -- Himadri Sekhar Basu Tue, 04 Jul 2023 12:40:52 +0530 28 | -------------------------------------------------------------------------------- /DEBIAN/control: -------------------------------------------------------------------------------- 1 | Source: forecast 2 | Section: utils 3 | Priority: optional 4 | Maintainer: Himadri Sekhar Basu 5 | Build-Depends: debhelper-compat (= 13), 6 | appstream-util, 7 | desktop-file-utils, 8 | meson (>=0.61), 9 | libglib2.0-bin, 10 | libglib2.0-dev-bin 11 | Standards-Version: 4.6.0.1 12 | Homepage: https://github.com/SalaniLeo/Forecast 13 | Package: forecast 14 | Architecture: all 15 | Depends: gir1.2-adw-1, 16 | gir1.2-webkit2-4.1, 17 | python3, 18 | python3-tldextract, 19 | python3-gi 20 | Description: ⛅ Weather and forecast app for Linux. 21 | Made also for mobile! 22 | Version: 1.0 23 | -------------------------------------------------------------------------------- /DEBIAN/copyright: -------------------------------------------------------------------------------- 1 | Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ 2 | Upstream-Name: forecast 3 | Upstream-Contact: Leonardo Salani 4 | Source: https://github.com/SalaniLeo/Forecast 5 | 6 | Files: \* 7 | Copyright: 2023 forecast 8 | License: GPL-3.0+ 9 | 10 | Files: debian/\* 11 | Copyright: 2023 Himadri Sekhar Basu 12 | License: GPL-3.0+ 13 | 14 | Files: po/tr.po 15 | Copyright: 2023 forecast 16 | License: GPL-3.0+ 17 | This file is distributed under the same license as the dev.salaniLeo.forecast package. 18 | 19 | Files: po/Forecast.pot 20 | Copyright: 2023 forecast 21 | License: GPL-3.0+ 22 | This file is distributed under the same license as the PACKAGE package. 23 | 24 | Files: forecast.in 25 | Copyright: 2023 forecast 26 | License: GPL-3.0+ 27 | 28 | License: GPL-3.0+ 29 | This program is free software: you can redistribute it and/or modify 30 | it under the terms of the GNU General Public License as published by 31 | the Free Software Foundation, either version 3 of the License, or 32 | (at your option) any later version. 33 | . 34 | This program is distributed in the hope that it will be useful, 35 | but WITHOUT ANY WARRANTY; without even the implied warranty of 36 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 37 | GNU General Public License for more details. 38 | . 39 | You should have received a copy of the GNU General Public License 40 | along with this program. If not, see . 41 | . 42 | SPDX-License-Identifier: GPL-3.0-or-later 43 | . 44 | On Debian systems, the complete text of the GNU General Public License 45 | Version 3 can be found in `/usr/share/common-licenses/GPL-3'. 46 | -------------------------------------------------------------------------------- /DEBIAN/patches/series: -------------------------------------------------------------------------------- 1 | # You must remove unused comment lines for the released package. 2 | -------------------------------------------------------------------------------- /DEBIAN/postinst: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # postinst script for forecast 3 | # 4 | # see: dh_installdeb(1) 5 | 6 | set -e 7 | 8 | 9 | case "$1" in 10 | configure) 11 | if which glib-compile-schemas >/dev/null 2>&1 12 | then 13 | glib-compile-schemas /usr/share/glib-2.0/schemas 14 | fi 15 | ;; 16 | 17 | abort-upgrade|abort-remove|abort-deconfigure) 18 | ;; 19 | 20 | *) 21 | echo "postinst called with unknown argument \`$1'" >&2 22 | exit 1 23 | ;; 24 | esac 25 | 26 | # dh_installdeb will replace this with shell code automatically 27 | # generated by other debhelper scripts. 28 | 29 | #DEBHELPER# 30 | 31 | exit 0 32 | -------------------------------------------------------------------------------- /DEBIAN/postrm: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # postrm script for forecast 3 | # 4 | # see: dh_installdeb(1) 5 | 6 | set -e 7 | 8 | 9 | case "$1" in 10 | purge|remove|upgrade|failed-upgrade|abort-install|abort-upgrade|disappear) 11 | if which glib-compile-schemas >/dev/null 2>&1 12 | then 13 | glib-compile-schemas /usr/share/glib-2.0/schemas 14 | fi 15 | ;; 16 | 17 | *) 18 | echo "postrm called with unknown argument \`$1'" >&2 19 | exit 1 20 | ;; 21 | esac 22 | 23 | # dh_installdeb will replace this with shell code automatically 24 | # generated by other debhelper scripts. 25 | 26 | #DEBHELPER# 27 | 28 | exit 0 29 | -------------------------------------------------------------------------------- /DEBIAN/rules: -------------------------------------------------------------------------------- 1 | #!/usr/bin/make -f 2 | # You must remove unused comment lines for the released package. 3 | export DH_VERBOSE = 1 4 | #export DEB_BUILD_MAINT_OPTIONS = hardening=+all 5 | #export DEB_CFLAGS_MAINT_APPEND = -Wall -pedantic 6 | #export DEB_LDFLAGS_MAINT_APPEND = -Wl,--as-needed 7 | 8 | %: 9 | dh $@ --buildsystem=meson 10 | 11 | override_dh_auto_test: 12 | -------------------------------------------------------------------------------- /DEBIAN/source/format: -------------------------------------------------------------------------------- 1 | 3.0 (quilt) 2 | -------------------------------------------------------------------------------- /DEBIAN/source/local-options: -------------------------------------------------------------------------------- 1 | #abort-on-upstream-changes 2 | #unapply-patches 3 | -------------------------------------------------------------------------------- /DEBIAN/watch: -------------------------------------------------------------------------------- 1 | # You must remove unused comment lines for the released package. 2 | version=3 3 | -------------------------------------------------------------------------------- /Forecast/data.py: -------------------------------------------------------------------------------- 1 | import requests, threading, gi, time, locale 2 | gi.require_version('Gtk', '4.0') 3 | gi.require_version('Adw', '1') 4 | from gi.repository import Gio, Adw, Gtk 5 | from datetime import datetime 6 | from gettext import gettext as _ 7 | from .style import * 8 | from datetime import datetime, timezone 9 | import subprocess, os, json 10 | 11 | class constants(): 12 | meters = _("Metric System") 13 | miles = _("Imperial System") 14 | metric_system = f'{meters}, °C - Km/h' 15 | imperial_system = f'{miles}, °F - mi/h' 16 | system_locale = locale.getdefaultlocale()[0].split("_")[0] 17 | binary_path = f'{os.path.dirname(os.path.realpath(__file__))}/weatherInfo' 18 | 19 | settings = Gio.Settings.new("dev.salaniLeo.forecast") 20 | units = settings.get_string('units').split(' ')[0].lower() 21 | raw_units = settings.get_string('units') 22 | degrees_unit = raw_units[raw_units.find(",")+1:raw_units.find("-")] 23 | speed_unit = raw_units[raw_units.find("-")+1:] 24 | poll_unit = ' μg/m3' 25 | icon_loc = None 26 | today = datetime.now() 27 | available_units = [metric_system, imperial_system] 28 | time_formats = ['12', '24'] 29 | time_am_pm = ['AM', 'PM'] 30 | css_classes = [] 31 | days_css_classes = [] 32 | day_names = [] 33 | root = None 34 | app = None 35 | toast_overlay= None 36 | city_page = None 37 | last_refresh = 0 38 | 39 | #pollution index 40 | air_good = _("Good") 41 | air_fair = _("Fair") 42 | air_moderate = _("Moderate") 43 | air_poor = _("Poor") 44 | air_very_poor = _("Very Poor") 45 | 46 | align_breakpoint = 700 47 | sidebar_breakpoint = 500 48 | 49 | def uv_index(uv_index): 50 | if uv_index >= 0 and uv_index <= 2: 51 | return _("Low") 52 | elif uv_index >= 3 and uv_index <= 7: 53 | return _("Seek shade during midday hours!") 54 | elif uv_index >= 8: 55 | return _("Avoid being outside during midday hours!") 56 | else: 57 | return _("Invalid UV index input.") 58 | 59 | def wind_dir(angle): 60 | directions = [ 61 | _("N"), _("NNE"), _("NE"), _("ENE"), _("E"), _("ESE"), _("SE"), _("SSE"), 62 | _("S"), _("SSW"), _("SW"), _("WSW"), _("W"), _("WNW"), _("NW"), _("NNW"), 63 | ] 64 | index = round(angle / (360.0 / len(directions))) % len(directions) 65 | return directions[index] 66 | 67 | class global_variables(): 68 | def get_saved_cities(): 69 | return constants.settings.get_strv('wthr-locs') 70 | 71 | def get_city_name(city): 72 | return str(city).split("-")[0] 73 | 74 | def get_default_city(): 75 | return constants.settings.get_int('selected-city') 76 | 77 | def get_temperature_units(): 78 | return constants.settings.get_string('units').split(',')[-1].split('-')[0] 79 | 80 | def get_current_units(): 81 | return constants.settings.get_string('units') 82 | 83 | def set_default_city(n): 84 | constants.settings.set_int("selected-city", n) 85 | 86 | def set_saved_cities(cities): 87 | constants.settings.set_strv('wthr-locs', cities) 88 | 89 | def set_default_units(units): 90 | constants.settings.set_string('units', units) 91 | 92 | def get_timezone_format(): 93 | return constants.settings.get_int('time-format') 94 | 95 | def set_timezone_format(time_format): 96 | constants.settings.set_int('time-format', int(time_format)) 97 | 98 | def set_use_dyn_bg(use): 99 | constants.settings.set_boolean('gradient-bg', use) 100 | 101 | def get_max_search_cities(): 102 | return 5 103 | 104 | def get_speed_units(): 105 | return constants.settings.get_string('units').split(',')[-1].split('-')[-1] 106 | 107 | def get_distance_units(): 108 | return global_variables.get_speed_units().split('/')[0] 109 | 110 | def get_use_dyn_bg(): 111 | return constants.settings.get_boolean('gradient-bg') 112 | 113 | def get_last_refresh(): 114 | return constants.last_refresh 115 | 116 | def set_last_refresh(time): 117 | constants.last_refresh = time 118 | 119 | def get_api_key(): 120 | if constants.settings.get_boolean("api-key-b"): 121 | return constants.settings.get_string('custom-api-key') 122 | else: 123 | return constants.settings.get_string('api-key-s') 124 | 125 | def set_api_key(key): 126 | return constants.settings.get_string('custom-api-key', key) 127 | 128 | class request(): 129 | def weather(lat, lon): 130 | command = f'exec {constants.binary_path} --request=weather --lat={lat} --lon={lon} --units={constants.units} --locale={constants.system_locale}' 131 | result = subprocess.run(command, shell=True, capture_output=True, text=True) 132 | return json.loads(result.stdout) 133 | 134 | def pollution(lat, lon): 135 | command = f'exec {constants.binary_path} --request=pollution --lat={lat} --lon={lon} --units={constants.units} --locale={constants.system_locale}' 136 | result = subprocess.run(command, shell=True, capture_output=True, text=True) 137 | return json.loads(result.stdout) 138 | 139 | row_list = [] 140 | class actions(): 141 | def show_hide_sidebar(button, application): 142 | application.side_pane.set_show_sidebar(not application.side_pane.get_show_sidebar()) 143 | 144 | def refresh_weather(button, app, cities_stack): 145 | i = 0 146 | 147 | now = time.time() 148 | 149 | if(now - global_variables.get_last_refresh() >= 120): 150 | global_variables.set_last_refresh(time.time()) 151 | for city in global_variables.get_saved_cities(): 152 | if app.loaded_list[i] == True: 153 | if i == global_variables.get_default_city() or city == cities_stack.get_visible_child_name(): 154 | load = True 155 | else: 156 | load = False 157 | cities_stack.remove(cities_stack.get_child_by_name(city)) 158 | app.day_selector_stack.remove(app.day_selector_stack.get_child_by_name(city)) 159 | 160 | stack_page = constants.city_page.new(app, city, load) 161 | constants.root.add_titled(child=stack_page, title=global_variables.get_city_name(city), name=city) 162 | if app.day_selector_stack.get_parent() != None: 163 | app.header_bar.remove(app.day_selector_stack) 164 | app.header_bar.pack_start(app.city_selector) 165 | if global_variables.get_use_dyn_bg(): 166 | constants.app.set_css_classes(constants.css_classes[global_variables.get_saved_cities().index(city)]) 167 | i = i + 1 168 | else: 169 | constants.toast_overlay.add_toast(Adw.Toast(title=_('Wait at least 2 minutes between refreshes!'))) 170 | 171 | 172 | def add_city(row, city, self=None): 173 | cities = global_variables.get_saved_cities() 174 | if city not in cities: 175 | cities.append(city) 176 | global_variables.set_saved_cities(cities) 177 | constants.app.add_city(False, city) 178 | else: 179 | return 180 | if self != None: 181 | city_num = 0 182 | actions.switch_search(None, self.locations_stack) 183 | actions.load_preferences_saved_cities(self, True, city_num) 184 | 185 | def switch_search(button, stack, names=['locations','search']): 186 | name = names[names.index(stack.get_visible_child_name())] 187 | child = not bool(names.index(name)) 188 | stack.set_visible_child(stack.get_child_by_name(names[int(child)])) 189 | 190 | def switch_day(combobox, stack, self): 191 | stack.set_visible_child(stack.get_child_by_name(combobox.get_active_text())) 192 | if(global_variables.get_use_dyn_bg()): 193 | constants.app.set_css_classes(constants.days_css_classes[global_variables.get_saved_cities().index(self.city)][0][constants.day_names.index(combobox.get_active_text())]) 194 | 195 | def switch_city(combobox): 196 | i = 0 197 | for city in global_variables.get_saved_cities(): 198 | if combobox.get_active_text() == global_variables.get_city_name(city): 199 | constants.root.set_visible_child(constants.root.get_child_by_name(city)) 200 | 201 | def load_preferences_saved_cities(self, reload, city_num): 202 | i = -1 203 | if reload: 204 | for row in row_list: 205 | self.locations.remove(row) 206 | 207 | default = Gtk.Button.new_from_icon_name("emblem-ok-symbolic") 208 | default.set_valign(Gtk.Align.CENTER) 209 | default.set_sensitive(False) 210 | default.set_css_classes(['flat']) 211 | 212 | row_list.clear() 213 | for loc in global_variables.get_saved_cities(): 214 | coords_raw = loc[loc.find("(")+1:loc.find(")")] 215 | 216 | place_name = loc.split('-') 217 | 218 | country_it = place_name[1][:3][1:] 219 | 220 | b = Gtk.Button() 221 | b.set_size_request(30,30) 222 | b.set_valign(Gtk.Align.CENTER) 223 | b.set_icon_name(icon_name='user-trash-symbolic') 224 | b.get_style_context().add_class(class_name='error') 225 | 226 | location = Adw.ActionRow.new() 227 | location.set_title(title=f'{place_name[0]}- {country_it}') 228 | location.set_subtitle(coords_raw) 229 | location.set_activatable(True) 230 | 231 | if i == global_variables.get_default_city()-1: 232 | location.add_suffix(default) 233 | location.add_prefix(b) 234 | self.locations.add(location) 235 | i += 1 236 | row_list.append(location) 237 | b.connect('clicked', self.remove_city, i, location, row_list) 238 | 239 | city_num = 0 240 | for row in row_list: 241 | row.connect("activated", self.set_default_city, city_num, row_list, default) 242 | city_num = city_num + 1 243 | 244 | class converters(): 245 | def convert_timezone(hours): 246 | if hours < 0: 247 | lbl = f'UTC {int(hours)}' 248 | else: 249 | lbl = f'UTC + {int(hours)}' 250 | return lbl 251 | 252 | def convert_timestamp(time): 253 | converted_time = datetime.fromtimestamp(time) 254 | formatted_time = converted_time.strftime("%H:%M") 255 | return formatted_time 256 | 257 | def convert_timestamp_full(time): 258 | converted_time = datetime.fromtimestamp(time) 259 | formatted_time = converted_time.strftime("%D - %H:%M") 260 | return formatted_time 261 | 262 | def convert_day(time): 263 | converted_time = datetime.fromtimestamp(time) 264 | formatted_time = converted_time.strftime("%A") 265 | return formatted_time 266 | 267 | # ---- converts the timezone of the selected city into real time ---- # 268 | def convert_time(offset): 269 | local_offset = offset//3600 270 | now_utc = datetime.now(timezone.utc) 271 | utc_hour = now_utc.hour 272 | local_time = int(utc_hour + local_offset) 273 | 274 | if int(local_time) >= 24: 275 | local_time = "0" + str(int(local_time) - 24) 276 | if(int(local_time) < 10) and int(local_time) > 0: 277 | local_time = "0" + str(int(local_time)) 278 | if(int(local_time) < 10) and int(local_time) < 0: 279 | local_time = '0' + str(local_time).split('-')[-1] 280 | local_full_time = str(local_time) + ":" + datetime.now().strftime("%M") 281 | 282 | return local_full_time 283 | 284 | cities = [] 285 | 286 | class search_city(): 287 | def init_thread(searchbar, preferenesgroup, self, reverse_query): 288 | global last_keydown, load 289 | 290 | search_thread = threading.Thread(target=search_city.get_search_result, args=(searchbar, preferenesgroup, self, reverse_query)) 291 | search_thread.start() 292 | search_thread.join() 293 | 294 | def get_search_result(searchbar, preferenesgroup, self, reverse_query): 295 | global cities 296 | 297 | place_to_search = "" 298 | 299 | if type(reverse_query) == list: 300 | lat = reverse_query[0].get_text() 301 | lon = reverse_query[1].get_text() 302 | 303 | command = f'exec {constants.binary_path} --request=reverse_geocoding --lat={lat} --lon={lon} --locale={constants.system_locale}' 304 | result = subprocess.run(command, shell=True, capture_output=True, text=True) 305 | data = json.loads(result.stdout) 306 | 307 | elif type(reverse_query) == bool: 308 | place_to_search = searchbar.get_text() 309 | command = f'exec {constants.binary_path} --request=geocoding --place_to_search={place_to_search}' 310 | result = subprocess.run(command, shell=True, capture_output=True, text=True) 311 | data = json.loads(result.stdout) 312 | if place_to_search == "": 313 | return 314 | 315 | elif type(reverse_query) == str: 316 | place_to_search = self 317 | command = f'exec {constants.binary_path} --request=geocoding --place_to_search={place_to_search}' 318 | result = subprocess.run(command, shell=True, capture_output=True, text=True) 319 | city = json.loads(result.stdout) 320 | 321 | if len(city) == 0: 322 | location = f'Ferrara - IT (44.8372737; 11.6186451)' 323 | else: 324 | location = f'{city[0]["name"]} - {city[0]["country"]} ({city[0]["lat"]}; {city[0]["lon"]})' 325 | 326 | return location 327 | 328 | if len(cities) != 0: 329 | for every in cities: 330 | preferenesgroup.remove(every) 331 | cities = [] 332 | 333 | for city in data: 334 | name = city['name'] 335 | coords = f'{city["lat"]} {city["lon"]}' 336 | country = city['country'] 337 | try: 338 | state = city['state'] 339 | except: 340 | None 341 | 342 | city_format = f'{name} - {country} ({city["lat"]}; {city["lon"]})' 343 | 344 | new_city = Adw.ActionRow() 345 | new_city.set_title(name) 346 | new_city.set_subtitle(coords) 347 | new_city.set_hexpand(True) 348 | new_city.set_vexpand(True) 349 | new_city.set_activatable(True) 350 | 351 | try: 352 | state_widget = Gtk.Label.new(f'{state}, {country}') 353 | state_widget.set_css_classes(['font_light', 'font_small']) 354 | new_city.add_suffix(Gtk.Label.new(f'{state}, {country}')) 355 | except: 356 | new_city.add_suffix(Gtk.Label.new(f'{country}')) 357 | 358 | # try: 359 | # response = requests.get(f'http://api.openweathermap.org/data/2.5/weather?lat={city["lat"]}&lon={city["lon"]}&units={constants.units}&limit={global_variables.get_max_search_cities()}&appid=72d251b81d30ef572ae667dfe6c4ee1a') 360 | # weather = response.json() 361 | # icon = weather['weather'][0]['icon'] 362 | # icon_widget = Gtk.Image() 363 | # app_style.forecast_icon(icon, 20, icon_widget, constants.icon_loc) 364 | # new_city.add_suffix(icon_widget) 365 | # temp = f'{round(weather["main"]["temp"])} {global_variables.get_temperature_units()}' 366 | # temp_widget = Gtk.Label.new(str(temp)) 367 | # temp_widget.set_css_classes(['font_bold']) 368 | # new_city.add_suffix(temp_widget) 369 | # except: 370 | # None 371 | 372 | new_city.connect('activated', actions.add_city, city_format, self) 373 | 374 | cities.append(new_city) 375 | preferenesgroup.add(new_city) 376 | -------------------------------------------------------------------------------- /Forecast/maps.py: -------------------------------------------------------------------------------- 1 | import gi, time 2 | from .data import * 3 | from gettext import gettext as _ 4 | gi.require_version('Gtk', '4.0') 5 | gi.require_version('WebKit', '6.0') 6 | from gi.repository import Gtk, WebKit 7 | 8 | class maps_page(Gtk.Box): 9 | def __init__(self, app, city): 10 | super().__init__() 11 | 12 | layer = 'clouds_new' 13 | 14 | browser = WebKit.WebView() 15 | # browser.load_uri(f'https://tile.openweathermap.org/map/{layer}/{0}/{0}/{0}.png?appid=') 16 | # browser.load_uri(f'https://weather.salanileo.dev') 17 | 18 | scrolled_window = Gtk.ScrolledWindow() 19 | scrolled_window.set_child(browser) 20 | scrolled_window.set_vexpand(True) 21 | self.append(scrolled_window) 22 | 23 | self.set_orientation(Gtk.Orientation.VERTICAL) 24 | self.set_hexpand(True) 25 | -------------------------------------------------------------------------------- /Forecast/start.py: -------------------------------------------------------------------------------- 1 | import os 2 | from .App import start 3 | 4 | AppId="dev.salaniLeo.forecast" 5 | app_type = None 6 | 7 | if 'FLATPAK_SANDBOX_DIR' in os.environ: 8 | app_type = 'flatpak' 9 | 10 | if 'IS_APP_APPIMAGE' in os.environ: 11 | app_type = 'appimage' 12 | 13 | if 'SNAP' in os.environ: 14 | app_type = 'snap' 15 | 16 | if 'IS_DEBIAN' in os.environ: 17 | app_type = 'debian' 18 | 19 | class main(): 20 | app = start(AppId, app_type) -------------------------------------------------------------------------------- /Forecast/style.py: -------------------------------------------------------------------------------- 1 | import gi, cairo, math 2 | gi.require_version('Gtk', '4.0') 3 | gi.require_version('Adw', '1') 4 | from gi.repository import Gtk 5 | from gettext import gettext as _ 6 | 7 | class app_style(): 8 | def forecast_icon(icon, size, img, loc): 9 | img.set_pixel_size(size) 10 | if icon == "01d": 11 | img.set_from_file(loc + 'weather-clear-large.svg') 12 | elif icon == "02d" or icon == "03d": 13 | img.set_from_file(loc + 'weather-few-clouds-large.svg') 14 | elif icon == "04d": 15 | img.set_from_file(loc + 'weather-overcast-large.svg') 16 | elif icon == "09d": 17 | img.set_from_file(loc + 'weather-showers-scattered-large.svg') 18 | elif icon == "10d": 19 | img.set_from_file(loc + 'weather-showers-large.svg') 20 | elif icon == "11d": 21 | img.set_from_file(loc + 'weather-storm-large.svg') 22 | elif icon == "13d": 23 | img.set_from_file(loc + 'weather-snow-large.svg') 24 | elif icon == "50d": 25 | img.set_from_file(loc + 'weather-fog-large.svg') 26 | # -------- night icons --------- # 27 | elif icon == "01n": 28 | img.set_from_file(loc + 'weather-clear-night-large.svg') 29 | elif icon == "02n" or icon == "03n": 30 | img.set_from_file(loc + 'weather-few-clouds-night-large.svg') 31 | elif icon == "04n": 32 | img.set_from_file(loc + 'weather-overcast-large.svg') 33 | elif icon == "09n": 34 | img.set_from_file(loc + 'weather-showers-scattered-large.svg') 35 | elif icon == "10n": 36 | img.set_from_file(loc + 'weather-showers-large.svg') 37 | elif icon == "11n": 38 | img.set_from_file(loc + 'weather-storm-large.svg') 39 | elif icon == "13n": 40 | img.set_from_file(loc + 'weather-snow-large.svg') 41 | elif icon == "50n": 42 | img.set_from_file(loc + 'weather-fog-large.svg') 43 | 44 | def get_css_bg(icon, night): 45 | if night == "d": 46 | if icon == "01": 47 | css_classes = ["clear_sky"] 48 | elif icon == "02" or icon == "03": 49 | css_classes = ['few_clouds'] 50 | elif icon == "04": 51 | css_classes = ['overcast'] 52 | elif icon == "09": 53 | css_classes = ['showers_scattered'] 54 | elif icon == "10": 55 | css_classes = ['showers_large'] 56 | elif icon == "11": 57 | css_classes = ['storm'] 58 | elif icon == "13": 59 | css_classes = ['snow'] 60 | elif icon == "50": 61 | css_classes = ['fog'] 62 | else: 63 | if icon == "01": 64 | css_classes = ['clear_sky_night'] 65 | elif icon == "02" or icon == "03": 66 | css_classes = ['few_clouds_night'] 67 | elif icon == "04": 68 | css_classes = ['overcast_night'] 69 | elif icon == "09": 70 | css_classes = ['showers_scattered_night'] 71 | elif icon == "10": 72 | css_classes = ['showers_large_night'] 73 | elif icon == "11": 74 | css_classes = ['storm_night'] 75 | elif icon == "13": 76 | css_classes = ['snow_night'] 77 | elif icon == "50": 78 | css_classes = ['fog_night'] 79 | css_classes.append('application_window') 80 | return css_classes 81 | 82 | def get_wttr_description(code): 83 | switcher = { 84 | 230 and 200: (_("Thunderstorm with Light Rain")), 85 | 231 and 201: (_("Thunderstorm with Rain")), 86 | 232 and 202: (_("Thunderstorm with Heavy Rain")), 87 | 210: (_("Light Thunderstorm")), 88 | 211: (_("Thunderstorm")), 89 | 212: (_("Heavy Thunderstorm")), 90 | 221: (_("Ragged Thunderstorm")), 91 | 300: (_("Light Drizzle")), 92 | 301: (_("Drizzle")), 93 | 302: (_("Heavy Drizzle")), 94 | 310: (_("Light Drizzle Rain")), 95 | 311: (_("Drizzle Rain")), 96 | 312: (_("Heavy Drizzle Rain")), 97 | 313: (_("Shower Rain and Drizzle")), 98 | 314: (_("Heavy Rain and Drizzle")), 99 | 321: (_("Shower Drizzle")), 100 | 500: (_("Light Rain")), 101 | 501: (_("Moderate Rain")), 102 | 502: (_("Heavy Rain")), 103 | 503: (_("Very Heavy Rain")), 104 | 504: (_("Extreme Rain")), 105 | 511: (_("Freezing Rain")), 106 | 520: (_("Light Shower Rain")), 107 | 521: (_("Shower Rain")), 108 | 522: (_("Heavy Shower Rain")), 109 | 531: (_("Ragged Shower Rain")), 110 | 600: (_("Light Snow")), 111 | 601: (_("Snow")), 112 | 602: (_("Heavy Snow")), 113 | 611: (_("Sleet")), 114 | 612: (_("Light Shower Sleet")), 115 | 613: (_("Shower Sleet")), 116 | 615: (_("Light Rain and Snow")), 117 | 616: (_("Rain and Snow")), 118 | 620: (_("Light Shower Snow")), 119 | 621: (_("Shower Snow")), 120 | 622: (_("Heavy Shower Snow")), 121 | 701: (_("Mist")), 122 | 711: (_("Smoke")), 123 | 721: (_("Haze")), 124 | 731: (_("Sand/Dust Whirls")), 125 | 741: (_("Fog")), 126 | 751: (_("Sand")), 127 | 761: (_("Dust")), 128 | 762: (_("Volcanic Ash")), 129 | 771: (_("Squalls")), 130 | 781: (_("Tornado")), 131 | 800: (_("Clear Sky")), 132 | 801: (_("Few Clouds")), 133 | 802: (_("Scattered Clouds")), 134 | 803: (_("Broken Clouds")), 135 | 804: (_("Overcast Clouds")) 136 | } 137 | return switcher.get(int(code), ('Not available')) 138 | 139 | def draw_aqi_index(da: Gtk.DrawingArea, context: cairo.Context, width, height, index): 140 | width_index = index*10*2 141 | width_curve_radius = 2.5 142 | 143 | start = width_curve_radius*2 144 | end = width_index-width_curve_radius*2 145 | 146 | fixed_end = width-width_curve_radius*2 147 | 148 | y_top = height/3+width_curve_radius 149 | y_middle = height/2 150 | y_bottom = height-(height/3)-width_curve_radius 151 | 152 | radius_end_pixel = end+width_curve_radius 153 | radius_start_pixel = start-width_curve_radius 154 | 155 | context.set_source_rgba(255,255,255,0.25) 156 | context.move_to(start, y_top) 157 | context.line_to(fixed_end, y_top) 158 | context.stroke() 159 | 160 | color_code = app_style.get_color_gradient(index) 161 | 162 | context.set_source_rgba(color_code['red'], color_code['green'], color_code['blue']) 163 | context.set_line_width(10) 164 | context.move_to(start, y_top) 165 | context.line_to(end, y_top) 166 | context.curve_to(end, y_top, radius_end_pixel, y_middle, end, y_bottom) 167 | context.line_to(start, y_bottom) 168 | context.curve_to(start, y_bottom, radius_start_pixel, y_middle, start+1, y_top) 169 | 170 | context.stroke() 171 | 172 | def get_color_gradient(number): 173 | if not (1 <= number <= 5): 174 | raise ValueError("Number must be between 1 and 5.") 175 | 176 | green_value = int((5 - number) * 255 / 4) 177 | red_value = int((number - 1) * 255 / 4) 178 | color_dict = {'red': red_value, 'green': green_value, 'blue': 0} 179 | return color_dict 180 | 181 | def draw_forecast_temps(da: Gtk.DrawingArea, context: cairo.Context, width, height, intervals, start, end): 182 | if not (min(intervals) <= start <= max(intervals)) or not (min(intervals) <= end <= max(intervals)): 183 | raise ValueError("Start and end values must be within the range of intervals.") 184 | 185 | gradient = cairo.LinearGradient(0, 0, width, 0) 186 | gradient.add_color_stop_rgb(0, 66/255, 135/255, 245/255) # Blue 187 | gradient.add_color_stop_rgb(1, 245/255, 209/255, 66/255) # Yellow 188 | 189 | context.set_source(gradient) 190 | 191 | width = width - (width / 20) 192 | max_val = max(intervals) + 1 193 | min_val = min(intervals) - 1 194 | 195 | width_curve_radius = 2.5 196 | start_pixel = app_style.map_to_pixel(start, min_val, max_val, width) 197 | end_pixel = app_style.map_to_pixel(end, min_val, max_val, width) 198 | 199 | y_top = height / 3 + width_curve_radius 200 | y_middle = height / 2 201 | y_bottom = height - (height / 3) - width_curve_radius 202 | 203 | # min_interval = width / (max_val - min_val) 204 | # if end_pixel - start_pixel < 1: 205 | # end_pixel = start_pixel + min_interval 206 | 207 | radius_end_pixel = end_pixel + width_curve_radius 208 | radius_start_pixel = start_pixel - width_curve_radius 209 | 210 | context.set_line_width(7.5) 211 | context.move_to(start_pixel, y_top) 212 | 213 | if round(start) == round(end): 214 | context.arc(start_pixel, y_middle, width_curve_radius, 0, 2 * math.pi) 215 | elif abs(round(start) - round(end)) == 1: 216 | context.line_to(end_pixel, y_top) 217 | context.curve_to(end_pixel, y_top, radius_end_pixel, y_middle, end_pixel, y_bottom) 218 | context.line_to(start_pixel, y_bottom) 219 | context.curve_to(start_pixel, y_bottom, radius_start_pixel, y_middle, start_pixel + 1, y_top) 220 | else: 221 | context.line_to(end_pixel, y_top) 222 | context.curve_to(end_pixel, y_top, radius_end_pixel, y_middle, end_pixel, y_bottom) 223 | context.line_to(start_pixel, y_bottom) 224 | context.curve_to(start_pixel, y_bottom, radius_start_pixel, y_middle, start_pixel + 1, y_top) 225 | 226 | context.stroke() 227 | 228 | def map_to_pixel(value, min_val, max_val, width): 229 | return ((value - min_val) / ( max_val - min_val)) * width 230 | 231 | def draw_single_temp(da: Gtk.DrawingArea, context: cairo.Context, width, height, temp_to_draw, max_temp, min_temp): 232 | gradient = cairo.LinearGradient(0, 0, width, 0) 233 | gradient.add_color_stop_rgb(0, 66/255, 135/255, 245/255) 234 | gradient.add_color_stop_rgb(1, 245/255, 209/255, 66/255) 235 | 236 | width=width-(width/25) 237 | 238 | width_curve_radius = 2.5 239 | 240 | temp_pixel = app_style.map_to_pixel(temp_to_draw, min_temp, max_temp, width) 241 | y_middle = height/2 242 | 243 | start = app_style.map_to_pixel(min_temp, min_temp, max_temp, width) 244 | end = app_style.map_to_pixel(max_temp, min_temp, max_temp, width) 245 | 246 | if temp_pixel < 2 * math.pi + width_curve_radius*2: 247 | temp_pixel += 2 * math.pi 248 | elif temp_pixel > 2 * math.pi - width_curve_radius*2: 249 | temp_pixel -= 2 * math.pi 250 | temp_pixel = round(temp_pixel) 251 | 252 | context.set_source_rgba(255,255,255,0.2) 253 | context.set_line_width(3.75) 254 | context.move_to(start,y_middle) 255 | context.line_to(end, y_middle) 256 | context.stroke() 257 | 258 | context.set_source(gradient) 259 | context.set_line_width(7.5) 260 | context.move_to(temp_pixel,y_middle) 261 | context.arc(temp_pixel, y_middle, width_curve_radius, 0, 2 * math.pi) 262 | context.stroke() 263 | 264 | def draw_astral_position(da: Gtk.DrawingArea, context: cairo.Context, width, height, hour): 265 | return 266 | 267 | class Spinner(Gtk.Stack): 268 | def __init__(self, child): 269 | super().__init__() 270 | spinner = Gtk.Spinner.new() 271 | spinner.set_size_request(100, 100) 272 | spinner.start() 273 | spinner_box = Gtk.Box() 274 | spinner_box.append(spinner) 275 | spinner_box.set_halign(Gtk.Align.CENTER) 276 | spinner_box.set_valign(Gtk.Align.CENTER) 277 | self.set_transition_type(Gtk.StackTransitionType.CROSSFADE) 278 | self.add_named(spinner_box, 'spinner') 279 | self.add_named(child, 'weather') 280 | self.set_vexpand(True) 281 | self.set_transition_duration(duration=250) -------------------------------------------------------------------------------- /Forecast/weatherInfo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SalaniLeo/Forecast/1d0c00a3b46282b151e1258fed48d8de8934d7b4/Forecast/weatherInfo -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |

icon Forecast

2 |

Beautiful weather app for Linux

3 |

Here with a complete rework!

4 |

Features 💬

5 |
    6 |
  • Clean UI 🪟
  • 7 |
  • 7 Day forecast 'graph' ☀️
  • 8 |
  • Day hourly forecast ⌛
  • 9 |
  • One week in depth forecast ☔
  • 10 |
  • Choose between Metric or Imperial systems 🌍
  • 11 |
  • ... And more to come! 😃
  • 12 |
13 |

Install ⬇️

14 | download 22 | 23 |

Previews

24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /__init__.py: -------------------------------------------------------------------------------- 1 | import shutil 2 | import os 3 | from pathlib import Path 4 | 5 | gschema_loc = str(Path.home()) + "/.local/glib-2.0/schemas" 6 | current_loc = str(Path.cwd()) 7 | 8 | if(not os.path.exists(gschema_loc)): 9 | os.makedirs(gschema_loc) 10 | shutil.copyfile(current_loc+"/data/dev.salaniLeo.forecast.gschema.xml", gschema_loc+"/dev.salaniLeo.forecast.gschema.xml") 11 | os.system("glib-compile-schemas "+gschema_loc) 12 | os.environ["GSETTINGS_SCHEMA_DIR"] = gschema_loc 13 | 14 | if __name__ == '__main__': 15 | from Forecast import start 16 | -------------------------------------------------------------------------------- /data/dependencies/python3-requests.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "python3-requests", 3 | "buildsystem": "simple", 4 | "build-commands": [ 5 | "pip3 install --verbose --exists-action=i --no-index --find-links=\"file://${PWD}\" --prefix=${FLATPAK_DEST} \"requests\" --no-build-isolation" 6 | ], 7 | "sources": [ 8 | { 9 | "type": "file", 10 | "url": "https://files.pythonhosted.org/packages/9d/19/59961b522e6757f0c9097e4493fa906031b95b3ebe9360b2c3083561a6b4/certifi-2023.5.7-py3-none-any.whl", 11 | "sha256": "c6c2e98f5c7869efca1f8916fed228dd91539f9f1b444c314c06eef02980c716" 12 | }, 13 | { 14 | "type": "file", 15 | "url": "https://files.pythonhosted.org/packages/ff/d7/8d757f8bd45be079d76309248845a04f09619a7b17d6dfc8c9ff6433cac2/charset-normalizer-3.1.0.tar.gz", 16 | "sha256": "34e0a2f9c370eb95597aae63bf85eb5e96826d81e3dcf88b8886012906f509b5" 17 | }, 18 | { 19 | "type": "file", 20 | "url": "https://files.pythonhosted.org/packages/fc/34/3030de6f1370931b9dbb4dad48f6ab1015ab1d32447850b9fc94e60097be/idna-3.4-py3-none-any.whl", 21 | "sha256": "90b77e79eaa3eba6de819a0c442c0b4ceefc341a7a2ab77d7562bf49f425c5c2" 22 | }, 23 | { 24 | "type": "file", 25 | "url": "https://files.pythonhosted.org/packages/96/80/034ffeca15c0f4e01b7b9c6ad0fb704b44e190cde4e757edbd60be404c41/requests-2.30.0-py3-none-any.whl", 26 | "sha256": "10e94cc4f3121ee6da529d358cdaeaff2f1c409cd377dbc72b825852f2f7e294" 27 | }, 28 | { 29 | "type": "file", 30 | "url": "https://files.pythonhosted.org/packages/4b/1d/f8383ef593114755429c307449e7717b87044b3bcd5f7860b89b1f759e34/urllib3-2.0.2-py3-none-any.whl", 31 | "sha256": "d055c2f9d38dc53c808f6fdc8eab7360b6fdbbde02340ed25cfbcd817c62469e" 32 | } 33 | ] 34 | } -------------------------------------------------------------------------------- /data/dev.salaniLeo.forecast.appdata.xml.in: -------------------------------------------------------------------------------- 1 | 2 | 3 | dev.salaniLeo.forecast 4 | Forecast 5 | ⛅ Check the weather! 6 | 7 |

Check the weather with a simple, intuitive and modern app

8 |
9 | SalaniLeo 10 | 11 | SalaniLeo 12 | 13 | dev.salaniLeo.forecast.desktop 14 | forecast 15 | https://forecast.salanileo.dev/ 16 | https://github.com/SalaniLeo/Forecast/issues 17 | https://github.com/SalaniLeo/Forecast 18 | https://github.com/SalaniLeo/Forecast/tree/master/po 19 | CC-BY-SA-3.0 20 | GPL-3.0 21 | 22 | 23 | 24 | 25 | 26 | https://raw.githubusercontent.com/SalaniLeo/Forecast/master/data/images/app1-dark.png 27 | Main window 28 | 29 | 30 | https://raw.githubusercontent.com/SalaniLeo/Forecast/master/data/images/app2-dark.png 31 | Forecast window 32 | 33 | 34 | https://raw.githubusercontent.com/SalaniLeo/Forecast/master/data/images/app3-dark.png 35 | Main window with custom background 36 | 37 | 38 | https://raw.githubusercontent.com/SalaniLeo/Forecast/master/data/images/app4-dark.png 39 | Preferences dialog 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 |

Version 1.1.1

48 |
    49 |
  • Api key is now hidden
  • 50 |
51 |
52 |
53 | 54 | 55 | 56 |

Version 1.1.0

57 |
    58 |
  • Fixed 12 hour bug
  • 59 |
  • Added mobile friendly UI
  • 60 |
  • Fixed week graph
  • 61 |
62 |
63 |
64 | 65 | 66 | 67 |

Version 1.0.0

68 |
    69 |
  • Rewritten from ground up!
  • 70 |
  • Added Forecast up to a week
  • 71 |
  • Added Forecast temperatures graph
  • 72 |
  • Added air quality index
  • 73 |
  • Added Forecast page
  • 74 |
  • You can now add a city with coordinates
  • 75 |
  • And much more...
  • 76 |
77 |
78 |
79 | 80 | 81 | 82 |

Version 0.2.2

83 |
    84 |
  • Complete redesign, see github for more
  • 85 |
  • Added locations page in preferences
  • 86 |
  • Now you can delete locations
  • 87 |
  • Added no network status page
  • 88 |
  • Added reload shortcut
  • 89 |
  • Fixed some bugs
  • 90 |
91 |
92 |
93 | 94 | 95 | 96 |

Version 0.2.1

97 |

Updates:

98 |
    99 |
  • Improved design
  • 100 |
  • Custom api-key option is now more legible
  • 101 |
102 |

Design changes:

103 |
    104 |
  • Added dark text on light backgrounds
  • 105 |
  • Added option to use glass-like background for all elements
  • 106 |
  • Readded local time for selected city
  • 107 |
108 |
109 |
110 | 111 | 112 | 113 |

Version 0.2

114 |

Updates:

115 |
    116 |
  • Improved design
  • 117 |
  • Searching for cities is a lot quicker
  • 118 |
  • Added roadmap on github
  • 119 |
  • Added one minute time pause for refreshing
  • 120 |
121 |

Design changes:

122 |
    123 |
  • Added 5 days forecast
  • 124 |
  • Modified current data label
  • 125 |
  • Added glass effect to 3 hours forecast and wind
  • 126 |
127 |
128 |
129 | 130 | 131 | 132 |

First release

133 |
134 |
135 | 136 |
137 |
138 | 139 | -------------------------------------------------------------------------------- /data/dev.salaniLeo.forecast.desktop.in: -------------------------------------------------------------------------------- 1 | [Desktop Entry] 2 | Name=Forecast 3 | Exec=forecast 4 | Icon=dev.salaniLeo.forecast 5 | Keywords=Weather;Forecast;Temperature; 6 | Comment=Forecast app for GNOME 7 | Terminal=false 8 | Type=Application 9 | Categories=Application;Utility; 10 | StartupNotify=true 11 | -------------------------------------------------------------------------------- /data/dev.salaniLeo.forecast.gschema.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | '' 7 | Stores the users api key 8 | stores the users api key 9 | 10 | 11 | 12 | false 13 | If false uses the default api key 14 | When this is true the app know to use the custom api key 15 | 16 | 17 | 18 | true 19 | Uses a weather based gradient as background 20 | Chooses wether the user wants a gradient for background 21 | 22 | 23 | 24 | [] 25 | List of weather places 26 | Stores all user selected location 27 | 28 | 29 | 30 | 'Metric System, °C - Km/h' 31 | Units 32 | Chooses between the metric and imperial systems of measurement 33 | 34 | 35 | 36 | 24 37 | use 12h or 24h 38 | Chooses between the 12h and the 24h time format 39 | 40 | 41 | 42 | 0 43 | Default weather city 44 | Chooses the default city for the weather 45 | 46 | 47 | 48 | 49 | -------------------------------------------------------------------------------- /data/forecast.gresource.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | style.css 5 | 6 | 7 | -------------------------------------------------------------------------------- /data/gschemas.compiled: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SalaniLeo/Forecast/1d0c00a3b46282b151e1258fed48d8de8934d7b4/data/gschemas.compiled -------------------------------------------------------------------------------- /data/images/app1-dark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SalaniLeo/Forecast/1d0c00a3b46282b151e1258fed48d8de8934d7b4/data/images/app1-dark.png -------------------------------------------------------------------------------- /data/images/app1-light.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SalaniLeo/Forecast/1d0c00a3b46282b151e1258fed48d8de8934d7b4/data/images/app1-light.png -------------------------------------------------------------------------------- /data/images/app2-dark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SalaniLeo/Forecast/1d0c00a3b46282b151e1258fed48d8de8934d7b4/data/images/app2-dark.png -------------------------------------------------------------------------------- /data/images/app2-light.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SalaniLeo/Forecast/1d0c00a3b46282b151e1258fed48d8de8934d7b4/data/images/app2-light.png -------------------------------------------------------------------------------- /data/images/app3-dark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SalaniLeo/Forecast/1d0c00a3b46282b151e1258fed48d8de8934d7b4/data/images/app3-dark.png -------------------------------------------------------------------------------- /data/images/app3-light.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SalaniLeo/Forecast/1d0c00a3b46282b151e1258fed48d8de8934d7b4/data/images/app3-light.png -------------------------------------------------------------------------------- /data/images/app4-dark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SalaniLeo/Forecast/1d0c00a3b46282b151e1258fed48d8de8934d7b4/data/images/app4-dark.png -------------------------------------------------------------------------------- /data/images/app4-light.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SalaniLeo/Forecast/1d0c00a3b46282b151e1258fed48d8de8934d7b4/data/images/app4-light.png -------------------------------------------------------------------------------- /data/meson.build: -------------------------------------------------------------------------------- 1 | desktop_file = i18n.merge_file( 2 | input: 'dev.salaniLeo.forecast.desktop.in', 3 | output: 'dev.salaniLeo.forecast.desktop', 4 | type: 'desktop', 5 | po_dir: '../po', 6 | install: true, 7 | install_dir: join_paths(get_option('datadir'), 'applications') 8 | ) 9 | 10 | desktop_utils = find_program('desktop-file-validate', required: false) 11 | if desktop_utils.found() 12 | test('Validate desktop file', desktop_utils, args: [desktop_file]) 13 | endif 14 | 15 | appstream_file = i18n.merge_file( 16 | input: 'dev.salaniLeo.forecast.appdata.xml.in', 17 | output: 'dev.salaniLeo.forecast.appdata.xml', 18 | po_dir: '../po', 19 | install: true, 20 | install_dir: join_paths(get_option('datadir'), 'appdata') 21 | ) 22 | 23 | appstream_util = find_program('appstream-util', required: false) 24 | if appstream_util.found() 25 | test('Validate appstream file', appstream_util, args: ['validate', appstream_file]) 26 | endif 27 | 28 | install_data('dev.salaniLeo.forecast.gschema.xml', 29 | install_dir: join_paths(get_option('datadir'), 'glib-2.0/schemas') 30 | ) 31 | 32 | compile_schemas = find_program('glib-compile-schemas', required: false) 33 | if compile_schemas.found() 34 | test('Validate schema file', 35 | compile_schemas, 36 | args: ['--strict', '--dry-run', meson.current_source_dir()]) 37 | endif 38 | 39 | gnome.compile_resources('forecast', 40 | 'forecast.gresource.xml', 41 | gresource_bundle: true, 42 | install: true, 43 | install_dir: pkgdatadir, 44 | ) 45 | 46 | python = import('python') 47 | py3 = python.find_installation('python3') 48 | app_install_dir = py3.get_install_dir() 49 | install_data( 50 | 'style.css', 51 | install_dir: join_paths(app_install_dir, 'Forecast/data') 52 | ) 53 | -------------------------------------------------------------------------------- /data/status/humidity.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /data/status/info-symbolic.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /data/status/temperature-symbolic.svg: -------------------------------------------------------------------------------- 1 | 2 | 17 | 19 | 20 | 22 | image/svg+xml 23 | 25 | 26 | 27 | 28 | 30 | 50 | 56 | 57 | -------------------------------------------------------------------------------- /data/status/weather-clear-large.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /data/status/weather-clear-night-large.svg: -------------------------------------------------------------------------------- 1 | 2 | 17 | 19 | 20 | 22 | image/svg+xml 23 | 25 | 26 | 27 | 28 | 42 | 44 | 53 | 55 | 59 | 63 | 67 | 68 | 69 | 72 | 76 | 80 | 84 | 85 | 93 | 96 | 100 | 105 | 106 | 113 | 119 | 123 | 124 | 126 | 129 | 133 | 134 | 135 | 138 | 142 | 147 | 148 | 155 | 157 | 160 | 161 | 169 | 176 | 178 | 181 | 185 | 186 | 187 | 194 | 196 | 199 | 200 | 204 | 208 | 212 | 217 | 221 | 225 | 226 | 230 | 234 | 238 | 243 | 247 | 251 | 252 | 257 | 262 | 267 | 268 | -------------------------------------------------------------------------------- /data/status/weather-clear-night-small.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /data/status/weather-clear-small.svg: -------------------------------------------------------------------------------- 1 | 2 | 16 | 18 | 19 | 21 | image/svg+xml 22 | 24 | 25 | 26 | 27 | 29 | 49 | 51 | 59 | 63 | 64 | 65 | -------------------------------------------------------------------------------- /data/status/weather-few-clouds-large.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /data/status/weather-few-clouds-night-large.svg: -------------------------------------------------------------------------------- 1 | 2 | 17 | 19 | 20 | 22 | image/svg+xml 23 | 25 | 26 | 27 | 28 | 42 | 44 | 46 | 50 | 54 | 58 | 62 | 66 | 70 | 71 | 73 | 77 | 81 | 85 | 86 | 94 | 102 | 106 | 110 | 111 | 120 | 121 | 124 | 128 | 132 | 136 | 137 | 145 | 148 | 152 | 157 | 158 | 165 | 171 | 175 | 176 | 178 | 181 | 185 | 186 | 187 | 190 | 194 | 199 | 200 | 207 | 209 | 212 | 213 | 221 | 228 | 230 | 233 | 237 | 238 | 239 | 246 | 248 | 251 | 252 | 256 | 260 | 264 | 269 | 273 | 277 | 278 | 282 | 286 | 291 | 296 | 301 | 305 | 309 | 314 | 318 | 322 | 323 | 328 | 332 | 337 | 338 | -------------------------------------------------------------------------------- /data/status/weather-few-clouds-night-small.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /data/status/weather-few-clouds-small.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /data/status/weather-fog-large.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /data/status/weather-fog-small.svg: -------------------------------------------------------------------------------- 1 | 2 | 16 | 18 | 19 | 21 | image/svg+xml 22 | 24 | 25 | 26 | 27 | 29 | 49 | 51 | 61 | 62 | 63 | -------------------------------------------------------------------------------- /data/status/weather-hourly-symbolic.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /data/status/weather-overcast-large.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /data/status/weather-overcast-small.svg: -------------------------------------------------------------------------------- 1 | 2 | 16 | 18 | 19 | 21 | image/svg+xml 22 | 24 | 25 | 26 | 27 | 29 | 49 | 51 | 56 | 61 | 62 | 63 | -------------------------------------------------------------------------------- /data/status/weather-severe-alert-large.svg: -------------------------------------------------------------------------------- 1 | 2 | 17 | 19 | 20 | 22 | image/svg+xml 23 | 25 | 26 | 27 | 28 | 43 | 45 | 53 | 55 | 59 | 63 | 67 | 71 | 75 | 79 | 83 | 87 | 88 | 98 | 101 | 105 | 109 | 113 | 117 | 121 | 125 | 129 | 130 | 140 | 141 | 147 | 152 | 157 | 162 | 163 | -------------------------------------------------------------------------------- /data/status/weather-severe-alert-small.svg: -------------------------------------------------------------------------------- 1 | 2 | 16 | 18 | 19 | 21 | image/svg+xml 22 | 24 | 25 | 26 | 27 | 29 | 49 | 51 | 58 | 66 | 67 | 68 | -------------------------------------------------------------------------------- /data/status/weather-showers-large.svg: -------------------------------------------------------------------------------- 1 | 2 | 17 | 19 | 20 | 22 | image/svg+xml 23 | 25 | 26 | 27 | 28 | 42 | 44 | 47 | 51 | 55 | 59 | 63 | 67 | 71 | 72 | 74 | 78 | 82 | 86 | 90 | 94 | 98 | 99 | 107 | 116 | 117 | 122 | 128 | 133 | 139 | 144 | 150 | 155 | 161 | 166 | 172 | 177 | 178 | 183 | 188 | 189 | -------------------------------------------------------------------------------- /data/status/weather-showers-scattered-large.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /data/status/weather-showers-scattered-small.svg: -------------------------------------------------------------------------------- 1 | 2 | 16 | 18 | 19 | 21 | image/svg+xml 22 | 24 | 25 | 26 | 27 | 29 | 50 | 55 | 59 | 60 | -------------------------------------------------------------------------------- /data/status/weather-showers-small.svg: -------------------------------------------------------------------------------- 1 | 2 | 16 | 18 | 19 | 21 | image/svg+xml 22 | 24 | 25 | 26 | 27 | 29 | 49 | 51 | 56 | 63 | 64 | 65 | -------------------------------------------------------------------------------- /data/status/weather-snow-large.svg: -------------------------------------------------------------------------------- 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 | -------------------------------------------------------------------------------- /data/status/weather-snow-small.svg: -------------------------------------------------------------------------------- 1 | 2 | 17 | 19 | 20 | 22 | image/svg+xml 23 | 25 | 26 | 27 | 28 | 30 | 50 | 52 | 62 | 70 | 78 | 79 | 80 | -------------------------------------------------------------------------------- /data/status/weather-storm-small.svg: -------------------------------------------------------------------------------- 1 | 2 | 16 | 18 | 19 | 21 | image/svg+xml 22 | 24 | 25 | 26 | 27 | 29 | 49 | 51 | 56 | 63 | 64 | 65 | -------------------------------------------------------------------------------- /data/status/weather-tornado-large.svg: -------------------------------------------------------------------------------- 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 | -------------------------------------------------------------------------------- /data/status/weather-tornado-small.svg: -------------------------------------------------------------------------------- 1 | 2 | 16 | 18 | 19 | 21 | image/svg+xml 22 | 24 | 25 | 26 | 27 | 29 | 49 | 51 | 60 | 61 | 62 | -------------------------------------------------------------------------------- /data/status/weather-windy-large.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /data/status/weather-windy-small.svg: -------------------------------------------------------------------------------- 1 | 2 | 16 | 18 | 19 | 21 | image/svg+xml 22 | 24 | 25 | 26 | 27 | 29 | 49 | 51 | 56 | 62 | 67 | 73 | 78 | 84 | 85 | 86 | -------------------------------------------------------------------------------- /data/style.css: -------------------------------------------------------------------------------- 1 | .glass{ 2 | border-radius: 7.5px; 3 | background-color: rgba(255, 255, 255, 0.2); 4 | } 5 | .flat{ 6 | outline: none; 7 | border: none; 8 | box-shadow: none; 9 | } 10 | .font_big{ 11 | font-size: 25px; 12 | font-weight: 900; 13 | } 14 | .title_box{ 15 | padding: 10px; 16 | } 17 | .font_medium{ 18 | font-size: 18px; 19 | font-weight: 600; 20 | } 21 | .font_bold{ 22 | font-weight: 600; 23 | } 24 | .font_small{ 25 | font-size: 14px; 26 | } 27 | .font_light{ 28 | opacity: 0.75; 29 | } 30 | .font_app_title{ 31 | font-size: 16px; 32 | font-weight: 550; 33 | } 34 | 35 | .application_window{ 36 | box-shadow: 0px 1px 6px rgba(0,0,0,0.3), 37 | 0px 2px 12px rgba(0,0,0,0.15), 38 | 0px 6px 32px rgba(0,0,0,0.1); 39 | border-radius:13px; 40 | border : 1px solid rgba(100, 100, 100,.3); 41 | } 42 | 43 | /* ------------- day --------------- */ 44 | 45 | .clear_sky, .few_clouds { 46 | 47 | background: linear-gradient(127deg, alpha(rgb(207, 208, 189), 1), alpha(rgb(0, 134, 218), 0) 100%), 48 | linear-gradient(217deg, alpha(rgb(207, 208, 189), 1), alpha(rgb(0, 134, 218), 1) 100%), 49 | linear-gradient(336deg, alpha(rgb(207, 208, 189), 1), alpha(rgb(0, 134, 218), 1) 100%); 50 | 51 | } .overcast, .showers_scattered{ 52 | 53 | background: linear-gradient(127deg, alpha(rgb(185, 185, 185), 1), alpha(rgb(0, 134, 218), 0) 100%), 54 | linear-gradient(217deg, alpha(rgb(185, 185, 185), 1), alpha(rgb(0, 134, 218), 1) 100%), 55 | linear-gradient(336deg, alpha(rgb(185, 185, 185), 1), alpha(rgb(0, 134, 218), 1) 100%); 56 | 57 | } .showers_large { 58 | 59 | background: linear-gradient(127deg, alpha(rgb(134, 137, 154), 1), alpha(rgb(134, 137, 154), 0) 100%), 60 | linear-gradient(217deg, alpha(rgb(134, 137, 154), 1), alpha(rgb(0, 134, 218), 1) 100%), 61 | linear-gradient(336deg, alpha(rgb(134, 137, 154), 1), alpha(rgb(0, 134, 218), 1) 100%); 62 | 63 | } .storm{ 64 | 65 | background: linear-gradient(127deg, alpha(rgb(117, 117, 102), 1), alpha(rgb(134, 137, 154), 0) 100%), 66 | linear-gradient(217deg, alpha(rgb(117, 117, 102), 1), alpha(rgb(14, 83, 126), 1) 100%), 67 | linear-gradient(336deg, alpha(rgb(117, 117, 102), 1), alpha(rgb(14, 83, 126), 1) 100%); 68 | 69 | } .snow{ 70 | 71 | background: linear-gradient(127deg, alpha(rgb(208, 209, 217), 1), alpha(rgb(134, 137, 154), 0) 100%), 72 | linear-gradient(217deg, alpha(rgb(208, 209, 217), 1), alpha(rgb(89, 89, 89), 1) 100%), 73 | linear-gradient(336deg, alpha(rgb(103, 103, 103), 1), alpha(rgb(118, 118, 118), 1) 100%); 74 | 75 | } .fog{ 76 | 77 | background: linear-gradient(127deg, alpha(rgb(126, 126, 126), 1), alpha(rgb(126, 126, 126), 1) 100%), 78 | linear-gradient(217deg, alpha(rgb(126, 126, 126), 1), alpha(rgb(126, 126, 126), 1) 100%), 79 | linear-gradient(336deg, alpha(rgb(126, 126, 126), 1), alpha(rgb(126, 126, 126), 1) 100%); 80 | 81 | } 82 | 83 | /* ------------- night --------------- */ 84 | 85 | .clear_sky_night, .few_clouds_night{ 86 | 87 | background: linear-gradient(127deg, alpha(rgb(0, 20, 33), 1), alpha(rgb(3, 0, 41), 0) 100%), 88 | linear-gradient(217deg, alpha(rgb(0, 15, 20), 1), alpha(rgb(3, 0, 41), 1) 100%), 89 | linear-gradient(336deg, alpha(rgb(0, 15, 20), 1), alpha(rgb(3, 0, 41), 1) 100%); 90 | 91 | 92 | } .overcast_night, .showers_scattered_night { 93 | 94 | background: linear-gradient(127deg, alpha(rgb(0, 34, 45), 1), alpha(rgb(3, 0, 41), 0) 100%), 95 | linear-gradient(217deg, alpha(rgb(0, 15, 20), 1), alpha(rgb(3, 0, 41), 1) 100%), 96 | linear-gradient(336deg, alpha(rgb(0, 15, 20), 1), alpha(rgb(3, 0, 41), 1) 100%); 97 | 98 | } .showers_large_night { 99 | 100 | background: linear-gradient(127deg, alpha(rgb(2, 27, 35), 1), alpha(rgb(3, 0, 41), 0) 100%), 101 | linear-gradient(217deg, alpha(rgb(31, 31, 31), 1), alpha(rgb(3, 0, 41), 1) 100%), 102 | linear-gradient(336deg, alpha(rgb(31, 31, 31), 1), alpha(rgb(3, 0, 41), 1) 100%); 103 | 104 | } .storm_night{ 105 | 106 | background: linear-gradient(127deg, alpha(rgb(33, 35, 2), 1), alpha(rgb(3, 0, 41), 0) 100%), 107 | linear-gradient(217deg, alpha(rgb(31, 31, 31), 1), alpha(rgb(3, 0, 41), 1) 100%), 108 | linear-gradient(336deg, alpha(rgb(31, 31, 31), 1), alpha(rgb(3, 0, 41), 1) 100%); 109 | 110 | } .snow_night{ 111 | 112 | background: linear-gradient(127deg, alpha(rgb(208, 209, 217), 1), alpha(rgb(208, 209, 217), 0) 100%), 113 | linear-gradient(217deg, alpha(rgb(208, 209, 217), 1), alpha(rgb(211, 238, 255), 1) 100%), 114 | linear-gradient(336deg, alpha(rgb(208, 209, 217), 1), alpha(rgb(181, 187, 190), 1) 100%); 115 | 116 | } .fog_night{ 117 | 118 | background: linear-gradient(127deg, alpha(rgb(0, 20, 33), 1), alpha(rgb(3, 0, 41), 0) 100%), 119 | linear-gradient(217deg, alpha(rgb(0, 15, 20), 1), alpha(rgb(47, 47, 47), 1) 100%), 120 | linear-gradient(336deg, alpha(rgb(0, 15, 20), 1), alpha(rgb(3, 0, 41), 1) 100%); 121 | } 122 | -------------------------------------------------------------------------------- /dev.salaniLeo.forecast.json: -------------------------------------------------------------------------------- 1 | { 2 | "app-id": "dev.salaniLeo.forecast", 3 | "runtime": "org.gnome.Platform", 4 | "runtime-version": "46", 5 | "sdk": "org.gnome.Sdk", 6 | "command": "forecast", 7 | "finish-args": [ 8 | "--share=network", 9 | "--share=ipc", 10 | "--socket=fallback-x11", 11 | "--socket=wayland", 12 | "--device=dri" 13 | ], 14 | "cleanup": [ 15 | "/include", 16 | "/lib/pkgconfig", 17 | "/share/pkgconfig", 18 | "/share/gtk-doc", 19 | "*.la", 20 | "*.a" 21 | ], 22 | "modules": [ 23 | "data/dependencies/python3-requests.json", 24 | { 25 | "name": "forecast", 26 | "buildsystem": "meson", 27 | "sources": [ 28 | { 29 | "type" : "git", 30 | "url" : "https://github.com/SalaniLeo/Forecast", 31 | "tag" : "0.2", 32 | "commit" : "89c9e4745b0022c7f6c1f36a8d4bebdb345f4d70" 33 | } 34 | ], 35 | "dependencies": [ 36 | "python3-requests" 37 | ] 38 | } 39 | ] 40 | } -------------------------------------------------------------------------------- /forecast.in: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | # forecast.in 4 | # 5 | # Copyright 2023 forecast 6 | # 7 | # This program is free software: you can redistribute it and/or modify 8 | # it under the terms of the GNU General Public License as published by 9 | # the Free Software Foundation, either version 3 of the License, or 10 | # (at your option) any later version. 11 | # 12 | # This program is distributed in the hope that it will be useful, 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | # GNU General Public License for more details. 16 | # 17 | # You should have received a copy of the GNU General Public License 18 | # along with this program. If not, see . 19 | # 20 | # SPDX-License-Identifier: GPL-3.0-or-later 21 | 22 | import os 23 | import sys 24 | import signal 25 | import locale 26 | import gettext 27 | 28 | VERSION = '@VERSION@' 29 | pkgdatadir = '@pkgdatadir@' 30 | localedir = '@localedir@' 31 | 32 | sys.path.insert(1, pkgdatadir) 33 | signal.signal(signal.SIGINT, signal.SIG_DFL) 34 | locale.bindtextdomain("forecast", localedir) 35 | locale.textdomain("forecast") 36 | gettext.bindtextdomain("forecast", localedir) 37 | gettext.textdomain("forecast") 38 | 39 | if __name__ == '__main__': 40 | import gi 41 | 42 | from gi.repository import Gio 43 | resource = Gio.Resource.load(os.path.join(pkgdatadir, 'forecast.gresource')) 44 | resource._register() 45 | 46 | from Forecast import start 47 | -------------------------------------------------------------------------------- /meson.build: -------------------------------------------------------------------------------- 1 | project('forecast', 2 | version: '1.0.0', 3 | meson_version: '>= 0.59.0', 4 | default_options: [ 'warning_level=2', 'werror=false', 'prefix=/app'], 5 | ) 6 | 7 | APPLICATION_ID = 'dev.salaniLeo.forecast@0@'.format('') 8 | PKGDATA_DIR = join_paths(get_option('prefix'), get_option('datadir'), APPLICATION_ID) 9 | PKGLIB_DIR = join_paths(get_option('prefix'), get_option('libdir'), APPLICATION_ID) 10 | 11 | i18n = import('i18n') 12 | gnome = import('gnome') 13 | 14 | pkgdatadir = join_paths(get_option('prefix'), get_option('datadir'), meson.project_name()) 15 | moduledir = join_paths(pkgdatadir, 'forecast') 16 | 17 | subdir('data') 18 | subdir('po') 19 | subdir('share/icons') 20 | 21 | python = import('python') 22 | 23 | conf = configuration_data() 24 | conf.set('PYTHON', python.find_installation('python3').full_path()) 25 | conf.set('VERSION', meson.project_version()) 26 | conf.set('localedir', join_paths(get_option('prefix'), get_option('localedir'))) 27 | conf.set('pkgdatadir', pkgdatadir) 28 | 29 | bindir = join_paths(get_option('prefix'), 'bin') 30 | 31 | py3 = python.find_installation('python3') 32 | app_install_dir = py3.get_install_dir() 33 | 34 | configure_file( 35 | input: 'forecast.in', 36 | output: 'forecast', 37 | configuration: conf, 38 | install: true, 39 | install_dir: bindir 40 | ) 41 | 42 | install_subdir('data/status', install_dir: join_paths(get_option('prefix'), 'share/icons/hicolor/scalable')) 43 | install_subdir('Forecast', install_dir: app_install_dir) 44 | install_subdir('data/status', install_dir: join_paths(app_install_dir, 'Forecast/data')) 45 | 46 | gnome.post_install( 47 | glib_compile_schemas: true, 48 | update_desktop_database: true, 49 | ) 50 | -------------------------------------------------------------------------------- /po/Forecast.pot: -------------------------------------------------------------------------------- 1 | # SOME DESCRIPTIVE TITLE. 2 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER 3 | # This file is distributed under the same license as the PACKAGE package. 4 | # FIRST AUTHOR , YEAR. 5 | # 6 | #, fuzzy 7 | msgid "" 8 | msgstr "" 9 | "Project-Id-Version: PACKAGE VERSION\n" 10 | "Report-Msgid-Bugs-To: \n" 11 | "POT-Creation-Date: 2024-09-04 14:14+0200\n" 12 | "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" 13 | "Last-Translator: FULL NAME \n" 14 | "Language-Team: LANGUAGE \n" 15 | "Language: \n" 16 | "MIME-Version: 1.0\n" 17 | "Content-Type: text/plain; charset=UTF-8\n" 18 | "Content-Transfer-Encoding: 8bit\n" 19 | 20 | #: Forecast/style.py:84 21 | msgid "Thunderstorm with Light Rain" 22 | msgstr "" 23 | 24 | #: Forecast/style.py:85 25 | msgid "Thunderstorm with Rain" 26 | msgstr "" 27 | 28 | #: Forecast/style.py:86 29 | msgid "Thunderstorm with Heavy Rain" 30 | msgstr "" 31 | 32 | #: Forecast/style.py:87 33 | msgid "Light Thunderstorm" 34 | msgstr "" 35 | 36 | #: Forecast/style.py:88 37 | msgid "Thunderstorm" 38 | msgstr "" 39 | 40 | #: Forecast/style.py:89 41 | msgid "Heavy Thunderstorm" 42 | msgstr "" 43 | 44 | #: Forecast/style.py:90 45 | msgid "Ragged Thunderstorm" 46 | msgstr "" 47 | 48 | #: Forecast/style.py:91 49 | msgid "Light Drizzle" 50 | msgstr "" 51 | 52 | #: Forecast/style.py:92 53 | msgid "Drizzle" 54 | msgstr "" 55 | 56 | #: Forecast/style.py:93 57 | msgid "Heavy Drizzle" 58 | msgstr "" 59 | 60 | #: Forecast/style.py:94 61 | msgid "Light Drizzle Rain" 62 | msgstr "" 63 | 64 | #: Forecast/style.py:95 65 | msgid "Drizzle Rain" 66 | msgstr "" 67 | 68 | #: Forecast/style.py:96 69 | msgid "Heavy Drizzle Rain" 70 | msgstr "" 71 | 72 | #: Forecast/style.py:97 73 | msgid "Shower Rain and Drizzle" 74 | msgstr "" 75 | 76 | #: Forecast/style.py:98 77 | msgid "Heavy Rain and Drizzle" 78 | msgstr "" 79 | 80 | #: Forecast/style.py:99 81 | msgid "Shower Drizzle" 82 | msgstr "" 83 | 84 | #: Forecast/style.py:100 85 | msgid "Light Rain" 86 | msgstr "" 87 | 88 | #: Forecast/style.py:101 89 | msgid "Moderate Rain" 90 | msgstr "" 91 | 92 | #: Forecast/style.py:102 93 | msgid "Heavy Rain" 94 | msgstr "" 95 | 96 | #: Forecast/style.py:103 97 | msgid "Very Heavy Rain" 98 | msgstr "" 99 | 100 | #: Forecast/style.py:104 101 | msgid "Extreme Rain" 102 | msgstr "" 103 | 104 | #: Forecast/style.py:105 105 | msgid "Freezing Rain" 106 | msgstr "" 107 | 108 | #: Forecast/style.py:106 109 | msgid "Light Shower Rain" 110 | msgstr "" 111 | 112 | #: Forecast/style.py:107 113 | msgid "Shower Rain" 114 | msgstr "" 115 | 116 | #: Forecast/style.py:108 117 | msgid "Heavy Shower Rain" 118 | msgstr "" 119 | 120 | #: Forecast/style.py:109 121 | msgid "Ragged Shower Rain" 122 | msgstr "" 123 | 124 | #: Forecast/style.py:110 125 | msgid "Light Snow" 126 | msgstr "" 127 | 128 | #: Forecast/style.py:111 129 | msgid "Snow" 130 | msgstr "" 131 | 132 | #: Forecast/style.py:112 133 | msgid "Heavy Snow" 134 | msgstr "" 135 | 136 | #: Forecast/style.py:113 137 | msgid "Sleet" 138 | msgstr "" 139 | 140 | #: Forecast/style.py:114 141 | msgid "Light Shower Sleet" 142 | msgstr "" 143 | 144 | #: Forecast/style.py:115 145 | msgid "Shower Sleet" 146 | msgstr "" 147 | 148 | #: Forecast/style.py:116 149 | msgid "Light Rain and Snow" 150 | msgstr "" 151 | 152 | #: Forecast/style.py:117 153 | msgid "Rain and Snow" 154 | msgstr "" 155 | 156 | #: Forecast/style.py:118 157 | msgid "Light Shower Snow" 158 | msgstr "" 159 | 160 | #: Forecast/style.py:119 161 | msgid "Shower Snow" 162 | msgstr "" 163 | 164 | #: Forecast/style.py:120 165 | msgid "Heavy Shower Snow" 166 | msgstr "" 167 | 168 | #: Forecast/style.py:121 169 | msgid "Mist" 170 | msgstr "" 171 | 172 | #: Forecast/style.py:122 173 | msgid "Smoke" 174 | msgstr "" 175 | 176 | #: Forecast/style.py:123 177 | msgid "Haze" 178 | msgstr "" 179 | 180 | #: Forecast/style.py:124 181 | msgid "Sand/Dust Whirls" 182 | msgstr "" 183 | 184 | #: Forecast/style.py:125 185 | msgid "Fog" 186 | msgstr "" 187 | 188 | #: Forecast/style.py:126 189 | msgid "Sand" 190 | msgstr "" 191 | 192 | #: Forecast/style.py:127 193 | msgid "Dust" 194 | msgstr "" 195 | 196 | #: Forecast/style.py:128 197 | msgid "Volcanic Ash" 198 | msgstr "" 199 | 200 | #: Forecast/style.py:129 201 | msgid "Squalls" 202 | msgstr "" 203 | 204 | #: Forecast/style.py:130 205 | msgid "Tornado" 206 | msgstr "" 207 | 208 | #: Forecast/style.py:131 209 | msgid "Clear Sky" 210 | msgstr "" 211 | 212 | #: Forecast/style.py:132 213 | msgid "Few Clouds" 214 | msgstr "" 215 | 216 | #: Forecast/style.py:133 217 | msgid "Scattered Clouds" 218 | msgstr "" 219 | 220 | #: Forecast/style.py:134 221 | msgid "Broken Clouds" 222 | msgstr "" 223 | 224 | #: Forecast/style.py:135 225 | msgid "Overcast Clouds" 226 | msgstr "" 227 | 228 | #: Forecast/App.py:38 Forecast/page.py:64 Forecast/page.py:292 229 | #: Forecast/page.py:341 230 | msgid "Weather" 231 | msgstr "" 232 | 233 | #: Forecast/App.py:43 Forecast/App.py:253 Forecast/App.py:277 234 | msgid "Locations" 235 | msgstr "" 236 | 237 | #: Forecast/App.py:206 Forecast/page.py:65 238 | #: data/dev.salaniLeo.forecast.desktop.in:3 239 | #: data/dev.salaniLeo.forecast.appdata.xml.in:4 240 | #: _build/data/dev.salaniLeo.forecast.appdata.xml:4 241 | #: _build/data/dev.salaniLeo.forecast.appdata.xml:5 242 | msgid "Forecast" 243 | msgstr "" 244 | 245 | #: Forecast/App.py:209 246 | msgid "" 247 | "⛅ Check the weather!.\n" 248 | "Uses openweathermap api" 249 | msgstr "" 250 | 251 | #: Forecast/App.py:230 252 | msgid "Refresh" 253 | msgstr "" 254 | 255 | #: Forecast/App.py:231 Forecast/App.py:243 Forecast/App.py:257 256 | msgid "Preferences" 257 | msgstr "" 258 | 259 | #: Forecast/App.py:232 260 | msgid "About Forecast" 261 | msgstr "" 262 | 263 | #: Forecast/App.py:284 264 | msgid "Units preferences" 265 | msgstr "" 266 | 267 | #: Forecast/App.py:286 268 | msgid "Appearance Preferences" 269 | msgstr "" 270 | 271 | #: Forecast/App.py:298 272 | msgid "Temperature units" 273 | msgstr "" 274 | 275 | #: Forecast/App.py:299 276 | msgid "Select which units to use" 277 | msgstr "" 278 | 279 | #: Forecast/App.py:315 280 | msgid "Time format" 281 | msgstr "" 282 | 283 | #: Forecast/App.py:316 284 | msgid "Select whether to use the 12h or 24h formats" 285 | msgstr "" 286 | 287 | #: Forecast/App.py:322 288 | msgid "Use dynamic background" 289 | msgstr "" 290 | 291 | #: Forecast/App.py:323 292 | msgid "" 293 | "When on, the background changes based on the weather. Restart needed to apply" 294 | msgstr "" 295 | 296 | #: Forecast/App.py:331 297 | msgid "API Preferences" 298 | msgstr "" 299 | 300 | #: Forecast/App.py:343 301 | msgid "Use Personal API Key" 302 | msgstr "" 303 | 304 | #: Forecast/App.py:345 305 | msgid "Choose whether to use default API key or personal key" 306 | msgstr "" 307 | 308 | #: Forecast/App.py:349 309 | msgid "Personal API Key" 310 | msgstr "" 311 | 312 | #: Forecast/App.py:367 Forecast/App.py:372 Forecast/App.py:376 313 | #: Forecast/App.py:388 314 | msgid "Restart needed to apply changes" 315 | msgstr "" 316 | 317 | #: Forecast/App.py:390 318 | msgid "Api key not valid" 319 | msgstr "" 320 | 321 | #: Forecast/App.py:426 322 | msgid "Latitude" 323 | msgstr "" 324 | 325 | #: Forecast/App.py:430 326 | msgid "Longitude" 327 | msgstr "" 328 | 329 | #: Forecast/App.py:459 330 | msgid "Use coordinates" 331 | msgstr "" 332 | 333 | #: Forecast/data.py:12 334 | msgid "Metric System" 335 | msgstr "" 336 | 337 | #: Forecast/data.py:13 338 | msgid "Imperial System" 339 | msgstr "" 340 | 341 | #: Forecast/data.py:40 342 | msgid "Good" 343 | msgstr "" 344 | 345 | #: Forecast/data.py:41 346 | msgid "Fair" 347 | msgstr "" 348 | 349 | #: Forecast/data.py:42 350 | msgid "Moderate" 351 | msgstr "" 352 | 353 | #: Forecast/data.py:43 354 | msgid "Poor" 355 | msgstr "" 356 | 357 | #: Forecast/data.py:44 358 | msgid "Very Poor" 359 | msgstr "" 360 | 361 | #: Forecast/data.py:51 362 | msgid "Low" 363 | msgstr "" 364 | 365 | #: Forecast/data.py:53 366 | msgid "Seek shade during midday hours!" 367 | msgstr "" 368 | 369 | #: Forecast/data.py:55 370 | msgid "Avoid being outside during midday hours!" 371 | msgstr "" 372 | 373 | #: Forecast/data.py:57 374 | msgid "Invalid UV index input." 375 | msgstr "" 376 | 377 | #: Forecast/data.py:61 378 | msgid "N" 379 | msgstr "" 380 | 381 | #: Forecast/data.py:61 382 | msgid "NNE" 383 | msgstr "" 384 | 385 | #: Forecast/data.py:61 386 | msgid "NE" 387 | msgstr "" 388 | 389 | #: Forecast/data.py:61 390 | msgid "ENE" 391 | msgstr "" 392 | 393 | #: Forecast/data.py:61 394 | msgid "E" 395 | msgstr "" 396 | 397 | #: Forecast/data.py:61 398 | msgid "ESE" 399 | msgstr "" 400 | 401 | #: Forecast/data.py:61 402 | msgid "SE" 403 | msgstr "" 404 | 405 | #: Forecast/data.py:61 406 | msgid "SSE" 407 | msgstr "" 408 | 409 | #: Forecast/data.py:62 410 | msgid "S" 411 | msgstr "" 412 | 413 | #: Forecast/data.py:62 414 | msgid "SSW" 415 | msgstr "" 416 | 417 | #: Forecast/data.py:62 418 | msgid "SW" 419 | msgstr "" 420 | 421 | #: Forecast/data.py:62 422 | msgid "WSW" 423 | msgstr "" 424 | 425 | #: Forecast/data.py:62 426 | msgid "W" 427 | msgstr "" 428 | 429 | #: Forecast/data.py:62 430 | msgid "WNW" 431 | msgstr "" 432 | 433 | #: Forecast/data.py:62 434 | msgid "NW" 435 | msgstr "" 436 | 437 | #: Forecast/data.py:62 438 | msgid "NNW" 439 | msgstr "" 440 | 441 | #: Forecast/data.py:169 442 | msgid "Wait at least 2 minutes between refreshes!" 443 | msgstr "" 444 | 445 | #: Forecast/page.py:32 446 | msgid "Exceeded limit of api calls :(" 447 | msgstr "" 448 | 449 | #: Forecast/page.py:34 450 | msgid "Could not retrieve weather data" 451 | msgstr "" 452 | 453 | #: Forecast/page.py:159 454 | #, python-brace-format 455 | msgid "- Feels like {0}{1}" 456 | msgstr "" 457 | 458 | #: Forecast/page.py:202 459 | msgid "Alerts" 460 | msgstr "" 461 | 462 | #: Forecast/page.py:223 Forecast/page.py:304 Forecast/page.py:786 463 | msgid "Conditions" 464 | msgstr "" 465 | 466 | #: Forecast/page.py:242 Forecast/page.py:319 467 | msgid "Wind" 468 | msgstr "" 469 | 470 | #: Forecast/page.py:243 Forecast/page.py:320 Forecast/page.py:321 471 | msgid "Pressure" 472 | msgstr "" 473 | 474 | #: Forecast/page.py:244 Forecast/page.py:781 475 | msgid "Humidity" 476 | msgstr "" 477 | 478 | #: Forecast/page.py:245 Forecast/page.py:322 479 | msgid "Visibility" 480 | msgstr "" 481 | 482 | #: Forecast/page.py:246 Forecast/page.py:824 483 | msgid "Sunrise" 484 | msgstr "" 485 | 486 | #: Forecast/page.py:247 Forecast/page.py:816 487 | msgid "Sunset" 488 | msgstr "" 489 | 490 | #: Forecast/page.py:248 491 | msgid "AQI" 492 | msgstr "" 493 | 494 | #: Forecast/page.py:318 495 | msgid "Feels Like" 496 | msgstr "" 497 | 498 | #: Forecast/page.py:354 499 | msgid "Today" 500 | msgstr "" 501 | 502 | #: Forecast/page.py:404 503 | msgid "Weekly forecast" 504 | msgstr "" 505 | 506 | #: Forecast/page.py:491 507 | msgid "Pollution" 508 | msgstr "" 509 | 510 | #: Forecast/page.py:496 511 | msgid "Details" 512 | msgstr "" 513 | 514 | #: Forecast/page.py:711 515 | msgid "Night" 516 | msgstr "" 517 | 518 | #: Forecast/page.py:725 519 | msgid "Evening" 520 | msgstr "" 521 | 522 | #: Forecast/page.py:739 523 | msgid "Morning" 524 | msgstr "" 525 | 526 | #: Forecast/page.py:753 527 | msgid "Afternoon" 528 | msgstr "" 529 | 530 | #: Forecast/page.py:766 531 | msgid "Temperatures" 532 | msgstr "" 533 | 534 | #: Forecast/page.py:779 535 | msgid "Temperature" 536 | msgstr "" 537 | 538 | #: Forecast/page.py:780 539 | msgid "Wind speed" 540 | msgstr "" 541 | 542 | #: Forecast/page.py:781 Forecast/page.py:782 Forecast/page.py:783 543 | #, python-brace-format 544 | msgid "{0}%" 545 | msgstr "" 546 | 547 | #: Forecast/page.py:782 548 | msgid "Cloudiness" 549 | msgstr "" 550 | 551 | #: Forecast/page.py:783 552 | msgid "Probability of rain" 553 | msgstr "" 554 | 555 | #: Forecast/page.py:784 556 | msgid "UV Index" 557 | msgstr "" 558 | 559 | #: Forecast/page.py:830 560 | msgid "Sun" 561 | msgstr "" 562 | 563 | #: Forecast/page.py:918 564 | msgid "Close" 565 | msgstr "" 566 | 567 | #: data/dev.salaniLeo.forecast.desktop.in:6 568 | msgid "Weather;Forecast;Temperature;" 569 | msgstr "" 570 | 571 | #: data/dev.salaniLeo.forecast.desktop.in:7 572 | msgid "Forecast app for GNOME" 573 | msgstr "" 574 | 575 | #: data/dev.salaniLeo.forecast.gschema.xml:7 576 | msgid "Stores the users api key" 577 | msgstr "" 578 | 579 | #: data/dev.salaniLeo.forecast.gschema.xml:8 580 | msgid "stores the users api key" 581 | msgstr "" 582 | 583 | #: data/dev.salaniLeo.forecast.gschema.xml:13 584 | msgid "If false uses the default api key" 585 | msgstr "" 586 | 587 | #: data/dev.salaniLeo.forecast.gschema.xml:14 588 | msgid "When this is true the app know to use the custom api key" 589 | msgstr "" 590 | 591 | #: data/dev.salaniLeo.forecast.gschema.xml:19 592 | msgid "Uses a weather based gradient as background" 593 | msgstr "" 594 | 595 | #: data/dev.salaniLeo.forecast.gschema.xml:20 596 | msgid "Chooses wether the user wants a gradient for background" 597 | msgstr "" 598 | 599 | #: data/dev.salaniLeo.forecast.gschema.xml:25 600 | msgid "List of weather places" 601 | msgstr "" 602 | 603 | #: data/dev.salaniLeo.forecast.gschema.xml:26 604 | msgid "Stores all user selected location" 605 | msgstr "" 606 | 607 | #: data/dev.salaniLeo.forecast.gschema.xml:31 608 | msgid "Units" 609 | msgstr "" 610 | 611 | #: data/dev.salaniLeo.forecast.gschema.xml:32 612 | msgid "Chooses between the metric and imperial systems of measurement" 613 | msgstr "" 614 | 615 | #: data/dev.salaniLeo.forecast.gschema.xml:37 616 | msgid "use 12h or 24h" 617 | msgstr "" 618 | 619 | #: data/dev.salaniLeo.forecast.gschema.xml:38 620 | msgid "Chooses between the 12h and the 24h time format" 621 | msgstr "" 622 | 623 | #: data/dev.salaniLeo.forecast.gschema.xml:43 624 | msgid "Default weather city" 625 | msgstr "" 626 | 627 | #: data/dev.salaniLeo.forecast.gschema.xml:44 628 | msgid "Chooses the default city for the weather" 629 | msgstr "" 630 | 631 | #: data/dev.salaniLeo.forecast.appdata.xml.in:5 632 | #: _build/data/dev.salaniLeo.forecast.appdata.xml:9 633 | msgid "⛅ Check the weather!" 634 | msgstr "" 635 | 636 | #: data/dev.salaniLeo.forecast.appdata.xml.in:7 637 | #: _build/data/dev.salaniLeo.forecast.appdata.xml:12 638 | msgid "Check the weather with a simple, intuitive and modern app" 639 | msgstr "" 640 | 641 | #: data/dev.salaniLeo.forecast.appdata.xml.in:27 642 | #: _build/data/dev.salaniLeo.forecast.appdata.xml:31 643 | msgid "Main window" 644 | msgstr "" 645 | 646 | #: data/dev.salaniLeo.forecast.appdata.xml.in:31 647 | #: _build/data/dev.salaniLeo.forecast.appdata.xml:37 648 | msgid "Forecast window" 649 | msgstr "" 650 | 651 | #: data/dev.salaniLeo.forecast.appdata.xml.in:35 652 | #: _build/data/dev.salaniLeo.forecast.appdata.xml:43 653 | msgid "Main window with custom background" 654 | msgstr "" 655 | 656 | #: data/dev.salaniLeo.forecast.appdata.xml.in:39 657 | #: _build/data/dev.salaniLeo.forecast.appdata.xml:49 658 | msgid "Preferences dialog" 659 | msgstr "" 660 | 661 | #: _build/data/dev.salaniLeo.forecast.appdata.xml:6 662 | msgid "Hava Tahmini" 663 | msgstr "" 664 | 665 | #: _build/data/dev.salaniLeo.forecast.appdata.xml:7 666 | msgid "Previsão do tempo" 667 | msgstr "" 668 | 669 | #: _build/data/dev.salaniLeo.forecast.appdata.xml:8 670 | msgid "फोरकास्ट" 671 | msgstr "" 672 | 673 | #: _build/data/dev.salaniLeo.forecast.appdata.xml:10 674 | msgid "⛅ Überprüfen Sie den Wetterbericht!" 675 | msgstr "" 676 | 677 | #: _build/data/dev.salaniLeo.forecast.appdata.xml:13 678 | msgid "" 679 | "Überprüfen Sie den Wetterbericht mit Hilfe einer simplen, intuitiven und " 680 | "modernen App" 681 | msgstr "" 682 | 683 | #: _build/data/dev.salaniLeo.forecast.appdata.xml:32 684 | msgid "Hauptfenster" 685 | msgstr "" 686 | 687 | #: _build/data/dev.salaniLeo.forecast.appdata.xml:33 688 | msgid "मुख्य खिड़की" 689 | msgstr "" 690 | 691 | #: _build/data/dev.salaniLeo.forecast.appdata.xml:38 692 | msgid "Wetterbericht Fenster" 693 | msgstr "" 694 | 695 | #: _build/data/dev.salaniLeo.forecast.appdata.xml:39 696 | msgid "पूर्वानुमान खिड़की" 697 | msgstr "" 698 | 699 | #: _build/data/dev.salaniLeo.forecast.appdata.xml:44 700 | msgid "Hauptfenster mit angepasstem Hintergrund" 701 | msgstr "" 702 | 703 | #: _build/data/dev.salaniLeo.forecast.appdata.xml:45 704 | msgid "तदनुकूल पृष्ठभूमि के साथ मुख्य खिड़की" 705 | msgstr "" 706 | 707 | #: _build/data/dev.salaniLeo.forecast.appdata.xml:50 708 | msgid "Einstellungsdialog" 709 | msgstr "" 710 | 711 | #: _build/data/dev.salaniLeo.forecast.appdata.xml:51 712 | msgid "प्राथमिकताएं संवाद" 713 | msgstr "" 714 | -------------------------------------------------------------------------------- /po/LINGUAS: -------------------------------------------------------------------------------- 1 | hi 2 | pt 3 | tr 4 | de 5 | -------------------------------------------------------------------------------- /po/POTFILES.in: -------------------------------------------------------------------------------- 1 | # List of source files containing translatable strings. 2 | data/dev.salaniLeo.forecast.appdata.xml.in 3 | data/dev.salaniLeo.forecast.desktop.in 4 | data/dev.salaniLeo.forecast.gschema.xml 5 | Forecast/App.py 6 | Forecast/data.py 7 | Forecast/page.py 8 | Forecast/start.py 9 | Forecast/style.py 10 | -------------------------------------------------------------------------------- /po/de.po: -------------------------------------------------------------------------------- 1 | # Forecast. 2 | # Copyright (C) 2024 Forecast contributors 3 | # This file is distributed under the same license as the Forecast application. 4 | # Konstantin Tutsch , 2024. 5 | # 6 | msgid "" 7 | msgstr "" 8 | "Project-Id-Version: unnamed project\n" 9 | "Report-Msgid-Bugs-To: \n" 10 | "POT-Creation-Date: 2024-09-04 14:14+0200\n" 11 | "PO-Revision-Date: 2024-09-04 14:14+0200\n" 12 | "Last-Translator: Konstantin Tutsch \n" 13 | "Language-Team: German\n" 14 | "Language: de\n" 15 | "MIME-Version: 1.0\n" 16 | "Content-Type: text/plain; charset=UTF-8\n" 17 | "Content-Transfer-Encoding: 8bit\n" 18 | "Plural-Forms: nplurals=2; plural=(n != 1);\n" 19 | "X-Generator: Poedit 3.4.4\n" 20 | 21 | #: Forecast/style.py:84 22 | msgid "Thunderstorm with Light Rain" 23 | msgstr "Gewitter mit Leichtem Regen" 24 | 25 | #: Forecast/style.py:85 26 | msgid "Thunderstorm with Rain" 27 | msgstr "Gewitter mit Regen" 28 | 29 | #: Forecast/style.py:86 30 | msgid "Thunderstorm with Heavy Rain" 31 | msgstr "Gewitter mit Starkem Regen" 32 | 33 | #: Forecast/style.py:87 34 | msgid "Light Thunderstorm" 35 | msgstr "Leichtes Gewitter" 36 | 37 | #: Forecast/style.py:88 38 | msgid "Thunderstorm" 39 | msgstr "Gewitter" 40 | 41 | #: Forecast/style.py:89 42 | msgid "Heavy Thunderstorm" 43 | msgstr "Starkes Gewitter" 44 | 45 | #: Forecast/style.py:90 46 | msgid "Ragged Thunderstorm" 47 | msgstr "Schweres Gewitter" 48 | 49 | #: Forecast/style.py:91 50 | msgid "Light Drizzle" 51 | msgstr "Leichter Nieselregen" 52 | 53 | #: Forecast/style.py:92 54 | msgid "Drizzle" 55 | msgstr "Nieselregen" 56 | 57 | #: Forecast/style.py:93 58 | msgid "Heavy Drizzle" 59 | msgstr "Starker Nieselregen" 60 | 61 | #: Forecast/style.py:94 62 | msgid "Light Drizzle Rain" 63 | msgstr "Leichter Nieselregen" 64 | 65 | #: Forecast/style.py:95 66 | msgid "Drizzle Rain" 67 | msgstr "Nieselregen" 68 | 69 | #: Forecast/style.py:96 70 | msgid "Heavy Drizzle Rain" 71 | msgstr "Starker Nieselregen" 72 | 73 | #: Forecast/style.py:97 74 | msgid "Shower Rain and Drizzle" 75 | msgstr "Schauer und Nieselregen" 76 | 77 | #: Forecast/style.py:98 78 | msgid "Heavy Rain and Drizzle" 79 | msgstr "Starkregen und Nieselregen" 80 | 81 | #: Forecast/style.py:99 82 | msgid "Shower Drizzle" 83 | msgstr "Vereinzelter Nieselregen" 84 | 85 | #: Forecast/style.py:100 86 | msgid "Light Rain" 87 | msgstr "Leichter Regen" 88 | 89 | #: Forecast/style.py:101 90 | msgid "Moderate Rain" 91 | msgstr "Mäßiger Regen" 92 | 93 | #: Forecast/style.py:102 94 | msgid "Heavy Rain" 95 | msgstr "Starker Regen" 96 | 97 | #: Forecast/style.py:103 98 | msgid "Very Heavy Rain" 99 | msgstr "Schwerer Regen" 100 | 101 | #: Forecast/style.py:104 102 | msgid "Extreme Rain" 103 | msgstr "Extremer Regen" 104 | 105 | #: Forecast/style.py:105 106 | msgid "Freezing Rain" 107 | msgstr "Gefrierender Regen" 108 | 109 | #: Forecast/style.py:106 110 | msgid "Light Shower Rain" 111 | msgstr "Leichte Regenschauer" 112 | 113 | #: Forecast/style.py:107 114 | msgid "Shower Rain" 115 | msgstr "Regenschauer" 116 | 117 | #: Forecast/style.py:108 118 | msgid "Heavy Shower Rain" 119 | msgstr "Starke Regenschauer" 120 | 121 | #: Forecast/style.py:109 122 | msgid "Ragged Shower Rain" 123 | msgstr "Schwere Regenschauer" 124 | 125 | #: Forecast/style.py:110 126 | msgid "Light Snow" 127 | msgstr "Leichter Schneefall" 128 | 129 | #: Forecast/style.py:111 130 | msgid "Snow" 131 | msgstr "Schneefall" 132 | 133 | #: Forecast/style.py:112 134 | msgid "Heavy Snow" 135 | msgstr "Starker Schneefall" 136 | 137 | #: Forecast/style.py:113 138 | msgid "Sleet" 139 | msgstr "Graupelhagel" 140 | 141 | #: Forecast/style.py:114 142 | msgid "Light Shower Sleet" 143 | msgstr "Leichter Graupelhagel" 144 | 145 | #: Forecast/style.py:115 146 | msgid "Shower Sleet" 147 | msgstr "Vereinzelte Graupelhagel" 148 | 149 | #: Forecast/style.py:116 150 | msgid "Light Rain and Snow" 151 | msgstr "Leichter Regen und Schneefall" 152 | 153 | #: Forecast/style.py:117 154 | msgid "Rain and Snow" 155 | msgstr "Regen und Schneefall" 156 | 157 | #: Forecast/style.py:118 158 | msgid "Light Shower Snow" 159 | msgstr "Leichter, Vereinzelter Schneefall" 160 | 161 | #: Forecast/style.py:119 162 | msgid "Shower Snow" 163 | msgstr "Vereinzelter Schneefall" 164 | 165 | #: Forecast/style.py:120 166 | msgid "Heavy Shower Snow" 167 | msgstr "Starker, Vereinzelter Schneefall" 168 | 169 | #: Forecast/style.py:121 170 | msgid "Mist" 171 | msgstr "Nebel" 172 | 173 | #: Forecast/style.py:122 174 | msgid "Smoke" 175 | msgstr "Rauch" 176 | 177 | #: Forecast/style.py:123 178 | msgid "Haze" 179 | msgstr "Dunst" 180 | 181 | #: Forecast/style.py:124 182 | msgid "Sand/Dust Whirls" 183 | msgstr "Sand-/Staubwirbel" 184 | 185 | #: Forecast/style.py:125 186 | msgid "Fog" 187 | msgstr "Nebel" 188 | 189 | #: Forecast/style.py:126 190 | msgid "Sand" 191 | msgstr "Sand" 192 | 193 | #: Forecast/style.py:127 194 | msgid "Dust" 195 | msgstr "Staub" 196 | 197 | #: Forecast/style.py:128 198 | msgid "Volcanic Ash" 199 | msgstr "Vulkanasche" 200 | 201 | #: Forecast/style.py:129 202 | msgid "Squalls" 203 | msgstr "Windböen" 204 | 205 | #: Forecast/style.py:130 206 | msgid "Tornado" 207 | msgstr "Tornado" 208 | 209 | #: Forecast/style.py:131 210 | msgid "Clear Sky" 211 | msgstr "Klarer Himmel" 212 | 213 | #: Forecast/style.py:132 214 | msgid "Few Clouds" 215 | msgstr "Wenige Wolken" 216 | 217 | #: Forecast/style.py:133 218 | msgid "Scattered Clouds" 219 | msgstr "Vereinzelte Wolken" 220 | 221 | #: Forecast/style.py:134 222 | msgid "Broken Clouds" 223 | msgstr "Durchbrochene Wolken" 224 | 225 | #: Forecast/style.py:135 226 | msgid "Overcast Clouds" 227 | msgstr "Bedeckter Himmel" 228 | 229 | #: Forecast/App.py:38 Forecast/page.py:64 Forecast/page.py:292 230 | #: Forecast/page.py:341 231 | msgid "Weather" 232 | msgstr "Wetter" 233 | 234 | #: Forecast/App.py:43 Forecast/App.py:253 Forecast/App.py:277 235 | msgid "Locations" 236 | msgstr "Orte" 237 | 238 | #: Forecast/App.py:206 Forecast/page.py:65 239 | #: data/dev.salaniLeo.forecast.desktop.in:3 240 | #: data/dev.salaniLeo.forecast.appdata.xml.in:4 241 | #: _build/data/dev.salaniLeo.forecast.appdata.xml:4 242 | #: _build/data/dev.salaniLeo.forecast.appdata.xml:5 243 | msgid "Forecast" 244 | msgstr "Forecast" 245 | 246 | #: Forecast/App.py:209 247 | msgid "" 248 | "⛅ Check the weather!.\n" 249 | "Uses openweathermap api" 250 | msgstr "" 251 | "⛅ Überprüfen Sie den Wetterberichte!\n" 252 | "Nutzt die OpenWeatherMap API" 253 | 254 | #: Forecast/App.py:230 255 | msgid "Refresh" 256 | msgstr "Aktualisieren" 257 | 258 | #: Forecast/App.py:231 Forecast/App.py:243 Forecast/App.py:257 259 | msgid "Preferences" 260 | msgstr "Einstellungen" 261 | 262 | #: Forecast/App.py:232 263 | msgid "About Forecast" 264 | msgstr "Über Forecast" 265 | 266 | #: Forecast/App.py:284 267 | msgid "Units preferences" 268 | msgstr "Einheiten" 269 | 270 | #: Forecast/App.py:286 271 | msgid "Appearance Preferences" 272 | msgstr "Erscheinungsbild" 273 | 274 | #: Forecast/App.py:298 275 | msgid "Temperature units" 276 | msgstr "Temperatureinheiten" 277 | 278 | #: Forecast/App.py:299 279 | msgid "Select which units to use" 280 | msgstr "Wählen Sie die zu verwendenden Einheiten" 281 | 282 | #: Forecast/App.py:315 283 | msgid "Time format" 284 | msgstr "Zeitformat" 285 | 286 | #: Forecast/App.py:316 287 | msgid "Select whether to use the 12h or 24h formats" 288 | msgstr "Wählen Sie zwischen dem 12 Stunden- und dem 24 Stundensystem" 289 | 290 | #: Forecast/App.py:322 291 | msgid "Use dynamic background" 292 | msgstr "Dynamischen Hintergrund anzeigen" 293 | 294 | #: Forecast/App.py:323 295 | msgid "" 296 | "When on, the background changes based on the weather. Restart needed to apply" 297 | msgstr "Lassen Sie den Hintergrund sich an das aktuelle Wetter anpassen" 298 | 299 | #: Forecast/App.py:331 300 | msgid "API Preferences" 301 | msgstr "API" 302 | 303 | #: Forecast/App.py:343 304 | msgid "Use Personal API Key" 305 | msgstr "Persönlichen API Schlüssel verwenden" 306 | 307 | #: Forecast/App.py:345 308 | msgid "Choose whether to use default API key or personal key" 309 | msgstr "Wählen Sie zwischen dem Standard oder einem persönlichen API Schlüssel" 310 | 311 | #: Forecast/App.py:349 312 | msgid "Personal API Key" 313 | msgstr "Persönlicher API Schlüssel" 314 | 315 | #: Forecast/App.py:367 Forecast/App.py:372 Forecast/App.py:376 316 | #: Forecast/App.py:388 317 | msgid "Restart needed to apply changes" 318 | msgstr "Neustart wird benötigt, um die Änderungen anzunehmen" 319 | 320 | #: Forecast/App.py:390 321 | msgid "Api key not valid" 322 | msgstr "API Schlüssel nicht valide" 323 | 324 | #: Forecast/App.py:426 325 | msgid "Latitude" 326 | msgstr "Breitengrad" 327 | 328 | #: Forecast/App.py:430 329 | msgid "Longitude" 330 | msgstr "Längengrad" 331 | 332 | #: Forecast/App.py:459 333 | msgid "Use coordinates" 334 | msgstr "Mit Koordinaten angeben" 335 | 336 | #: Forecast/data.py:12 337 | msgid "Metric System" 338 | msgstr "Metrisches System (SI)" 339 | 340 | #: Forecast/data.py:13 341 | msgid "Imperial System" 342 | msgstr "Angloamerikanisches System" 343 | 344 | #: Forecast/data.py:40 345 | msgid "Good" 346 | msgstr "Gut" 347 | 348 | #: Forecast/data.py:41 349 | msgid "Fair" 350 | msgstr "Angemessen" 351 | 352 | #: Forecast/data.py:42 353 | msgid "Moderate" 354 | msgstr "Mäßig" 355 | 356 | #: Forecast/data.py:43 357 | msgid "Poor" 358 | msgstr "Schlecht" 359 | 360 | #: Forecast/data.py:44 361 | msgid "Very Poor" 362 | msgstr "Sehr Schlecht" 363 | 364 | #: Forecast/data.py:51 365 | msgid "Low" 366 | msgstr "Niedrig" 367 | 368 | #: Forecast/data.py:53 369 | msgid "Seek shade during midday hours!" 370 | msgstr "Suchen Sie in der Mittagszeit schattige Orte auf!" 371 | 372 | #: Forecast/data.py:55 373 | msgid "Avoid being outside during midday hours!" 374 | msgstr "Vermeiden Sie es, während der Mittagszeit draußen zu sein!" 375 | 376 | #: Forecast/data.py:57 377 | msgid "Invalid UV index input." 378 | msgstr "Ungültige UV Index Eingabe!" 379 | 380 | #: Forecast/data.py:61 381 | msgid "N" 382 | msgstr "N" 383 | 384 | #: Forecast/data.py:61 385 | msgid "NNE" 386 | msgstr "NNE" 387 | 388 | #: Forecast/data.py:61 389 | msgid "NE" 390 | msgstr "NE" 391 | 392 | #: Forecast/data.py:61 393 | msgid "ENE" 394 | msgstr "ENE" 395 | 396 | #: Forecast/data.py:61 397 | msgid "E" 398 | msgstr "E" 399 | 400 | #: Forecast/data.py:61 401 | msgid "ESE" 402 | msgstr "ESE" 403 | 404 | #: Forecast/data.py:61 405 | msgid "SE" 406 | msgstr "SE" 407 | 408 | #: Forecast/data.py:61 409 | msgid "SSE" 410 | msgstr "SSE" 411 | 412 | #: Forecast/data.py:62 413 | msgid "S" 414 | msgstr "S" 415 | 416 | #: Forecast/data.py:62 417 | msgid "SSW" 418 | msgstr "SSW" 419 | 420 | #: Forecast/data.py:62 421 | msgid "SW" 422 | msgstr "SW" 423 | 424 | #: Forecast/data.py:62 425 | msgid "WSW" 426 | msgstr "WSW" 427 | 428 | #: Forecast/data.py:62 429 | msgid "W" 430 | msgstr "W" 431 | 432 | #: Forecast/data.py:62 433 | msgid "WNW" 434 | msgstr "WNW" 435 | 436 | #: Forecast/data.py:62 437 | msgid "NW" 438 | msgstr "NW" 439 | 440 | #: Forecast/data.py:62 441 | msgid "NNW" 442 | msgstr "NNW" 443 | 444 | #: Forecast/data.py:169 445 | msgid "Wait at least 2 minutes between refreshes!" 446 | msgstr "Warten Sie mindestens 2 Minuten zwischen Aktualisierungen!" 447 | 448 | #: Forecast/page.py:32 449 | msgid "Exceeded limit of api calls :(" 450 | msgstr "" 451 | 452 | #: Forecast/page.py:34 453 | msgid "Could not retrieve weather data" 454 | msgstr "Wetterbericht konnte nicht geladen werden" 455 | 456 | #: Forecast/page.py:159 457 | #, python-brace-format 458 | msgid "- Feels like {0}{1}" 459 | msgstr "- Gefühlt {0}{1}" 460 | 461 | #: Forecast/page.py:202 462 | msgid "Alerts" 463 | msgstr "Warnungen" 464 | 465 | #: Forecast/page.py:223 Forecast/page.py:304 Forecast/page.py:786 466 | msgid "Conditions" 467 | msgstr "Konditionen" 468 | 469 | #: Forecast/page.py:242 Forecast/page.py:319 470 | msgid "Wind" 471 | msgstr "Wind" 472 | 473 | #: Forecast/page.py:243 Forecast/page.py:320 Forecast/page.py:321 474 | msgid "Pressure" 475 | msgstr "Luftdruck" 476 | 477 | #: Forecast/page.py:244 Forecast/page.py:781 478 | msgid "Humidity" 479 | msgstr "Luftfeuchte" 480 | 481 | #: Forecast/page.py:245 Forecast/page.py:322 482 | msgid "Visibility" 483 | msgstr "Sicht" 484 | 485 | #: Forecast/page.py:246 Forecast/page.py:824 486 | msgid "Sunrise" 487 | msgstr "Sonnenaufgang" 488 | 489 | #: Forecast/page.py:247 Forecast/page.py:816 490 | msgid "Sunset" 491 | msgstr "Sonnenuntergang" 492 | 493 | #: Forecast/page.py:248 494 | msgid "AQI" 495 | msgstr "AQI" 496 | 497 | #: Forecast/page.py:318 498 | msgid "Feels Like" 499 | msgstr "Gefühlt" 500 | 501 | #: Forecast/page.py:354 502 | msgid "Today" 503 | msgstr "Heute" 504 | 505 | #: Forecast/page.py:404 506 | msgid "Weekly forecast" 507 | msgstr "Wöchentlicher Wetterbericht" 508 | 509 | #: Forecast/page.py:491 510 | msgid "Pollution" 511 | msgstr "Luftverschmutzung" 512 | 513 | #: Forecast/page.py:496 514 | msgid "Details" 515 | msgstr "Details" 516 | 517 | #: Forecast/page.py:711 518 | msgid "Night" 519 | msgstr "Nacht" 520 | 521 | #: Forecast/page.py:725 522 | msgid "Evening" 523 | msgstr "Abend" 524 | 525 | #: Forecast/page.py:739 526 | msgid "Morning" 527 | msgstr "Morgen" 528 | 529 | #: Forecast/page.py:753 530 | msgid "Afternoon" 531 | msgstr "Nachmittag" 532 | 533 | #: Forecast/page.py:766 534 | msgid "Temperatures" 535 | msgstr "Temperaturen" 536 | 537 | #: Forecast/page.py:779 538 | msgid "Temperature" 539 | msgstr "Temperatur" 540 | 541 | #: Forecast/page.py:780 542 | msgid "Wind speed" 543 | msgstr "Windgeschwindigkeit" 544 | 545 | #: Forecast/page.py:781 Forecast/page.py:782 Forecast/page.py:783 546 | #, python-brace-format 547 | msgid "{0}%" 548 | msgstr "{0}%" 549 | 550 | #: Forecast/page.py:782 551 | msgid "Cloudiness" 552 | msgstr "Bewölkung" 553 | 554 | #: Forecast/page.py:783 555 | msgid "Probability of rain" 556 | msgstr "Regenwahrscheinlichkeit" 557 | 558 | #: Forecast/page.py:784 559 | msgid "UV Index" 560 | msgstr "UV Index" 561 | 562 | #: Forecast/page.py:830 563 | msgid "Sun" 564 | msgstr "Sonnen" 565 | 566 | #: Forecast/page.py:918 567 | msgid "Close" 568 | msgstr "Schließen" 569 | 570 | #: data/dev.salaniLeo.forecast.desktop.in:6 571 | msgid "Weather;Forecast;Temperature;" 572 | msgstr "Wetter;Wetterbericht;Temperatur;" 573 | 574 | #: data/dev.salaniLeo.forecast.desktop.in:7 575 | msgid "Forecast app for GNOME" 576 | msgstr "Wetterapp für GNOME" 577 | 578 | #: data/dev.salaniLeo.forecast.gschema.xml:7 579 | msgid "Stores the users api key" 580 | msgstr "Speichert den persönlichen API Schlüssel" 581 | 582 | #: data/dev.salaniLeo.forecast.gschema.xml:8 583 | msgid "stores the users api key" 584 | msgstr "Speichert den persönlichen API Schlüssel" 585 | 586 | #: data/dev.salaniLeo.forecast.gschema.xml:13 587 | msgid "If false uses the default api key" 588 | msgstr "Nutzt den Standard API Schlüssel wenn falsch" 589 | 590 | #: data/dev.salaniLeo.forecast.gschema.xml:14 591 | msgid "When this is true the app know to use the custom api key" 592 | msgstr "" 593 | "Die App weiß, dass sie den Standard API Schlüssel nutzt, wenn eingeschaltet" 594 | 595 | #: data/dev.salaniLeo.forecast.gschema.xml:19 596 | msgid "Uses a weather based gradient as background" 597 | msgstr "Nutzt einen wetterbasierten Übergang als Hintergrund" 598 | 599 | #: data/dev.salaniLeo.forecast.gschema.xml:20 600 | msgid "Chooses wether the user wants a gradient for background" 601 | msgstr "Wählen Sie, ob Sie einen Übergang als Hintergrund nutzen möchten" 602 | 603 | #: data/dev.salaniLeo.forecast.gschema.xml:25 604 | msgid "List of weather places" 605 | msgstr "Liste der Orte" 606 | 607 | #: data/dev.salaniLeo.forecast.gschema.xml:26 608 | msgid "Stores all user selected location" 609 | msgstr "Speichert alle vom Nutzer ausgewählten Orte" 610 | 611 | #: data/dev.salaniLeo.forecast.gschema.xml:31 612 | msgid "Units" 613 | msgstr "Einheiten" 614 | 615 | #: data/dev.salaniLeo.forecast.gschema.xml:32 616 | msgid "Chooses between the metric and imperial systems of measurement" 617 | msgstr "" 618 | "Wählen Sie zwischen dem metrischen (SI) und dem angloamerikanischen " 619 | "Einheitensystem" 620 | 621 | #: data/dev.salaniLeo.forecast.gschema.xml:37 622 | msgid "use 12h or 24h" 623 | msgstr "Zeitsystem" 624 | 625 | #: data/dev.salaniLeo.forecast.gschema.xml:38 626 | msgid "Chooses between the 12h and the 24h time format" 627 | msgstr "Wählt zwischen dem 12 Stunden- oder dem 24 Stundensystem" 628 | 629 | #: data/dev.salaniLeo.forecast.gschema.xml:43 630 | msgid "Default weather city" 631 | msgstr "Standard Ort" 632 | 633 | #: data/dev.salaniLeo.forecast.gschema.xml:44 634 | msgid "Chooses the default city for the weather" 635 | msgstr "Wählt den Standard Ort für Wetter" 636 | 637 | #: data/dev.salaniLeo.forecast.appdata.xml.in:5 638 | #: _build/data/dev.salaniLeo.forecast.appdata.xml:9 639 | msgid "⛅ Check the weather!" 640 | msgstr "⛅ Überprüfen Sie den Wetterbericht!" 641 | 642 | #: data/dev.salaniLeo.forecast.appdata.xml.in:7 643 | #: _build/data/dev.salaniLeo.forecast.appdata.xml:12 644 | msgid "Check the weather with a simple, intuitive and modern app" 645 | msgstr "" 646 | "Überprüfen Sie den Wetterbericht mit Hilfe einer simplen, intuitiven und " 647 | "modernen App" 648 | 649 | #: data/dev.salaniLeo.forecast.appdata.xml.in:27 650 | #: _build/data/dev.salaniLeo.forecast.appdata.xml:31 651 | msgid "Main window" 652 | msgstr "Hauptfenster" 653 | 654 | #: data/dev.salaniLeo.forecast.appdata.xml.in:31 655 | #: _build/data/dev.salaniLeo.forecast.appdata.xml:37 656 | msgid "Forecast window" 657 | msgstr "Wetterbericht Fenster" 658 | 659 | #: data/dev.salaniLeo.forecast.appdata.xml.in:35 660 | #: _build/data/dev.salaniLeo.forecast.appdata.xml:43 661 | msgid "Main window with custom background" 662 | msgstr "Hauptfenster mit angepasstem Hintergrund" 663 | 664 | #: data/dev.salaniLeo.forecast.appdata.xml.in:39 665 | #: _build/data/dev.salaniLeo.forecast.appdata.xml:49 666 | msgid "Preferences dialog" 667 | msgstr "Einstellungsdialog" 668 | 669 | #: _build/data/dev.salaniLeo.forecast.appdata.xml:6 670 | msgid "Hava Tahmini" 671 | msgstr "" 672 | 673 | #: _build/data/dev.salaniLeo.forecast.appdata.xml:7 674 | msgid "Previsão do tempo" 675 | msgstr "" 676 | 677 | #: _build/data/dev.salaniLeo.forecast.appdata.xml:8 678 | msgid "फोरकास्ट" 679 | msgstr "" 680 | 681 | #: _build/data/dev.salaniLeo.forecast.appdata.xml:10 682 | msgid "⛅ Überprüfen Sie den Wetterbericht!" 683 | msgstr "" 684 | 685 | #: _build/data/dev.salaniLeo.forecast.appdata.xml:13 686 | msgid "" 687 | "Überprüfen Sie den Wetterbericht mit Hilfe einer simplen, intuitiven und " 688 | "modernen App" 689 | msgstr "" 690 | 691 | #: _build/data/dev.salaniLeo.forecast.appdata.xml:32 692 | msgid "Hauptfenster" 693 | msgstr "" 694 | 695 | #: _build/data/dev.salaniLeo.forecast.appdata.xml:33 696 | msgid "मुख्य खिड़की" 697 | msgstr "" 698 | 699 | #: _build/data/dev.salaniLeo.forecast.appdata.xml:38 700 | msgid "Wetterbericht Fenster" 701 | msgstr "" 702 | 703 | #: _build/data/dev.salaniLeo.forecast.appdata.xml:39 704 | msgid "पूर्वानुमान खिड़की" 705 | msgstr "" 706 | 707 | #: _build/data/dev.salaniLeo.forecast.appdata.xml:44 708 | msgid "Hauptfenster mit angepasstem Hintergrund" 709 | msgstr "" 710 | 711 | #: _build/data/dev.salaniLeo.forecast.appdata.xml:45 712 | msgid "तदनुकूल पृष्ठभूमि के साथ मुख्य खिड़की" 713 | msgstr "" 714 | 715 | #: _build/data/dev.salaniLeo.forecast.appdata.xml:50 716 | msgid "Einstellungsdialog" 717 | msgstr "" 718 | 719 | #: _build/data/dev.salaniLeo.forecast.appdata.xml:51 720 | msgid "प्राथमिकताएं संवाद" 721 | msgstr "" 722 | -------------------------------------------------------------------------------- /po/meson.build: -------------------------------------------------------------------------------- 1 | i18n.gettext('forecast', preset: 'glib') 2 | -------------------------------------------------------------------------------- /share/icons/hicolor/scalable/apps/dev.salaniLeo.forecast.Devel.svg: -------------------------------------------------------------------------------- 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 | -------------------------------------------------------------------------------- /share/icons/hicolor/scalable/apps/dev.salaniLeo.forecast.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /share/icons/hicolor/symbolic/apps/dev.salaniLeo.forecast-symbolic.svg: -------------------------------------------------------------------------------- 1 | 2 | 14 | 16 | 24 | 28 | 32 | 33 | 34 | 53 | 57 | 62 | 66 | 70 | 75 | 79 | 83 | 87 | 88 | 89 | -------------------------------------------------------------------------------- /share/icons/meson.build: -------------------------------------------------------------------------------- 1 | application_id = 'dev.salaniLeo.forecast' 2 | 3 | scalable_dir = join_paths('hicolor', 'scalable', 'apps') 4 | install_data( 5 | join_paths(scalable_dir, ('@0@.svg').format(application_id)), 6 | install_dir: join_paths(get_option('datadir'), 'icons', scalable_dir) 7 | ) 8 | 9 | symbolic_dir = join_paths('hicolor', 'symbolic', 'apps') 10 | install_data( 11 | join_paths(symbolic_dir, ('@0@-symbolic.svg').format(application_id)), 12 | install_dir: join_paths(get_option('datadir'), 'icons', symbolic_dir) 13 | ) 14 | --------------------------------------------------------------------------------