├── pwy ├── __init__.py ├── _version.py ├── __version__.py ├── __main__.py ├── ascii.py ├── cli.py └── translation.py ├── pwy.png ├── .gitignore ├── requirements.txt ├── CONTRIBUTING.md ├── .vscode └── settings.json ├── setup.py ├── LICENSE ├── README.md ├── CHANGELOG.md └── CODE_OF_CONDUCT.md /pwy/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /pwy/_version.py: -------------------------------------------------------------------------------- 1 | __version__ = "1.4.7" 2 | -------------------------------------------------------------------------------- /pwy.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/egargo/pwygit/HEAD/pwy.png -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | env 2 | __pycache__ 3 | build 4 | dist 5 | pwy.egg-info -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | certifi==2022.12.7 2 | charset-normalizer==2.1.1 3 | commonmark==0.9.1 4 | idna==3.4 5 | Pygments==2.13.0 6 | requests==2.28.1 7 | rich==12.6.0 8 | urllib3==1.26.13 9 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing Guide 2 | 3 | Read our [Code of Conduct](./CODE_OF_CONDUCT.md) to keep our community approachable and respectable. 4 | 5 | In this guide you will get an overview of the contribution workflow from opening an issue, creating a PR, reviewing, and merging the PR. 6 | 7 | Use the table of contents icon on the top left corner of this document to get to a specific section of this guide quickly. 8 | 9 | ## Getting started 10 | 11 | 1. Fork the repository 12 | 2. Commit and push your changes 13 | 3. Create a pull request 14 | 4. Wait for the maintainers to review and merge your pull request 15 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "workbench.editorAssociations": [ 3 | { 4 | "viewType": "jupyter.notebook.ipynb", 5 | "filenamePattern": "*.ipynb" 6 | } 7 | ], 8 | "git.confirmSync": false, 9 | "editor.formatOnPaste": true, 10 | "editor.formatOnSave": true, 11 | "python.formatting.provider": "autopep8", 12 | "explorer.confirmDelete": false, 13 | "python.showStartPage": false, 14 | "explorer.confirmDragAndDrop": false, 15 | "python.linting.pylintArgs": ["--load-plugins=pylint_django"], 16 | "javascript.updateImportsOnFileMove.enabled": "always", 17 | "editor.defaultFormatter": "esbenp.prettier-vscode", 18 | "[python]": { 19 | "editor.defaultFormatter": "ms-python.python" 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /setup.py: -------------------------------------------------------------------------------- 1 | from setuptools import setup 2 | from pwy.__version__ import __version__ 3 | 4 | 5 | README = open("README.md").read() 6 | 7 | setup( 8 | name="pwy", 9 | version=__version__, 10 | description="A simple weather information tool", 11 | long_description=README, 12 | long_description_content_type="text/markdown", 13 | url="https://github.com/cliegargo/pwy", 14 | author="Clint", 15 | license="MIT", 16 | classifiers=[ 17 | "License :: OSI Approved :: MIT License", 18 | "Operating System :: POSIX :: Linux", 19 | "Operating System :: MacOS", 20 | "Operating System :: Microsoft :: Windows", 21 | "Programming Language :: Python :: 3.10", 22 | ], 23 | packages=["pwy"], 24 | include_package_data=True, 25 | package_data={"pwy": ["pwy/*"]}, 26 | install_requires=["requests", "rich"], 27 | entry_points={"console_scripts": ["pwy = pwy.__main__:main"]}, 28 | ) 29 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) egargo 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /pwy/__version__.py: -------------------------------------------------------------------------------- 1 | # MIT License 2 | # 3 | # Copyright (c) cegargo 4 | # 5 | # Permission is hereby granted, free of charge, to any person obtaining a copy 6 | # of this software and associated documentation files (the "Software"), to deal 7 | # in the Software without restriction, including without limitation the rights 8 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | # copies of the Software, and to permit persons to whom the Software is 10 | # furnished to do so, subject to the following conditions: 11 | # 12 | # The above copyright notice and this permission notice shall be included in all 13 | # copies or substantial portions of the Software. 14 | # 15 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | # SOFTWARE. 22 | 23 | 24 | __version__ = "2.1.2" 25 | -------------------------------------------------------------------------------- /pwy/__main__.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # 3 | # 4 | # MIT License 5 | # 6 | # Copyright (c) cegargo 7 | # 8 | # Permission is hereby granted, free of charge, to any person obtaining a copy 9 | # of this software and associated documentation files (the "Software"), to deal 10 | # in the Software without restriction, including without limitation the rights 11 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 12 | # copies of the Software, and to permit persons to whom the Software is 13 | # furnished to do so, subject to the following conditions: 14 | # 15 | # The above copyright notice and this permission notice shall be included in all 16 | # copies or substantial portions of the Software. 17 | 18 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 21 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 23 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 24 | # SOFTWARE. 25 | 26 | 27 | import sys 28 | from pwy.cli import main 29 | 30 | if __name__ == "__main__": 31 | sys.exit(main()) 32 | -------------------------------------------------------------------------------- /pwy/ascii.py: -------------------------------------------------------------------------------- 1 | # MIT License 2 | # 3 | # Copyright (c) cegargo 4 | # 5 | # Permission is hereby granted, free of charge, to any person obtaining a copy 6 | # of this software and associated documentation files (the "Software"), to deal 7 | # in the Software without restriction, including without limitation the rights 8 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | # copies of the Software, and to permit persons to whom the Software is 10 | # furnished to do so, subject to the following conditions: 11 | # 12 | # The above copyright notice and this permission notice shall be included in all 13 | # copies or substantial portions of the Software. 14 | # 15 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | # SOFTWARE. 22 | 23 | 24 | from rich import color 25 | 26 | clear_sky = [ 27 | "[b yellow] \\ / [/]", 28 | "[b yellow] .-. [/]", 29 | "[b yellow] ‒ ( ) ‒ [/]", 30 | "[b yellow] `-᾿ [/]", 31 | "[b yellow] / \\ [/]", 32 | ] 33 | 34 | 35 | few_clouds = [ 36 | "[b yellow] \\ / [/]", 37 | '[b yellow] _ /""[/][b white].-. [/]', 38 | "[b yellow] \\ [/][b white]_( ).-. [/]", 39 | "[b yellow] /[/][b white](________)[/]", 40 | " ", 41 | ] 42 | 43 | 44 | overcast_cloud = [ 45 | "[b grey] [/]", 46 | "[b grey] .-. [/]", 47 | "[b grey] ( ).-. [/]", 48 | "[b grey](________)[/]", 49 | "[b grey] [/]", 50 | ] 51 | 52 | 53 | rain = [ 54 | "[b grey] .-. [/]", 55 | "[b grey] ( ).-. [/]", 56 | "[b grey] (________)[/]", 57 | "[b blue] ‚ʻ‚ʻ‚ʻ‚ʻ [/]", 58 | "[b blue] ‚ʻ‚ʻ‚ʻ‚ʻ [/]", 59 | " ", 60 | ] 61 | 62 | 63 | thunderstorm = [ 64 | "[b grey] .-. [/]", 65 | "[b grey] ( ).-. [/]", 66 | "[b grey](________)[/]", 67 | "[b blue]‚ʻ[/][b yellow]⚡[/][b blue]ʻ‚[/][b yellow]⚡[/][b blue]‚ʻ[/]", 68 | "[b blue]‚ʻ‚ʻ[/][b yellow]⚡[/][b blue]ʻ‚ʻ [/]", 69 | " ", 70 | ] 71 | 72 | 73 | snow = [ 74 | "[b grey] .-. [/]", 75 | "[b grey] ( ).-. [/]", 76 | "[b grey](________)[/]", 77 | "[b white] * * * * [/]", 78 | "[b white] * * * * [/]", 79 | ] 80 | 81 | 82 | mist = [ 83 | "[b grey] [/]", 84 | "[b grey] _ - _ - _ - [/]", 85 | "[b grey] _ - _ - _ [/]", 86 | "[b grey] _ - _ - _ - [/]", 87 | " ", 88 | ] 89 | 90 | 91 | unknown = [ 92 | "[b white] .-. [/]", 93 | "[b white] __) [/]", 94 | "[b white] ( [/]", 95 | "[b white] `-᾿ [/]", 96 | "[b white] • [/]", 97 | ] 98 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |
2 |

pwy

3 |

A simple weather information tool.

4 |
5 | 6 | 7 | 8 | 9 |
10 | 11 | ## Table of Contents 12 | 13 | - [Features](#features) 14 | - [Dependencies](#dependencies) 15 | - [Installation](#installation) 16 | - [Usage](#usage) 17 | - [Update](#update) 18 | - [Development](#development) 19 | - [Changelog](#changelog) 20 | - [Credits](#credits) 21 | - [License](#license) 22 | 23 | ## Features 24 | 25 | - ASCII art 26 | - Display weather information 27 | - The name of the location. 28 | - Temperature (and what the temperature feels like). 29 | - Weather and weather description. 30 | - Wind pressure, humidity, wind direction, and wind speed. 31 | - Time and timezone of the location. 32 | 33 | ## Dependencies 34 | 35 | - OpenWeatherMap API key 36 | - Python 3.10 or higher 37 | - requests 38 | - rich 39 | - Internet connection 40 | 41 | ## Installation 42 | 43 | ### Pip install 44 | 45 | #### Unix-like | Windows 46 | 47 | ```sh 48 | pip install pwy 49 | ``` 50 | 51 | ### Manual/Git install 52 | 53 | #### Unix-like | Windows 54 | 55 | Download the latest pwy package [here](https://github.com/cliegargo/pwy/releases/latest) and uncompress it. 56 | Go to pwy directory. 57 | 58 | ```sh 59 | cd pwy 60 | ``` 61 | 62 | Install pwy. 63 | 64 | ```sh 65 | pip install . 66 | ``` 67 | 68 | ## Configuration 69 | 70 | ### Unix-like | Windows 71 | 72 | Before you can use pwy, you need to configure pwy. Run the command below and fill the required files, these fields are for the OWM API key, location, unit, and language. 73 | 74 | ```sh 75 | pwy 76 | ``` 77 | 78 | After you're through, the `pwy.json` (`~/.config/pwy.json` for Unix-like and `pwy.json` for Windows) config file, containing your OWM API key, location, unit, and language, will be generated. 79 | 80 | Get your OWM key by [signing up](https://home.openweathermap.org/users/sign_up). 81 | 82 | If you want to edit your pwy configuration. 83 | 84 | ```sh 85 | pwy --config 86 | ``` 87 | 88 | ## Usage 89 | 90 | ### Unix-like | Windows 91 | 92 | To display weather in your current city (from pwy.json). 93 | 94 | ```sh 95 | pwy 96 | ``` 97 | 98 | To display weather in your current city. 99 | 100 | ```sh 101 | pwy tokyo 102 | ``` 103 | 104 | You can also specify what country you are in by. 105 | 106 | ```sh 107 | pwy tokyo,jp 108 | ``` 109 | 110 | To display weather with specific unit of measurement. By default the unit is Metric system. 111 | 112 | ```sh 113 | pwy tokyo --unit imperial 114 | ``` 115 | 116 | To display weather with specific language. 117 | 118 | ```sh 119 | pwy tokyo --lang ja 120 | ``` 121 | 122 | To display help information. 123 | 124 | ```sh 125 | pwy --help 126 | ``` 127 | 128 | ## Availabe options 129 | 130 | ```sh 131 | usage: __main__.py [-h] [-c] [-u] [-l] [-v] [location ...] 132 | 133 | pwy - A simple weather information tool 134 | 135 | positional arguments: 136 | location input location 137 | 138 | options: 139 | -h, --help show this help message and exit 140 | -c, --config configure pwy 141 | -u, --unit input unit 142 | -l, --lang input language 143 | -v, --version show program's version number and exit 144 | ``` 145 | 146 | ## Update 147 | 148 | ### Unix-like | Windows 149 | 150 | ```sh 151 | pip install --upgrade pwy 152 | ``` 153 | 154 | ## Development 155 | 156 | ```sh 157 | # Create a virtual environment and enable it. 158 | python3 -m venv 159 | . env/bin/activate 160 | 161 | # Install dependencies. 162 | pip install -r requirements.txt 163 | ``` 164 | 165 | ## Changelog 166 | 167 | View [Changelog](./CHANGELOG.md). 168 | 169 | ## Credits 170 | 171 | - [pwy Contributors](https://github.com/cliegargo/pwy/graphs/contributors) 172 | - [OpenWeatherMap](https://openweathermap.org/current) - API 173 | - [wego](https://github.com/schachmat/wego) - ASCII art 174 | 175 | ## License 176 | 177 | This program is provided under the [MIT License](./LICENSE). 178 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | All notable changes to this project will be documented in this file. 4 | 5 | The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), 6 | and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). 7 | 8 | ## [Unreleased] 9 | 10 | ## [2.1.2] - 2022.12.25 11 | 12 | - Changed license from GPLv3 to [MIT](./LICENSE). 13 | - Added MIT License notice to source code files 14 | - Added requirements.txt 15 | - Removed unused codes 16 | - Implemented comprehensions 17 | - Formatted with autopep8 18 | - Added .vscode settings 19 | 20 | ## 1.4.7 - 2021.12.05 (Patch) 21 | 22 | - [Windows] Fixed typo in pwy/cli.py #13 (@patevs). 23 | 24 | ## 1.4.6 - 2021.12.01 25 | 26 | - Fixed KeyError in cli.py 27 | - Added default value when configuring unit and language for `pwy.json`. 28 | 29 | ## [1.4.5] - 2021.11.09 30 | 31 | - Replaced `pwyrc` with `pwy.json`. 32 | - pwy.json 33 | - Set OWM API key. 34 | - Set default location. 35 | - Set default unit. 36 | - Set default language. 37 | - Ability to display weather using the `pwy` command. 38 | - pwy reads the values set in the pwy.json file. 39 | - If there is/are arguments, `pwy` will satisfy the arguments. 40 | - Minor code cleanup. 41 | 42 | ## [1.4.4] - 2021.09.30 43 | 44 | - Implemented rich. 45 | - Replaced colours.py with rich library. 46 | - Removed colours.py. 47 | - Formatted using black module. 48 | - Minor code cleanup 49 | 50 | ## [1.4.3] - 2021.09.26 51 | 52 | - Added default value to the arguments and removed the unnecessary if else. 53 | - Removed the unnecessary f-strings 54 | - Added `sys.exit(1)`. 55 | - Moved `.pwyrc` to `~/.config/pwyrc` (in Unix-like OS). 56 | - Minor code refactor. 57 | 58 | ## [1.4.2] - 2021.09.17 59 | 60 | - Moved `__main__.py` to `cli.py`. 61 | - Added `_version.py`. 62 | - Added `--version` argument. 63 | - Remove `key.py`. 64 | - Added `--config` argument to setup pwy. 65 | - API key is now stored in `.pwyrc`. 66 | 67 | ## 1.4.1 - 2021.08.27 [YANKED] 68 | 69 | - Changed `key.py` to `key.json` 70 | - Removed the `main` function and its contents to `if __name__ == "__main__`. 71 | 72 | ## [1.4.0] - 2021.06.26 73 | 74 | - Separated get_ascii() and get_weather_translation(). 75 | - Removed the output labels. 76 | - Added main.py 77 | - Added zip and tar.gz archives for manual installation. 78 | 79 | ## 1.3.1 - 2021.06.22 80 | 81 | - Refactored `__main__.py` to process JSON. 82 | - Refactored `translation.py` for easier access and readability. 83 | - Added `run_pwy.py` for manual installation. 84 | - Updated the API key and removed the API key in the `key.py` file. PyPi package can still be used without any problems. 85 | - Added a space before between the wind direction and wind speed. 86 | - Removed unused variable. 87 | 88 | ## 1.3.0 - 2021.06.19 89 | 90 | - Added wind direction. 91 | - Wildcard imports removed. 92 | - Merged pull request #7 from @ChaseParate. 93 | - Known issues: 94 | - Incomplete translation for Heavy Intensity Rain 95 | - Missing weather translations for Heavy Rain, Thunderstorm, and Snow. 96 | - No translations for Arabic, Persian, and Hebrews languages. 97 | 98 | ## 1.2.1 - 2021.06.12 99 | 100 | - Patch 101 | - Added `requests` on setup.py. 102 | 103 | ## 1.2.0 - 2021.06.12 104 | 105 | - Added `standard` unit (Kelvin). 106 | - Added text colour on the current time. 107 | - Minor code refactor: 108 | - Changed pwy/translation.py: `lang_list` to `LANGUAGES`. 109 | - Removed wildcard import for `colours` 110 | - Added `Mist` translation. 111 | 112 | ## 1.1.1 - 2021.06.08 113 | 114 | - Fixed the local time and time zone. 115 | - Minor ASCII art fix to match the new UI. 116 | 117 | ## 1.1.0 - 2021.06.07 118 | 119 | - Added Moderate Rain translation. 120 | - Added local time (24 hour format) and time zone. 121 | 122 | ## [1.0.0] - 2021.06.03 123 | 124 | - Name change from `wwy` to `pwy`. 125 | - Revamped UI. 126 | - `--unit` argument for the units (metric, imperial). 127 | - `--lang` argument for the languages. 128 | - Added translations. 129 | 130 | - Known issues 131 | - Missing weather translations for Moderate Rain, Heavy Rain, Thunderstorm, Snow, and Snow. 132 | - No translations for Arabic, Persian, and Hebrews languages. 133 | 134 | ## 0.1.4 135 | 136 | - Minor typo fix. 137 | 138 | ## 0.1.3 139 | 140 | - Changed .format() to f-string. 141 | - Added wind speed information. 142 | 143 | ## 0.1.2 144 | 145 | - Fixed the incorrect ASCII art. 146 | 147 | ## 0.1.1 148 | 149 | - Minor fixes. 150 | 151 | ## 0.1.0 152 | 153 | - Added -u parameter for the units (metric, imperial). 154 | - Changed the city name from optional argument to positional argument. 155 | 156 | ## 0.0.12 157 | 158 | - Fixed missing 'light_rain' ASCII art. 159 | - Fixed name 'light_rain' is not defined. 160 | - Added Mist ASCII art. 161 | 162 | [Unreleased]: https://github.com/egargo/pwygit/compare/2.1.2...HEAD 163 | [2.1.2]: https://github.com/egargo/pwygit/compare/1.4.5...2.1.2 164 | [1.4.5]: https://github.com/egargo/pwygit/compare/1.4.4...1.4.5 165 | [1.4.4]: https://github.com/egargo/pwygit/compare/1.4.3...1.4.4 166 | [1.4.3]: https://github.com/egargo/pwygit/compare/1.4.2...1.4.3 167 | [1.4.2]: https://github.com/egargo/pwygit/compare/1.4.0...1.4.2 168 | [1.4.0]: https://github.com/egargo/pwygit/releases/tag/1.4.0 169 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Contributor Covenant Code of Conduct 2 | 3 | ## Our Pledge 4 | 5 | We as members, contributors, and leaders pledge to make participation in our 6 | community a harassment-free experience for everyone, regardless of age, body 7 | size, visible or invisible disability, ethnicity, sex characteristics, gender 8 | identity and expression, level of experience, education, socio-economic status, 9 | nationality, personal appearance, race, religion, or sexual identity 10 | and orientation. 11 | 12 | We pledge to act and interact in ways that contribute to an open, welcoming, 13 | diverse, inclusive, and healthy community. 14 | 15 | ## Our Standards 16 | 17 | Examples of behavior that contributes to a positive environment for our 18 | community include: 19 | 20 | - Demonstrating empathy and kindness toward other people 21 | - Being respectful of differing opinions, viewpoints, and experiences 22 | - Giving and gracefully accepting constructive feedback 23 | - Accepting responsibility and apologizing to those affected by our mistakes, 24 | and learning from the experience 25 | - Focusing on what is best not just for us as individuals, but for the 26 | overall community 27 | 28 | Examples of unacceptable behavior include: 29 | 30 | - The use of sexualized language or imagery, and sexual attention or 31 | advances of any kind 32 | - Trolling, insulting or derogatory comments, and personal or political attacks 33 | - Public or private harassment 34 | - Publishing others' private information, such as a physical or email 35 | address, without their explicit permission 36 | - Other conduct which could reasonably be considered inappropriate in a 37 | professional setting 38 | 39 | ## Enforcement Responsibilities 40 | 41 | Community leaders are responsible for clarifying and enforcing our standards of 42 | acceptable behavior and will take appropriate and fair corrective action in 43 | response to any behavior that they deem inappropriate, threatening, offensive, 44 | or harmful. 45 | 46 | Community leaders have the right and responsibility to remove, edit, or reject 47 | comments, commits, code, wiki edits, issues, and other contributions that are 48 | not aligned to this Code of Conduct, and will communicate reasons for moderation 49 | decisions when appropriate. 50 | 51 | ## Scope 52 | 53 | This Code of Conduct applies within all community spaces, and also applies when 54 | an individual is officially representing the community in public spaces. 55 | Examples of representing our community include using an official e-mail address, 56 | posting via an official social media account, or acting as an appointed 57 | representative at an online or offline event. 58 | 59 | ## Enforcement 60 | 61 | Instances of abusive, harassing, or otherwise unacceptable behavior may be 62 | reported to the community leaders responsible for enforcement at 63 | [@egargo](https://github.com/egargo). 64 | All complaints will be reviewed and investigated promptly and fairly. 65 | 66 | All community leaders are obligated to respect the privacy and security of the 67 | reporter of any incident. 68 | 69 | ## Enforcement Guidelines 70 | 71 | Community leaders will follow these Community Impact Guidelines in determining 72 | the consequences for any action they deem in violation of this Code of Conduct: 73 | 74 | ### 1. Correction 75 | 76 | **Community Impact**: Use of inappropriate language or other behavior deemed 77 | unprofessional or unwelcome in the community. 78 | 79 | **Consequence**: A private, written warning from community leaders, providing 80 | clarity around the nature of the violation and an explanation of why the 81 | behavior was inappropriate. A public apology may be requested. 82 | 83 | ### 2. Warning 84 | 85 | **Community Impact**: A violation through a single incident or series 86 | of actions. 87 | 88 | **Consequence**: A warning with consequences for continued behavior. No 89 | interaction with the people involved, including unsolicited interaction with 90 | those enforcing the Code of Conduct, for a specified period of time. This 91 | includes avoiding interactions in community spaces as well as external channels 92 | like social media. Violating these terms may lead to a temporary or 93 | permanent ban. 94 | 95 | ### 3. Temporary Ban 96 | 97 | **Community Impact**: A serious violation of community standards, including 98 | sustained inappropriate behavior. 99 | 100 | **Consequence**: A temporary ban from any sort of interaction or public 101 | communication with the community for a specified period of time. No public or 102 | private interaction with the people involved, including unsolicited interaction 103 | with those enforcing the Code of Conduct, is allowed during this period. 104 | Violating these terms may lead to a permanent ban. 105 | 106 | ### 4. Permanent Ban 107 | 108 | **Community Impact**: Demonstrating a pattern of violation of community 109 | standards, including sustained inappropriate behavior, harassment of an 110 | individual, or aggression toward or disparagement of classes of individuals. 111 | 112 | **Consequence**: A permanent ban from any sort of public interaction within 113 | the community. 114 | 115 | ## Attribution 116 | 117 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], 118 | version 2.0, available at 119 | https://www.contributor-covenant.org/version/2/0/code_of_conduct.html. 120 | 121 | Community Impact Guidelines were inspired by [Mozilla's code of conduct 122 | enforcement ladder](https://github.com/mozilla/diversity). 123 | 124 | [homepage]: https://www.contributor-covenant.org 125 | 126 | For answers to common questions about this code of conduct, see the FAQ at 127 | https://www.contributor-covenant.org/faq. Translations are available at 128 | https://www.contributor-covenant.org/translations. 129 | -------------------------------------------------------------------------------- /pwy/cli.py: -------------------------------------------------------------------------------- 1 | # MIT License 2 | # 3 | # Copyright (c) cegargo 4 | # 5 | # Permission is hereby granted, free of charge, to any person obtaining a copy 6 | # of this software and associated documentation files (the "Software"), to deal 7 | # in the Software without restriction, including without limitation the rights 8 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | # copies of the Software, and to permit persons to whom the Software is 10 | # furnished to do so, subject to the following conditions: 11 | # 12 | # The above copyright notice and this permission notice shall be included in all 13 | # copies or substantial portions of the Software. 14 | # 15 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | # SOFTWARE. 22 | 23 | 24 | import os 25 | import sys 26 | import argparse 27 | import json 28 | import requests 29 | import datetime 30 | from rich import print 31 | 32 | from pwy.translation import TRANSLATIONS_JSON 33 | from pwy.ascii import (clear_sky, few_clouds, overcast_cloud, 34 | rain, thunderstorm, snow, mist, unknown) 35 | from pwy.__version__ import __version__ 36 | 37 | 38 | home = os.path.expanduser("~") 39 | path = f"{home}/.config/pwy.json" if os.name == "posix" else f"{home}\pwy.json" 40 | 41 | 42 | def get_config_data(): 43 | """Read the user's OWM API key from the pwy.json file""" 44 | 45 | config = {} 46 | 47 | with open(path) as pwy_json: 48 | data = json.load(pwy_json) 49 | config = {key: value for key, value in data.items()} 50 | 51 | return config 52 | 53 | 54 | def get_weather_data(location, unit, lang): 55 | """Get weather data from the API and return the necessary data.""" 56 | 57 | url = ( 58 | f"https://api.openweathermap.org/data/2.5/weather?q={location}" 59 | f"&appid={get_config_data()['api_key']}&units={unit}&lang={lang}" 60 | ) 61 | 62 | try: 63 | response = requests.get(url, timeout=10) 64 | response.raise_for_status() 65 | except requests.exceptions.HTTPError as http_err: 66 | status = response.status_code if response else None 67 | if status == 401: 68 | print("[orange1]Error: Invalid API key.[/]") 69 | elif status == 404: 70 | print("[orange1]Error: Location not found. Please check your input or see pwy -h for help.[/]") 71 | elif status == 429: 72 | print("[orange1]Error: API rate limit exceeded. Please wait and try again.[/]") 73 | else: 74 | print(f"[orange1]HTTP error occurred: {http_err}[/]") 75 | sys.exit(1) 76 | except requests.exceptions.ConnectionError: 77 | print("[orange1]Error: Network problem (connection error). Please check your internet connection.[/]") 78 | sys.exit(1) 79 | except requests.exceptions.Timeout: 80 | print("[orange1]Error: Request timed out. Please try again later.[/]") 81 | sys.exit(1) 82 | except requests.exceptions.RequestException as err: 83 | print(f"[orange1]Unexpected error: {err}[/]") 84 | sys.exit(1) 85 | 86 | try: 87 | data = response.json() 88 | except ValueError: 89 | print("[orange1]Error: Unable to parse response from server.[/]") 90 | sys.exit(1) 91 | 92 | try: 93 | weather_info = { 94 | "name": data["name"], 95 | "country": data["sys"]["country"], 96 | "temp": data["main"]["temp"], 97 | "feels_like": data["main"]["feels_like"], 98 | "main": data["weather"][0]["main"], 99 | "description": data["weather"][0]["description"].title(), 100 | "pressure": data["main"]["pressure"], 101 | "humidity": data["main"]["humidity"], 102 | "speed": data["wind"]["speed"], 103 | "deg": data["wind"]["deg"], 104 | "timezone": data["timezone"], 105 | "unit": unit, 106 | "lang": lang, 107 | } 108 | except (KeyError, IndexError) as e: 109 | print(f"[orange1]Error: Unexpected response format ({e}).[/]") 110 | sys.exit(1) 111 | 112 | return weather_info 113 | 114 | 115 | def get_ascii(info): 116 | """Get the weather's ASCII art.""" 117 | 118 | weather = info["description"] 119 | language = get_weather_translation(info) 120 | 121 | if weather == language[0]: 122 | return clear_sky 123 | elif weather in (language[1], language[2]): 124 | return overcast_cloud 125 | elif weather in (language[3], language[4]): 126 | return few_clouds 127 | elif weather in (language[5], language[6], language[7], language[8]): 128 | return rain 129 | elif weather == language[9]: 130 | return thunderstorm 131 | elif weather == language[10]: 132 | return snow 133 | elif weather == language[11]: 134 | return mist 135 | else: 136 | return unknown 137 | 138 | 139 | def get_units(info): 140 | """Return the appropriate unit's indecis.""" 141 | 142 | units = ["°C", "m/s", "°F", "mph", "K"] 143 | 144 | if info["unit"] == "metric": 145 | return (units[0], units[1]) 146 | elif info["unit"] == "imperial": 147 | return (units[2], units[3]) 148 | else: 149 | return (units[4], units[1]) 150 | 151 | 152 | def get_localtime(info): 153 | """Convert data['timezone'] to 'Hour:Minute Timezone' format.""" 154 | 155 | timezone = datetime.timezone(datetime.timedelta(seconds=info["timezone"])) 156 | 157 | return datetime.datetime.now(tz=timezone).strftime("%H:%M %Z") 158 | 159 | 160 | def get_wind_direction(info): 161 | """Convert data['deg'] to cardinal directions.""" 162 | 163 | arrows = ["↓", "↙", "←", "↖", "↑", "↗", "→", "↘"] 164 | direction = int((info["deg"] + 11.25) / 45) 165 | 166 | return arrows[direction % 8] 167 | 168 | 169 | def display_weather_info(info): 170 | """Display the weather information.""" 171 | 172 | ascii = get_ascii(info) 173 | units = get_units(info) 174 | time = get_localtime(info) 175 | dirs = get_wind_direction(info) 176 | 177 | return ( 178 | f"\t{ascii[0]} [b white]{info['name']}, {info['country']}[/]\n" 179 | f"\t{ascii[1]} [green]{info['temp']}[/] " 180 | f"({info['feels_like']}) {units[0]}\n" 181 | f"\t{ascii[2]} [b white]{info['main']}[/]. {info['description']}\n" 182 | f"\t{ascii[3]} [b green]{info['pressure']}[/]hPa " 183 | f"[b green]{info['humidity']}[/]% [b white]{dirs}[/] " 184 | f"[b green]{info['speed']}[/]{units[1]}\n" 185 | f"\t{ascii[4]} {time}\n" 186 | ) 187 | 188 | 189 | def configuration(): 190 | """Configure OWM API key and save it in the pwy.json file.""" 191 | 192 | config = {} 193 | 194 | config["api_key"] = input("OWM API key : ") 195 | config["location"] = input("Location : ") 196 | config["unit"] = input("Unit (metric/imperial) : ") or "metric" 197 | config["lang"] = input("Language : ") or "en" 198 | 199 | with open(path, "w+") as pwy_json: 200 | json.dump(config, pwy_json, indent=4) 201 | 202 | return "[green]Configuration finished.[/]" 203 | 204 | 205 | def main(): 206 | """Get user arguments.""" 207 | 208 | try: 209 | parser = argparse.ArgumentParser( 210 | description="pwy - A simple weather information tool" 211 | ) 212 | 213 | data = get_config_data() 214 | 215 | parser.add_argument( 216 | "location", 217 | nargs="*", 218 | default=f"{data['location']}", 219 | help="input location", 220 | ) 221 | parser.add_argument( 222 | "-c", "--config", action="store_true", help="configure pwy") 223 | parser.add_argument( 224 | "-u", 225 | "--unit", 226 | dest="unit", 227 | default=f"{data['unit']}", 228 | metavar="\b", 229 | help="input unit", 230 | ) 231 | parser.add_argument( 232 | "-l", 233 | "--lang", 234 | dest="language", 235 | default=f"{data['lang']}", 236 | metavar="\b", 237 | help="input language", 238 | ) 239 | parser.add_argument( 240 | "-v", "--version", action="version", version=f"pwy {__version__}" 241 | ) 242 | 243 | args = parser.parse_args() 244 | location = " ".join(args.location) if len( 245 | sys.argv) > 1 else args.location 246 | config = args.config 247 | unit = args.unit 248 | lang = args.language 249 | 250 | if config: 251 | print(configuration()) 252 | else: 253 | info = get_weather_data(location, unit, lang) 254 | print(display_weather_info(info)) 255 | except FileNotFoundError: 256 | print("[orange1]pwy.json does not exist.[/]\n") 257 | print(configuration()) 258 | -------------------------------------------------------------------------------- /pwy/translation.py: -------------------------------------------------------------------------------- 1 | # MIT License 2 | # 3 | # Copyright (c) cegargo 4 | # 5 | # Permission is hereby granted, free of charge, to any person obtaining a copy 6 | # of this software and associated documentation files (the "Software"), to deal 7 | # in the Software without restriction, including without limitation the rights 8 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | # copies of the Software, and to permit persons to whom the Software is 10 | # furnished to do so, subject to the following conditions: 11 | # 12 | # The above copyright notice and this permission notice shall be included in all 13 | # copies or substantial portions of the Software. 14 | # 15 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | # SOFTWARE. 22 | 23 | 24 | TRANSLATIONS_JSON = """ 25 | { 26 | "LANGUAGES": [ 27 | "en", 28 | "af", 29 | "al", 30 | "ar", 31 | "az", 32 | "bg", 33 | "ca", 34 | "cz", 35 | "da", 36 | "de", 37 | "el", 38 | "eu", 39 | "fa", 40 | "fi", 41 | "fr", 42 | "gl", 43 | "he", 44 | "hi", 45 | "hr", 46 | "hu", 47 | "id", 48 | "it", 49 | "ja", 50 | "kr", 51 | "la", 52 | "lt", 53 | "mk", 54 | "no", 55 | "nl", 56 | "pl", 57 | "pt", 58 | "ro", 59 | "ru", 60 | "se", 61 | "sk", 62 | "sl", 63 | "es", 64 | "sr", 65 | "th", 66 | "tr", 67 | "uk", 68 | "vi", 69 | "zu", 70 | "pt_br", 71 | "zh_cn", 72 | "zh_tw" 73 | ], 74 | 75 | "TRANSLATIONS": [ 76 | { 77 | "en": [ 78 | "Clear Sky", 79 | "Broken Clouds", 80 | "Overcast Clouds", 81 | "Few Clouds", 82 | "Scattered Clouds", 83 | "Light Rain", 84 | "Moderate Rain", 85 | "Heavy Rain", 86 | "Heavy Intensity Rain", 87 | "Thunderstorm", 88 | "Snow", 89 | "Mist" 90 | ], 91 | "af": [ 92 | "Helder Lug", 93 | "Los Wolke", 94 | "Bewolk", 95 | "Enkele Wolke", 96 | "Verstrooide Wolke", 97 | "Ligte Reën", 98 | "Matige Reën", 99 | "", 100 | "Swaar Reën", 101 | "", 102 | "", 103 | "Newel" 104 | ], 105 | "al": [ 106 | "Clear Sky", 107 | "Broken Clouds", 108 | "Overcast Clouds", 109 | "Few Clouds", 110 | "Scattered Clouds", 111 | "Light Rain", 112 | "Moderate Rain", 113 | "Heavy Rain", 114 | "Heavy Intensity Rain", 115 | "", 116 | "Snow", 117 | "Mist" 118 | ], 119 | "ar": [ 120 | "", 121 | "", 122 | "", 123 | "", 124 | "", 125 | "", 126 | "", 127 | "", 128 | "", 129 | "", 130 | "", 131 | "" 132 | ], 133 | "az": [ 134 | "Aydın Səma", 135 | "Az Buludlu", 136 | "Qapalı Buludlu", 137 | "Az Buludlu", 138 | "Dağınıq Buludlu", 139 | "Yüngül Yağış", 140 | "Mülayim Yağış", 141 | "", 142 | "Şiddətli Yağış", 143 | "", 144 | "", 145 | "Duman" 146 | ], 147 | "bg": [ 148 | "Ясно Небе", 149 | "Предимно Облачно", 150 | "Облачно", 151 | "Предимно Ясно", 152 | "Разкъсана Облачност", 153 | "Слаб Дъжд", 154 | "Умерен Дъжд", 155 | "", 156 | "", 157 | "", 158 | "", 159 | "Лека Мъгла" 160 | ], 161 | "ca": [ 162 | "Cel Net", 163 | "Nuvolositat Variable", 164 | "Lleugerament Ennuvolat", 165 | "Núvols Dispersos", 166 | "", 167 | "Pluja Suau", 168 | "Pluja", 169 | "", 170 | "", 171 | "", 172 | "", 173 | "Boira" 174 | ], 175 | "cz": [ 176 | "Jasno", 177 | "Oblačno", 178 | "Ennuvolat", 179 | "Skoro Jasno", 180 | "Polojasno", 181 | "Slabý Déšť", 182 | "Déšť", 183 | "", 184 | "", 185 | "", 186 | "", 187 | "Mlha" 188 | ], 189 | "da": [ 190 | "Klar Himmel", 191 | "Spredt Skydække", 192 | "Skydække", 193 | "Få Skyer", 194 | "Spredte Skyer", 195 | "Let Regn", 196 | "Regn", 197 | "", 198 | "", 199 | "", 200 | "", 201 | "Dis" 202 | ], 203 | "de": [ 204 | "Klarer Himmel", 205 | "Überwiegend Bewölkt", 206 | "Bedeckt", 207 | "Ein Paar Wolken", 208 | "Mäßig Bewölkt", 209 | "Leichter Regen", 210 | "Mäßiger Regen", 211 | "Starker Rege", 212 | "", 213 | "", 214 | "", 215 | "Trüb" 216 | ], 217 | "el": [ 218 | "Αίθριος Καιρός", 219 | "Αραιές Νεφώσεις", 220 | "Αυξημένες Νεφώσεις", 221 | "Ελαφρές Νεφώσεις", 222 | "Σποραδικές Νεφώσεις", 223 | "Ασθενείς Βροχοπτώσεις", 224 | "Βροχοπτώσεις Μέτριας Έντασης", 225 | "", 226 | "", 227 | "", 228 | "", 229 | "Ασθενής Ομίχλη" 230 | ], 231 | "es": [ 232 | "Cielo Claro", 233 | "Muy Nuboso", 234 | "Nubes", 235 | "Algo De Nubes", 236 | "Nubes Dispersas", 237 | "Lluvia Ligera", 238 | "Lluvia Moderada", 239 | "", 240 | "", 241 | "", 242 | "", 243 | "Niebla" 244 | ], 245 | "eu": [ 246 | "Oskarbi", 247 | "Hodeiak Eta Ostarteak", 248 | "Zeru Estalia", 249 | "Hodei Gutxi", 250 | "Hodei Sakabanatuak", 251 | "Euri Arina", 252 | "Euria", 253 | "", 254 | "", 255 | "", 256 | "", 257 | "Lainobera" 258 | ], 259 | "fa": [ 260 | "", 261 | "", 262 | "", 263 | "", 264 | "", 265 | "", 266 | "", 267 | "", 268 | "", 269 | "", 270 | "", 271 | "" 272 | ], 273 | "fi": [ 274 | "Taivas On Selkeä", 275 | "Hajanaisia Pilviä", 276 | "Pilvinen", 277 | "Vähän Pilviä", 278 | "Ajoittaisia Pilviä", 279 | "Pieni Sade", 280 | "Kohtalainen Sade", 281 | "", 282 | "", 283 | "", 284 | "", 285 | "Sumu" 286 | ], 287 | "fr": [ 288 | "Ciel Dégagé", 289 | "Nuageux", 290 | "Couvert", 291 | "Peu Nuageux", 292 | "Partiellement Nuageux", 293 | "Légère Pluie", 294 | "Pluie Modérée", 295 | "", 296 | "", 297 | "", 298 | "", 299 | "Brume" 300 | ], 301 | "gl": [ 302 | "Ceo Claro", 303 | "Nubes Rotas", 304 | "Nubes", 305 | "Algo De Nubes", 306 | "Nubes Dispersas", 307 | "Choiva Lixeira", 308 | "Choiva Moderada", 309 | "", 310 | "", 311 | "", 312 | "", 313 | "Néboa" 314 | ], 315 | "he": [ 316 | "", 317 | "", 318 | "", 319 | "", 320 | "", 321 | "", 322 | "", 323 | "", 324 | "", 325 | "", 326 | "", 327 | "" 328 | ], 329 | "hi": [ 330 | "साफ आकाश", 331 | "टूटे हुए बादल", 332 | "घनघोर बादल", 333 | "कुछ बादल", 334 | "छितरे हुए बादल", 335 | "हल्की वर्षा", 336 | "मध्यम वर्षा", 337 | "", 338 | "", 339 | "", 340 | "", 341 | "धुंध" 342 | ], 343 | "hr": [ 344 | "Vedro", 345 | "Isprekidani Oblaci", 346 | "Oblačno", 347 | "Blaga Naoblaka", 348 | "Raštrkani Oblaci", 349 | "Slaba Kiša", 350 | "Umjerena kiša", 351 | "", 352 | "", 353 | "", 354 | "", 355 | "Sumaglica" 356 | ], 357 | "hu": [ 358 | "Tiszta Égbolt", 359 | "Erős Felhőzet", 360 | "Borús Égbolt", 361 | "Kevés Felhő", 362 | "Szórványos Felhőzet", 363 | "Enyhe Eső", 364 | "Közepes Eső", 365 | "", 366 | "", 367 | "", 368 | "", 369 | "Gyenge Köd" 370 | ], 371 | "id": [ 372 | "Langit Cerah", 373 | "Awan Pecah", 374 | "Awan Mendung", 375 | "Sedikit Berawan", 376 | "Awan Tersebar", 377 | "Hujan Rintik-Rintik", 378 | "Hujan Sedang", 379 | "", 380 | "", 381 | "", 382 | "", 383 | "Halimun" 384 | ], 385 | "it": [ 386 | "Cielo Sereno", 387 | "Nubi Sparse", 388 | "Cielo Coperto", 389 | "Poche Nuvole", 390 | "Nubi Sparse", 391 | "Pioggia Leggera", 392 | "Pioggia Moderata", 393 | "", 394 | "", 395 | "", 396 | "", 397 | "Foschia" 398 | ], 399 | "ja": [ 400 | "晴天", 401 | "曇りがち", 402 | "厚い雲", 403 | "薄い雲", 404 | "雲", 405 | "小雨", 406 | "適度な雨", 407 | "強い雨", 408 | "", 409 | "", 410 | "", 411 | "霧" 412 | ], 413 | "kr": [ 414 | "맑음", 415 | "튼구름", 416 | "온흐림", 417 | "약간의 구름이 낀 하늘", 418 | "구름조금", 419 | "실 비", 420 | "보통 비", 421 | "", 422 | "", 423 | "", 424 | "", 425 | "박무"], 426 | "la": [ 427 | "Skaidrs Laiks", 428 | "Mākoņains", 429 | "Mākoņains", 430 | "Mākoņains", 431 | "Mākoņains", 432 | "Smidzina", 433 | "Lietus", 434 | "", 435 | "", 436 | "", 437 | "", 438 | "Migla" 439 | ], 440 | "lt": [ 441 | "Giedra", 442 | "Debesuota Su Pragiedruliais", 443 | "Debesuota", 444 | "Keli Debesys", 445 | "Mažai Debesuota", 446 | "Lengvas Lietus", 447 | "Nepastovus Lietus", 448 | "", 449 | "", 450 | "", 451 | "", 452 | "Migla" 453 | ], 454 | "mk": [ 455 | "Чисто Небо", 456 | "Облаци", 457 | "Облачно", 458 | "Неколку Облаци", 459 | "Одвоени Облаци", 460 | "Слаб Дожд", 461 | "Слаб Дожд", 462 | "", 463 | "", 464 | "", 465 | "", 466 | "Магла" 467 | ], 468 | "no": [ 469 | "Klart", 470 | "Spredt Skydekke", 471 | "Overskyet", 472 | "Enkelte Skyer", 473 | "Spredte Skyer", 474 | "Lett Regn", 475 | "Moderat Regn", 476 | "", 477 | "", 478 | "", 479 | "", 480 | "Tåke"], 481 | "nl": [ 482 | "Onbewolkt", 483 | "Half Bewolkt", 484 | "Bewolkt", 485 | "Zeer Lichte Bewolking", 486 | "Licht Bewolkt", 487 | "Lichte Regen", 488 | "Matige Regen", 489 | "", 490 | "", 491 | "", 492 | "", 493 | "Mist" 494 | ], 495 | "pl": [ 496 | "Bezchmurnie", 497 | "Pochmurno Z Przejaśnieniami", 498 | "Całkowite Zachmurzenie", 499 | "Lekkie Zachmurzenie", 500 | "Rozproszone Chmury", 501 | "Słabe Opady Deszczu", 502 | "Umiarkowane Opady Deszczu", 503 | "", 504 | "", 505 | "", 506 | "", 507 | "Zamglenie" 508 | ], 509 | "pt": [ 510 | "Céu Limpo", 511 | "Nuvens Quebradas", 512 | "Nublado", 513 | "Céu Pouco Nublado", 514 | "Nuvens Dispersas", 515 | "Chuva Fraca", 516 | "Chuva Moderada", 517 | "", 518 | "", 519 | "", 520 | "", 521 | "Nevoeiro" 522 | ], 523 | "ro": [ 524 | "Cer Senin", 525 | "Cer Fragmentat", 526 | "Cer Acoperit De Nori", 527 | "Câțiva Nori", 528 | "Nori Împrăștiați", 529 | "Ploaie Ușoară", 530 | "Ploaie", 531 | "", 532 | "", 533 | "", 534 | "", 535 | "Ceață" 536 | ], 537 | "ru": [ 538 | "Ясно", 539 | "Облачно С Прояснениями", 540 | "Пасмурно", 541 | "Небольшая Облачность", 542 | "Переменная Облачность", 543 | "Небольшой Дождь", 544 | "Дождь", 545 | "", 546 | "", 547 | "", 548 | "", 549 | "Туман"], 550 | "se": [ 551 | "Klar Himmel", 552 | "Molnigt", 553 | "Mulet", 554 | "Lätt Molnighet", 555 | "Växlande Molnighet", 556 | "Lätt Regn", 557 | "Något Regn", 558 | "", 559 | "", 560 | "", 561 | "", 562 | "Dimma" 563 | ], 564 | "sk": [ 565 | "Jasná Obloha", 566 | "Oblačno", 567 | "Zamračené", 568 | "Takmer Jasno", 569 | "Polojasno", 570 | "Slabý Dážď", 571 | "Mierny Dážď", 572 | "", 573 | "", 574 | "", 575 | "", 576 | "Hmla" 577 | ], 578 | "sl": [ 579 | "Jasno", 580 | "Pretežno Oblačno", 581 | "Oblačno", 582 | "Pretrgana Oblačnost", 583 | "Delno Oblačno", 584 | "Rahel Dež", 585 | "Dež", 586 | "", 587 | "", 588 | "", 589 | "", 590 | "Megla"], 591 | "sr": ["Ведро Небо", 592 | "Испрекидани Облаци", 593 | "Ниски Облаци", 594 | "Местимични Облаци", 595 | "Разбацани Облаци", 596 | "Кишица", 597 | "Умерена Киша", 598 | "", 599 | "", 600 | "", 601 | "", 602 | "Сумаглица" 603 | ], 604 | "th": [ 605 | "ท้องฟ้าแจ่มใส", 606 | "เมฆเป็นหย่อม ๆ", 607 | "เมฆเต็มท้องฟ้า", 608 | "เมฆเล็กน้อย", 609 | "เมฆกระจาย", 610 | "ฝนเบา ๆ", 611 | "ฝนปานกลาง", 612 | "", 613 | "", 614 | "", 615 | "", 616 | "หมอก" 617 | ], 618 | "tr": [ 619 | "Açık", 620 | "Parçalı Bulutlu", 621 | "Kapalı", 622 | "Az Bulutlu", 623 | "Parçalı Az Bulutlu", 624 | "Hafif Yağmur", 625 | "Orta Şiddetli Yağmur", 626 | "", 627 | "", 628 | "", 629 | "", 630 | "Sisli" 631 | ], 632 | "uk": [ 633 | "Чисте Небо", 634 | "Рвані Хмари", 635 | "Хмарно", 636 | "Кілька Хмар", 637 | "Уривчасті Хмари", 638 | "Легкий Дощ", 639 | "Помірний Дощ", 640 | "", 641 | "", 642 | "", 643 | "", 644 | "Димка" 645 | ], 646 | "vi": [ 647 | "Bầu Trời Quang Đãng", 648 | "Mây Cụm", 649 | "Mây Đen U Ám", 650 | "Mây Thưa", 651 | "Mây Rải Rác", 652 | "Mưa Nhẹ", 653 | "Mưa Vừa", 654 | "", 655 | "", 656 | "", 657 | "", 658 | "Sương Mờ" 659 | ], 660 | "zu": [ 661 | "Isibhakabhaka Esingenalutho", 662 | "Amafu Angenamandla", 663 | "Liguqubele", 664 | "Gqwagqwa Ngamafu", 665 | "Amafu Lapho Nalapho", 666 | "Imvudlana", 667 | "Imvula Ekahle", 668 | "", 669 | "", 670 | "", 671 | "", 672 | "Inkungu" 673 | ], 674 | "pt_br": [ 675 | "Céu Limpo", 676 | "Nublado", 677 | "Nublado", 678 | "Algumas Nuvens", 679 | "Nuvens Dispersas", 680 | "Chuva Leve", 681 | "Chuva Moderada", 682 | "", 683 | "", 684 | "", 685 | "", 686 | "Névoa" 687 | ], 688 | "zh_cn": [ 689 | "晴", 690 | "多云", 691 | "阴,多云", 692 | "晴,少云", 693 | "多云", 694 | "小雨", 695 | "中雨", 696 | "", 697 | "", 698 | "", 699 | "", 700 | "薄雾" 701 | ], 702 | "zh_tw": [ 703 | "晴", 704 | "多雲", 705 | "陰,多雲", 706 | "晴,少雲", 707 | "多雲", 708 | "小雨", 709 | "中雨", 710 | "", 711 | "", 712 | "", 713 | "", 714 | "薄霧" 715 | ] 716 | } 717 | ] 718 | } 719 | """ 720 | --------------------------------------------------------------------------------