Merge branch 'master' into master

This commit is contained in:
Igor Chubin 2019-07-07 18:55:15 +02:00 committed by GitHub
commit c9ea3315a7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
80 changed files with 10597 additions and 580 deletions

7
.gitignore vendored Normal file
View File

@ -0,0 +1,7 @@
ve/
share/static/fonts/
*.pyc
data/
log/
.idea/
*.swp

19
.travis.yml Normal file
View File

@ -0,0 +1,19 @@
group: travis_latest
language: python
cache: pip
python:
- 2.7
- 3.6
install:
- pip install -r requirements.txt
- pip install flake8 # pytest # add another testing frameworks later
before_script:
# stop the build if there are Python syntax errors or undefined names
- flake8 . --count --select=E901,E999,F821,F822,F823 --show-source --statistics
# exit-zero treats all errors as warnings. The GitHub editor is 127 chars wide
- flake8 . --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics
script:
- true # pytest --capture=sys # add other tests here
notifications:
on_success: change
on_failure: change # `always` will be the setting once code changes slow down.

257
README.md
View File

@ -1,16 +1,17 @@
*wttr.in — the right way to check the weather.*
*wttr.in — the right way to check the weather!*
wttr.in is a console-oriented weather forecast service that supports various information
representation methods like terminal-oriented ANSI-sequences for console HTTP clients
(curl, httpie, or wget), HTML for web browsers, or PNG for graphical viewers.
wttr.in is a console oriented weather forecast service, that supports various information representation methods
like terminal oriented ANSI-sequences for console HTTP clients such as curl, httpie or wget;
HTML for web browsers; or PNG for graphical viewers.
wttr.in uses [wego](http://github.com/schachmat/wego) for visualization
and various data sources for weather forecast information.
You can check it at [wttr.in](http://wttr.in).
You can see it running here: [wttr.in](http://wttr.in).
## Usage
You can access the service from a shell or from a Web browser:
You can access the service from a shell or from a Web browser like this:
$ curl wttr.in
Weather for City: Paris, France
@ -22,42 +23,42 @@ You can access the service from a shell or from a Web browser:
/ \ 0.0 mm
That is how the actual weather report for your location looks like (it is live!):
Here is an actual weather report for your location (it's live!):
![Weather Report](http://wttr.in/MyLocation.png?)
(it's not your location actually, becasue GitHub's CDN hides your real IP address with its own IP address,
but it is still a live weather report in your language).
(It's not your actual location - GitHub's CDN hides your real IP address with its own IP address,
but it's still a live weather report in your language.)
You can specify the location that you want to get the weather information for.
If you omit the location name, you will get the report for your current location,
based on your IP address.
Want to get the weather information for a specific location? You can add the desired location to the URL in your
request like this:
$ curl wttr.in/London
$ curl wttr.in/Moscow
You can use 3-letters airport codes if you want to get the weather information
about some airports:
If you omit the location name, you will get the report for your current location based on your IP address.
Use 3-letter airport codes in order to get the weather information at a certain airport:
$ curl wttr.in/muc # Weather for IATA: muc, Munich International Airport, Germany
$ curl wttr.in/ham # Weather for IATA: ham, Hamburg Airport, Germany
If you want to specify a location that is not a city/town's name, but a name of some geographical location
(e.g. it can be a site in a city, a mountain name, a special location etc.) you should place `~` before its name.
That means the location name should be looked up before:
Let's say you'd like to get the weather for a geographical location other than a town or city - maybe an attraction
in a city, a mountain name, or some special location. Add the character `~` before the name to look up that special
location name before the weather is then retrieved:
$ curl wttr.in/~Vostok+Station
$ curl wttr.in/~Eiffel+Tower
$ curl wttr.in/~Kilimanjaro
In this case there is a line below the weather forecast output describing the founded precise position:
For these examples, you'll see a line below the weather forecast output that shows the geolocation
results of looking up the location:
Location: Vostok Station, станция Восток, AAT, Antarctica [-78.4642714,106.8364678]
Location: Tour Eiffel, 5, Avenue Anatole France, Gros-Caillou, 7e, Paris, Île-de-France, 75007, France [48.8582602,2.29449905432]
Location: Kilimanjaro, Northern, Tanzania [-3.4762789,37.3872648]
You can also use IP-addresses (direct) or domain names (prefixed with @)
as a location specificator:
You can also use IP-addresses (direct) or domain names (prefixed with `@`) to specify a location:
$ curl wttr.in/@github.com
$ curl wttr.in/@msu.ru
@ -66,20 +67,20 @@ To get detailed information online, you can access the [/:help](http://wttr.in/:
$ curl wttr.in/:help
## Additional options
### Weather Units
By default the USCS units are used for the queries from the USA and the
metric system for the rest of the world.
You can override this behavior with the following options:
By default the USCS units are used for the queries from the USA and the metric system for the rest of the world.
You can override this behavior by adding `?u` or `?m` to a URL like this:
$ curl wttr.in/Amsterdam?u
$ curl wttr.in/Amsterdam?m
## Supported formats
## Supported output formats
wttr.in supports three output formats at the moment:
wttr.in currently supports three output formats:
* ANSI for the terminal;
* ANSI for the terminal, one-line mode;
* HTML for the browser;
* PNG for the graphical viewers.
@ -93,44 +94,143 @@ to separate them with `_` instead of `?` and `&`:
$ wget wttr.in/Paris_0tqp_lang=fr.png
Special useful options for the PNG format:
Useful options for the PNG format:
* `t` for transparency (`transparency=150`);
* transparency=0..255 for a custom transparency level.
Transparency is a useful feature when the weather PNGs are used to
add weather data to the pictures:
Transparency is a useful feature when weather PNGs are used to add weather data to pictures:
$ convert 1.jpg <( curl wttr.in/Oymyakon_tqp0.png ) -geometry +50+50 -composite 2.jpg
$ convert source.jpg <( curl wttr.in/Oymyakon_tqp0.png ) -geometry +50+50 -composite target.jpg
Here:
In this example:
* `1.jpg` - source file;
* `2.jpg` - target file;
* Oymyakon - name of the location;
* tqp0 - options (recommended).
* `source.jpg` - source file;
* `target.jpg` - target file;
* `Oymyakon` - name of the location;
* `tqp0` - options (recommended).
![Picture with weather data](https://pbs.twimg.com/media/C69-wsIW0AAcAD5.jpg)
## Special pages
## One-line output
wttr.in can be used not only to check the weather, but also for some other purposes:
For one-line output format, specify additional URL parameter `format`:
```
$ curl wttr.in/Nuremberg?format=3
Nuremberg: 🌦 +11⁰C
```
Available preconfigured formats: 1, 2, 3, 4 and the custom format using the percent notation (see below).
You can specify multiple locations separated with `:` (for repeating queries):
```
$ curl wttr.in/Nuremberg:Hamburg:Berlin?format=3
Nuremberg: 🌦 +11⁰C
```
Or to process all this queries at once:
```
$ curl -s 'wttr.in/{Nuremberg,Hamburg,Berlin}?format=3'
Nuremberg: 🌦 +11⁰C
Hamburg: 🌦 +8⁰C
Berlin: 🌦 +8⁰C
```
To specify your own custom output format, use the special `%`-notation:
```
c Weather condition,
C Weather condition textual name,
h Humidity,
t Temperature,
w Wind,
l Location,
m Moonphase 🌑🌒🌓🌔🌕🌖🌗🌘,
M Moonday,
p precipitation (mm),
P pressure (hPa),
```
So, these two calls are the same:
```
$ curl wttr.in/London?format=3
London: ⛅️ +7⁰C
$ curl wttr.in/London?format="%l:+%c+%t"
London: ⛅️ +7⁰C
```
Keep in mind, that when using in `tmux.conf`, you have to escape `%` with `%`, i.e. write there `%%` instead of `%`.
In progams, that are querying the service automatically (such as tmux),it is better to use some reasonable update interval. In tmux, you can configure it with `status-interval`.
If several, `:` separated locations, are specified in the query, specify update period
as an additional query parameter `period=`:
```
set -g status-interval 60
WEATHER='#(curl -s wttr.in/London:Stockholm:Moscow\?format\="%%l:+%%c%%20%%t%%60%%w&period=60")'
set -g status-right "$WEATHER ..."
```
![wttr.in in tmux status bar](https://wttr.in/files/example-tmux-status-line.png)
To see emojis in terminal, you need:
1. Terminal support for emojis (was added to Cairo 1.15.8);
2. Font with emojis support.
For the Emoji font, we recommend *Noto Color Emoji*, and a good alternative option would be the *Emoji One* font;
both of them support all necessary emoji glyphs.
Font configuration:
```
$ cat ~/.config/fontconfig/fonts.conf
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE fontconfig SYSTEM "fonts.dtd">
<fontconfig>
<alias>
<family>serif</family>
<prefer>
<family>Noto Color Emoji</family>
</prefer>
</alias>
<alias>
<family>sans-serif</family>
<prefer>
<family>Noto Color Emoji</family>
</prefer>
</alias>
<alias>
<family>monospace</family>
<prefer>
<family>Noto Color Emoji</family>
</prefer>
</alias>
</fontconfig>
```
(to apply the configuration, run `fc-cache -f -v`)
## Moon phases
wttr.in can also be used to check the phase of the Moon. This example shows how to see the current Moon phase:
$ curl wttr.in/Moon
To see the current Moon phase (uses [pyphoon](https://github.com/chubin/pyphoon) as its backend).
Get the Moon phase for a particular date by adding `@YYYY-MM-DD`:
$ curl wttr.in/Moon@2016-12-25
To see the Moon phase for the specified date (2016-12-25).
The Moon phase information uses [pyphoon](https://github.com/chubin/pyphoon) as its backend.
## Internationalization and localization
wttr.in supports multilingual locations names: they can be specified in any language in the world
(it may be surprising, but many locations in the world do not have any English name at all).
wttr.in supports multilingual locations names that can be specified in any language in the world
(it may be surprising, but many locations in the world don't have an English name).
The query string should be specified in Unicode (hex encoded or not). If it contains spaces
they must be replaced with +:
The query string should be specified in Unicode (hex-encoded or not). Spaces in the query string
must be replaced with `+`:
$ curl wttr.in/станция+Восток
Weather report: станция Восток
@ -145,48 +245,51 @@ The language used for the output (except the location name) does not depend on t
and it is either English (by default) or the preferred language of the browser (if the query
was issued from a browser) that is specified in the query headers (`Accept-Language`).
It can be set explicitly when using console clients by means of the appropriate command line options
(for example: `curl -H "Accept-Language: fr" wttr.in` or `http GET wttr.in Accept-Language:ru`).
The language can be set explicitly when using console clients by using command-line options like this:
curl -H "Accept-Language: fr" wttr.in
http GET wttr.in Accept-Language:ru
The preferred language can be forced using the `lang` option:
$ curl wttr.in/Berlin?lang=de
The third option is to choose the language using DNS name used in the query:
The third option is to choose the language using the DNS name used in the query:
$ curl de.wttr.in/Berlin
wttr.in is currently translated in more than 45 languages and the number of supported languages
is constantly growing.
wttr.in is currently translated into 54 languages, and the number of supported languages is constantly growing.
See [/:translation](http://wttr.in/:translation) to learn more about the translation process,
to see the list of supported languages and contributors, or to know how you can help to translate wttr.in in your language.
to see the list of supported languages and contributors, or to know how you can help to translate wttr.in
in your language.
![Queries to wttr.in in various languages](https://pbs.twimg.com/media/C7hShiDXQAES6z1.jpg)
## Installation
To install the program:
To install the application:
1. Install external dependencies
2. Install python dependencies used by the service
3. Get WorldWeatherOnline API Key
4. Configure wego
2. Install Python dependencies used by the service
3. Configure IP2Location (optional)
4. Get a WorldWeatherOnline API and configure wego
5. Configure wttr.in
6. Configure HTTP-frontend service
6. Configure the HTTP-frontend service
### Install external dependencies
External requirements:
wttr.in has the following external dependencies:
* [golang](https://golang.org/doc/install), wego dependency
* [wego](https://github.com/schachmat/wego), weather client for terminal
To install `wego` you must have [golang](https://golang.org/doc/install) installed. After that:
After you install [golang](https://golang.org/doc/install), install `wego`:
$ go get -u github.com/schachmat/wego
$ go install github.com/schachmat/wego
### Install python dependencies
### Install Python dependencies
Python requirements:
@ -196,7 +299,7 @@ Python requirements:
* requests
* gevent
If you want to get weather reports as PNG files, install also:
If you want to get weather reports as PNG files, you'll also need to install:
* PIL
* pyte (>=0.6)
@ -208,22 +311,33 @@ If `virtualenv` is used:
$ virtualenv ve
$ ve/bin/pip install -r requirements.txt
$ ve/bin/pip bin/srv.py
(pyte 0.6 is not yet released and it should be installed direct from the source code from its GitHub repository at the moment).
$ ve/bin/python bin/srv.py
Also, you need to install the geoip2 database.
You can use a free database GeoLite2, that can be downloaded from http://dev.maxmind.com/geoip/geoip2/geolite2/
You can use a free database GeoLite2 that can be downloaded from (http://dev.maxmind.com/geoip/geoip2/geolite2/).
### Get WorldWeatherOnline key
### Configure IP2Location (optional)
To get the WorldWeatherOnline API key, you must register here:
If you want to use the IP2location service for IP-addresses that are not covered by GeoLite2,
you have to obtain a API key of that service, and after that save into the `~/.ip2location.key` file:
```
$ echo 'YOUR_IP2LOCATION_KEY' > ~/.ip2location.key
```
If you don't have this file, the service will be silently skipped (it is not a big problem,
because the MaxMind database is pretty good).
### Get a WorldWeatherOnline key and configure wego
To get a WorldWeatherOnline API key, you must register here:
https://developer.worldweatheronline.com/auth/register
### Configure wego
After you have a WorldWeatherOnline key, you can save it into the
WWO key file: `~/.wwo.key`
After you have the key, configure `wego`:
Also, you have to specify the key in the `wego` configuration:
$ cat ~/.wegorc
{
@ -238,8 +352,8 @@ The `City` parameter in `~/.wegorc` is ignored.
### Configure wttr.in
Configure the following environment variables specifing the path to the local `wttr.in`
installation, to the GeoLite database and to the `wego` installation. For example:
Configure the following environment variables that define the path to the local `wttr.in`
installation, to the GeoLite database, and to the `wego` installation. For example:
export WTTR_MYDIR="/home/igor/wttr.in"
export WTTR_GEOLITE="/home/igor/wttr.in/GeoLite2-City.mmdb"
@ -248,10 +362,9 @@ installation, to the GeoLite database and to the `wego` installation. For exampl
export WTTR_LISTEN_PORT="8002"
### Configure HTTP-frontend service
### Configure the HTTP-frontend service
Configure the web server, that will be used
to access the service (if you want to use a web frontend; it's recommended):
It's recommended that you also configure the web server that will be used to access the service:
server {
listen [::]:80;
@ -281,5 +394,3 @@ to access the service (if you want to use a web frontend; it's recommended):
expires off;
}
}

202
bin/proxy.py Normal file
View File

@ -0,0 +1,202 @@
#vim: fileencoding=utf-8
"""
The proxy server acts as a backend for the wttr.in service.
It caches the answers and handles various data sources transforming their
answers into format supported by the wttr.in service.
"""
from __future__ import print_function
from gevent.pywsgi import WSGIServer
from gevent.monkey import patch_all
patch_all()
# pylint: disable=wrong-import-position,wrong-import-order
import sys
import os
import time
import json
import requests
import cyrtranslit
from flask import Flask, request
APP = Flask(__name__)
MYDIR = os.path.abspath(
os.path.dirname(os.path.dirname('__file__')))
sys.path.append("%s/lib/" % MYDIR)
from globals import PROXY_CACHEDIR, PROXY_HOST, PROXY_PORT
from translations import PROXY_LANGS
# pylint: enable=wrong-import-position
def load_translations():
"""
load all translations
"""
translations = {}
for f_name in PROXY_LANGS:
f_name = 'share/translations/%s.txt' % f_name
translation = {}
lang = f_name.split('/')[-1].split('.', 1)[0]
with open(f_name, "r") as f_file:
for line in f_file:
if ':' not in line:
continue
if line.count(':') == 3:
_, trans, orig, _ = line.strip().split(':', 4)
else:
_, trans, orig = line.strip().split(':', 3)
trans = trans.strip()
orig = orig.strip()
translation[orig] = trans
translations[lang] = translation
return translations
TRANSLATIONS = load_translations()
def _find_srv_for_query(path, query): # pylint: disable=unused-argument
return 'http://api.worldweatheronline.com/'
def _load_content_and_headers(path, query):
timestamp = time.strftime("%Y%m%d%H", time.localtime())
cache_file = os.path.join(PROXY_CACHEDIR, timestamp, path, query)
try:
return (open(cache_file, 'r').read(),
json.loads(open(cache_file+".headers", 'r').read()))
except IOError:
return None, None
def _save_content_and_headers(path, query, content, headers):
timestamp = time.strftime("%Y%m%d%H", time.localtime())
cache_file = os.path.join(PROXY_CACHEDIR, timestamp, path, query)
cache_dir = os.path.dirname(cache_file)
if not os.path.exists(cache_dir):
os.makedirs(cache_dir)
open(cache_file + ".headers", 'w').write(json.dumps(headers))
open(cache_file, 'w').write(content)
def translate(text, lang):
"""
Translate `text` into `lang`
"""
translated = TRANSLATIONS.get(lang, {}).get(text, text)
if text.encode('utf-8') == translated:
print("%s: %s" % (lang, text))
return translated
def cyr(to_translate):
"""
Transliterate `to_translate` from latin into cyrillic
"""
return cyrtranslit.to_cyrillic(to_translate)
def _patch_greek(original):
return original.decode('utf-8').replace(u"Ηλιόλουστη/ο", u"Ηλιόλουστη").encode('utf-8')
def add_translations(content, lang):
"""
Add `lang` translation to `content` (JSON)
returned by the data source
"""
languages_to_translate = TRANSLATIONS.keys()
try:
d = json.loads(content) # pylint: disable=invalid-name
except ValueError as exception:
print("---")
print(exception)
print("---")
try:
weather_condition = d['data']['current_condition'][0]['weatherDesc'][0]['value']
if lang in languages_to_translate:
d['data']['current_condition'][0]['lang_%s' % lang] = \
[{'value': translate(weather_condition, lang)}]
elif lang == 'sr':
d['data']['current_condition'][0]['lang_%s' % lang] = \
[{'value': cyr(
d['data']['current_condition'][0]['lang_%s' % lang][0]['value']\
.encode('utf-8'))}]
elif lang == 'el':
d['data']['current_condition'][0]['lang_%s' % lang] = \
[{'value': _patch_greek(
d['data']['current_condition'][0]['lang_%s' % lang][0]['value']\
.encode('utf-8'))}]
elif lang == 'sr-lat':
d['data']['current_condition'][0]['lang_%s' % lang] = \
[{'value':d['data']['current_condition'][0]['lang_sr'][0]['value']\
.encode('utf-8')}]
fixed_weather = []
for w in d['data']['weather']: # pylint: disable=invalid-name
fixed_hourly = []
for h in w['hourly']: # pylint: disable=invalid-name
weather_condition = h['weatherDesc'][0]['value']
if lang in languages_to_translate:
h['lang_%s' % lang] = \
[{'value': translate(weather_condition, lang)}]
elif lang == 'sr':
h['lang_%s' % lang] = \
[{'value': cyr(h['lang_%s' % lang][0]['value'].encode('utf-8'))}]
elif lang == 'el':
h['lang_%s' % lang] = \
[{'value': _patch_greek(h['lang_%s' % lang][0]['value'].encode('utf-8'))}]
elif lang == 'sr-lat':
h['lang_%s' % lang] = \
[{'value': h['lang_sr'][0]['value'].encode('utf-8')}]
fixed_hourly.append(h)
w['hourly'] = fixed_hourly
fixed_weather.append(w)
d['data']['weather'] = fixed_weather
content = json.dumps(d)
except (IndexError, ValueError) as exception:
print(exception)
return content
@APP.route("/<path:path>")
def proxy(path):
"""
Main proxy function. Handles incoming HTTP queries.
"""
lang = request.args.get('lang', 'en')
query_string = request.query_string
query_string = query_string.replace('sr-lat', 'sr')
content, headers = _load_content_and_headers(path, query_string)
if content is None:
srv = _find_srv_for_query(path, query_string)
url = '%s/%s?%s' % (srv, path, query_string)
print(url)
attempts = 5
while attempts:
response = requests.get(url, timeout=10)
try:
json.loads(response.content)
break
except ValueError:
attempts -= 1
headers = {}
headers['Content-Type'] = response.headers['content-type']
content = add_translations(response.content, lang)
_save_content_and_headers(path, query_string, content, headers)
return content, 200, headers
if __name__ == "__main__":
#app.run(host='0.0.0.0', port=5001, debug=False)
#app.debug = True
SERVER = WSGIServer((PROXY_HOST, PROXY_PORT), APP)
SERVER.serve_forever()

View File

@ -1,280 +1,54 @@
import logging
import os
import re
import requests
import socket
import time
#!/usr/bin/env python
# vim: set encoding=utf-8
import geoip2.database
from geopy.geocoders import Nominatim
import jinja2
from gevent.wsgi import WSGIServer
from gevent.pywsgi import WSGIServer
from gevent.monkey import patch_all
from gevent.subprocess import Popen, PIPE
patch_all()
import dns.resolver
from dns.exception import DNSException
# pylint: disable=wrong-import-position,wrong-import-order
import sys
import os
import jinja2
from flask import Flask, request, render_template, send_from_directory
app = Flask(__name__)
from flask import Flask, request, send_from_directory
APP = Flask(__name__)
MYDIR = os.environ.get('WTTR_MYDIR', os.path.abspath(os.path.dirname( os.path.dirname('__file__') )))
GEOLITE = os.environ.get('WTTR_GEOLITE', os.path.join( MYDIR, "GeoLite2-City.mmdb" ))
WEGO = os.environ.get('WTTR_WEGO', "/home/igor/go/bin/wego")
LISTEN_HOST = os.environ.get('WTTR_LISTEN_HOST', "127.0.0.1")
LISTEN_PORT = int(os.environ.get('WTTR_LISTEN_PORT', "8002"))
MYDIR = os.path.abspath(
os.path.dirname(os.path.dirname('__file__')))
sys.path.append("%s/lib/" % MYDIR)
CACHEDIR = os.path.join( MYDIR, "cache" )
IP2LCACHE = os.path.join( MYDIR, "cache/ip2l" )
ALIASES = os.path.join( MYDIR, "share/aliases" )
ANSI2HTML = os.path.join( MYDIR, "share/ansi2html.sh" )
HELP_FILE = os.path.join( MYDIR, 'share/help.txt' )
LOG_FILE = os.path.join( MYDIR, 'log/main.log' )
TEMPLATES = os.path.join( MYDIR, 'share/templates' )
STATIC = os.path.join( MYDIR, 'share/static' )
import wttr_srv
from globals import TEMPLATES, STATIC, LISTEN_HOST, LISTEN_PORT
# pylint: enable=wrong-import-position,wrong-import-order
NOT_FOUND_LOCATION = "NOT_FOUND"
DEFAULT_LOCATION = "Oymyakon"
NOT_FOUND_MESSAGE = """
We were unable to find your location,
so we have brought you to Oymyakon,
one of the coldest permanently inhabited locales on the planet.
"""
PLAIN_TEXT_AGENTS = [
"curl",
"httpie",
"lwp-request",
"wget",
"python-requests"
]
if not os.path.exists(os.path.dirname( LOG_FILE )):
os.makedirs( os.path.dirname( LOG_FILE ) )
logging.basicConfig(filename=LOG_FILE, level=logging.DEBUG)
reader = geoip2.database.Reader(GEOLITE)
geolocator = Nominatim()
my_loader = jinja2.ChoiceLoader([
app.jinja_loader,
MY_LOADER = jinja2.ChoiceLoader([
APP.jinja_loader,
jinja2.FileSystemLoader(TEMPLATES),
])
app.jinja_loader = my_loader
APP.jinja_loader = MY_LOADER
class Limits:
def __init__( self ):
self.intervals = [ 'min', 'hour', 'day' ]
self.divisor = {
'min': 60,
'hour': 3600,
'day': 86400,
}
self.counter = {
'min': {},
'hour': {},
'day': {},
}
self.limit = {
'min': 10,
'hour': 20,
'day': 100,
}
self.last_update = {
'min': 0,
'hour': 0,
'day': 0,
}
self.clear_counters()
def check_ip( self, ip ):
self.clear_counters()
for interval in self.intervals:
if ip not in self.counter[interval]:
self.counter[interval][ip] = 0
self.counter[interval][ip] += 1
if self.limit[interval] <= self.counter[interval][ip]:
log("Too many queries: %s in %s for %s" % (self.limit[interval], interval, ip) )
raise RuntimeError("Not so fast! Number of queries per %s is limited to %s" % (interval, self.limit[interval]))
print self.counter
def clear_counters( self ):
t = int( time.time() )
for interval in self.intervals:
if t / self.divisor[interval] != self.last_update[interval]:
self.counter[interval] = {}
self.last_update[interval] = t / self.divisor[interval]
limits = Limits()
def error( text ):
print text
raise RuntimeError(text)
def log( text ):
print text.encode('utf-8')
logging.info( text.encode('utf-8') )
def is_ip( ip ):
try:
socket.inet_pton(socket.AF_INET, ip)
return True
except socket.error:
try:
socket.inet_pton(socket.AF_INET6, ip)
return True
except socket.error:
return False
def save_weather_data( location, filename ):
if location == NOT_FOUND_LOCATION:
location_not_found = True
location = DEFAULT_LOCATION
else:
location_not_found = False
p = Popen( [ WEGO, '-location=%s' % location ], stdout=PIPE, stderr=PIPE )
stdout, stderr = p.communicate()
if p.returncode != 0:
error( stdout + stderr )
dirname = os.path.dirname( filename )
if not os.path.exists( dirname ):
os.makedirs( dirname )
if location_not_found:
stdout += NOT_FOUND_MESSAGE
open( filename, 'w' ).write( stdout )
p = Popen( [ "bash", ANSI2HTML, "--palette=solarized", "--bg=dark" ], stdin=PIPE, stdout=PIPE, stderr=PIPE )
stdout, stderr = p.communicate( stdout )
if p.returncode != 0:
error( stdout + stderr )
open( filename+'.html', 'w' ).write( stdout )
def get_filename( location ):
location = location.replace('/', '_')
timestamp = time.strftime( "%Y%m%d%H", time.localtime() )
return "%s/%s/%s" % ( CACHEDIR, location, timestamp )
def get_wetter(location, ip, html=False):
filename = get_filename( location )
if not os.path.exists( filename ):
limits.check_ip( ip )
save_weather_data( location, filename )
if html:
filename += '.html'
return open(filename).read()
def ip2location( ip ):
cached = os.path.join( IP2LCACHE, ip )
if os.path.exists( cached ):
return open( cached, 'r' ).read()
try:
t = requests.get( 'http://api.ip2location.com/?ip=%s&key=demo&package=WS10' % ip ).text
if ';' in t:
location = t.split(';')[3]
if not os.path.exists( IP2LCACHE ):
os.makedirs( IP2LCACHE )
open( cached, 'w' ).write( location )
return location
except:
pass
def get_location( ip_addr ):
response = reader.city( ip_addr )
city = response.city.name
if city is None and response.location:
coord = "%s, %s" % (response.location.latitude, response.location.longitude)
location = geolocator.reverse(coord, language='en')
city = location.raw.get('address', {}).get('city')
if city is None:
print ip_addr
city = ip2location( ip_addr )
return city or NOT_FOUND_LOCATION
def load_aliases( aliases_filename ):
aliases_db = {}
with open( aliases_filename, 'r' ) as f:
for line in f.readlines():
from_, to_ = line.split(':', 1)
aliases_db[ from_.strip().lower() ] = to_.strip()
return aliases_db
location_alias = load_aliases( ALIASES )
def location_canonical_name( location ):
if location.lower() in location_alias:
return location_alias[location.lower()]
return location
def show_help():
return open(HELP_FILE, 'r').read()
@app.route('/files/<path:path>')
@APP.route('/files/<path:path>')
def send_static(path):
"Send any static file located in /files/"
return send_from_directory(STATIC, path)
@app.route('/favicon.ico')
@APP.route('/favicon.ico')
def send_favicon():
"Send static file favicon.ico"
return send_from_directory(STATIC, 'favicon.ico')
@app.route("/")
@app.route("/<string:location>")
def wttr(location = None):
@APP.route('/malformed-response.html')
def send_malformed():
"Send static file malformed-response.html"
return send_from_directory(STATIC, 'malformed-response.html')
user_agent = request.headers.get('User-Agent').lower()
if any(agent in user_agent for agent in PLAIN_TEXT_AGENTS):
html_output = False
else:
html_output = True
if location == ':help':
help_ = show_help()
if html_output:
return render_template( 'index.html', body=help_ )
else:
return help_
orig_location = location
if request.headers.getlist("X-Forwarded-For"):
ip = request.headers.getlist("X-Forwarded-For")[0]
if ip.startswith('::ffff:'):
ip = ip[7:]
else:
ip = request.remote_addr
try:
if location is None:
location = get_location( ip )
if is_ip( location ):
location = get_location( location )
if location.startswith('@'):
try:
loc = dns.resolver.query( location[1:], 'LOC' )
location = str("%.7f,%.7f" % (loc[0].float_latitude, loc[0].float_longitude))
except DNSException, e:
location = get_location( socket.getaddrinfo( location[1:], None )[0][4][0] )
location = location_canonical_name( location )
log("%s %s %s %s" % (ip, user_agent, orig_location, location))
return get_wetter( location, ip, html=html_output )
except Exception, e:
logging.error("Exception has occurred", exc_info=1)
return str(e).rstrip()+"\n"
server = WSGIServer((LISTEN_HOST, LISTEN_PORT), app)
server.serve_forever()
@APP.route("/")
@APP.route("/<string:location>")
def wttr(location=None):
"Main function wrapper"
return wttr_srv.wttr(location, request)
SERVER = WSGIServer((LISTEN_HOST, LISTEN_PORT), APP)
SERVER.serve_forever()

View File

@ -4,18 +4,17 @@ TWITTER_BUTTON = """
"""
GITHUB_BUTTON = """
<!-- Place this tag where you want the button to render. -->
<a aria-label="Star chubin/wttr.in on GitHub" data-count-aria-label="# stargazers on GitHub" data-count-api="/repos/chubin/wttr.in#stargazers_count" data-count-href="/chubin/wttr.in/stargazers" data-icon="octicon-star" href="https://github.com/chubin/wttr.in" class="github-button">wttr.in</a>
<a aria-label="Star chubin/wttr.in on GitHub" data-count-aria-label="# stargazers on GitHub" data-count-api="/repos/chubin/wttr.in#stargazers_count" data-count-href="/chubin/wttr.in/stargazers" data-show-count="true" data-icon="octicon-star" href="https://github.com/chubin/wttr.in" class="github-button">wttr.in</a>
"""
GITHUB_BUTTON_2 = """
<!-- Place this tag where you want the button to render. -->
<a aria-label="Star schachmat/wego on GitHub" data-count-aria-label="# stargazers on GitHub" data-count-api="/repos/schachmat/wego#stargazers_count" data-count-href="/schachmat/wego/stargazers" data-icon="octicon-star" href="https://github.com/schachmat/wego" class="github-button">wego</a>
<a aria-label="Star schachmat/wego on GitHub" data-count-aria-label="# stargazers on GitHub" data-count-api="/repos/schachmat/wego#stargazers_count" data-count-href="/schachmat/wego/stargazers" data-show-count="true" data-icon="octicon-star" href="https://github.com/schachmat/wego" class="github-button">wego</a>
"""
GITHUB_BUTTON_3 = """
<!-- Place this tag where you want the button to render. -->
<a aria-label="Star chubin/pyphoon on GitHub" data-count-aria-label="# stargazers on GitHub" data-count-api="/repos/chubin/pyphoon#stargazers_count" data-count-href="/chubin/pyphoon/stargazers" data-icon="octicon-star" href="https://github.com/chubin/pyphoon" class="github-button">pyphoon</a>
<a aria-label="Star chubin/pyphoon on GitHub" data-count-aria-label="# stargazers on GitHub" data-count-api="/repos/chubin/pyphoon#stargazers_count" data-count-href="/chubin/pyphoon/stargazers" data-show-count="true" data-icon="octicon-star" href="https://github.com/chubin/pyphoon" class="github-button">pyphoon</a>
"""
GITHUB_BUTTON_FOOTER = """
@ -23,3 +22,14 @@ GITHUB_BUTTON_FOOTER = """
<script async defer id="github-bjs" src="https://buttons.github.io/buttons.js"></script>
"""
def add_buttons(output):
"""
Add buttons to html output
"""
return output.replace('</body>',
(TWITTER_BUTTON
+ GITHUB_BUTTON
+ GITHUB_BUTTON_3
+ GITHUB_BUTTON_2
+ GITHUB_BUTTON_FOOTER) + '</body>')

78
lib/constants.py Normal file
View File

@ -0,0 +1,78 @@
#vim: fileencoding=utf-8
WWO_CODE = {
"113": "Sunny",
"116": "PartlyCloudy",
"119": "Cloudy",
"122": "VeryCloudy",
"143": "Fog",
"176": "LightShowers",
"179": "LightSleetShowers",
"182": "LightSleet",
"185": "LightSleet",
"200": "ThunderyShowers",
"227": "LightSnow",
"230": "HeavySnow",
"248": "Fog",
"260": "Fog",
"263": "LightShowers",
"266": "LightRain",
"281": "LightSleet",
"284": "LightSleet",
"293": "LightRain",
"296": "LightRain",
"299": "HeavyShowers",
"302": "HeavyRain",
"305": "HeavyShowers",
"308": "HeavyRain",
"311": "LightSleet",
"314": "LightSleet",
"317": "LightSleet",
"320": "LightSnow",
"323": "LightSnowShowers",
"326": "LightSnowShowers",
"329": "HeavySnow",
"332": "HeavySnow",
"335": "HeavySnowShowers",
"338": "HeavySnow",
"350": "LightSleet",
"353": "LightShowers",
"356": "HeavyShowers",
"359": "HeavyRain",
"362": "LightSleetShowers",
"365": "LightSleetShowers",
"368": "LightSnowShowers",
"371": "HeavySnowShowers",
"374": "LightSleetShowers",
"377": "LightSleet",
"386": "ThunderyShowers",
"389": "ThunderyHeavyRain",
"392": "ThunderySnowShowers",
"395": "HeavySnowShowers",
}
WEATHER_SYMBOL = {
"Unknown": u"",
"Cloudy": u"☁️",
"Fog": u"🌫",
"HeavyRain": u"🌧",
"HeavyShowers": u"🌧",
"HeavySnow": u"❄️",
"HeavySnowShowers": u"❄️",
"LightRain": u"🌦",
"LightShowers": u"🌦",
"LightSleet": u"🌧",
"LightSleetShowers": u"🌧",
"LightSnow": u"🌨",
"LightSnowShowers": u"🌨",
"PartlyCloudy": u"⛅️",
"Sunny": u"☀️",
"ThunderyHeavyRain": u"🌩",
"ThunderyShowers": u"",
"ThunderySnowShowers": u"",
"VeryCloudy": u"☁️",
}
WIND_DIRECTION = [
u"", u"", u"", u"", u"", u"", u"", u"",
]

View File

@ -1,41 +1,124 @@
"""
global configuration of the project
External environment variables:
WTTR_MYDIR
WTTR_GEOLITE
WTTR_WEGO
WTTR_LISTEN_HOST
WTTR_LISTEN_PORT
"""
from __future__ import print_function
import logging
import os
MYDIR = os.path.abspath(os.path.dirname( os.path.dirname('__file__') ))
MYDIR = os.path.abspath(os.path.dirname(os.path.dirname('__file__')))
GEOLITE = os.path.join( MYDIR, "GeoLite2-City.mmdb" )
WEGO = "/home/igor/go/bin/we-lang"
PYPHOON = "/home/igor/wttr.in/pyphoon/bin/pyphoon-lolcat"
if "WTTR_GEOLITE" in os.environ:
GEOLITE = os.environ["WTTR_GEOLITE"]
else:
GEOLITE = os.path.join(MYDIR, 'data', "GeoLite2-City.mmdb")
CACHEDIR = os.path.join( MYDIR, "cache" )
IP2LCACHE = os.path.join( MYDIR, "cache/ip2l" )
WEGO = os.environ.get("WTTR_WEGO", "/home/igor/go/bin/we-lang")
PYPHOON = "/home/igor/pyphoon/bin/pyphoon-lolcat"
ALIASES = os.path.join( MYDIR, "share/aliases" )
ANSI2HTML = os.path.join( MYDIR, "share/ansi2html.sh" )
BLACKLIST = os.path.join( MYDIR, "share/blacklist" )
_DATADIR = "/wttr.in"
_LOGDIR = "/wttr.in/log"
HELP_FILE = os.path.join( MYDIR, 'share/help.txt' )
BASH_FUNCTION_FILE = os.path.join( MYDIR, 'share/bash-function.txt' )
TRANSLATION_FILE = os.path.join( MYDIR, 'share/translation.txt' )
CACHEDIR = os.path.join(_DATADIR, "cache/wego/")
IP2LCACHE = os.path.join(_DATADIR, "cache/ip2l/")
PNG_CACHE = os.path.join(_DATADIR, "cache/png")
LOG_FILE = os.path.join( MYDIR, 'log/main.log' )
TEMPLATES = os.path.join( MYDIR, 'share/templates' )
STATIC = os.path.join( MYDIR, 'share/static' )
LOG_FILE = os.path.join(_LOGDIR, 'main.log')
ALIASES = os.path.join(MYDIR, "share/aliases")
ANSI2HTML = os.path.join(MYDIR, "share/ansi2html.sh")
BLACKLIST = os.path.join(MYDIR, "share/blacklist")
HELP_FILE = os.path.join(MYDIR, 'share/help.txt')
BASH_FUNCTION_FILE = os.path.join(MYDIR, 'share/bash-function.txt')
TRANSLATION_FILE = os.path.join(MYDIR, 'share/translation.txt')
TEST_FILE = os.path.join(MYDIR, 'share/test-NAME.txt')
IATA_CODES_FILE = os.path.join(MYDIR, 'share/list-of-iata-codes.txt')
TEMPLATES = os.path.join(MYDIR, 'share/templates')
STATIC = os.path.join(MYDIR, 'share/static')
NOT_FOUND_LOCATION = "not found"
DEFAULT_LOCATION = "oymyakon"
MALFORMED_RESPONSE_HTML_PAGE = open(os.path.join(STATIC, 'malformed-response.html')).read()
GEOLOCATOR_SERVICE = 'http://localhost:8004'
# number of queries from the same IP address is limited
# (minute, hour, day) limitations:
QUERY_LIMITS = (300, 3600, 24*3600)
LISTEN_HOST = os.environ.get("WTTR_LISTEN_HOST", "")
try:
LISTEN_PORT = int(os.environ.get("WTTR_LISTEN_PORT"))
except (TypeError, ValueError):
LISTEN_PORT = 8002
PROXY_HOST = "127.0.0.1"
PROXY_PORT = 5001
PROXY_CACHEDIR = os.path.join(_DATADIR, "cache/proxy-wwo/")
MY_EXTERNAL_IP = '5.9.243.187'
PLAIN_TEXT_AGENTS = [
"curl",
"httpie",
"lwp-request",
"wget",
"python-requests",
"OpenBSD ftp"
]
PLAIN_TEXT_PAGES = [':help', ':bash.function', ':translation']
_IP2LOCATION_KEY_FILE = os.environ['HOME'] + '/.ip2location.key'
IP2LOCATION_KEY = None
if os.path.exists(_IP2LOCATION_KEY_FILE):
IP2LOCATION_KEY = open(_IP2LOCATION_KEY_FILE, 'r').read().strip()
_WWO_KEY_FILE = os.environ['HOME'] + '/.wwo.key'
WWO_KEY = "key-is-not-specified"
if os.path.exists(_WWO_KEY_FILE):
WWO_KEY = open(_WWO_KEY_FILE, 'r').read().strip()
def error(text):
"log error `text` and raise a RuntimeError exception"
if not text.startswith('Too many queries'):
print text
logging.error("ERROR "+text)
print(text)
logging.error("ERROR %s", text)
raise RuntimeError(text)
def log(text):
"log error `text` and do not raise any exceptions"
if not text.startswith('Too many queries'):
print text
print(text)
logging.info(text)
def debug_log(text):
"""
Write `text` to the debug log
"""
with open('/tmp/wttr.in-debug.log', 'a') as f_debug:
f_debug.write(text+'\n')
def get_help_file(lang):
"Return help file for `lang`"
help_file = os.path.join(MYDIR, 'share/translations/%s-help.txt' % lang)
if os.path.exists(help_file):
return help_file
return HELP_FILE

108
lib/limits.py Normal file
View File

@ -0,0 +1,108 @@
"""
Connection limitation.
Number of connections from one IP is limited.
We have nothing against scripting and automated queries.
Even the opposite, we encourage them. But there are some
connection limits that even we can't handle.
Currently the limits are quite restrictive, but they will be relaxed
in the future.
Usage:
limits = Limits()
not_allowed = limits.check_ip(ip_address)
if not_allowed:
return "ERROR: %s" % not_allowed
[Taken from github.com/chubin/cheat.sh]
"""
import time
from globals import log
def _time_caps(minutes, hours, days):
return {
'min': minutes,
'hour': hours,
'day': days,
}
class Limits(object):
"""
Queries limitation (by IP).
Exports:
check_ip(ip_address)
"""
def __init__(self, whitelist=None, limits=None):
self.intervals = ['min', 'hour', 'day']
self.divisor = _time_caps(60, 3600, 86400)
self.last_update = _time_caps(0, 0, 0)
if limits:
self.limit = _time_caps(*limits)
else:
self.limit = _time_caps(30, 600, 1000)
if whitelist:
self.whitelist = whitelist[:]
else:
self.whitelist = []
self.counter = {
'min': {},
'hour': {},
'day': {},
}
self._clear_counters_if_needed()
def _log_visit(self, interval, ip_address):
if ip_address not in self.counter[interval]:
self.counter[interval][ip_address] = 0
self.counter[interval][ip_address] += 1
def _limit_exceeded(self, interval, ip_address):
visits = self.counter[interval][ip_address]
limit = self._get_limit(interval)
return visits > limit
def _get_limit(self, interval):
return self.limit[interval]
def _report_excessive_visits(self, interval, ip_address):
log("%s LIMITED [%s for %s]" % (ip_address, self._get_limit(interval), interval))
def check_ip(self, ip_address):
"""
Check if `ip_address` is allowed, and if not raise an RuntimeError exception.
Return True otherwise
"""
if ip_address in self.whitelist:
return None
self._clear_counters_if_needed()
for interval in self.intervals:
self._log_visit(interval, ip_address)
if self._limit_exceeded(interval, ip_address):
self._report_excessive_visits(interval, ip_address)
return ("Not so fast! Number of queries per %s is limited to %s"
% (interval, self._get_limit(interval)))
return None
def reset(self):
"""
Reset all counters for all IPs
"""
for interval in self.intervals:
self.counter[interval] = {}
def _clear_counters_if_needed(self):
current_time = int(time.time())
for interval in self.intervals:
if current_time // self.divisor[interval] != self.last_update[interval]:
self.counter[interval] = {}
self.last_update[interval] = current_time / self.divisor[interval]

273
lib/location.py Normal file
View File

@ -0,0 +1,273 @@
"""
All location related functions and converters.
The main entry point is `location_processing`
which gets `location` and `source_ip_address`
and basing on this information generates
precise location description.
"""
from __future__ import print_function
import os
import json
import re
import socket
import requests
import geoip2.database
from globals import GEOLITE, GEOLOCATOR_SERVICE, IP2LCACHE, IP2LOCATION_KEY, NOT_FOUND_LOCATION, \
ALIASES, BLACKLIST, IATA_CODES_FILE
GEOIP_READER = geoip2.database.Reader(GEOLITE)
def ascii_only(string):
"Check if `string` contains only ASCII symbols"
try:
for _ in range(5):
string = string.encode('utf-8')
return True
except UnicodeDecodeError:
return False
def is_ip(ip_addr):
"""
Check if `ip_addr` looks like an IP Address
"""
if re.match(r'\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}', ip_addr) is None:
return False
try:
socket.inet_aton(ip_addr)
return True
except socket.error:
return False
def location_normalize(location):
"""
Normalize location name `location`
"""
#translation_table = dict.fromkeys(map(ord, '!@#$*;'), None)
def _remove_chars(chars, string):
return ''.join(x for x in string if x not in chars)
location = location.lower().replace('_', ' ').replace('+', ' ').strip()
if not location.startswith('moon@'):
location = _remove_chars(r'!@#$*;:\\', location)
return location
def geolocator(location):
"""
Return a GPS pair for specified `location` or None
if nothing can't be found
"""
try:
geo = requests.get('%s/%s' % (GEOLOCATOR_SERVICE, location)).text
except requests.exceptions.ConnectionError as exception:
print("ERROR: %s" % exception)
return None
if geo == "":
return None
try:
answer = json.loads(geo.encode('utf-8'))
return answer
except ValueError as exception:
print("ERROR: %s" % exception)
return None
return None
def ip2location(ip_addr):
"Convert IP address `ip_addr` to a location name"
cached = os.path.join(IP2LCACHE, ip_addr)
if not os.path.exists(IP2LCACHE):
os.makedirs(IP2LCACHE)
location = None
if os.path.exists(cached):
location = open(cached, 'r').read()
else:
# if IP2LOCATION_KEY is not set, do not the query,
# because the query wont be processed anyway
if IP2LOCATION_KEY:
try:
ip2location_response = requests\
.get('http://api.ip2location.com/?ip=%s&key=%s&package=WS3' \
% (ip_addr, IP2LOCATION_KEY)).text
if ';' in ip2location_response:
open(cached, 'w').write(ip2location_response)
location = ip2location_response
except requests.exceptions.ConnectionError:
pass
if location and ';' in location:
location = location.split(';')[3], location.split(';')[1]
else:
location = location, None
return location
def get_location(ip_addr):
"""
Return location pair (CITY, COUNTRY) for `ip_addr`
"""
try:
response = GEOIP_READER.city(ip_addr)
country = response.country.name
city = response.city.name
except geoip2.errors.AddressNotFoundError:
country = None
city = None
#
# temporary disabled it because of geoip services capcacity
#
#if city is None and response.location:
# coord = "%s, %s" % (response.location.latitude, response.location.longitude)
# try:
# location = geolocator.reverse(coord, language='en')
# city = location.raw.get('address', {}).get('city')
# except:
# pass
if city is None:
city, country = ip2location(ip_addr)
# workaround for the strange bug with the country name
# maybe some other countries has this problem too
if country == 'Russian Federation':
country = 'Russia'
if city:
return city, country
else:
return NOT_FOUND_LOCATION, None
def location_canonical_name(location):
"Find canonical name for `location`"
location = location_normalize(location)
if location.lower() in LOCATION_ALIAS:
return LOCATION_ALIAS[location.lower()]
return location
def load_aliases(aliases_filename):
"""
Load aliases from the aliases file
"""
aliases_db = {}
with open(aliases_filename, 'r') as f_aliases:
for line in f_aliases.readlines():
from_, to_ = line.decode('utf-8').split(':', 1)
aliases_db[location_normalize(from_)] = location_normalize(to_)
return aliases_db
def load_iata_codes(iata_codes_filename):
"""
Load IATA codes from the IATA codes file
"""
with open(iata_codes_filename, 'r') as f_iata_codes:
result = []
for line in f_iata_codes.readlines():
result.append(line.strip())
return set(result)
LOCATION_ALIAS = load_aliases(ALIASES)
LOCATION_BLACK_LIST = [x.strip() for x in open(BLACKLIST, 'r').readlines()]
IATA_CODES = load_iata_codes(IATA_CODES_FILE)
def is_location_blocked(location):
"""
Return True if this location is blocked
or False if it is allowed
"""
return location is not None and location.lower() in LOCATION_BLACK_LIST
def location_processing(location, ip_addr):
"""
"""
# if location is starting with ~
# or has non ascii symbols
# it should be handled like a search term (for geolocator)
override_location_name = None
full_address = None
hide_full_address = False
force_show_full_address = location is not None and location.startswith('~')
# location ~ means that it should be detected automatically,
# and shown in the location line below the report
if location == '~':
location = None
if location and location.lstrip('~ ').startswith('@'):
try:
location, country = get_location(
socket.gethostbyname(
location.lstrip('~ ')[1:]))
location = '~' + location
if country:
location += ", %s" % country
hide_full_address = not force_show_full_address
except:
location, country = NOT_FOUND_LOCATION, None
query_source_location = get_location(ip_addr)
country = None
if not location or location == 'MyLocation':
location = ip_addr
if is_ip(location):
location, country = get_location(location)
# here too
if location:
location = '~' + location
if country:
location += ", %s" % country
hide_full_address = not force_show_full_address
if location and not location.startswith('~'):
tmp_location = location_canonical_name(location)
if tmp_location != location:
override_location_name = location
location = tmp_location
# up to this point it is possible that the name
# contains some unicode symbols
# here we resolve them
if location is not None and not ascii_only(location):
location = "~" + location.lstrip('~ ')
if location is not None and location.upper() in IATA_CODES:
location = '~%s' % location
if location is not None and location.startswith('~'):
geolocation = geolocator(location_canonical_name(location[1:]))
if geolocation is not None:
override_location_name = location[1:].replace('+', ' ')
location = "%s,%s" % (geolocation['latitude'], geolocation['longitude'])
country = None
if not hide_full_address:
full_address = geolocation['address']
else:
full_address = None
else:
location = NOT_FOUND_LOCATION #location[1:]
return location, \
override_location_name, \
full_address, \
country, \
query_source_location

View File

@ -1,3 +1,29 @@
def metric_or_imperial(query, lang, us_ip=False):
"""
"""
# what units should be used
# metric or imperial
# based on query and location source (imperial for US by default)
if query.get('use_metric', False) and not query.get('use_imperial', False):
query['use_imperial'] = False
query['use_metric'] = True
elif query.get('use_imperial', False) and not query.get('use_metric', False):
query['use_imperial'] = True
query['use_metric'] = False
elif lang == 'us':
# slack uses m by default, to override it speciy us.wttr.in
query['use_imperial'] = True
query['use_metric'] = False
else:
if us_ip:
query['use_imperial'] = True
query['use_metric'] = False
else:
query['use_imperial'] = False
query['use_metric'] = True
return query
def parse_query(args):
result = {}
@ -19,6 +45,8 @@ def parse_query(args):
if q is None:
return result
if 'A' in q:
result['force-ansi'] = True
if 'n' in q:
result['narrow'] = True
if 'm' in q:
@ -46,6 +74,8 @@ def parse_query(args):
result['no-caption'] = True
if 'Q' in q:
result['no-city'] = True
if 'F' in q:
result['no-follow-line'] = True
for key, val in args.items():
if val == 'True':

View File

@ -1,20 +1,31 @@
# vim: set encoding=utf-8
# vim: fileencoding=utf-8
"""
Translation of almost everything.
"""
FULL_TRANSLATION = [
"de", "nb",
"af", "da", "de", "el", "et", "fr", "fa", "hu",
"id", "it", "nb", "nl", "pl", "pt-br", "ro", "ru",
"uk"
]
PARTIAL_TRANSLATION = [
"az", "be", "bg", "bs", "ca", "cy", "cs",
"da", "el", "eo", "es", "et", "fi", "fr",
"hi", "hr", "hu", "hy", "is", "it", "ja",
"jv", "ka", "kk", "ko", "ky", "lt", "lv",
"mk", "ml", "nl", "nn", "pt", "pl", "ro",
"ru", "sk", "sl", "sr", "sr-lat", "sv",
"sw", "th", "tr", "uk", "uz", "vi", "zh",
"zu",
"az", "be", "bg", "bs", "ca", "cy", "cs",
"eo", "es", "fi", "ga", "hi", "hr",
"hy", "is", "ja", "jv", "ka", "kk",
"ko", "ky", "lt", "lv", "mk", "ml", "nl", "fy",
"nn", "pt", "pt-br", "sk", "sl", "sr", "sr-lat",
"sv", "sw", "th", "tr", "te", "uz", "vi",
"zh", "zu", "he",
]
PROXY_LANGS = [
"af", "az", "be", "bs", "ca", "cy", "el", "eo",
"et", "fa", "fy", "he", "hr", "hu", "hy", "id", "is",
"it", "ja", "kk", "lv", "mk", "nb", "nn",
"ro", "ru", "sl", "pt-br", "uk", "uz",
]
SUPPORTED_LANGS = FULL_TRANSLATION + PARTIAL_TRANSLATION
@ -24,202 +35,302 @@ MESSAGE = {
We were unable to find your location
so we have brought you to Oymyakon,
one of the coldest permanently inhabited locales on the planet.
""",
'af': u"""
Ons kon nie u ligging opspoor nie
gevolglik het ons vir u na Oymyakon geneem,
een van die koudste permanent bewoonde plekke op aarde.
""",
'be': u"""
Ваша месцазнаходжанне вызначыць не атрымалася,
таму мы пакажам вам надвор'е ў Аймяконе,
самым халодным населеным пункце на планеце.
Будзем спадзявацца, што ў вас сёння надвор'е лепей!
""",
'bg':u"""
Не успяхме да открием вашето местоположение
така че ви доведохме в Оймякон,
едно от най-студените постоянно обитавани места на планетата.
""",
'bs': u"""
Nismo mogli pronaći vašu lokaciju,
tako da smo te doveli do Oymyakon,
jedan od najhladnijih stalno naseljena mjesta na planeti.
Nadamo se da ćete imati bolje vreme!
Nadamo se da ćete imati bolje vreme!
""",
'ca': u"""
Hem estat incapaços de trobar la seva ubicació,
és per aquest motiu que l'hem portat fins Oymyakon,
un dels llocs més freds inhabitats de manera permanent al planeta.
per això l'hem portat fins Oymyakon,
un dels llocs més freds i permanentment deshabitats del planeta.
""",
'cs': u"""
Nepodařilo se nám najít vaši polohu,
takže jsme vás přivedl do Ojmjakonu.
Je to jedno z nejchladnějších trvale obydlených míst na planetě.
Doufáme, že budete mít lepší počasí!
""",
'cy': u"""
Ni darganfyddwyd eich lleoliad,
felly rydym wedi dod â chi i Oymyakon,
un o'r llefydd oerach ar y blaned lle mae pobl yn fyw!
un o'r llefydd oeraf ar y blaned ble mae pobl yn dal i fyw!
""",
'de': u"""
Wir konnten Ihren Standort nicht finden,
also haben wir Sie nach Oimjakon gebracht,
einer der kältesten dauerhaft bewohnten Orte auf dem Planeten.
Wir hoffen, dass Sie besseres Wetter haben!
""",
""",
'el': u"""
Δεν μπορέσαμε να βρούμε την τοποθεσία σου,
για αυτό διαλέξαμε το Οϊμιάκον για εσένα,
μία από τις πιο κρύες μόνιμα κατοικημένες περιοχές στον πλανήτη.
Ελπίζουμε να έχεις καλύτερο καιρό!
""",
'es': u"""
No hemos logrado encontrar tu ubicación,
asi que hemos decidido enseñarte el tiempo en Oymyakon,
uno de los sitios más fríos y permanentemente deshabitados del planeta.
""",
'fa': u"""
ما نتونستیم مکان شما رو پیدا کنیم. به همین خاطر شما رو به om بردیم
، یکی از سردترین مکان های روی زمین که اصلا قابل سکونت نیست!
""",
'fi': u"""
Emme löytänyt sijaintiasi, joten toimme sinut Oimjakoniin,
yhteen maailman kylmimmistä pysyvästi asutetuista paikoista.
Toivottavasti sinulla on parempi sää!
""",
'fr': u"""
Nous n'avons pas pu déterminer votre position,
Nous vous avons donc amenés à Oïmiakon,
l'un des endroits les plus froids habités en permanence sur la planète.
Nous espérons qu'il fait meilleur chez vous !
""",
'hu': u"""
Nem sikerült megtalálni a pozíciódat,
így elhoztunk Ojmjakonba;
az egyik leghidegebb állandóan lakott településre a bolygón.
""",
'hy': u"""
Ձեր գտնվելու վայրը չհաջողվեց որոշել,
այդ պատճառով մենք ձեզ կցուցադրենք եղանակը Օյմյակոնում.
երկրագնդի ամենասառը բնակավայրում։
Հույս ունենք որ ձեր եղանակը այսօր ավելի լավն է։
""",
'id': u"""
Kami tidak dapat menemukan lokasi anda,
jadi kami membawa anda ke Oymyakon,
salah satu tempat terdingin yang selalu dihuni di planet ini!
""",
'is': u"""
Við finnum ekki staðsetninguna þína og vísum þér þar með á Ojmjakon,
ein af köldustu byggðum jarðar.
Vonandi er betra veður hjá þér.
""",
'it': u"""
Non siamo riusciti a trovare la sua posizione
quindi la abbiamo portato a Oymyakon,
uno dei luoghi abitualmente abitati più freddi del pianeta.
Ci auguriamo che le condizioni dove lei si trova siano migliori!
""",
'ja': u"""
指定された場所が見つかりませんでした
代わりにオイミャコンの天気予報を表示しています
オイミャコンは地球上で最も寒い居住地の一つです
""",
'ko': u"""
지정된 장소를 찾을 없습니다,
대신 오이먀콘의 일기 예보를 표시합니다,
오이먀콘은 지구상에서 가장 추운 곳에 위치한 마을입니다!
""",
'lv': u"""
Mēs nevarējām atrast jūsu atrašanās vietu tādēļ nogādājām jūs Oimjakonā,
vienā no aukstākajām apdzīvotajām vietām uz planētas.
""",
'mk': u"""
Неможевме да ја пронајдеме вашата локација,
затоа ве однесовме во Ојмајкон,
еден од најладните трајно населени места на планетата.
""",
'nb': u"""
Vi kunne ikke finne din lokasjon,
her får du Ojmjakon, et av de kaldeste bebodde stedene planeten.
Vi håper været er bedre hos deg!
""",
'nl': u"""
Wij konden uw locatie niet vaststellen
dus hebben we u naar Ojmjakon gebracht,
één van de koudste permanent bewoonde gebieden op deze planeet.
""",
'fy': u"""
Wy koenen jo lokaasje net fêststelle
dus wy ha jo nei Ojmjakon brocht,
ien fan de kâldste permanent bewenbere plakken op ierde.
""",
'pt': u"""
Não conseguimos encontrar a sua localização,
então decidimos te mostrar o tempo em Oymyakon,
um dos lugares mais frios e permanentemente desabitados do planeta.
""",
'pt-br': u"""
Não conseguimos encontrar a sua localização,
então decidimos te mostrar o tempo em Oymyakon,
um dos lugares mais frios e permanentemente desabitados do planeta.
""",
'pl': u"""
Nie udało nam się znaleźć podanej przez Ciebie lokalizacji,
więc zabraliśmy Cię do Ojmiakonu,
jednego z najzimniejszych, stale zamieszkanych miejsc na Ziemi.
Mamy nadzieję, że u Ciebie jest cieplej!
""",
'ro': u"""
Nu v-am putut identifica locația, prin urmare va aratam vremea din Oimiakon,
Nu v-am putut identifica localitatea, prin urmare arătăm vremea din Oimiakon,
una dintre cele mai reci localități permanent locuite de pe planetă.
Sperăm aveți vreme mai bună!
""",
'ru': u"""
Ваше местоположение определить не удалось,
поэтому мы покажем вам погоду в Оймяконе,
самом холодном населённом пункте на планете.
Будем надеяться, что у вас сегодня погода лучше!
""",
'sk': u"""
Nepodarilo sa nám nájsť vašu polohu,
takže sme vás priviedli do Ojmiakonu.
Je to jedno z najchladnejších trvale obývaných miest na planéte.
Dúfame, že budete mať lepšie počasie!
""",
'sr': u"""
Нисмо успели да пронађемо Вашу локацију,
па смо Вас довели у Ојмјакон,
једно од најхладнијих стално насељених места на планети.
Надамо се да је време код Вас боље него што је то случај овде!
""",
'sv': u"""
Vi lyckades inte hitta er plats vi har istället tagit er till Ojmjakon,
en av planetens kallaste platser med permanent bosättning.
Vi hoppas att vädret är bättre hos dig!
""",
'tr': u"""
Aradığınız bölge bulunamadı. O yüzden sizi dünyadaki en soğuk sürekli
Aradığınız konum bulunamadı. O yüzden sizi dünyadaki en soğuk sürekli
yerleşim yerlerinden biri olan Oymyakon'e getirdik.
Umarız sizin olduğunuz yerde havalar daha iyidir!
""",
'uk': u"""
Ваше місце розташування визначити не вдалося,
тому ми покажемо вам погоду в Оймяконе,
найхолоднішому населеному пункті на планеті.
Будемо сподіватися, що у вас сьогодні погода краще!
'te': u"""
ి కననలకప
కన మన "ఓమాయకాన్కు" ి వచ,
ి అతయల వత ివసి ి రదలల ఒకటి.
""",
'uk': u"""
Ми не змогли визначити Ваше місцезнаходження,
тому покажемо Вам погоду в Оймяконі
найхолоднішому населеному пункті на планеті.
Будемо сподіватися, що у Вас сьогодні погода краще!
""",
'uz': u"""
Sizning joylashuvingizni aniqlay olmadik,
shuning uchun sizga sayyoramizning eng sovuq aholi punkti - Oymyakondagi ob-havo haqida ma'lumot beramiz.
Umid qilamizki, sizda bugungi ob-havo bundan yaxshiroq!
"""
},
""",
'da': u"""
Vi kunne desværre ikke finde din lokation
vi har bragt dig til Oymyakon,
En af koldeste og helt ubolige lokationer planeten.
""",
'et': u"""
Me ei suutnud tuvastada teie asukohta
ning seetõttu paigutasime teid Oymyakoni,
mis on üks kõige külmemaid püsivalt asustatud paiku planeedil.
""",
},
'UNKNOWN_LOCATION': {
'en': u'Unknown location',
'af': u'Onbekende ligging',
'be': u'Невядомае месцазнаходжанне',
'bg': u'Неизвестно местоположение',
'bs': u'Nepoznatoja lokacija',
'ca': u'Localització desconeguda',
'ca': u'Ubicació desconeguda',
'cs': u'Neznámá poloha',
'cy': u'Lleoliad anhysbys',
'de': u'Unbekannter Ort',
'da': u'Ukendt lokation',
'el': u'Άνγωστη τοποθεσία',
'es': u'Ubicación desconocida',
'et': u'Tundmatu asukoht',
'fa': u'مکان نامعلوم',
'fi': u'Tuntematon sijainti',
'fr': u'Emplacement inconnu',
'hu': u'Ismeretlen lokáció',
'hy': u'Անհայտ գտնվելու վայր',
'id': u'Lokasi tidak diketahui',
'is': u'Óþekkt staðsetning',
'it': u'Località sconosciuta',
'ja': u'未知の場所です',
'ko': u'알 수 없는 장소',
'kk': u'',
'lv': u'Nezināma atrašanās vieta',
'mk': u'Непозната локација',
'nb': u'Ukjent sted',
'ro': u'Locaţie necunoscută',
'nl': u'Onbekende locatie',
'fy': u'Ûnbekende lokaasje',
'pl': u'Nieznana lokalizacja',
'pt': u'Localização desconhecida',
'pt-br': u'Localização desconhecida',
'ro': u'Localitate necunoscută',
'ru': u'Неизвестное местоположение',
'sk': u'Neznáma poloha',
'sl': u'Neznano lokacijo',
'sr': u'Непозната локација',
'sv': u'Okänd plats',
'tr': u'Bölge bulunamadı',
'ua': u'Невідоме місце',
'te': u'తెలియని ప్రదేశం',
'tr': u'Bilinmeyen konum',
'uk': u'Невідоме місце',
'uz': u'Аникланмаган худуд',
},
'LOCATION': {
'en': u'Location',
'af': u'Ligging',
'be': u'Месцазнаходжанне',
'bg': u'Местоположение',
'bs': u'Lokacija',
'ca': u'Localització',
'ca': u'Ubicació',
'cs': u'Poloha',
'cy': u'Lleoliad',
'de': u'Ort',
'da': u'Lokation',
'el': u'Τοποθεσία',
'es': u'Ubicación',
'et': u'Asukoht',
'fa': u'مکان',
'fi': u'Tuntematon sijainti',
'fr': u'Emplacement',
'hu': u'Lokáció',
'hy': u'Դիրք',
'id': u'Lokasi',
'is': u'Staðsetning',
'it': u'Località',
'ja': u'位置情報',
'ko': u'위치',
'kk': u'',
'lv': u'Atrašanās vieta',
'mk': u'Локација',
'nb': u'Sted',
'ro': u'Locaţie',
'nl': u'Locatie',
'fy': u'Lokaasje',
'pl': u'Lokalizacja',
'pt': u'Localização',
'pt-br': u'Localização',
'ro': u'Localitate',
'ru': u'Местоположение',
'sk': u'Poloha',
'sl': u'Lokacijo',
'sr': u'Локација',
'sv': u'Plats',
'tr': u'Bölge bulunamadı',
'ua': u'Місце',
'te': u'స్థానము',
'tr': u'Konum',
'uk': u'Місцезнаходження'
},
'CAPACITY_LIMIT_REACHED': {
@ -229,6 +340,26 @@ Here is the weather report for the default city (just to show you, how it looks
We will get new queries as soon as possible.
You can follow https://twitter.com/igor_chubin for the updates.
======================================================================================
""",
'af': u"""
Verskoning, ons oorskry tans die vermoë om navrae aan die weerdiens te rig.
Hier is die weerberig van 'n voorbeeld ligging (bloot om aan u te wys hoe dit lyk).
Ons sal weereens nuwe navrae kan hanteer so gou as moontlik.
U kan vir https://twitter.com/igor_chubin volg vir opdaterings.
======================================================================================
""",
'be': u"""
Прабачце, мы выйшлі за ліміты колькасці запытаў да службы надвор'я ў дадзены момант.
Вось прагноз надвор'я для горада па змаўчанні (толькі, каб паказаць вам, як гэта выглядае).
Мы вернемся як мага хутчэй.
Вы можаце сачыць на https://twitter.com/igor_chubin за абнаўленнямі.
======================================================================================
""",
'bg': u"""
Съжаляваме, количеството заявки към услугата за предсказване на време е почти изчерпано.
Ето доклад за града по подразбиране (просто да видите как изглежда).
Ще осогурим допълнителни заявки максимално бързо.
Може да последвате https://twitter.com/igor_chubin за обновления.
""",
'bs': u"""
Žao mi je, mi ponestaje upita i vremenska prognoza u ovom trenutku.
@ -238,24 +369,10 @@ Možete pratiti https://twitter.com/igor_chubin za ažuriranja.
======================================================================================
""",
'ca': u"""
Disculpi'ns, ens hem quedat sense consultes al servei meteorològic momentàniament.
Aquí li oferim l'informe del temps a la ciutat per defecte (només per mostrar, quin aspecte té).
Disculpa'ns, ens hem quedat momentàniament sense consultes al servei meteorològic.
Aquí t'oferim l'informe del temps a la ciutat per defecte (només per mostrar quin aspecte ).
Obtindrem noves consultes tan aviat com ens sigui possible.
Pot seguir https://twitter.com/igor_chubin per noves actualitzacions.
======================================================================================
""",
'fr': u"""
Désolé, nous avons épuisé les requêtes vers le service météo.
Voici un bulletin météo de l'emplacement par défaut (pour vous donner un aperçu).
Nous serons très bientôt en mesure de faire de nouvelles requêtes.
Vous pouvez suivre https://twitter.com/igor_chubin pour rester informé.
======================================================================================
""",
'mk': u"""
Извинете, ни снемуваат барања за до сервисот кој ни нуди временска прогноза во моментот.
Еве една временска прогноза за град (за да видите како изгледа).
Ќе добиеме нови барања најбрзо што можеме.
Следете го https://twitter.com/igor_chubin за известувања
Pots seguir https://twitter.com/igor_chubin per noves actualitzacions.
======================================================================================
""",
'de': u"""
@ -264,6 +381,41 @@ Dafür zeigen wir Ihnen das Wetter an einem Beispielort, damit Sie sehen wie die
Wir werden versuchen das Problem so schnell wie möglich zu beheben.
Folgen Sie https://twitter.com/igor_chubin für Updates.
======================================================================================
""",
'cy': u"""
Rydym yn brin o ymholiadau i'r gwasanaeth tywydd ar hyn o bryd.
Felly dyma'r adroddiad tywydd ar gyfer y ddinas ragosod (er mwyn arddangos sut mae'n edrych).
Byddwn gyda ymholiadau newydd yn fuan.
Gellir dilyn https://twitter.com/igor_chubin i gael newyddion pellach.
======================================================================================
""",
'es': u"""
Lo siento, hemos alcanzado el límite de peticiones al servicio de previsión del tiempo en este momento.
A continuación, la previsión del tiempo para una ciudad estándar (solo para que puedas ver que aspecto tiene el informe).
Muy pronto volveremos a tener acceso a las peticiones.
Puedes seguir https://twitter.com/igor_chubin para estar al tanto de la situación.
======================================================================================
""",
'fa': u"""
متأسفانه در حال حاضر ظرفیت ما برای درخواست به سرویس هواشناسی به اتمام رسیده.
اینجا می تونید گزارش هواشناسی برای شهر پیش فرض رو ببینید (فقط برای اینه که بهتون نشون بدیم چه شکلی هست)
ما تلاش میکنیم در اسرع وقت ظرفیت جدید به دست بیاریم.
برای دنبال کردن اخبار جدید میتونید https://twitter.com/igor_chubin رو فالو کنید.
======================================================================================
""",
'fr': u"""
Désolé, nous avons épuisé les requêtes vers le service météo.
Voici un bulletin météo de l'emplacement par défaut (pour vous donner un aperçu).
Nous serons très bientôt en mesure de faire de nouvelles requêtes.
Vous pouvez suivre https://twitter.com/igor_chubin pour rester informé.
======================================================================================
""",
'hu': u"""
Sajnáljuk, kifogytunk az időjárási szolgáltatásra fordított erőforrásokból.
Itt van az alapértelmezett város időjárási jelentése (hogy lásd, hogyan néz ki).
A lehető leghamarabb új erőforrásokat fogunk kapni.
A frissítésekért tekintsd meg a https://twitter.com/igor_chubin oldalt.
======================================================================================
""",
'hy': u"""
Կներեք, այս պահին մենք գերազանցել ենք եղանակային տեսության կայանին հարցումների քանակը.
@ -271,6 +423,20 @@ Folgen Sie https://twitter.com/igor_chubin für Updates.
Մենք մշտապես աշխատում ենք հարցումների քանակը բարելավելու ուղղությամբ:
Կարող եք հետևել մեզ https://twitter.com/igor_chubin թարմացումների համար.
======================================================================================
""",
'id': u"""
Maaf, kami kehabian permintaan ke layanan cuaca saat ini.
Ini adalah laporan cuaca dari kota standar (hanya untuk menunjukkan kepada anda bagaimana tampilannya).
Kami akan mencoba permintaan baru lagi sesegera mungkin.
Anda dapat mengikuti https://twitter.com/igor_chubin untuk informasi terbaru.
======================================================================================
""",
'it': u"""
Scusate, attualmente stiamo esaurendo le risorse a disposizione del servizio meteo.
Qui trovate il bollettino del tempo per la città di default (solo per mostrarvi come si presenta).
Potremo elaborare nuove richieste appena possibile.
Potete seguire https://twitter.com/igor_chubin per gli aggiornamenti.
======================================================================================
""",
'ko': u"""
죄송합니다. 현재 날씨 정보를 가져오는 쿼리 요청이 한도에 도달했습니다.
@ -278,12 +444,19 @@ Folgen Sie https://twitter.com/igor_chubin für Updates.
쿼리 요청이 가능한 빨리 이루어질 있도록 하겠습니다.
업데이트 소식을 원하신다면 https://twitter.com/igor_chubin 팔로우 해주세요.
======================================================================================
""",
'lv': u"""
Atvainojiet, uz doto brīdi mēs esam mazliet noslogoti.
Šeit ir laika ziņas noklusējuma pilsētai (lai parādītu jums, izskatās izveidotais ziņojums).
Mēs atsāksim darbu cik ātri vien varēsim.
Jūs varat sekot https://twitter.com/igor_chubin lai redzētu visus jaunumus.
======================================================================================
""",
'mk': u"""
Извинете, ни снемуваат барања за до сервисот кој ни нуди временска прогноза во моментот.
Еве една временска прогноза за град (за да видите како изгледа).
Ќе добиеме нови барања најбрзо што можеме.
Следете го https://twitter.com/igor_chubin за известувања.
Следете го https://twitter.com/igor_chubin за известувања
======================================================================================
""",
'nb': u"""
@ -293,39 +466,158 @@ Vi vil forsøke å fikse problemet så snart som mulig.
Du kan følge https://twitter.com/igor_chubin for oppdateringer.
======================================================================================
""",
'nl': u"""
Excuse, wij kunnen u op dit moment dit weerbericht niet laten zien.
Hier is het weerbericht voor de standaard stad(zodat u weet hoe het er uitziet)
Wij lossen dit probleem zo snel mogelijk op.
voor updates kunt u ons op https://twitter.com/igor_chubin volgen.
======================================================================================
""",
'fy': u"""
Excuses, wy kinne op dit moment 't waarberjocht net sjin litte.
Hjir is 't waarberjocht foar de standaard stêd.
Wy losse dit probleem sa gau mooglik op.
Foar updates kinne jo ús op https://twitter.com/igor_chubin folgje.
======================================================================================
""",
'pl': u"""
Bardzo nam przykro, ale chwilowo wykorzystaliśmy limit zapytań do serwisu pogodowego.
To, co widzisz jest przykładowym raportem pogodowym dla domyślnego miasta.
Postaramy się przywrócić funkcjonalność tak szybko, jak to tylko możliwe.
Możesz śledzić https://twitter.com/igor_chubin na Twitterze, aby być na bieżąco.
======================================================================================
""",
'pt': u"""
Desculpe-nos, estamos atingindo o limite de consultas ao serviço de previsão do tempo neste momento.
Veja a seguir a previsão do tempo para uma cidade padrão (apenas para você ver que aspecto o relatório tem).
Em breve voltaremos a ter acesso às consultas.
Você pode seguir https://twitter.com/igor_chubin para acompanhar a situação.
======================================================================================
""",
'pt-br': u"""
Desculpe-nos, atingimos o limite de consultas ao serviço de previsão do tempo neste momento.
Veja a seguir a previsão do tempo para uma cidade padrão (apenas para você ver que aspecto o relatório tem).
Em breve voltaremos a ter acesso às consultas.
Você pode seguir https://twitter.com/igor_chubin para acompanhar a situação.
======================================================================================
""",
'ro': u"""
Ne pare rău, momentan am epuizat cererile alocate de către serviciul de prognoză meteo.
arătăm prognoza meteo pentru localitatea implicită (ca exemplu, vedeți cum arată).
Vom obține alocarea de cereri noi cât de curând posibil.
Puteți urmări https://twitter.com/igor_chubin pentru actualizări.
======================================================================================
""",
'te': u"""
షమిి, రసిి వరణ వక రశనలన గడ.
ఇకకడ ి నగర వరణ ిి (వల ిచడిి, ఇది ఎల కనిిి).
యమ వరల రశనలన .
నవకరణల https://twitter.com/igor_chubin అనసరిచవచ.
======================================================================================
""",
'tr': u"""
Üzgünüz, an itibariyle hava durumu servisine yapabileceğimiz sorgu limitine ulaştık.
Varsayılan şehir için hava durumu bilgisini görüyorsunuz (neye benzediğini gösterebilmek için).
Mümkün olan en kısa sürede servise yeniden sorgu yapmaya başlayacağız.
Gelişmeler için https://twitter.com/igor_chubin adresini takip edebilirsiniz.
======================================================================================
""",
'da': u"""
Beklager, men vi er ved at løbe tør for forespørgsler til vejr-servicen lige nu.
Her er vejr rapporten for standard byen (bare du ved hvordan det kan se ud).
Vi får nye forespørsler hurtigst muligt.
Du kan følge https://twitter.com/igor_chubin for at opdateringer.
======================================================================================
""",
'et': u"""
Vabandage, kuid hetkel on päringud ilmateenusele piiratud.
Selle asemel kuvame hetkel näidislinna ilmaprognoosi (näitamaks, kuidas see välja näeb).
Üritame probleemi lahendada niipea kui võimalik.
Jälgige https://twitter.com/igor_chubin värskenduste jaoks.
======================================================================================
""",
'uk': u"""
Вибачте, ми перевищили максимальну кількість запитів до сервісу погоди.
Ось прогноз погоди у нашому місті (просто показати Вам як це виглядає).
Ми відновимо роботу як тільки зможемо.
Ви можете підписатися на https://twitter.com/igor_chubin для отримання новин.
======================================================================================
"""
},
#'Check new Feature: \033[92mwttr.in/Moon\033[0m or \033[92mwttr.in/Moon@2016-Mar-23\033[0m to see the phase of the Moon'
#'New feature: \033[92mwttr.in/Rome?lang=it\033[0m or \033[92mcurl -H "Accept-Language: it" wttr.in/Rome\033[0m for the localized version. Your lang instead of "it"'
# Historical messages:
# 'Check new Feature: \033[92mwttr.in/Moon\033[0m or \033[92mwttr.in/Moon@2016-Mar-23\033[0m to see the phase of the Moon'
# 'New feature: \033[92mwttr.in/Rome?lang=it\033[0m or \033[92mcurl -H "Accept-Language: it" wttr.in/Rome\033[0m for the localized version. Your lang instead of "it"'
'NEW_FEATURE': {
'en': u'New feature: multilingual location names \033[92mwttr.in/станция+Восток\033[0m (in UTF-8) and location search \033[92mwttr.in/~Kilimanjaro\033[0m (just add ~ before)',
'bs': u'XXXXXXXXXXXXXXXXXXXX: XXXXXXXXXXXXXXXXXXXXXXXXXXXXX\ 033[92mwttr.in/станция+Восток\033 [0m (XX UTF-8) XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX',
'ca': u'Noves funcionalitats: noms d\'ubicació multilingües \033[92mwttr.in/станция+Восток\033 [0m (en UTF-8) i la ubicació de recerca \ 033 [92mwttr.in/~Kilimanjaro\033 [0m (només cal afegir ~ abans)',
'fr': u'Nouvelles fonctionnalités: noms d\'emplacements multilingues \033[92mwttr.in/станция+Восток\033 [0m (en UTF-8) et recherche d\'emplacement \ 033 [92mwttr.in/~Kilimanjaro\033 [0m (ajouter ~ devant)',
'af': u'Nuwe eienskap: veeltalige name vir liggings \033[92mwttr.in/станция+Восток\033[0m (in UTF-8) en ligging soek \033[92mwttr.in/~Kilimanjaro\033[0m (plaas net ~ vooraan)',
'be': u'Новыя магчымасці: назвы месц на любой мове \033[92mwttr.in/станция+Восток\033[0m (в UTF-8) i пошук месц \033[92mwttr.in/~Kilimanjaro\033[0m (трэба дадаць ~ ў пачатак)',
'bg': u'Нова функционалност: многоезични имена на места\033[92mwttr.in/станция+Восток\033[0m (в UTF-8) и в търсенето \033[92mwttr.in/~Kilimanjaro\033[0m (добавете ~ преди)',
'bs': u'XXXXXXXXXXXXXXXXXXXX: XXXXXXXXXXXXXXXXXXXXXXXXXXXXX\033[92mwttr.in/станция+Восток\033[0m (XX UTF-8) XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX',
'ca': u'Noves funcionalitats: noms d\'ubicació multilingües \033[92mwttr.in/станция+Восток\033[0m (en UTF-8) i la ubicació de recerca \033[92mwttr.in/~Kilimanjaro\033[0m (només cal afegir ~ abans)',
'es': u'Nuevas funcionalidades: los nombres de las ubicaciones en vários idiomas \033[92mwttr.in/станция+Восток\033[0m (em UTF-8) y la búsqueda por ubicaciones \033[92mwttr.in/~Kilimanjaro\033[0m (tan solo inserte ~ en frente)',
'fa': u'قابلیت جدید: پشتیبانی از نام چند زبانه مکانها \033[92mwttr.in/станция+Восток\033[0m (در فرمت UTF-8) و جسجتوی مکان ها \033[92mwttr.in/~Kilimanjaro\033[0m (فقط قبل از اون ~ اضافه کنید)',
'fr': u'Nouvelles fonctionnalités: noms d\'emplacements multilingues \033[92mwttr.in/станция+Восток\033[0m (en UTF-8) et recherche d\'emplacement \033[92mwttr.in/~Kilimanjaro\033[0m (ajouter ~ devant)',
'mk': u'Нова функција: повеќе јазично локациски имиња \033[92mwttr.in/станция+Восток\033[0m (во UTF-8) и локациско пребарување \033[92mwttr.in/~Kilimanjaro\033[0m (just add ~ before)',
'nb': u'Ny funksjon: flerspråklige stedsnavn \033[92mwttr.in/станция+Восток\033[0m (i UTF-8) og lokasjonssøk \033[92mwttr.in/~Kilimanjaro\033[0m (bare legg til ~ foran)',
'cy': u'Nodwedd newydd: enwau lleoliad amlieithog \033[92mwttr.in/станция+Восток\033[0m (yn UTF-8) a chwilio lleoliad \033[92mwttr.in/~Kilimanjaro\033[0m (ychwanegwch ~ yn gyntaf)',
'nl': u'Nieuwe functie: tweetalige locatie namen \033[92mwttr.in/станция+Восток\033[0m (in UTF-8) en locatie zoeken \033[92mwttr.in/~Kilimanjaro\033[0m (zet er gewoon een ~ voor)',
'fy': u'Nije funksje: twatalige lokaasje nammen \033[92mwttr.in/станция+Восток\033[0m (in UTF-8) en lokaasje sykjen \033[92mwttr.in/~Kilimanjaro\033[0m (set er gewoan in ~ foar)',
'cy': u'Nodwedd newydd: enwau lleoliadau amlieithog \033[92mwttr.in/станция+Восток\033[0m (yn UTF-8) a chwilio am leoliad \033[92mwttr.in/~Kilimanjaro\033[0m (ychwanegwch ~ yn gyntaf)',
'de': u'Neue Funktion: mehrsprachige Ortsnamen \033[92mwttr.in/станция+Восток\033[0m (in UTF-8) und Ortssuche \033[92mwttr.in/~Kilimanjaro\033[0m (fügen Sie ein ~ vor dem Ort ein)',
'hu': u'Új funkcinalitás: többnyelvű helynevek \033[92mwttr.in/станция+Восток\033[0m (UTF-8-ban) és pozíció keresés \033[92mwttr.in/~Kilimanjaro\033[0m (csak adj egy ~ jelet elé)',
'hy': u'Փորձարկեք: տեղամասերի անունները կամայական լեզվով \033[92mwttr.in/Դիլիջան\033[0m (в UTF-8) և տեղանքի որոնում \033[92mwttr.in/~Kilimanjaro\033[0m (հարկավոր է ~ ավելացնել դիմացից)',
'id': u'Fitur baru: nama lokasi dalam multibahasa \033[92mwttr.in/станция+Восток\033[0m (in UTF-8) dan pencarian lokasi \033[92mwttr.in/~Kilimanjaro\033[0m (hanya tambah tanda ~ sebelumnya)',
'it': u'Nuove funzionalità: nomi delle località multilingue \033[92mwttr.in/станция+Восток\033[0m (in UTF-8) e ricerca della località \033[92mwttr.in/~Kilimanjaro\033[0m (basta premettere ~)',
'ko': u'새로운 기능: 다국어로 대응된 위치 \033[92mwttr.in/서울\033[0m (UTF-8에서) 장소 검색 \033[92mwttr.in/~Kilimanjaro\033[0m (앞에 ~를 붙이세요)',
'kk': u'',
'lv': u'Jaunums: Daudzvalodu atrašanās vietu nosaukumi \033[92mwttr.in/станция+Восток\033[0m (in UTF-8) un dabas objektu meklēšana \033[92mwttr.in/~Kilimanjaro\033[0m (tikai priekšā pievieno ~)',
'mk': u'Нова функција: повеќе јазично локациски имиња \033[92mwttr.in/станция+Восток\033[0m (во UTF-8) и локациско пребарување \033[92mwttr.in/~Kilimanjaro\033[0m (just add ~ before)',
'pl': u'Nowa funkcjonalność: wielojęzyczne nazwy lokalizacji \033[92mwttr.in/станция+Восток\033[0m (w UTF-8) i szukanie lokalizacji \033[92mwttr.in/~Kilimanjaro\033[0m (poprzedź zapytanie ~ - znakiem tyldy)',
'pt': u'Nova funcionalidade: nomes de localidades em várias línguas \033[92mwttr.in/станция+Восток\033[0m (em UTF-8) e procura por localidades \033[92mwttr.in/~Kilimanjaro\033[0m (é só colocar ~ antes)',
'pt-br': u'Nova funcionalidade: nomes de localidades em várias línguas \033[92mwttr.in/станция+Восток\033[0m (em UTF-8) e procura por localidades \033[92mwttr.in/~Kilimanjaro\033[0m (é só colocar ~ antes)',
'ro': u'Funcționalitate nouă: nume de localități multilingve \033[92mwttr.in/станция+Восток\033[0m (in UTF-8) și căutare de localități \033[92mwttr.in/~Kilimanjaro\033[0m (adăuați ~ în față)',
'ru': u'Попробуйте: названия мест на любом языке \033[92mwttr.in/станция+Восток\033[0m (в UTF-8) и поиск мест \033[92mwttr.in/~Kilimanjaro\033[0m (нужно добавить ~ спереди)',
'tr': u'Yeni özellik: çok dilli konum isimleri \033[92mwttr.in/станция+Восток\033[0m (UTF-8 ile) ve konum arama \033[92mwttr.in/~Kilimanjaro\033[0m (sadece önüne ~ ekleyin)',
'te': u'క్రొత్త లక్షణం: బహుభాషా స్థాన పేర్లు \ 033 [92mwttr.in/stancelя+Vostок\033 [0 U (UTF-8 లో) మరియు స్థానం శోధన \ 033 [92mwttr.in/~kilimanjaro\033 [0m (కేవలం ~ ముందుకి జోడించండి)',
'da': u'Ny funktion: flersprogede lokationsnavne \033[92mwttr.in/станция+Восток\033[0m (som UTF-8) og lokations søgning \033[92mwttr.in/~Kilimanjaro\033[0m (bare tilføj ~ inden)',
'et': u'Uus funktsioon: mitmekeelsed asukohanimed \033[92mwttr.in/станция+Восток\033[0m (UTF-8 vormingus) ja asukoha otsing \033[92mwttr.in/~Kilimanjaro\033[0m (lisa ~ enne)',
'uk': u'Спробуйте: назви місць будь-якою мовою \033[92mwttr.in/станція+Восток\033[0m (в UTF-8) та пошук місць \033[92mwttr.in/~Kilimanjaro\033[0m (потрібно додати ~ спочатку)'
},
'FOLLOW_ME': {
'en': u'Follow \033[46m\033[30m@igor_chubin\033[0m for wttr.in updates',
'bs': u'XXXXXX \033[46m\033[30m@igor_chubin\033[0m XXXXXXXXXXXXXXXXXXX',
'ca': u'Seguiu \033[46m\033[30m@igor_chubin\033[0m per actualitzacions de wttr.in',
'cy': u'Dilyn \033[46m\033[30m@igor_Chubin\033[0m am diweddariadau wttr.in',
'af': u'Volg \033[46m\033[30m@igor_chubin\033[0m vir wttr.in opdaterings',
'be': u'Сачыце за \033[46m\033[30m@igor_chubin\033[0m за навінамі wttr.in',
'bg': u'Последвай \033[46m\033[30m@igor_chubin\033[0m за обновления свързани с wttr.in',
'bs': u'XXXXXX \033[46m\033[30m@igor_chubin\033[0m XXXXXXXXXXXXXXXXXXX',
'ca': u'Segueix \033[46m\033[30m@igor_chubin\033[0m per actualitzacions de wttr.in',
'es': u'Seguir \033[46m\033[30m@igor_chubin\033[0m para recibir las novedades de wttr.in',
'cy': u'Dilyner \033[46m\033[30m@igor_Chubin\033[0m am diweddariadau wttr.in',
'fa': u'برای دنبال کردن خبرهای wttr.in شناسه \033[46m\033[30m@igor_chubin\033[0m رو فالو کنید.',
'fr': u'Suivez \033[46m\033[30m@igor_Chubin\033[0m pour rester informé sur wttr.in',
'de': u'Folgen Sie \033[46m\033[30mhttps://twitter.com/igor_chubin\033[0m für wttr.in Updates',
'hu': u'Kövesd \033[46m\033[30m@igor_chubin\033[0m-t további wttr.in információkért',
'hy': u'Նոր ֆիչռների համար հետևեք՝ \033[46m\033[30m@igor_chubin\033[0m',
'id': u'Ikuti \033[46m\033[30m@igor_chubin\033[0m untuk informasi wttr.in terbaru',
'it': u'Seguite \033[46m\033[30m@igor_chubin\033[0m per aggiornamenti a wttr.in',
'ko': u'wttr.in의 업데이트 소식을 원하신다면 \033[46m\033[30m@igor_chubin\033[0m 을 팔로우 해주세요',
'kk': u'',
'lv': u'Seko \033[46m\033[30m@igor_chubin\033[0m , lai uzzinātu wttr.in jaunumus',
'mk': u'Следете \033[46m\033[30m@igor_chubin\033[0m за wttr.in новости',
'nb': u'Følg \033[46m\033[30m@igor_chubin\033[0m for wttr.in oppdateringer',
'nl': u'Volg \033[46m\033[30m@igor_chubin\033[0m voor wttr.in updates',
'fy': u'Folgje \033[46m\033[30m@igor_chubin\033[0m foar wttr.in updates',
'pl': u'Śledź \033[46m\033[30m@igor_chubin\033[0m aby być na bieżąco z nowościami dotyczącymi wttr.in',
'pt': u'Seguir \033[46m\033[30m@igor_chubin\033[0m para as novidades de wttr.in',
'pt-br': u'Seguir \033[46m\033[30m@igor_chubin\033[0m para as novidades de wttr.in',
'ro': u'Urmăriți \033[46m\033[30m@igor_chubin\033[0m pentru actualizări despre wttr.in',
'ru': u'Все новые фичи публикуются здесь: \033[46m\033[30m@igor_chubin\033[0m',
'te': u'అనుసరించండి \ 033 [46m \ 033 [30m @ igor_chubin \ 033 [wttr.in నవీకరణలను కోసం',
'tr': u'wttr.in ile ilgili gelişmeler için \033[46m\033[30m@igor_chubin\033[0m adresini takip edin',
'da': u'Følg \033[46m\033[30m@igor_chubin\033[0m for at få wttr.in opdateringer',
'et': u'Jälgi \033[46m\033[30m@igor_chubin\033[0m wttr.in uudiste tarbeks',
'uk': u'Нові можливості wttr.in публікуються тут: \033[46m\033[30m@igor_chubin\033[0m'
},
}

View File

@ -1,3 +1,4 @@
from __future__ import print_function
from unicodedata import *
script_data = {
@ -599,7 +600,7 @@ def _compile_scripts_txt():
idx.append((int(a, 16), int(b or a, 16), names.index(name), cats.index(cat)))
idx.sort()
print 'script_data = {\n"names":%s,\n"cats":%s,\n"idx":[\n%s\n]}' % (
print('script_data = {\n"names":%s,\n"cats":%s,\n"idx":[\n%s\n]}' % (
'\n'.join(textwrap.wrap(repr(names), 80)),
'\n'.join(textwrap.wrap(repr(cats), 80)),
'\n'.join(textwrap.wrap(', '.join('(0x%x,0x%x,%d,%d)' % c for c in idx), 80)))
'\n'.join(textwrap.wrap(', '.join('(0x%x,0x%x,%d,%d)' % c for c in idx), 80))))

24
lib/weather_data.py Normal file
View File

@ -0,0 +1,24 @@
"""
Weather data source
"""
import json
import requests
from globals import WWO_KEY
def get_weather_data(location, lang):
"""
Get weather data for `location`
"""
key = WWO_KEY
url = ('/premium/v1/weather.ashx'
'?key=%s&q=%s&format=json'
'&num_of_days=3&tp=3&lang=%s') % (key, location, lang)
url = 'http://127.0.0.1:5001' + url
response = requests.get(url, timeout=1)
try:
data = json.loads(response.content)
except ValueError:
data = {}
return data

View File

@ -1,7 +1,8 @@
# vim: set encoding=utf-8
from __future__ import print_function
import gevent
from gevent.wsgi import WSGIServer
from gevent.pywsgi import WSGIServer
from gevent.queue import Queue
from gevent.monkey import patch_all
from gevent.subprocess import Popen, PIPE, STDOUT
@ -10,18 +11,53 @@ patch_all()
import os
import re
import time
import dateutil
import dateutil.parser
from translations import get_message, FULL_TRANSLATION, PARTIAL_TRANSLATION, SUPPORTED_LANGS
from globals import WEGO, PYPHOON, CACHEDIR, ANSI2HTML, \
NOT_FOUND_LOCATION, DEFAULT_LOCATION, \
NOT_FOUND_LOCATION, DEFAULT_LOCATION, TEST_FILE, \
log, error
def _is_invalid_location(location):
if '.png' in location:
return True
def get_wetter(location, ip, html=False, lang=None, query=None, location_name=None, full_address=None):
def remove_ansi(sometext):
ansi_escape = re.compile(r'(\x9B|\x1B\[)[0-?]*[ -\/]*[@-~]')
return ansi_escape.sub('', sometext)
def get_wetter(location, ip, html=False, lang=None, query=None, location_name=None, full_address=None, url=None):
local_url = url
local_location = location
def get_opengraph():
if local_url is None:
url = ""
else:
url = local_url.encode('utf-8')
if local_location is None:
location = ""
else:
location = local_location.encode('utf-8')
pic_url = url.replace('?', '_')
return (
'<meta property="og:image" content="%(pic_url)s_0pq.png" />'
'<meta property="og:site_name" content="wttr.in" />'
'<meta property="og:type" content="profile" />'
'<meta property="og:url" content="%(url)s" />'
) % {
'pic_url': pic_url,
'url': url,
'location': location,
}
# '<meta property="og:title" content="Weather report: %(location)s" />'
# '<meta content="Partly cloudy // 6-8 °C // ↑ 9 km/h // 10 km // 0.4 mm" property="og:description" />'
def get_filename(location, lang=None, query=None, location_name=None):
location = location.replace('/', '_')
@ -45,20 +81,22 @@ def get_wetter(location, ip, html=False, lang=None, query=None, location_name=No
return "%s/%s/%s%s%s%s%s" % (CACHEDIR, location, timestamp, imperial_suffix, lang_suffix, query_line, location_name)
def save_weather_data(location, filename, lang=None, query=None, location_name=None, full_address=None):
ansi_escape = re.compile(r'(\x9B|\x1B\[)[0-?]*[ -\/]*[@-~]')
def remove_ansi(sometext):
return ansi_escape.sub('', sometext)
if _is_invalid_location( location ):
error("Invalid location: %s" % location)
NOT_FOUND_MESSAGE_HEADER = ""
while True:
location_not_found = False
if location in [ "test-thunder" ]:
test_name = location[5:]
test_file = TEST_FILE.replace('NAME', test_name)
stdout = open(test_file, 'r').read()
stderr = ""
break
if location == NOT_FOUND_LOCATION:
location_not_found = True
location = DEFAULT_LOCATION
else:
location_not_found = False
cmd = [WEGO, '--city=%s' % location]
@ -83,7 +121,7 @@ def get_wetter(location, ip, html=False, lang=None, query=None, location_name=No
p = Popen(cmd, stdout=PIPE, stderr=PIPE)
stdout, stderr = p.communicate()
if p.returncode != 0:
print "ERROR: location not found: %s" % location
print("ERROR: location not found: %s" % location)
if 'Unable to find any matching weather location to the query submitted' in stderr:
if location != NOT_FOUND_LOCATION:
NOT_FOUND_MESSAGE_HEADER = u"ERROR: %s: %s\n---\n\n" % (get_message('UNKNOWN_LOCATION', lang), location)
@ -128,8 +166,13 @@ def get_wetter(location, ip, html=False, lang=None, query=None, location_name=No
if query.get('no-city', False):
stdout = "\n".join(stdout.splitlines()[2:]) + "\n"
if full_address:
line = "%s: %s [%s]\n" % (get_message('LOCATION', lang).encode('utf-8'), full_address.encode('utf-8'), location)
if full_address \
and query.get('format', 'txt') != 'png' \
and (not query.get('no-city') and not query.get('no-caption')):
line = "%s: %s [%s]\n" % (
get_message('LOCATION', lang).encode('utf-8'),
full_address.encode('utf-8'),
location.encode('utf-8'))
stdout += line
if query.get('padding', False):
@ -153,7 +196,8 @@ def get_wetter(location, ip, html=False, lang=None, query=None, location_name=No
stdout = stdout.replace('<body class="">', '<body class="" style="background:white;color:#777777">')
title = "<title>%s</title>" % first.encode('utf-8')
stdout = re.sub("<head>", "<head>" + title, stdout)
opengraph = get_opengraph()
stdout = re.sub("<head>", "<head>" + title + opengraph, stdout)
open(filename+'.html', 'w').write(stdout)
filename = get_filename(location, lang=lang, query=query, location_name=location_name)
@ -164,7 +208,10 @@ def get_wetter(location, ip, html=False, lang=None, query=None, location_name=No
return open(filename).read()
def get_moon(location, html=False, lang=None):
def get_moon(location, html=False, lang=None, query=None):
if query is None:
query = {}
date = None
if '@' in location:
date = location[location.index('@')+1:]
@ -174,18 +221,20 @@ def get_moon(location, html=False, lang=None):
if date:
try:
dateutil.parser.parse(date)
except:
pass
except Exception as e:
print("ERROR: %s" % e)
else:
cmd += [date]
env = os.environ.copy()
if lang:
env['LANG'] = lang
print cmd
p = Popen(cmd, stdout=PIPE, stderr=PIPE, env=env)
stdout = p.communicate()[0]
if query.get('no-terminal', False):
stdout = remove_ansi(stdout)
if html:
p = Popen(["bash", ANSI2HTML, "--palette=solarized", "--bg=dark"], stdin=PIPE, stdout=PIPE, stderr=PIPE)
stdout, stderr = p.communicate(stdout)

259
lib/wttr_line.py Normal file
View File

@ -0,0 +1,259 @@
#vim: fileencoding=utf-8
"""
One-line output mode.
Initial implementation of one-line output mode.
[ ] forecast
[ ] spark
[ ] several locations
[ ] location handling
[ ] more preconfigured format lines
[ ] add information about this mode to /:help
"""
import sys
import re
import datetime
from astral import Astral, Location
from constants import WWO_CODE, WEATHER_SYMBOL, WIND_DIRECTION
from weather_data import get_weather_data
PRECONFIGURED_FORMAT = {
'1': u'%c %t',
'2': u'%c 🌡️%t 🌬️%w',
'3': u'%l: %c %t',
'4': u'%l: %c 🌡️%t 🌬️%w',
}
MOON_PHASES = (
u"🌑", u"🌒", u"🌓", u"🌔", u"🌕", u"🌖", u"🌗", u"🌘"
)
def convert_to_fahrenheit(temp):
"Convert Celcius `temp` to Fahrenheit"
return (temp*9.0/5)+32
def render_temperature(data, query):
"""
temperature (t)
"""
if query.get('use_imperial', False):
temperature = u'%s°F' % data['temp_F']
else:
temperature = u'%s°C' % data['temp_C']
if temperature[0] != '-':
temperature = '+' + temperature
return temperature
def render_condition(data, query):
"""
condition (c)
"""
weather_condition = WEATHER_SYMBOL[WWO_CODE[data['weatherCode']]]
return weather_condition
def render_condition_fullname(data, query):
"""
condition_fullname (C)
"""
found = None
for key, val in data.items():
if key.startswith('lang_'):
found = val
break
if not found:
found = data['weatherDesc']
try:
weather_condition = found[0]['value']
except KeyError:
weather_condition = ''
return weather_condition
def render_humidity(data, query):
"""
humidity (h)
"""
humidity = data.get('humidity', '')
if humidity:
humidity += '%'
return humidity
def render_precipitation(data, query):
"""
precipitation (p)
"""
answer = data.get('precipMM', '')
if answer:
answer += 'mm'
return answer
def render_pressure(data, query):
"""
pressure (P)
"""
answer = data.get('pressure', '')
if answer:
answer += 'hPa'
return answer
def render_wind(data, query):
"""
wind (w)
"""
try:
degree = data["winddirDegree"]
except KeyError:
degree = ""
try:
degree = int(degree)
except ValueError:
degree = ""
if degree:
wind_direction = WIND_DIRECTION[((degree+22)%360)/45]
else:
wind_direction = ""
if query.get('use_ms_for_wind', False):
unit = ' m/s'
wind = u'%s%.1f%s' % (wind_direction, float(data['windspeedKmph'])/36.0*10.0, unit)
elif query.get('use_imperial', False):
unit = ' mph'
wind = u'%s%s%s' % (wind_direction, data['windspeedMiles'], unit)
else:
unit = ' km/h'
wind = u'%s%s%s' % (wind_direction, data['windspeedKmph'], unit)
return wind
def render_location(data, query):
"""
location (l)
"""
return (data['override_location'] or data['location']) # .title()
def render_moonphase(_, query):
"""
A symbol describing the phase of the moon
"""
astral = Astral()
moon_index = int(
int(32.0*astral.moon_phase(date=datetime.datetime.today())/28+2)%32/4
)
return MOON_PHASES[moon_index]
def render_moonday(_, query):
"""
An number describing the phase of the moon (days after the New Moon)
"""
astral = Astral()
return str(int(astral.moon_phase(date=datetime.datetime.today())))
def render_sunset(data, query):
location = data['location']
city_name = location
astral = Astral()
location = Location(('Nuremberg', 'Germany',
49.453872, 11.077298, 'Europe/Berlin', 0))
sun = location.sun(date=datetime.datetime.today(), local=True)
return str(sun['sunset'])
FORMAT_SYMBOL = {
'c': render_condition,
'C': render_condition_fullname,
'h': render_humidity,
't': render_temperature,
'w': render_wind,
'l': render_location,
'm': render_moonphase,
'M': render_moonday,
's': render_sunset,
'p': render_precipitation,
'P': render_pressure,
}
def render_line(line, data, query):
"""
Render format `line` using `data`
"""
def render_symbol(match):
"""
Render one format symbol from re `match`
using `data` from external scope.
"""
symbol_string = match.group(0)
symbol = symbol_string[-1]
if symbol not in FORMAT_SYMBOL:
return ''
render_function = FORMAT_SYMBOL[symbol]
return render_function(data, query)
return re.sub(r'%[^%]*[a-zA-Z]', render_symbol, line)
def format_weather_data(format_line, location, override_location, data, query):
"""
Format information about current weather `data` for `location`
with specified in `format_line` format
"""
if 'data' not in data:
return 'Unknown location; please try ~%s' % location
current_condition = data['data']['current_condition'][0]
current_condition['location'] = location
current_condition['override_location'] = override_location
output = render_line(format_line, current_condition, query)
return output
def wttr_line(location, override_location_name, query, lang):
"""
Return 1line weather information for `location`
in format `line_format`
"""
format_line = query.get('format', '')
if format_line in PRECONFIGURED_FORMAT:
format_line = PRECONFIGURED_FORMAT[format_line]
weather_data = get_weather_data(location, lang)
output = format_weather_data(format_line, location, override_location_name, weather_data, query)
output = output.rstrip("\n")+"\n"
return output
def main():
"""
Function for standalone module usage
"""
location = sys.argv[1]
query = {
'line': sys.argv[2],
}
sys.stdout.write(wttr_line(location, location, query, 'en'))
if __name__ == '__main__':
main()

269
lib/wttr_srv.py Normal file
View File

@ -0,0 +1,269 @@
#!/usr/bin/env python
# vim: set encoding=utf-8
"""
Main wttr.in rendering function implementation
"""
import logging
import os
import time
from flask import render_template, send_file, make_response
import wttrin_png
import parse_query
from translations import get_message, FULL_TRANSLATION, PARTIAL_TRANSLATION, SUPPORTED_LANGS
from buttons import add_buttons
from globals import get_help_file, log, \
BASH_FUNCTION_FILE, TRANSLATION_FILE, LOG_FILE, \
NOT_FOUND_LOCATION, \
MALFORMED_RESPONSE_HTML_PAGE, \
PLAIN_TEXT_AGENTS, PLAIN_TEXT_PAGES, \
MY_EXTERNAL_IP, QUERY_LIMITS
from location import is_location_blocked, location_processing
from limits import Limits
from wttr import get_wetter, get_moon
from wttr_line import wttr_line
if not os.path.exists(os.path.dirname(LOG_FILE)):
os.makedirs(os.path.dirname(LOG_FILE))
logging.basicConfig(filename=LOG_FILE, level=logging.DEBUG, format='%(asctime)s %(message)s')
LIMITS = Limits(whitelist=[MY_EXTERNAL_IP], limits=QUERY_LIMITS)
def show_text_file(name, lang):
"""
show static file `name` for `lang`
"""
text = ""
if name == ":help":
text = open(get_help_file(lang), 'r').read()
text = text.replace('FULL_TRANSLATION', ' '.join(FULL_TRANSLATION))
text = text.replace('PARTIAL_TRANSLATION', ' '.join(PARTIAL_TRANSLATION))
elif name == ":bash.function":
text = open(BASH_FUNCTION_FILE, 'r').read()
elif name == ":translation":
text = open(TRANSLATION_FILE, 'r').read()
text = text\
.replace('NUMBER_OF_LANGUAGES', str(len(SUPPORTED_LANGS)))\
.replace('SUPPORTED_LANGUAGES', ' '.join(SUPPORTED_LANGS))
return text.decode('utf-8')
def client_ip_address(request):
"""
Return client ip address for `request`.
Flask related
"""
if request.headers.getlist("X-Forwarded-For"):
ip_addr = request.headers.getlist("X-Forwarded-For")[0]
if ip_addr.startswith('::ffff:'):
ip_addr = ip_addr[7:]
else:
ip_addr = request.remote_addr
return ip_addr
def get_answer_language(request):
"""
Return preferred answer language based on
domain name, query arguments and headers
"""
def _parse_accept_language(accept_language):
languages = accept_language.split(",")
locale_q_pairs = []
for language in languages:
try:
if language.split(";")[0] == language:
# no q => q = 1
locale_q_pairs.append((language.strip(), "1"))
else:
locale = language.split(";")[0].strip()
weight = language.split(";")[1].split("=")[1]
locale_q_pairs.append((locale, weight))
except IndexError:
pass
return locale_q_pairs
def _find_supported_language(accepted_languages):
for lang_tuple in accepted_languages:
lang = lang_tuple[0]
if '-' in lang:
lang = lang.split('-', 1)[0]
if lang in SUPPORTED_LANGS:
return lang
return None
lang = None
hostname = request.headers['Host']
if hostname != 'wttr.in' and hostname.endswith('.wttr.in'):
lang = hostname[:-8]
if 'lang' in request.args:
lang = request.args.get('lang')
header_accept_language = request.headers.get('Accept-Language', '')
if lang is None and header_accept_language:
lang = _find_supported_language(
_parse_accept_language(header_accept_language))
return lang
def get_output_format(request, query):
"""
Return preferred output format: ansi, text, html or png
based on arguments and headers in `request`.
Return new location (can be rewritten)
"""
if 'format' in query:
return False
# FIXME
user_agent = request.headers.get('User-Agent', '').lower()
if query.get('force-ansi'):
return False
html_output = not any(agent in user_agent for agent in PLAIN_TEXT_AGENTS)
return html_output
def cyclic_location_selection(locations, period):
"""
Return one of `locations` (: separated list)
basing on the current time and query interval `period`
"""
locations = locations.split(':')
max_len = max(len(x) for x in locations)
locations = [x.rjust(max_len) for x in locations]
try:
period = int(period)
except ValueError:
period = 1
index = int(time.time())/period % len(locations)
return locations[index]
def wttr(location, request):
"""
Main rendering function, it processes incoming weather queries.
Depending on user agent it returns output in HTML or ANSI format.
Incoming data:
request.args
request.headers
request.remote_addr
request.referrer
request.query_string
"""
def _wrap_response(response_text, html_output):
response = make_response(response_text)
response.mimetype = 'text/html' if html_output else 'text/plain'
return response
if is_location_blocked(location):
return ""
ip_addr = client_ip_address(request)
try:
LIMITS.check_ip(ip_addr)
except RuntimeError as exception:
return str(exception)
png_filename = None
if location is not None and location.lower().endswith(".png"):
png_filename = location
location = location[:-4]
lang = get_answer_language(request)
query = parse_query.parse_query(request.args)
html_output = get_output_format(request, query)
user_agent = request.headers.get('User-Agent', '').lower()
if location in PLAIN_TEXT_PAGES:
help_ = show_text_file(location, lang)
if html_output:
return _wrap_response(render_template('index.html', body=help_), html_output)
return _wrap_response(help_, html_output)
if location and ':' in location:
location = cyclic_location_selection(location, query.get('period', 1))
orig_location = location
if not png_filename:
location, override_location_name, full_address, country, query_source_location = \
location_processing(location, ip_addr)
us_ip = query_source_location[1] == 'United States' and 'slack' not in user_agent
query = parse_query.metric_or_imperial(query, lang, us_ip=us_ip)
# logging query
orig_location_utf8 = (orig_location or "").encode('utf-8')
location_utf8 = location.encode('utf-8')
use_imperial = query.get('use_imperial', False)
log(" ".join(map(str,
[ip_addr, user_agent, orig_location_utf8, location_utf8, use_imperial, lang])))
if country and location != NOT_FOUND_LOCATION:
location = "%s,%s" % (location, country)
# We are ready to return the answer
try:
if 'format' in query:
return _wrap_response(wttr_line(location, override_location_name, query, lang), html_output)
if png_filename:
options = {
'lang': lang,
'location': location}
options.update(query)
cached_png_file = wttrin_png.make_wttr_in_png(png_filename, options=options)
response = make_response(send_file(cached_png_file,
attachment_filename=png_filename,
mimetype='image/png'))
for key, value in {
'Cache-Control': 'no-cache, no-store, must-revalidate',
'Pragma': 'no-cache',
'Expires': '0',
}.items():
response.headers[key] = value
# Trying to disable github caching
return response
if location.lower() == 'moon' or location.lower().startswith('moon@'):
output = get_moon(location, html=html_output, lang=lang, query=query)
else:
output = get_wetter(location, ip_addr,
html=html_output,
lang=lang,
query=query,
location_name=override_location_name,
full_address=full_address,
url=request.url,
)
if query.get('days', '3') != '0' and not query.get('no-follow-line'):
if html_output:
output = add_buttons(output)
else:
#output += '\n' + get_message('NEW_FEATURE', lang).encode('utf-8')
output += '\n' + get_message('FOLLOW_ME', lang).encode('utf-8') + '\n'
return _wrap_response(output, html_output)
except RuntimeError as exception:
if 'Malformed response' in str(exception) \
or 'API key has reached calls per day allowed limit' in str(exception):
if html_output:
return _wrap_response(MALFORMED_RESPONSE_HTML_PAGE, html_output)
return _wrap_response(get_message('CAPACITY_LIMIT_REACHED', lang).encode('utf-8'), html_output)
logging.error("Exception has occured", exc_info=1)
return "ERROR"

View File

@ -1,6 +1,7 @@
#!/usr/bin/python
#vim: encoding=utf-8
from __future__ import print_function
import sys
import os
import re
@ -32,7 +33,7 @@ MYDIR = os.path.abspath(os.path.dirname(os.path.dirname('__file__')))
sys.path.append("%s/lib/" % MYDIR)
import parse_query
PNG_CACHE = os.path.join(MYDIR, "cache/png")
from globals import PNG_CACHE, log
COLS = 180
ROWS = 100
@ -95,7 +96,8 @@ def strip_buf(buf):
break
number_of_lines += 1
buf = buf[:-number_of_lines]
if number_of_lines:
buf = buf[:-number_of_lines]
max_len = max(line_len(x) for x in buf)
buf = [line[:max_len] for line in buf]
@ -118,7 +120,7 @@ def script_category(char):
def gen_term(filename, buf, options=None):
buf = strip_buf(buf)
cols = len(buf[0])
cols = max(len(x) for x in buf)
rows = len(buf)
image = Image.new('RGB', (cols * CHAR_WIDTH, rows * CHAR_HEIGHT))
@ -142,14 +144,15 @@ def gen_term(filename, buf, options=None):
(x_pos+CHAR_WIDTH, y_pos+CHAR_HEIGHT)),
fill=color_mapping(char.bg))
cat = script_category(char.data)
if cat not in font:
print "Unknown font category: %s" % cat
draw.text(
(x_pos, y_pos),
char.data,
font=font.get(cat, font.get('default')),
fill=current_color)
if char.data:
cat = script_category(char.data)
if cat not in font:
log("Unknown font category: %s" % cat)
draw.text(
(x_pos, y_pos),
char.data,
font=font.get(cat, font.get('default')),
fill=current_color)
#sys.stdout.write(c.data)
x_pos += CHAR_WIDTH
@ -198,7 +201,10 @@ def typescript_to_one_frame(png_file, text, options=None):
stream.feed(text)
gen_term(png_file, screen.buffer, options=options)
buf = sorted(screen.buffer.items(), key=lambda x: x[0])
buf = [[x[1] for x in sorted(line[1].items(), key=lambda x: x[0])] for line in buf]
gen_term(png_file, buf, options=options)
#
# wttr.in related functions
@ -266,6 +272,8 @@ def make_wttrin_query(parsed):
for key, val in parsed.items():
args.append('%s=%s' % (key, val))
args.append('filetype=png')
url = "http://wttr.in/%s" % location
if args != []:
url += "?%s" % ("&".join(args))
@ -280,13 +288,10 @@ def make_wttr_in_png(png_name, options=None):
"""
parsed = parse_wttrin_png_name(png_name)
print "------"
print parsed
print "------"
# if location is MyLocation it should be overriden
# with autodetected location (from options)
if parsed.get('location', 'MyLocation') == 'MyLocation':
if parsed.get('location', 'MyLocation') == 'MyLocation' or not parsed.get('location', ''):
del parsed['location']
if options is not None:
@ -294,7 +299,7 @@ def make_wttr_in_png(png_name, options=None):
if key not in parsed:
parsed[key] = val
url = make_wttrin_query(parsed)
print "URL = ", url
print("URL = ", url)
timestamp = time.strftime("%Y%m%d%H", time.localtime())
cached_basename = url[14:].replace('/','_')
@ -305,11 +310,9 @@ def make_wttr_in_png(png_name, options=None):
if not os.path.exists(dirname):
os.makedirs(dirname)
print "Cached file: %s" % cached_png_file
if os.path.exists(cached_png_file):
return cached_png_file
print "Requesting URL: %s" % url
text = requests.get(url).text.replace('\n', '\r\n')
curl_output = text.encode('utf-8')

View File

@ -4,3 +4,10 @@ geopy
requests
gevent
dnspython
pylint
cyrtranslit
astral
timezonefinder
Pillow
pyte
python-dateutil

View File

@ -1,8 +1,9 @@
Msk : Moscow
Moskva : Moscow
Moskau : Moscow
Kyiv : Kiev
Kiew : Kiev
Kyiv : Kiev,Ukraine
Kiew : Kiev,Ukraine
Kiev : Kiev,Ukraine
Kijev : Kiev
Kharkov : Kharkiv
spb : Saint Petersburg
@ -35,8 +36,14 @@ tel-aviv : Tel Aviv
sao paulo : São Paulo
los-angeles : Los Angeles
Sevastopol : Sevastopol, Ukraine
Simferopol : Simferopol, Ukraine
Beersheva : Beersheba
Be'ersheva : Beersheba
Be'er Sheva : Beersheba
Lugansk : Luhansk
Bjalistoko : Białystok
Chicago : Chicago,IL
Paris : Paris,France
Giessen : Giessen, Germany
Braga : Braga, Portugal
Kashan : ~Kashan,Iran

View File

@ -104,7 +104,6 @@ printf '%s' "<html>
<head>
<meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\"/>
<link rel=\"stylesheet\" type=\"text/css\" href=\"/files/style.css\" />
<link rel=\"stylesheet\" type=\"text/css\" href=\"/files/fonts/stylesheet.css\" />
<style type=\"text/css\">
.ef0,.f0 { color: #$P0; } .eb0,.b0 { background-color: #$P0; }
.ef1,.f1 { color: #$P1; } .eb1,.b1 { background-color: #$P1; }

View File

@ -1,5 +1,7 @@
wttr()
{
# change Paris to your default location
curl -H "Accept-Language: ${LANG%_*}" wttr.in/"${1:-Paris}"
local request="wttr.in/${1-Paris}"
[ "$(tput cols)" -lt 125 ] && request+='?n'
curl -H "Accept-Language: ${LANG%_*}" --compressed "$request"
}

View File

@ -1,7 +1,7 @@
Usage:
$ curl wttr.in # current location
$ curl wttr.in/muc # weather in the Munic airport
$ curl wttr.in/muc # weather in the Munich airport
Supported location types:
@ -20,25 +20,27 @@ Special locations:
Units:
?m # metric (SI) (used by default everywhere except US)
?u # USCS (used by default in US)
?M # show wind speed in m/s
m # metric (SI) (used by default everywhere except US)
u # USCS (used by default in US)
M # show wind speed in m/s
View options:
?0 # only current weather
?1 # current weather + 1 day
?2 # current weather + 2 days
?n # narrow version (only day and night)
?q # quiet version (no "Weather report" text)
?Q # superquiet version (no "Weather report", no city name)
?T # switch terminal sequences off (no colors)
0 # only current weather
1 # current weather + 1 day
2 # current weather + 2 days
A # ignore User-Agent and force ANSI output format (terminal)
F # do not show the "Follow" line
n # narrow version (only day and night)
q # quiet version (no "Weather report" text)
Q # superquiet version (no "Weather report", no city name)
T # switch terminal sequences off (no colors)
PNG options:
/paris.png # generate a PNG file
?p # add frame arond the output
?t # transparency 150
p # add frame around the output
t # transparency 150
transparency=... # transparency from 0 to 255 (255 = not transparent)
Options can be combined:

5656
share/list-of-iata-codes.txt Normal file

File diff suppressed because it is too large Load Diff

11
share/salt/README.md Normal file
View File

@ -0,0 +1,11 @@
# Opinionated example of deployment via Salt Stack
## Assumptions:
* user & group srv:srv exist, this is used as a generic service runner
* you want to run the service on port 80, directly exposed to the interwebs (you really want to add a reverse SSL proxy in between)
* You have, or are willing to deploy Salt Stack.
* A bit of assembly is required since you need to move pillar.sls into your saltroot/pillar/ and the rest into saltroot/wttr/
* You want metric-sm units. Just roll your own wegorc to change this
## Caveats:
* Doesn't do enough to make a recent master checkout work, i.e. needs further improvement. Latest known working revision is 0d76ba4a3e112694665af6653040807835883b22

112
share/salt/init.sls Normal file
View File

@ -0,0 +1,112 @@
wttr:
service.running:
- enable: True
- watch:
- file: /srv/ephemeral/start.sh
- git: wttr-repo
- require:
- pkg: wttr-dependencies
- git: wttr-repo
- cmd: wego
- archive: geolite-db
# package names are from Ubuntu 18.04, you may need to adjust if on a different distribution
wttr-dependencies:
pkg.installed:
- pkgs:
- golang
- gawk
- python-setuptools
- python-dev
- python-dnspython
- python-geoip2
- python-geopy
- python-gevent
- python-flask
- python-pil
- authbind
wttr-repo:
git.latest:
- name: https://github.com/chubin/wttr.in
- rev: master
- target: /srv/ephemeral/wttr.in
- require:
- /srv/ephemeral
wttr-start:
file.managed:
- name: /srv/ephemeral/start.sh
- source: salt://wttr/start.sh
- mode: '0770'
- user: srv
- group: srv
wegorc:
file.managed:
- name: /srv/ephemeral/.wegorc
- user: srv
- group: srv
- source: salt://wttr/wegorc
- template: jinja
- context:
apikey: {{ pillar['wttr']['apikey'] }}
geolite-db:
archive.extracted:
- name: /srv/ephemeral
- source: http://geolite.maxmind.com/download/geoip/database/GeoLite2-City.tar.gz
- source_hash: http://geolite.maxmind.com/download/geoip/database/GeoLite2-City.tar.gz.md5
- keep_source: True
- options: --strip-components=1 # flatten directory structure
- enforce_toplevel: False
# Could benefit from improvement, won't get updated automatically at all
wego:
cmd.run:
- onlyif: 'test ! -e /srv/ephemeral/bin/wego'
- env:
- GOPATH: /srv/ephemeral
- name: go get -u github.com/schachmat/wego && go install github.com/schachmat/wego
- cwd: /srv/ephemeral/
- require:
- pkg: wttr-dependencies
- file: wegorc
/srv/ephemeral:
file.directory:
- makedirs: True
{% for dir in '/srv/ephemeral/wttr.in/log','/srv/ephemeral/wttr.in/cache' %}
{{ dir }}:
file.directory:
- user: srv
- group: srv
- makedirs: True
- recurse:
- user
- group
- require_in:
- service: wttr
{% endfor %}
/etc/systemd/system/wttr.service:
file:
- managed
- source: salt://wttr/wttr.service
- require:
- file: wttr-start
- file: authbind-80
- require_in:
- service: wttr
authbind-80:
file:
- managed
- name: /etc/authbind/byport/80
- user: srv
- group: srv
- mode: 770
- replace: False
- require:
- pkg: wttr-dependencies

2
share/salt/pillar.sls Normal file
View File

@ -0,0 +1,2 @@
wttr:
apikey: insert-api-key-here-and-make-this-pillar-available-to-salt

12
share/salt/start.sh Executable file
View File

@ -0,0 +1,12 @@
#!/bin/sh
export WEGORC="/srv/ephemeral/.wegorc"
export GOPATH="/srv/ephemeral"
export WTTR_MYDIR="/srv/ephemeral/wttr.in"
export WTTR_GEOLITE="/srv/ephemeral/GeoLite2-City.mmdb"
export WTTR_WEGO="$GOPATH/bin/wego"
export WTTR_LISTEN_HOST="0.0.0.0"
export WTTR_LISTEN_PORT="80"
python $WTTR_MYDIR/bin/srv.py

58
share/salt/wegorc Normal file
View File

@ -0,0 +1,58 @@
# wego configuration
#
# This config has https://github.com/schachmat/ingo syntax.
# Empty lines or lines starting with # will be ignored.
# All other lines must look like "KEY=VALUE" (without the quotes).
# The VALUE must not be enclosed in quotes as well!
# aat-frontend: Show geo coordinates (default false)
aat-coords=false
# aat-frontend: Monochrome output (default false)
aat-monochrome=false
# BACKEND to be used (default forecast.io)
backend=forecast.io
# NUMBER of days of weather forecast to be displayed (default 3)
days=3
# forecast backend: the api KEY to use (default )
forecast-api-key={{ apikey }}
# forecast backend: print raw requests and responses (default false)
forecast-debug=false
# forecast backend: the LANGUAGE to request from forecast.io (default en)
forecast-lang=en
# FRONTEND to be used (default ascii-art-table)
frontend=ascii-art-table
# json frontend: do not indent the output (default false)
jsn-no-indent=false
# LOCATION to be queried (default 40.748,-73.985)
location=40.748,-73.985
# openweathermap backend: the api KEY to use (default )
owm-api-key=
# openweathermap backend: print raw requests and responses (default false)
owm-debug=false
# openweathermap backend: the LANGUAGE to request from openweathermap (default en)
owm-lang=en
# UNITSYSTEM to use for output.
# Choices are: metric, imperial, si, metric-ms (default metric)
units=metric-ms
# worldweatheronline backend: the api KEY to use (default )
wwo-api-key=
# worldweatheronline backend: print raw requests and responses (default false)
wwo-debug=false
# worldweatheronline backend: the LANGUAGE to request from worldweatheronline (default en)
wwo-lang=en

9
share/salt/wttr.service Normal file
View File

@ -0,0 +1,9 @@
[Unit]
Description=Wttr weather service
[Service]
ExecStart=/usr/bin/authbind --deep /srv/ephemeral/start.sh
Restart=always
[Install]
WantedBy=multi-user.target

2
share/screenrc Normal file
View File

@ -0,0 +1,2 @@
screen -t srv.py bash -c "cd ~/wttr.in; ve/bin/python bin/srv.py; bash -i"
screen -t proxy.py bash -c "cd ~/wttr.in; ve/bin/python bin/proxy.py; bash -i"

15
share/scripts/clean-cache.sh Executable file
View File

@ -0,0 +1,15 @@
#!/bin/bash
CACHEDIR="/wttr.in/cache"
for dir in wego proxy-wwo png
do
mv "${CACHEDIR}/${dir}" "${CACHEDIR}/${dir}.old"
mkdir "${CACHEDIR}/${dir}"
rm -rf "${CACHEDIR}/${dir}.old"
done
cd /wttr.in/log
mv main.log main.log.1
touch main.log

7
share/scripts/start-screen.sh Executable file
View File

@ -0,0 +1,7 @@
#!/bin/bash
SESSION_NAME=wttr.in
SCREENRC_PATH=$(dirname $(dirname "$0"))/screenrc
screen -dmS "$SESSION_NAME" -c "$SCREENRC_PATH"

View File

@ -0,0 +1,24 @@
<html>
<title>wttr.in</title>
<head>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
</head>
<body style='background:black'>
<pre style='color:#cccccc'>
Sorry, we processed more than 1M requests today and we ran out of our datasource capacity.
We hope to solve the problem as soon as possible, so you can enjoy
your favourite weather service 24x365 even if it rains or snows.
We will solve the problem as soon as possible.
<a href="https://twitter.com/igor_chubin" class="twitter-follow-button" data-show-count="false" data-button="grey">Follow @igor_chubin</a> <script>!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0],p=/^http:/.test(d.location)?'http':'https';if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src=p+'://platform.twitter.com/widgets.js';fjs.parentNode.insertBefore(js,fjs);}}(document, 'script', 'twitter-wjs');</script><span style='position: relative; bottom: 6px;'>for the updates. </span>
If you like to code (and you surely do), you can check the <span style='position: relative; bottom: -6px;'><a aria-label="Star chubin/wttr.in on GitHub" data-count-aria-label="# stargazers on GitHub" data-count-api="/repos/chubin/wttr.in#stargazers_count" data-count-href="/chubin/wttr.in/stargazers" data-icon="octicon-star" href="https://github.com/chubin/wttr.in" class="github-button">wttr.in</a></span> repository
to see how the scalability problem is (not yet) solved.
</pre>
<blockquote class="twitter-tweet" data-theme="dark" data-lang="en"><p lang="en" dir="ltr">How do you check the weather? curl wttr.in — Sure thing! <a href="https://twitter.com/hashtag/wttrin?src=hash">#wttrin</a> <a href="https://t.co/mgYzW2ajyq">pic.twitter.com/mgYzW2ajyq</a></p>&mdash; Igor Chubin (@igor_chubin) <a href="https://twitter.com/igor_chubin/status/700846126467944448">February 20, 2016</a></blockquote>
<script async src="//platform.twitter.com/widgets.js" charset="utf-8"></script>
<script async defer id="github-bjs" src="https://buttons.github.io/buttons.js"></script>
</body>
</html>

View File

@ -2,7 +2,17 @@ body {
background: black;
color: #bbbbbb;
}
pre {
font-family: DejaVu Sans Mono, Menlo, monospace;
/* font-family: source_code_proregular; */
/*
font-family: Courier New,Courier,Lucida Sans Typewriter,Lucida Typewriter,monospace;
font-size: 70%;
*/
/*font-family: Lucida Console,Lucida Sans Typewriter,monaco,Bitstream Vera Sans Mono,monospace; */
/*Droid Sans Mono*/
font-family: "Source Code Pro", "DejaVu Sans Mono", Menlo, "Lucida Sans Typewriter", "Lucida Console", monaco, "Bitstream Vera Sans Mono", monospace;
/*font-family: bitstream_vera_sans_monoroman;*/
font-size: 75%;
}

View File

@ -1,5 +1,6 @@
<html>
<head>
<link rel="stylesheet" type="text/css" href="https://adobe-fonts.github.io/source-code-pro/source-code-pro.css">
<link rel="stylesheet" type="text/css" href="/files/style.css" />
</head>
<body>

37
share/test-thunder.txt Normal file
View File

@ -0,0 +1,37 @@
Prévisions météo pour: Test-Milon, France
 _`/"".-.  Averse de pluie légère
 ,\_( ).  17 °C
 /(___(__)  ↙ 5 km/h
  14 km
  3.6 mm
┌─────────────┐
┌──────────────────────────────┬───────────────────────┤ sam. 09 juin├───────────────────────┬──────────────────────────────┐
│ Matin │ Après-midi └──────┬──────┘ Soir │ Nuit │
├──────────────────────────────┼──────────────────────────────┼──────────────────────────────┼──────────────────────────────┤
│ Brume │ Nuageux │  _`/"".-.  Foyers orageux │  _`/"".-.  Averse de plui…│
 _ - _ - _ -  21 °C │  .--.  25-26 °C │  ,\_( ).  25-27 °C │  ,\_( ).  22 °C │
 _ - _ - _  ← 5-6 km/h │  .-( ).  ← 4-5 km/h │  /(___(__)  ↑ 4-6 km/h │  /(___(__)  → 5-9 km/h │
 _ - _ - _ -  19 km │  (___.__)__)  18 km │  ⚡⚡  16 km │   15 km │
│ 0.0 mm | 0% │ 0.0 mm | 0% │   0.7 mm | 46% │   2.4 mm | 82% │
└──────────────────────────────┴──────────────────────────────┴──────────────────────────────┴──────────────────────────────┘
┌─────────────┐
┌──────────────────────────────┬───────────────────────┤ dim. 10 juin├───────────────────────┬──────────────────────────────┐
│ Matin │ Après-midi └──────┬──────┘ Soir │ Nuit │
├──────────────────────────────┼──────────────────────────────┼──────────────────────────────┼──────────────────────────────┤
 \ / Partiellement …│  \ / Partiellement …│  _`/"".-.  Averse de plui…│  _`/"".-.  Averse de plui…│
 _ /"".-.  22-24 °C │  _ /"".-.  25-27 °C │  ,\_( ).  24-26 °C │  ,\_( ).  21 °C │
 \_( ).  ↙ 9-10 km/h │  \_( ).  ↙ 13-19 km/h │  /(___(__)  ↙ 17-30 km/h │  /(___(__)  ↙ 15-31 km/h │
 /(___(__)  20 km │  /(___(__)  20 km │   17 km │   18 km │
│ 0.0 mm | 0% │ 1.8 mm | 56% │   4.1 mm | 82% │   1.6 mm | 72% │
└──────────────────────────────┴──────────────────────────────┴──────────────────────────────┴──────────────────────────────┘
┌─────────────┐
┌──────────────────────────────┬───────────────────────┤ lun. 11 juin├───────────────────────┬──────────────────────────────┐
│ Matin │ Après-midi └──────┬──────┘ Soir │ Nuit │
├──────────────────────────────┼──────────────────────────────┼──────────────────────────────┼──────────────────────────────┤
 _`/"".-.  Pluie éparse à │ Nuageux │  _`/"".-.  Averse de plui…│  _`/"".-.  Averse de plui…│
 ,\_( ).  21 °C │  .--.  24-26 °C │  ,\_( ).  23-25 °C │  ,\_( ).  20 °C │
 /(___(__)  ↑ 14-23 km/h │  .-( ).  ↑ 18-22 km/h │  /(___(__)  ↗ 13-23 km/h │  /(___(__)  ↗ 10-21 km/h │
  18 km │  (___.__)__)  18 km │   14 km │   14 km │
  0.1 mm | 22% │ 0.0 mm | 0% │   5.2 mm | 73% │   5.3 mm | 72% │
└──────────────────────────────┴──────────────────────────────┴──────────────────────────────┴──────────────────────────────┘

View File

@ -3,34 +3,51 @@ wttr.in is translated in NUMBER_OF_LANGUAGES languages:
SUPPORTED_LANGUAGES
Translated/improved/corrected by:
* Afrikaans: Casper Labuschage @casperl (on github)
* Armenian: Aram Bayadyan @aramix, Mikayel Ghazaryan @mkdotam, Grigor Khachatryan @grigortw
* Azerbaijani: Dmytro Nikitiuk, Elsevar Abbasov
* Belarusian: Igor Chubin
* Belarusian: Igor Chubin, Anton Zhavoronkov @edogby (on github)
* Bosnian: Ismar Kunc @ismarkunc
* Bulgarian: Vladimir Vitkov @zeridon (on github)
* Brazilian-PT: Tupã Negreiros @TupaNegreiros (on github)
* Catalan: Angel Jarabo @legna29A
* Croatian: Siniša Kusić @ku5ic
* Czech: Juraj Kakody
* Danish: Kim Schulz @kimusan (on github)
* Dutch: Youri Claes
* Frisian: Anne Douwe Bouma @anned20 (on github)
* Esperanto: Igor Chubin
* Estonian: Jaan Jänesmäe @janesmae (on github)
* Finnish: @Maxifi
* French: Igor Chubin, @daftaupe
* German: Igor Chubin, @MAGICC (https://kthx.at)
* Greek: Panayotis Vryonis
* Greek: Panayotis Vryonis and @Petewg (on github)
* Hebrew: E.R.
* Hungarian: Mark Petruska
* Italian: Diego Maniacco
* Icelandic: Óli G. @dvergur, Skúli Arnlaugsson @Arnlaugsson
* Indonesian: Andria Arisal @andria009
* Japanese: @ryunix
* Kazakh: Akku Tutkusheva, Oleg Tropinin
* Korean: Jeremy Bae @opt9, Jung Winter @res_tin
* Latvian: Gunārs Danovskis
* Macedonian: Matej Plavevski @MatejMecka
* Norwegian: Fredrik Fjeld @fredrikfjeld
* Nynorsk: Kevin Brubeck Unhammer (https://unhammer.org/k/)
* Persian: Javad @threadripper_
* Polish: Wojtek Łukasiewicz @wojtuch (on github)
* Portuguese: Fernando Bitti Loureiro @fbitti (on github)
* Romanian: Gabriel Moruz
* Russian: Igor Chubin
* Spanish: Fernando Bitti Loureiro @fbitti (on github)
* Slovak: Juraj Kakody
* Slovenian: B.S.
* Swedish: John Eriksson
* Serbian: Milan Stevanović @FathVader
* Swahili: Joel Mukuthu
* Turkish: Atabey Kaygun
* Ukrainian: Igor Chubin
* Turkish: Atabey Kaygun, Yilmaz @edigu
* Ukrainian: Igor Chubin, Serhiy @pavse
* Uzbek: Shukhrat Mukimov
* Welsh: Daniel Thomas

View File

@ -0,0 +1,68 @@
Gebruik:
$ curl wttr.in # huidige ligging
$ cur wttr.in/muc # weerberig in München se lughawe
Ondersteunde soorte ligging:
/paris # stadsnaam
/~Eiffel+tower # enige ligging
/Москва # Unikode naam van enige ligging in enige taal
/muc # lughawe kode (3 letters)
/@stackoverflow.com # domeinnaam
/94107 # gebiedskodes
/-78.46,106.79 # GPS koördinate
Besondere liggings:
/moon # Fase van die maan (voeg +US of ,+France by vir daardie stede)
/moon@2016-10-25 # Fase van die maan vir die datum (@2016-10-25)
Eenhede:
m # metrike (SI) (word orals gebruik behalwe vir die VSA)
u # USCS (gebruik in die VSA)
M # vertoon die spoed van die wind in m/s
Besigtig keuses:
0 # slegs die huidige weer
1 # huidige weer + 1 dag
2 # huidige weer + 2 dae
F # moet nie die "Volg" lyn wys nie
n # smal weergawe (slegs dag en nag)
q # stil weergawe (geen "Weerberig" teks nie)
Q # baie stil weergawe (geen "Weerberig), geen stadsnaam
T # skakel terminaal kodes af (geen kleur)
PNG keuses:
/paris.png # skep 'n PNG leêr
p # voeg 'n raam by rondom die uitset
t # deursigtigheid 150
transparency=... # deursigtigheid vanaf 0 tot 255 (255 = nie deursigtig nie)
Keuses can saamgevoeg word
/Paris?0pq
/Paris?0pq&lang=fr
/Paris_0pq.png # met PNG word die lêer mode daarna gegee
/Rome_0pq_lang=it.png # lang keuses word met 'n onderstreping verdeel
Lokalisering:
$ curl fr.wttr.in/Paris
$ curl wttr.in/paris?lang=fr
$ curl -H "Accept-Language: fr" wttr.in/paris
Ondersteunde tale:
FULL_TRANSLATION (word ondersteun)
PARTIAL_TRANSLATION (in wording)
Spesiale URLe:
/:help # vertoon hierdie bladsy
/:bash.function # vertoon aanbeveling vir bash funksie wttr()
/:translation # vertoon die besonderhede van die vertalers

47
share/translations/af.txt Normal file
View File

@ -0,0 +1,47 @@
113: Helder : Clear
113: Sonnig : Sunny
116: Gedeeltelik bewolk : Partly cloudy
119: Bewolk : Cloudy
122: Oortrokke : Overcast
143: Mis toestande : Mist
176: Gedeeltelike reën moontlik : Patchy rain possible
179: Gedeeltelike sneeu moontlik : Patchy snow possible
182: Gedeeltelike ysreën moontlik : Patchy sleet possible
185: Gedeeltelik ysige motreën moontlik : Patchy freezing drizzle possible
200: Donderbuie moontlik : Thundery outbreaks possible
227: Waaiende sneeu : Blowing snow
230: Sneeustorm : Blizzard
248: Mis toestande : Fog
260: Vriesende mis toestande : Freezing fog
263: Gedeeltelike ligte motreën : Patchy light drizzle
266: Ligte motreën : Light drizzle
281: Vriesende motreën : Freezing drizzle
284: Erg vriesende motreën : Heavy freezing drizzle
293: Gedeeltelike ligte reën : Patchy light rain
296: Ligte reën : Light rain
299: Matige reën by tye : Moderate rain at times
302: Matige reën : Moderate rain
305: Swaar reën by tye : Heavy rain at times
308: Swaar reën : Heavy rain
311: Ligte vriesende reën : Light freezing rain
314: Matige tot swaar vriesende reën : Moderate or heavy freezing rain
317: Ligte ysreën : Light sleet
320: Matige tot swaar ysreën : Moderate or heavy sleet
323: Verspreide ligte sneeu : Patchy light snow
326: Ligte sneeu : Light snow
329: Verspreide ligte sneeu : Patchy moderate snow
332: Matige sneeu : Moderate snow
335: Verspreide swaar sneeu : Patchy heavy snow
338: Swaar sneeu : Heavy snow
350: Haelkorrels : Ice pellets
353: Ligte bui reën : Light rain shower
356: Matige tot swaar bui reënbui : Moderate or heavy rain shower
359: Stortreën : Torrential rain shower
362: Ligte buie ysreën : Light sleet showers
365: Ligte tot swaar buie ysreën : Moderate or heavy sleet showers
368: Ligte buie sneeu : Light snow showers
371: Ligte tot swaar buie sneeu : Moderate or heavy snow showers
386: Verspreide ligte buie en donderbuie : Patchy light rain with thunder
389: Ligte tot swaar buie en donderbuie : Moderate or heavy rain with thunder
392: Verspreide ligte sneeu met donderbuie : Patchy light snow with thunder
395: Matige of swaar sneeu met donderbuie : Moderate or heavy snow with thunder

47
share/translations/be.txt Normal file
View File

@ -0,0 +1,47 @@
113: Ясна : Clear :
113: Сонечна : Sunny :
116: Пераменная воблачнасць : Partly cloudy :
119: Воблачнасць : Cloudy :
122: Хмарна : Overcast :
143: Смуга : Mist :
176: Месцамі дождж : Patchy rain possible :
179: Месцамі снег : Patchy snow possible :
182: Месцамі дождж са снегам : Patchy sleet possible :
185: Месцамі студзёная імжа : Patchy freezing drizzle possible :
200: Месцамі навальніцы : Thundery outbreaks possible :
227: Нізавая завіруха : Blowing snow :
230: Мяцеліца : Blizzard :
248: Туман : Fog :
260: Студзёны туман : Freezing fog :
263: Месцамі невялікая імжа : Patchy light drizzle :
266: Невялікая імжа : Light drizzle :
281: Студзёная імжа : Freezing drizzle :
284: Моцная студзёная імжа : Heavy freezing drizzle :
293: Месцамі невялікі дождж : Patchy light rain :
296: Невялікі дождж : Light rain :
299: Часам умераны дождж : Moderate rain at times :
302: Умераны дождж : Moderate rain :
305: Часам моцны дождж : Heavy rain at times :
308: Моцны дождж : Heavy rain :
311: Невялікі студзёны дождж : Light freezing rain :
314: Умераны ці моцны студзёны дождж : Moderate or heavy freezing rain :
317: Невялікі дождж са снегам : Light sleet :
320: Умераны ці моцны дождж са снегам : Moderate or heavy sleet :
323: Месцамі невялікі снег : Patchy light snow :
326: Невялікі снег : Light snow :
329: Месцамі умераны снег : Patchy moderate snow :
332: Умераны снег : Moderate snow :
335: Месцамі моцны снег : Patchy heavy snow :
338: Моцны снег : Heavy snow :
350: Ледзяны дождж : Ice pellets :
353: Слабы ліўневы дождж : Light rain shower :
356: Умераны ці моцны ліўневы дождж : Moderate or heavy rain shower :
359: Вельмі моцны ліўневы дождж : Torrential rain shower :
362: Невялікі ліўневы дождж са снегам : Light sleet showers :
365: Умераны ці моцны ліўневы дождж са снегам : Moderate or heavy sleet showers :
368: Невялікі ліўневы снег : Light snow showers :
371: Умераны ці моцны ліўневы снег : Moderate or heavy snow showers :
386: Месцамі невялікі дождж з навальніцай : Patchy light rain with thunder :
389: Умераны ці моцны дождж з навальніцай : Moderate or heavy rain with thunder :
392: Месцамі невялікі снег з навальніцай : Patchy light snow with thunder :
395: Умераны ці моцны снег з навальніцай : Moderate or heavy snow with thunder :

View File

@ -0,0 +1,69 @@
Употреба:
$ curl wttr.in # текущо местоположение
$ curl wttr.in/sof # времето на Софийското летище
Поддържани типове местоположения:
/paris # име на град
/~Eiffel+tower # място/забележителност
/Москва # Юникод име на местоположение
/sof # Код на летище (3 букви)
/@stackoverflow.com # име на домейн
/94107 # пощенски код
/-78.46,106.79 # GPS координати
Специални местоположение:
/moon # Фаза на луната (добавете ,+US or ,+France за тези места)
/moon@2016-10-25 # Фаза на луната за дата (@2016-10-25)
Мерни единици:
m # метрични (SI) (по подразбиране навсякъде извън US)
u # USCS (използвани по подразбиране в US)
M # покажи скоростта на вятъра в m/s
Възможности на изгледа:
0 # само текущото време
1 # текущо време + 1 ден
2 # текущо време + 2 дни
A # игнорирай User-Agent и форсирай ANSI формат (за терминал)
F # не показвай реда "Следвай"
n # тясна версия (само ден и нощ)
q # тиха версия (без текст "Прогноза за времето")
Q # свръх тиха версия(без "Прогноза за времето", без име на местоположение)
T # изключи терминалните настройки (без цветове)
PNG възможности:
/paris.png # генериране на PNG
p # Сложи рамка около резултата
t # полупрозрачен фон 150
transparency=... # полупрозрачен фон от 0 до 255 (255 = непрозрачно)
Опциите могат да се комбинират:
/Paris?0pq
/Paris?0pq&lang=bg
/Paris_0pq.png # при генериране на PNG възможностите са отделени с _
/Rome_0pq_lang=bg.png # дългите опции са разделени с подчертавка
Локализация:
$ curl fr.wttr.in/Paris
$ curl wttr.in/paris?lang=bg
$ curl -H "Accept-Language: bg" wttr.in/paris
Поддържани преводи:
FULL_TRANSLATION (Напълно преведени)
PARTIAL_TRANSLATION (В процес на превод)
Специални Адреси (URL):
/:help # тази страница
/:bash.function # препоръчителна bash функция wttr()
/:translation # покажи информация за преводачите

View File

@ -0,0 +1,66 @@
Brugsanvisning:
$ curl wttr.in # nuværende lokation
$ curl wttr.in/osl # vejret på Gardermoen flyveplads
Understøttede lokationsspecifikationer:
/gistrup # bynavn
/~Aalborg+stadion # valgfri lokation
/Москва # Unicode navn på lokation på alle sprog
/cph # flyvepladskode (3 bogstaver)
/@stackoverflow.com # domønenavn
/94107 # postnummer (kun USA)
/-78.46,106.79 # GPS-koordinater
Specielle lokationer:
/moon # Månefase (brug med ,+US eller ,+France for disse lokationer)
/moon@2014-10-26 # Månefase for specifik dato (@2014-10-26)
Enheder:
?m # metrisk (SI) (standard alle steder undtaget i USA)
?u # USCS (standard i USA)
?M # vindstyrke i meter per sekund
Visningsvalg:
?0 # kun vejret nu
?1 # vejret nu + 1 dag
?2 # vejret nu + 2 dage
?n # smal visning (kun dag og nat)
?q # stille visning (ingen "Vejrmelding"-tekst)
?Q # superstille visning (ingen "Vejrmelding", ingen bynavn)
?T # ingen terminalsekvenser (ingen farver)
PNG valg:
/paris.png # generer en PNG-fil
?p # tegn ramme på
?t # gennemsigtighed 150
transparency=... # gennemsigtighed fra 0 til 255 (255 = ikke gennemsigtigt)
Tilvalg kan kombineres:
/Paris?0pq
/Paris?0pq&lang=fr
/Paris_0pq.png # for PNG er filmodus specificeret efter _
/Rome_0pq_lang=it.png # lange tilvalg separeres med underscore (_)
Oversættelser:
$ curl fr.wttr.in/Paris
$ curl wttr.in/paris?lang=fr
$ curl -H "Accept-Language: fr" wttr.in/paris
Understøttede sprog:
FULL_TRANSLATION (understøttet)
PARTIAL_TRANSLATION (under udarbejdning)
Specielle URLer:
/:help # vis denne side
/:bash.function # vis den foreslåede bash-funktion wttr()
/:translation # vis information om oversætterne

47
share/translations/da.txt Normal file
View File

@ -0,0 +1,47 @@
113: Klart : Clear
113: Sol : Sunny
116: Delvis skyet : Partly cloudy
119: Skyet : Cloudy
122: Overskyet : Overcast
143: Dis : Mist
176: Chance for skiftende regn : Patchy rain possible
179: Chance for skiftende sne : Patchy snow possible
182: Chance for skiftende slud : Patchy sleet possible
185: Chance for skiftende, kold småregn : Patchy freezing drizzle possible
200: Fare for torden : Thundery outbreaks possible
227: Snefygning : Blowing snow
230: Snestorm : Blizzard
248: Tåge : Fog
260: Kold tåge : Freezing fog
263: Skiftende, let støvregn : Patchy light drizzle
266: Let støvregn : Light drizzle
281: Kold støvregn : Freezing drizzle
284: Kraftig, kold regn : Heavy freezing drizzle
293: Skiftende, let regn : Patchy light rain
296: Let regn : Light rain
299: Til tider en smule regn : Moderate rain at times
302: En smule regn : Moderate rain
305: Til tider kraftig regn : Heavy rain at times
308: Kraftig regn : Heavy rain
311: Let, kold regn : Light freezing rain
314: Moderat eller kraftig, kold, regn : Moderate or heavy freezing rain
317: Let slud : Light sleet
320: Moderat eller kraftig slud : Moderate or heavy sleet
323: Byger af let sne : Patchy light snow
326: Let sne : Light snow
329: Byger med moderat sne : Patchy moderate snow
332: Moderat snevej : Moderate snow
335: Byger med kraftigt snefald : Patchy heavy snow
338: Kraftigt snefald : Heavy snow
350: Hagl : Ice pellets
353: Lette regnbyger : Light rain shower
356: Moderat til tunge regnskyl : Moderate or heavy rain shower
359: Styrtregn : Torrential rain shower
362: Lette sludbyger : Light sleet showers
365: Moderat til tunge sludbyger : Moderate or heavy sleet showers
368: Lette snebyger : Light snow showers
371: Moderat til kraftige snebyger : Moderate or heavy snow showers
386: Byger af let regn med torden : Patchy light rain with thunder
389: Moderat eller krafig regn med torden : Moderate or heavy rain with thunder
392: Byger af let sne med torden : Patchy light snow with thunder
395: Moderat til krafitg sne med torden : Moderate or heavy snow with thunder

View File

@ -0,0 +1,66 @@
Brugsanvisning:
$ curl wttr.in # nuværende lokation
$ curl wttr.in/osl # vejret på Gardermoen flyveplads
Understøttede lokationsspecifikationer:
/gistrup # bynavn
/~Aalborg+stadion # valgfri lokation
/Москва # Unicode navn på lokation på alle sprog
/cph # flyvepladskode (3 bogstaver)
/@stackoverflow.com # domønenavn
/94107 # postnummer (kun USA)
/-78.46,106.79 # GPS-koordinater
Specielle lokationer:
/moon # Månefase (brug med ,+US eller ,+France for disse lokationer)
/moon@2014-10-26 # Månefase for specifik dato (@2014-10-26)
Enheder:
?m # metrisk (SI) (standard alle steder undtaget i USA)
?u # USCS (standard i USA)
?M # vindstyrke i meter per sekund
Visningsvalg:
?0 # kun vejret nu
?1 # vejret nu + 1 dag
?2 # vejret nu + 2 dage
?n # smal visning (kun dag og nat)
?q # stille visning (ingen "Vejrmelding"-tekst)
?Q # superstille visning (ingen "Vejrmelding", ingen bynavn)
?T # ingen terminalsekvenser (ingen farver)
PNG valg:
/paris.png # generer en PNG-fil
?p # tegn ramme på
?t # gennemsigtighed 150
transparency=... # gennemsigtighed fra 0 til 255 (255 = ikke gennemsigtigt)
Tilvalg kan kombineres:
/Paris?0pq
/Paris?0pq&lang=fr
/Paris_0pq.png # for PNG er filmodus specificeret efter _
/Rome_0pq_lang=it.png # lange tilvalg separeres med underscore (_)
Oversættelser:
$ curl fr.wttr.in/Paris
$ curl wttr.in/paris?lang=fr
$ curl -H "Accept-Language: fr" wttr.in/paris
Understøttede sprog:
FULL_TRANSLATION (understøttet)
PARTIAL_TRANSLATION (under udarbejdning)
Specielle URLer:
/:help # vis denne side
/:bash.function # vis den foreslåede bash-funktion wttr()
/:translation # vis information om oversætterne

View File

@ -0,0 +1,72 @@
Χρήση:
$ curl wttr.in # καιρός τρέχουσας τοποθεσίας (κατά προσέγγιση, βάσει IP)
$ curl wttr.in/ath # ο καιρός στο Διεθνή Αερολιμένα Αθηνών «Ελ. Βενιζέλος»
Υποστηριζόμενες μορφές τοποθεσιών:
/paris # όνομα πόλης
/~Eiffel+tower # κάποια τοποθεσία
/Москва # Unicode όνομα οποιασδήποτε τοποθεσίας σε οποιαδήποτε γλώσσα
/ath # κωδικός αεροδρομίου (3 γράμματα)
/@stackoverflow.com # (διαδικτυακό) όνομα τομέα (domain)
/94107 # κωδικός περιοχής
/-78.46,106.79 # γεωγραφικές συντεταγμένες (GPS)
Εξειδικευμένες τοποθεσίες:
/moon # Φάση Σελήνης (προσθέστε ,+US ή ,+France για τις πόλεις)
/moon@2016-10-25 # Φάση Σελήνης για την ημερομηνία (@2016-10-25)
/moon@2019-06-18.png?T -omoon.png # Φάση Σελήνης για την ημερομηνία (@2019-06-18), όχι ANSI, εξοδος στο αρχείο `moon.png`
Σύστημα μέτρησης:
m # μετρικό (SI) (προεπιλογή για οπουδήποτε εκτός ΗΠΑ)
u # USCS (προεπιλογή για τις ΗΠΑ)
M # εμφάνιση ταχύτητας ανέμου σε m/s
Επιλογές Προβολής:
0 # καιρός τρέχουσας ημέρας μόνο
1 # καιρός τρέχουσας ημέρας + 1 ημέρα
2 # καιρός τρέχουσας ημέρας + 2 ημέρες
A # παραβλέπει τον User-Agent και επιβάλει μορφή εξόδου ANSI (τερματικό)
F # μη εμφάνιση της γραμμής "Follow"
n # συνοπτική εκδοχή (ημέρα και νύχτα μόνο)
q # σιωπηλή εκδοχή (όχι κείμενο "Weather report")
Q # υπερσιωπηλή εκδοχή (όχι κείμενο "Weather report", όχι όνομα πόλης)
T # απενεργοποίηση ακολουθιών τερματικού (όχι χρώματα)
Επιλογές PNG:
/paris.png # δημιουργία PNG αρχείου
p # προσθήκη πλαισίου γύρω από τα περιέχομενα εξόδου
t # διαφάνεια 150
transparency=nnn # διαφάνεια nnn (από 0 έως 255 - 255 = αδιαφανές)
Οι επιλογές μπορούν να συνδυαστούν:
/Paris?0pq
/Paris?0pq&lang=fr
/Paris?_0pq.png # η έξοδος σε PNG αρχείο ορίζεται μετά από το _
/Rome?_0pq_lang=it.png # μακροσκελείς επιλογές διαχωριζόμενες με κάτω παύλα (underscore)
/Athens?"1pTng&lang=el" # συνδυασμένες επιλογές μπορούν να περικλείονται σε εισαγωγικά!
Τοπικοποίηση:
$ curl fr.wttr.in/Paris
$ curl wttr.in/paris?lang=fr
$ curl -H "Accept-Language: fr" wttr.in/paris
Υποστηριζόμενες γλώσσες:
FULL_TRANSLATION (πλήρως υποστηριζόμενες)
PARTIAL_TRANSLATION (εργασία σε εξέλιξη)
Ειδικά URLs:
/:help # εμφάνιση της παρούσας βοήθειας
/:bash.function # εμφάνιση συνιστώμενων bash λειτουργιών wttr()
/:translation # εμφάνιση πληροφοριών για τους μεταφραστές

47
share/translations/el.txt Normal file
View File

@ -0,0 +1,47 @@
113: Καθαρός : Clear
113: Λιακάδα : Sunny
116: Αραιή συννεφιά : Partly cloudy
119: Συννεφιά : Cloudy
122: Πυκνή νέφωση : Overcast
143: Αραιή ομίχλη : Mist
176: Πιθανή βροχή τοπικά : Patchy rain possible
179: Πιθανή χιονόπτωση τοπικά : Patchy snow possible
182: Πιθανή χαλαζόπτωση τοπικά : Patchy sleet possible
185: Πιθανό παγωμ. ψιλόβροχο τοπικά : Patchy freezing drizzle possible
200: Πιθανή πτώση κεραυνών : Thundery outbreaks possible
227: Ριπές χιονιού : Blowing snow
230: Χιονοθύελλα : Blizzard
248: Ομίχλη : Fog
260: Παγωμένη ομίχλη : Freezing fog
263: Ασθενής ψιχάλα τοπικά : Patchy light drizzle
266: Ασθενής ψιχάλα : Light drizzle
281: Παγωμένο ψιλόβροχο : Freezing drizzle
284: Πυκνό παγωμένο ψιλόβροχο : Heavy freezing drizzle
293: Ασθενής όμβρος τοπικά : Patchy light rain
296: Ασθενής βροχόπτωση : Light rain
299: Μέτρια βροχή παροδικά : Moderate rain at times
302: Μέτρια βροχόπτωση : Moderate rain
305: Έντονη βροχή παροδικά : Heavy rain at times
308: Έντονη βροχόπτωση : Heavy rain
311: Αραιό χιονόνερο : Light freezing rain
314: Μέτριο ή έντονο χιονόνερο : Moderate or heavy freezing rain
317: Ασθενής χαλαζόπτωση : Light sleet
320: Μέτρια ή έντονη χαλαζόπτωση : Moderate or heavy sleet
323: Αραιή χιονόπτωση κατά τόπους : Patchy light snow
326: Αραιή χιονόπτωση : Light snow
329: Μέτρια χιονόπτωση τοπικά : Patchy moderate snow
332: Μέτρια χιονόπτωση : Moderate snow
335: Πυκνή χιονόπτωση τοπικά : Patchy heavy snow
338: Πυκνή χιονόπτωση : Heavy snow
350: Χιονόνερο : Ice pellets
353: Ασθενής βροχή παροδικά : Light rain shower
356: Μέτρια ή έντονη βροχή παροδικά : Moderate or heavy rain shower
359: Καταρρακτώδης βροχή παροδικά : Torrential rain shower
362: Ασθενής χαλαζόπτωση παροδικά : Light sleet showers
365: Μέτρια/έντονη χαλαζόπτωση παροδικά : Moderate or heavy sleet showers
368: Αραιή χιονόπτωση παροδικά : Light snow showers
371: Μέτρια ή πυκνή χιονόπτωση παροδικά : Moderate or heavy snow showers
386: Ασθενής βροχή με κεραυνούς τοπικά : Patchy light rain with thunder
389: Μέτρια ή δυνατή βροχή με κεραυνούς : Moderate or heavy rain with thunder
392: Ασθενής χιονόπτωση-κεραυνοί τοπικά : Patchy light snow with thunder
395: Μέτρια ή πυκνή χιονόπτωση-κεραυνοί : Moderate or heavy snow with thunder

View File

@ -0,0 +1,66 @@
Instrucciones:
$ curl wttr.in # el clima en su ubicación actual
$ curl wttr.in/muc # el clima en el aeropuerto de Múnich
Tipos de ubicación soportados:
/paris # el nombre de una ciudad
/~Eiffel+tower # el nombre de cualquier sitio famoso
/Москва # el nombre Unicode de cualquier sitio en cualquier idioma
/muc # el código de un aeropuerto (3 letras)
/@stackoverflow.com # el nombre de un dominio web
/94107 # un código de area
/-78.46,106.79 # coordenadas de GPS
Sitios especiales:
/moon # la fase de la luna (añade ,+US o ,+France para estos paises)
/moon@2016-10-25 # la fase de la luna en una fecha específica (@2016-10-25)
Unidades:
?m # métricas (SI) (el estándar en todos los sitios excepto en EEUU)
?u # Sistema Unificado de Clasificación del Suelo o USCS (el estándar en EEUU)
?M # mostrar la velocidad del viento en m/s
Opciones de visualización:
?0 # solamente el clima actual
?1 # el clima actual + la previsión de 1 día
?2 # el clima actual + la previsión de 2 días
?n # versión corta (solo el día y la noche)
?q # versión silenciosa (sin el texto de "El tiempo en")
?Q # versión supersilenciosa (ni "El tiempo en" ni el nombre de la ciudad)
?T # desactiva las secuencias de terminal (sin colores)
Opciones de PNG:
/paris.png # genera una imagen PNG
?p # añade un borde alrededor de la imagen
?t # transparencia 150
transparency=... # transparencia de 0 a 255 (255 = sin transparencia)
Las opciones se pueden utilizar conjuntamente:
/Paris?0pq
/Paris?0pq&lang=fr
/Paris_0pq.png # en PNG las opciones se especifican después del carácter _
/Rome_0pq_lang=it.png # una larga secuencia de opciones se puede separar por el carácter _
Ubicación:
$ curl fr.wttr.in/Paris
$ curl wttr.in/paris?lang=fr
$ curl -H "Accept-Language: fr" wttr.in/paris
Idiomas soportados:
FULL_TRANSLATION (soportados)
PARTIAL_TRANSLATION (en progreso)
URLs especiales:
/:help # muestra esta página
/:bash.function # sugiere una función wttr() en bash
/:translation # muestra información acerca de los traductores

View File

@ -0,0 +1,66 @@
Kasutus:
$ curl wttr.in # praegune asukoht
$ curl wttr.in/tll # ilmaprognoos Tallinna Lennujaamas
Toetatud asukohatüübid:
/paris # linna nimi
/~suur+munamägi # mistahes asukoht
/Москва # Ükskõik millises keeles Unicode'i vormingus asukoha nimi
/muc # IATA Lennujaama kood (3 tähemärki)
/@stackoverflow.com # domeeninimi
/94107 # Piirkonna kood (Ainult USA)
/-78.46,106.79 # GPS-koordinaadid
Erilised asukohad:
/moon # Kuu faas (lisage, +US või +France linnade jaoks))
/moon@2016-10-25 # Kuu faas kindlal kuupäeval (@2016-10-25)
Ühikud:
?m # meetriline (SI) (kasutatakse vaikimisi kõikjal peale USA)
?u # USCS (kasutusel vaikimisi USA)
?M # kuva tuule kiirust m/s
Vaadete valikuid:
?0 # kuva ainult praegune ilm
?1 # kuva praegune ilm + 1 päeva prognoos
?2 # kuva praegune ilm + 2 päeva prognoos
?n # kitsas vaade (Päeva & Öö prognoos)
?q # taltsas variant ('ilmaprognoos' tekstita)
?Q # eriti taltsas variant (asukohata ja 'ilmaprognoos' tekstita)
?T # värvideta
PNG valikud:
/paris.png # loo PNG fail
?p # lisab raami ümber väljundi
?t # läbipaistvus 150
transparency=... # läbipaistvus 0-st kuni 255-ni (255 = pole läbipaistev)
Valikuid saab kombineerida:
/Paris?0pq
/Paris?0pq&lang=fr
/Paris_0pq.png # PNG failis saab valikuid määrata peale _ (alakriips) tähemärki
/Rome_0pq_lang=it.png # pikad valikud on eraldatud alakriipsuga
Lokaliseerimine:
$ curl fr.wttr.in/Paris
$ curl wttr.in/paris?lang=fr
$ curl -H "Accept-Language: fr" wttr.in/paris
Toetattud keeled:
FULL_TRANSLATION (toetatud)
PARTIAL_TRANSLATION (teoksil)
Erilehed:
/:help # kuvab käesolevat lehte
/:bash.function # kuvab soovitatud bash-funktsiooni wttr()
/:translation # kuvab infot tõlkijate kohta

55
share/translations/et.txt Normal file
View File

@ -0,0 +1,55 @@
113: Selge : Clear
113: Päikeseline : Sunny
116: Vahelduv pilvisus : Partly cloudy
119: Pilvine : Cloudy
122: Sombune : Overcast
143: Uduvine : Mist
176: Paiguti vihmasaju võimalus : Patchy rain possible
179: Paiguti lumesaju võimalus : Patchy snow possible
182: Paiguti lörtsisaju võimalus : Patchy sleet possible
185: Paiguti jääudu võimalus : Patchy freezing drizzle possible
200: Äikese võimalus : Thundery outbreaks possible
227: Tuisk : Blowing snow
230: Lumetorm : Blizzard
248: Udu : Fog
260: Jääudu : Freezing fog
263: Paiguti nõrk uduvihm : Patchy light drizzle
266: Nõrk uduvihm : Light drizzle
281: Jääudu : Freezing drizzle
284: Tugev uduvihm : Heavy freezing drizzle
293: Vahelduv nõrk vihm : Patchy light rain
296: Nõrk vihm : Light rain
299: Vahelduv mõõdukas vihm : Moderate rain at times
302: Mõõdukas vihm : Moderate rain
305: Vahelduv tugev vihm : Heavy rain at times
308: Tugev vihm : Heavy rain
311: Nõrk jäävihm : Light freezing rain
314: Mõõdukas või tugev jäävihm : Moderate or heavy freezing rain
317: Nõrk lörtsisadu : Light sleet
320: Mõõdukas või tugev lörtsisadu : Moderate or heavy sleet
323: Paiguti nõrk lumesadu : Patchy light snow
326: Nõrk lumesadu : Light snow
329: Paiguti mõõdukas lumesadu : Patchy moderate snow
332: Mõõdukas lumesadu : Moderate snow
335: Paiguti tugev lumesadu : Patchy heavy snow
338: Tugev lumesadu : Heavy snow
350: Rahe : Ice pellets
353: Nõrk hoogvihm : Light rain shower
356: Mõõdukas või tugev hoogvihm : Moderate or heavy rain shower
359: Padu hoogvihm : Torrential rain shower
362: Nõrk hooglörts : Light sleet showers
365: Mõõdukas või tugev hooglörts : Moderate or heavy sleet showers
368: Nõrk hooglumi : Light snow showers
371: Mõõdukas või tugev hooglumi : Moderate or heavy snow showers
386: Paiguti nõrk vihm äikesega : Patchy light rain with thunder
389: Mõõdukas või tugev vihm äikesega : Moderate or heavy rain with thunder
392: Paiguti nõrk lumesadu äikesega : Patchy light snow with thunder
395: Mõõdukas või tugev lumesadu äikesega : Moderate or heavy snow with thunder
: Hoogvihm : Rain shower
: Tugev hoogvihm : Heavy showers
: Nõrk hoogvihm : Light showers
: Tugev hooglumi : Heavy snow showers
: Äikesevihm : Thundery showers
: Tugev äikesevihm : Thundery heavy rain
: Äikesega lumesadu : Thundery snow showers
: Tugev hooglumi : Heavy snow showers

View File

@ -0,0 +1,67 @@
:نحوه استفاده
$ curl wttr.in # موقعیت فعلی
$ curl wttr.in/muc # وضعیت اب و هوا در فرودگاه مونیخ
:انواع مکان های پشتیبانی شده
/paris # نام شهر
/~Eiffel+tower # هر مکانی
/Москва # نام یونیکد هر مکانی در هر زبانی
/muc # کد فرودگاه (3 حرفی)
/@stackoverflow.com # نام دامنه
/94107 # کد منطقه
/-78.46,106.79 # موقعیت جغرافیایی
:مکان های خاص
/moon # فازهای ماه (+US یا +France را برای این شهرها اضافه کنید)
/moon@2016-10-25 # فازهای ماه برای تاریخ خاص (@2016-10-25)
:واحدها
?m # متریک (سیستم SI) (به طور پیشفرض در همه جا به جز امریکا استفاده می شود.)
?u # USCS (به طور پیشفرض در امریکا استفاده می شود)
?M # نمایش سرعت باد بر حسب متر بر ثانیه
:تنظیمات نمایش
?0 # فقط اب و هوای امروز
?1 # اب و هوای امروز + 1 روز
?2 # اب و هوای امروز + 2 روز
?n # نسخه باریک (فقط روز و شب)
?q # نسخه ساکت (بدون نوشته "گزارش اب و هوا")
?Q # نسخه خیلی ساکت (بدون نوشته "گزارش اب و هوا" و اسم شهر)
?T # حالت بدون رنگ
:تنظیمات خروجی PNG
/paris.png # ساختن فایل PNG
?p # اضافه کردن حاشیه در خروجی
?t # قرار دادن شفافیت روی 150
transparency=... # شفافیت از 0 تا 255 (255 یعنی بدون شفافیت)
:تنظیمات ترکیبی
/Paris?0pq
/Paris?0pq&lang=fr
/Paris_0pq.png # در PNG حالت فایل بعد از _ ذکر می شود
/Rome_0pq_lang=it.png # تنظیمات بلند توسط اندرلاین جدا می شوند
:محلی سازی
$ curl fr.wttr.in/Paris
$ curl wttr.in/paris?lang=fr
$ curl -H "Accept-Language: fr" wttr.in/paris
:زبان های پشتیبانی شده
FULL_TRANSLATION (پشتیبانی شده)
PARTIAL_TRANSLATION (در حال پیشرفت)
:ادرس های خاص
/:help # نمایش این صفحه
/:bash.function # نمایش تابع پیشنهادی بش برای wttr()
/:translation # نمایش اطلاعات در مورد مترجمین

47
share/translations/fa.txt Normal file
View File

@ -0,0 +1,47 @@
113: صاف : Clear
113: آفتابی : Sunny
116: نیمه ابری : Partly cloudy
119: ابری : Cloudy
122: پوشیده از ابر : Overcast
143: شبنم : Mist
176: احتمال بارش پراکنده باران : Patchy rain possible
179: احتمال بارش پراکنده برف : Patchy snow possible
182: احتمال بارش پراکنده تگرگ : Patchy sleet possible
185: احتمال بارش پراکنده قطرات منجمد باران : Patchy freezing drizzle possible
200: احتمال رعد و برق : Thundery outbreaks possible
227: بارش سنگین برف : Blowing snow
230: کولاک : Blizzard
248: مه : Fog
260: مه یخ زده : Freezing fog
263: بارش پراکنده نم نم باران : Patchy light drizzle
266: بارش نم نم باران : Light drizzle
281: بارش ریزباران یخ بسته : Freezing drizzle
284: بارش سنگین ریزباران یخ بسته : Heavy freezing drizzle
293: بارش پراکنده باران : Patchy light rain
296: بارش باران : Light rain
299: بارش یکنواخت و ملایم باران : Moderate rain at times
302: بارش ملایم باران : Moderate rain
305: بارش سنگین باران به صورت یکنواخت : Heavy rain at times
308: بارش سنگین باران : Heavy rain
311: بارش نم نم باران یخ بسته : Light freezing rain
314: بارش ملایم یا سنگین باران یخ بسته : Moderate or heavy freezing rain
317: بارش سبک تگرگ : Light sleet
320: بارش ملایم یا سنگین تگرگ : Moderate or heavy sleet
323: بارش پراکنده و سبک برف : Patchy light snow
326: بارش سبک برف : Light snow
329: بارش پراکنده و ملایم برف : Patchy moderate snow
332: بارش ملایم برف : Moderate snow
335: بارش پراکنده و سنگین برف : Patchy heavy snow
338: بارش سنگین برف : Heavy snow
350: بارش دانه های ریز یخ : Ice pellets
353: دوش باران سبک : Light rain shower
356: دوش باران ملایم یا سنگین : Moderate or heavy rain shower
359: دوش باران سیلی : Torrential rain shower
362: بارش سبک دوش تگرگ : Light sleet showers
365: بارش ملایم یا سنگین دوش تگرگ : Moderate or heavy sleet showers
368: بارش سبک دوش برف : Light snow showers
371: بارش ملایم یا سنگین دوش برف : Moderate or heavy snow showers
386: بارش پراکنده باران همراه با رعد و برق : Patchy light rain with thunder
389: بارش ملایم یا سنگین باران همراه با رعد و برق : Moderate or heavy rain with thunder
392: بارش پراکنده برف ملایم یا سنگین همراه با رعد و برق : Patchy light snow with thunder
395: بارش ملایم یا سنگین برف همراه با رعد و برق : Moderate or heavy snow with thunder

47
share/translations/fy.txt Normal file
View File

@ -0,0 +1,47 @@
113: Helder : Clear
113: Sinnich : Sunny
116: Bytsje bewolkt : Partly cloudy
119: Bewolkt : Cloudy
122: Bewolkt : Overcast
143: Mistich : Mist
176: Misskien lokaal reinbui : Patchy rain possible
179: Misskien lokaal snie : Patchy snow possible
182: Misskien lokaal hagel : Patchy sleet possible
185: Misskien lokaal izel : Patchy freezing drizzle possible
200: Misskien in onwaarsbui : Thundery outbreaks possible
227: Snie wyn : Blowing snow
230: Sniestoarm : Blizzard
248: Mistich : Fog
260: Rijp : Freezing fog
263: Lokaal motrein : Patchy light drizzle
266: Motrein : Light drizzle
281: Izel : Freezing drizzle
284: Swiere izel : Heavy freezing drizzle
293: Lokaal in bytsje rein : Patchy light rain
296: Bytsje rein : Light rain
299: Út en troch rein : Moderate rain at times
302: Rein : Moderate rain
305: Út en troch swiere rein : Heavy rain at times
308: Swiere rein : Heavy rain
311: Lichte izel : Light freezing rain
314: Swiere izel : Moderate or heavy freezing rain
317: Lichte hagel : Light sleet
320: Swiere hagel : Moderate or heavy sleet
323: Lokaal lichte snie : Patchy light snow
326: Lichte snie : Light snow
329: Lokaal snie : Patchy moderate snow
332: Snie : Moderate snow
335: Lokaal swiere snie : Patchy heavy snow
338: Swiere snie : Heavy snow
350: Hagel : Ice pellets
353: Lichte reinbuien : Light rain shower
356: Reinbuien : Moderate or heavy rain shower
359: Ekstreem swiere reinbuien : Torrential rain shower
362: Lichte hagelbuien : Light sleet showers
365: Hagelbuien : Moderate or heavy sleet showers
368: Lichte sniebuien : Light snow showers
371: Sniebuien : Moderate or heavy snow showers
386: Lokaal lichte rein mei onwaar: Patchy light rain with thunder weer
389: Rein mei onwaar : Moderate or heavy rain with thunder
392: Lokaal lichte snie mei onwaar: Patchy light snow with thunder nweer
395: Snie mei onwaar : Moderate or heavy snow with thunder

47
share/translations/he.txt Normal file
View File

@ -0,0 +1,47 @@
113 : בהיר: Clear
113 : שמשי: Sunny
116 : מעונן חלקית : Partly cloudy
119 : מעונן : Cloudy
122 : מעונן : Overcast
143 : ערפל : Mist
176 : סיכוי לגשם מקומי : Patchy rain possible
179 : סיכוי לשלג מקומי : Patchy snow possible
182 : סיכוי לגשם מעורב בשלג מקומי : Patchy sleet possible
185 : סיכוי לברד מקומי : Patchy freezing drizzle possible
200 : סיכוי לסופת ברקים : Thundery outbreaks possible
227 : משבי שלג : Blowing snow
230 : סופת שלג : Blizzard
248 : ערפל : Fog
260 : קרה : Freezing fog
263 : ברד מקומי קל : Patchy light drizzle
266 : ברד קל : Light drizzle
281 : ברד : Freezing drizzle
284 : ברד כבד : Heavy freezing drizzle
293 : גשם מקומי קל : Patchy light rain
296 : גשם קל : Light rain
299 : גשם לסירוגין : Moderate rain at times
302 : גשם : Moderate rain
305 : גשם כבד לסירוגין : Heavy rain at times
308 : גשם כבד : Heavy rain
311 : גשם קופא קל : Light freezing rain
314 : גשם קופא בינוני עד כבד : Moderate or heavy freezing rain
317 : גשם מעורב בשלג קל : Light sleet
320 : גשם מעורב בשלג בינוני עד כבד : Moderate or heavy sleet
323 : שלג מקומי קל : Patchy light snow
326 : שלג קל : Light snow
329 : שלג מקומי בינוני : Patchy moderate snow
332 : שלג בינוני : Moderate snow
335 : שלג מקומי כבד : Patchy heavy snow
338 : שלג כבד : Heavy snow
350 : ברד : Ice pellets
353 : גשם קל : Light rain shower
356 : גשם בינוני עד כבד : Moderate or heavy rain shower
359 : ממטרים כבדים : Torrential rain shower
362 : גשם מעורב בשלג קל : Light sleet showers
365 : גשם מעורב בשלג בינוני עד כבד : Moderate or heavy sleet showers
368 : שלג קל : Light snow showers
371 : שלג בינוני עד כבד : Moderate or heavy snow showers
386 : גשם מקומי קל ורעמים : Patchy light rain with thunder
389 : גשם בינוני עד כבד ורעמים : Moderate or heavy rain with thunder
392 : שלג קל ורעמים : Patchy light snow with thunder
395 : שלג בינוני עד כבד ורעמים : Moderate or heavy snow with thunder

View File

@ -0,0 +1,69 @@
Használat:
$ curl wttr.in # jelenlegi tartózkodási hely
$ curl wttr.in/muc # időjárás a müncheni repülőtéren
Támogatott pozíciómeghatározások:
/paris # város
/~Eiffel+tower # bármilyen hely
/Москва # Unicode név bármilyen nyelven
/muc # repülőtér kód (3 betű)
/@stackoverflow.com # domain név
/94107 # körzetszám
/-78.46,106.79 # GPS koordináták
Speciális helyek:
/moon # holdfázis (a végére tehető ,+US vagy ,+France például)
/moon@2016-10-25 # holdfázis az adott dátumhoz (@2016-10-25)
Mértékegységek:
m # metrikus (SI) (használatban mindenhol az USA kivételével)
u # USA hagyományos (alapértelmezett az USA-ban)
M # szélsebesség m/s-ban
Megjelenítési beállítások:
0 # csak az aktuális időjárás
1 # aktuális időjárás + 1 nap
2 # aktuális időjárás + 2 nap
A # User-Agent figyelmen kívül hagyása, ANSI output kikényszerítése (terminálokban)
F # ne jeneítse meg a "Kövesd" sort
n # keskeny változat (csak nappal és éjszaka)
q # csendes verzió ("Időjárás előrejelzés" szöveg nélkül)
Q # szupercsendes verzió ("Időjárás előrejelzés" szöveg és hely nélkül)
T # terminál szekvenciák kikapcsolása (színek nélküli megjelenés)
PNG beállítások:
/paris.png # PNG kép készítése
p # keret a kép köré
t # 150-es "átlátszóság"
transparency=... # "átlátszóság" 0 és 255 között (255 = egyáltalán nem átlátszó)
A beállítások kombinálhatók:
/Paris?0pq
/Paris?0pq&lang=fr
/Paris_0pq.png # PNG módban az opciók egy aláhúzásjel után megadhatók
/Rome_0pq_lang=it.png # a hosszú opcióneveket aláhúzásjelekkel kell elválasztani
Megjelenítés különböző nyelveken:
$ curl fr.wttr.in/Paris
$ curl wttr.in/paris?lang=fr
$ curl -H "Accept-Language: fr" wttr.in/paris
Támogatott nyelvek:
FULL_TRANSLATION (teljesen támogatott)
PARTIAL_TRANSLATION (folyamatban...)
Speciális URL-ek:
/:help # segítség (ez az oldal)
/:bash.function # ajánlott bash függvény
/:translation # információ a fordítókról

47
share/translations/hu.txt Normal file
View File

@ -0,0 +1,47 @@
113: Tiszta : Clear
113: Napos : Sunny
116: Részben felhős : Partly cloudy
119: Felhős : Cloudy
122: Borult : Overcast
143: Köd : Mist
176: Szórványos zápor előfordulhat : Patchy rain possible
179: Szórványos havazás előfordulhat : Patchy snow possible
182: Szórványos havas eső előfordulhat : Patchy sleet possible
185: Szórványos ónos eső előfordulhat : Patchy freezing drizzle possible
200: Viharos széllökések előfordulhatnak : Thundery outbreaks possible
227: Hófúvás : Blowing snow
230: Hóvihar : Blizzard
248: Köd : Fog
260: Jeges köd : Freezing fog
263: Szórványosan enyhe önos eső : Patchy light drizzle
266: Gyenge önös eső : Light drizzle
281: Ónos eső : Freezing drizzle
284: Erős ónos eső : Heavy freezing drizzle
293: Szórványosan gyenge eső : Patchy light rain
296: Gyenge eső : Light rain
299: Időnként eső : Moderate rain at times
302: Eső : Moderate rain
305: Időnként intenzív eső : Heavy rain at times
308: Intenzív eső : Heavy rain
311: Enyhe jéges eső : Light freezing rain
314: Jéges eső : Moderate or heavy freezing rain
317: Enyhe havas eső : Light sleet
320: Havas eső : Moderate or heavy sleet
323: Szórványos hószállingózás : Patchy light snow
326: Hószállingózás : Light snow
329: Szórványos havazás : Patchy moderate snow
332: Havazás : Moderate snow
335: Szórványosan intenzív havazás : Patchy heavy snow
338: Intenzív havazás : Heavy snow
350: Jégeső : Ice pellets
353: Enyhe zápor : Light rain shower
356: Zápor : Moderate or heavy rain shower
359: Zuhogó eső : Torrential rain shower
362: Enyhe havas eső : Light sleet showers
365: Havas eső : Moderate or heavy sleet showers
368: Hószállingózás : Light snow showers
371: Havazás : Moderate or heavy snow showers
386: Szórványos zivatar : Patchy light rain with thunder
389: Zivatar : Moderate or heavy rain with thunder
392: Szórványos hózivatar : Patchy light snow with thunder
395: Hózivatar : Moderate or heavy snow with thunder

View File

@ -0,0 +1,67 @@
Cara penggunaan:
$ curl wttr.in # lokasi saat ini
$ curl wttr.in/muc # cuaca di bandara Munich
Dukungan tipe lokasi:
/paris # nama kota
/~Eiffel+tower # sembarang lokasi
/Москва # nama Unicode dari semabarang lokasi dalam sembarang bahasa
/muc # kode bandara (3 huruf)
/@stackoverflow.com # nama domain
/94107 # kode area
/-78.46,106.79 # koordinat GPS
Lokasi khusus:
/moon # bentuk Bulan (tambahkan ,+US atau ,+France untuk kota-kota tersebut)
/moon@2016-10-25 # bentuk Bulan untuk tanggal (@2016-10-25)
Satuan:
?m # metrik (SI) (digunakan sebagai standar di semua tempat kecuali US)
?u # USCS (digunakan sebagai standar di US)
?M # tampilkan kecepatan angin dalam m/s
Opsi tampilan:
?0 # hanya cuaca saat ini
?1 # cuaca saat ini + 1 hari
?2 # cuaca saat ini + 2 hari
?n # versi sempit (hanya siang dan malam)
?q # versi diam (tanpa teks "Laporan cuaca")
?Q # versi sangat diam (tanpa teks "Laporan cuaca", tanpa nama kota)
?T # ganti urutan terminal (tanpa warna)
Opsi PNG:
/paris.png # hasilkan suatu berkas PNG
?p # tambahkan bingkai di sekeliling hasil
?t # transparansi 150
transparency=... # transparansi dari 0 sampai 255 (255 = tidak transparan)
Opsi dapat digabung:
/Paris?0pq
/Paris?0pq&lang=fr
/Paris_0pq.png # dalam PNG mode berkas ditentukan sesudah _
/Rome_0pq_lang=it.png # opsi panjang dipisahkan dengan underscore
Lokalisasi:
$ curl fr.wttr.in/Paris
$ curl wttr.in/paris?lang=fr
$ curl -H "Accept-Language: fr" wttr.in/paris
Dukungan bahasa:
FULL_TRANSLATION (supported)
PARTIAL_TRANSLATION (in progress)
URL khusus:
/:help # tampilkan halaman ini
/:bash.function # tampilkan fungsi bash yang direkomendasikan wttr()
/:translation # tampilkan informasi tentang translator

81
share/translations/id.txt Normal file
View File

@ -0,0 +1,81 @@
113: Langit bersih : Clear
113: Cerah : Sunny
116: Sebagian berawan : Partly cloudy
119: Berawan : Cloudy
122: Mendung : Overcast
143: Berkabut : Mist
176: Mungkin hujan tidak merata : Patchy rain possible
179: Mungkin bersalju tidak merata : Patchy snow possible
182: Mungkin hujan es tidak merata : Patchy sleet possible
185: Mungkin gerimis beku tidak merata : Patchy freezing drizzle possible
200: Mungkin banyak petir : Thundery outbreaks possible
227: Hembusan salju : Blowing snow
230: Badai salju : Blizzard
248: Kabut : Fog
260: Kabut beku : Freezing fog
263: Gerimis ringan tidak merata : Patchy light drizzle
266: Gerimis ringan : Light drizzle
281: Gerimis beku : Freezing drizzle
284: Gerimis beku rapat : Heavy freezing drizzle
293: Hujan ringan tidak merata : Patchy light rain
296: Hujan ringan : Light rain
299: Hujan di beberapa waktu : Moderate rain at times
302: Hujan : Moderate rain
305: Hujan lebat di beberapa waktu : Heavy rain at times
308: Hujan lebat : Heavy rain
311: Hujan beku ringan : Light freezing rain
314: Hujan beku : Moderate or heavy freezing rain
317: Hujan es ringan : Light sleet
320: Hujan es : Moderate or heavy sleet
323: Salju ringan tidak merata : Patchy light snow
326: Salju ringan : Light snow
329: Salju tidak merata : Patchy moderate snow
332: Salju : Moderate snow
335: Salju lebat tidak merata : Patchy heavy snow
338: Salju lebat : Heavy snow
350: Bongkahan es : Ice pellets
353: Hujan ringan : Light rain shower
356: Hujan lebat : Moderate or heavy rain shower
359: Hujan sangat lebat : Torrential rain shower
362: Hujan es ringan : Light sleet showers
365: Hujan es : Moderate or heavy sleet showers
368: Hujan salju ringan : Light snow showers
371: Hujan salju : Moderate or heavy snow showers
386: Hujan ringan dengan petir tidak merata : Patchy light rain with thunder
389: Hujan dengan petir : Moderate or heavy rain with thunder
392: Salju ringan dengan petir tidak merata : Patchy light snow with thunder
395: Salju dengan petir : Moderate or heavy snow with thunder

View File

@ -43,5 +43,5 @@
371 : Dálítil eða mikil snjóél : Moderate or heavy snow showers
386 : Lítilsháttar skúrir með þrumuveðri á köflum : Patchy light rain with thunder
389 : Dálítil eða mikil rigning með þrumuveðri : Moderate or heavy rain with thunder
392 : Lítilsháttar él þrumuveðri á köflum : Patchy light snow with thunder
392 : Lítilsháttar él með þrumuveðri á köflum : Patchy light snow with thunder
395 : Dálítil eða mikill snjórkoma með þrumuveðri : Moderate or heavy snow with thunder

81
share/translations/it.txt Normal file
View File

@ -0,0 +1,81 @@
113: Sereno : Clear
113: Soleggiato : Sunny
116: Parzialmente nuvoloso : Partly cloudy
119: Nuvoloso : Cloudy
122: Coperto : Overcast
143: Nebbia : Mist
176: Possibile pioggia a zone : Patchy rain possible
179: Possibili nevicate a zone : Patchy snow possible
182: Possibile nevischio a zone : Patchy sleet possible
185: Possibile pioviggine ghiacciata : Patchy freezing drizzle possible
200: Possibili violenti temporali improvvisi : Thundery outbreaks possible
227: Neve a raffiche : Blowing snow
230: Bufera di neve : Blizzard
248: Nebbia : Fog
260: Nebbia gelata : Freezing fog
263: Pioggerellina leggera a zone : Patchy light drizzle
266: Pioggerellina leggera : Light drizzle
281: Pioggia gelata : Freezing drizzle
284: Pioviggine ghiacciata : Heavy freezing drizzle
293: Pioggia leggera a zone : Patchy light rain
296: Pioggia leggera : Light rain
299: Pioggia moderata irregolare : Moderate rain at times
302: Pioggia moderata : Moderate rain
305: Pioggia forte irregolare : Heavy rain at times
308: Pioggia forte : Heavy rain
311: Pioggia leggera ghiacciata : Light freezing rain
314: Pioggia gelata moderata o pesante : Moderate or heavy freezing rain
317: Nevischio leggero : Light sleet
320: Nevischio moderato o pesante : Moderate or heavy sleet
323: Neve leggera a zone chiare : Patchy light snow
326: Neve leggera : Light snow
329: Neve moderata a zone : Patchy moderate snow
332: Neve moderata : Moderate snow
335: Abbondante nevicata a zone : Patchy heavy snow
338: Abbondante nevicata : Heavy snow
350: Grandine : Ice pellets
353: Pioggia leggera a scrosci : Light rain shower
356: Pioggia moderata o intensa a scrosci : Moderate or heavy rain shower
359: Piogge torrenziali a scrosci : Torrential rain shower
362: Nevischio leggero a colpi : Light sleet showers
365: Rovesci di pioggia moderati o pesanti : Moderate or heavy sleet showers
368: Deboli rovesci di neve : Light snow showers
371: Rovesci di neve moderati o abbondanti : Moderate or heavy snow showers
386: Pioggia leggera con tuoni e fulmini : Patchy light rain with thunder
389: Pioggia moderata o intensa con tuoni e fulmini : Moderate or heavy rain with thunder
392: Neve leggera a zone con tuoni : Patchy light snow with thunder
395: Neve moderata o pesante con tuoni : Moderate or heavy snow with thunder

View File

@ -0,0 +1,67 @@
Использование:
$ curl wttr.in # текущее местоположение
$ curl wttr.in/svo # погода в аэропорту Шереметьево (код ICAO: SVO)
Поддерживаемые типы местоположений:
/paris # город
/~Eiffel+tower # любое местоположение
/Москва # юникодное имя любого местоположения на любом языке
/muc # код аэропорта ICAO (3 буквы)
/@stackoverflow.com # доменное имя
/94107 # почтовый индекс (только для США)
/-78.46,106.79 # GPS-координаты
Специальные условные местоположения:
/moon # Фаза Луны (добавьте ,+US или ,+France для города Moon в США/Франции)
/moon@2016-10-25 # Фаза Луны для указанной даты (@2016-10-25)
Единицы измерений:
?m # метрические (СИ) (используются везде кроме США)
?u # USCS (используются в США)
?M # показывать скорость ветра в м/с
Опции отображения:
?0 # только текущая погода
?1 # погода сегодня + 1 день
?2 # погода сегодня + 2 дня
?n # узкая версия (только день и ночь)
?q # тихая версия (без текста "Прогноз погоды")
?Q # сверхтихая версия (без "Прогноз погоды", нет названия города)
?T # отключить терминальные последовательности (без цветов)
PNG-опции:
/paris.png # сгенерировать PNG-файл
?p # добавить рамочку вокруг
?t # transparency=150 (прозрачность 150)
transparency=... # прозрачность от 0 до 255 (255 = не прозрачный)
Опции можно комбинировать:
/Paris?0pq
/Paris?0pq&lang=fr
/Paris_0pq.png # в PNG-запросах опции указываются после _
/Rome_0pq_lang=it.png # длинные опции разделяются знаком подчёркивания _
Локализация:
$ curl fr.wttr.in/Paris
$ curl wttr.in/paris?lang=fr
$ curl -H "Accept-Language: fr" wttr.in/paris
Поддерживаемые языки:
FULL_TRANSLATION (поддерживаются)
PARTIAL_TRANSLATION (в процессе)
Специальные страницы:
/:help # показать эту страницу
/:bash.function # показать рекомендованную функцию wttr()
/:translation # показать список переводчиков wttr.in

47
share/translations/kk.txt Normal file
View File

@ -0,0 +1,47 @@
113: Ашық : Clear : Ясно
113: Шуақ күн : Sunny : Солнечно
116: Көшпелі бұлт : Partly cloudy : Переменная облачность
119: Күн бұлтты : Cloudy : Облачно
122: Бұлыңғыр күн : Overcast : Пасмурно
143: Мұнар : Mist : Дымка
176: Кей жерлерде жаңбыр жауады : Patchy rain possible : Местами дождь
179: Кей жерлерде кар жауады : Patchy snow possible : Местами снег
182: Кей жерлерде қар және жауын аралас : Patchy sleet possible : Местами дождь со снегом
185: Кей жерлерде үсік сіркіреме : Patchy freezing drizzle possible : Местами замерзающая морось
200: Кей жерлерде найзағай : Thundery outbreaks possible : Местами грозы
227: Жаяу бұрқасын : Blowing snow : Поземок
230: Бұрқасын : Blizzard : Метель
248: Тұман : Fog : Туман
260: Аса суықтау тұман : Freezing fog : Переохлажденный туман
263: Кей жерлерде әлсіз аяз : Patchy light drizzle : Местами слабая морось
266: Әлсіз аяз : Light drizzle : Слабая морось
281: Қақаған аяз : Freezing drizzle : Замерзающая морось
284: Қатты қақаған аяз : Heavy freezing drizzle : Сильная замерзающая морось
293: Кей жерлерде аз ғана жаңбыр : Patchy light rain : Местами небольшой дождь
296: Аздаған жаңбыр : Light rain : Небольшой дождь
299: Орташа жауын кезеңдері : Moderate rain at times : Временами умеренный дождь
302: Орташа жауын : Moderate rain : Умеренный дождь
305: Қатты жауын кезеңдері : Heavy rain at times : Временами сильный дождь
308: Қатты жаңбыр : Heavy rain : Сильный дождь
311: Әлсіз суықтау жаңбыр : Light freezing rain : Слабый переохлажденный дождь
314: Орташа немесе қатты суықтау жаңбыр : Moderate or heavy freezing rain : Умеренный или сильный переохлажденный дождь
317: Аздаған жаңбыр аралас қар : Light sleet : Небольшой дождь со снегом
320: Орташа немесе қатты жаңбыр аралас қар : Moderate or heavy sleet : Умеренный или сильный дождь со снегом
323: Кей жерлерде аздаған қар : Patchy light snow : Местами небольшой снег
326: Аздаған қар : Light snow : Небольшой снег
329: Кей жерлерде орташа жауған қар : Patchy moderate snow : Местами умеренный снег
332: Орташа жауған қар : Moderate snow : Умеренный снег
335: Кей жерлерде қатты жауған қар : Patchy heavy snow : Местами сильный снег
338: Қатты жауған қар : Heavy snow : Сильный снег
350: Мұздай жаңбыр : Ice pellets : Ледяной дождь
353: Аздаған нөсер жауын : Light rain shower : Небольшой ливневый дождь
356: Орташа немесе қатты нөсер жауын : Moderate or heavy rain shower : Умеренный или сильный ливневый дождь
359: Өте қатты нөсер жауын : Torrential rain shower : Очень сильный ливень
362: Аздаған нөсер жауын аралас қар : Light sleet showers : Небольшой ливневый дождь со снегом
365: Аздаған қар : Moderate or heavy sleet showers : Небольшой снег
368: Аздаған нөсер жауын аралас қар : Light snow showers : Небольшой ливневый дождь со снегом
371: Орташа немесе қатты қарлы нөсер : Moderate or heavy snow showers : Умеренный или сильный снежный ливень
386: Кей жерлерде шамалы найзағайлы жауын : Patchy light rain with thunder : Местами небольшой дождь с грозой
389: Орташа немесе қатты найзағайлы нөсер : Moderate or heavy rain with thunder : Умеренный или сильный дождь с грозой
392: Кей жерлерде шамалы қар және найзағай : Patchy light snow with thunder : Местами небольшой снег с грозой
395: Орташа немесе қатты қар және найзағай : Moderate or heavy snow with thunder : Умеренный или сильный снег с грозой

View File

@ -0,0 +1,66 @@
Lietošana:
$ curl wttr.in # pašreizējā atrašanās vieta
$ curl wttr.in/rix # laikapstākļi Rīgas lidostā
Atbalstītie lokācijas tipi:
/paris # pilsētas nosaukums
/~Eiffel+tower # jebkura dabas objekts
/Москва # Unicode nosaukums jebkurā valodā
/rix # lidostas kods (3 letters)
/@stackoverflow.com # Domēna vārds
/94107 # pasta indekss (tikai ASV)
/-78.46,106.79 # GPS koordinātes
Speciālās atrašanās vietas:
/moon # Mēness fāze (pievieno ,+US vai ,+France specifiskai pilsētai)
/moon@2016-10-25 # Mēness fāze datumā (@2016-10-25)
Mērvienības:
?m # Metriskā sistēma (SI) (izmantoto kā standartu visās vietās izņemot ASV)
?u # USCS (ASV vietām izmanto kā standartu)
?M # vēja ātrums m/s
Skata iespējas:
?0 # tikai pašreizējos laikapstākļus
?1 # pašreizējos laikapstākļus + 1 dienu
?2 # pašreizējos laikapstākļus + 2 dienas
?n # īsā versija (tkai diena un nakts)
?q # apgrieztā versija (bez "Laika ziņas" teksta)
?Q # ļoti apgrieztā versija (bez "Laika ziņas" teksta, pilsētas nosaukuma)
?T # rādīt nekrāsainu
PNG iespējas:
/paris.png # izveidot PNG failu
?p # pievienot rāmi ap izvades failu
?t # caurspīdīgums 150
transparency=... # caurspīdīgums no 0 - 255 (255 = necaurspīdīgs)
Parametrus var apvienot:
/Paris?0pq
/Paris?0pq&lang=fr
/Paris_0pq.png # PNG failā iestatījumi tiek rakstīti aiz _
/Rome_0pq_lang=it.png # gari parametri tiek apvienoti ar _
Lokalizācija:
$ curl fr.wttr.in/Paris
$ curl wttr.in/paris?lang=fr
$ curl -H "Accept-Language: fr" wttr.in/paris
Atbalstītās valodas:
FULL_TRANSLATION (Atbalstīts)
PARTIAL_TRANSLATION (Tiek strādāts pie tā)
Īpašie URLs:
/:help # parāda palīgā tekstu
/:bash.function # parāda ieteicamo bash funkciju wttr()
/:translation # parāda informāciju par tukojumiem

47
share/translations/lv.txt Normal file
View File

@ -0,0 +1,47 @@
113: Skaidrs : Clear :
113: Saulains : Sunny :
116: Daļēji mākoņains : Partly cloudy :
119: Mākoņains : Cloudy :
122: Apmācies : Overcast :
143: Viegla migla : Mist :
176: Vietām iespējams lietus : Patchy rain possible :
179: Vietām iespējams sniegs : Patchy snow possible :
182: Vietām iespējams sals : Patchy sleet possible :
185: Vietām iespējams auksts lietus : Patchy freezing drizzle possible :
200: Iespējams pērkons : Thundery outbreaks possible :
227: Sniegputenis : Blowing snow :
230: Sniega vētra : Blizzard :
248: Migla : Fog :
260: Auksta migla : Freezing fog :
263: Vietām viegli smidzina : Patchy light drizzle :
266: Viegli smidzina : Light drizzle :
281: Smalks un auksts lietus : Freezing drizzle :
284: Spēcīgs auksts lietus : Heavy freezing drizzle :
293: Vietām viegls lietus : Patchy light rain :
296: Viegls lietus : Light rain :
299: Īslaicīgs lietus : Moderate rain at times :
302: Lietus : Moderate rain :
305: Īslaicīgs stiprs lietus : Heavy rain at times :
308: Stiprs : Heavy rain :
311: Viegls un auksts lietus : Light freezing rain :
314: Mērens/Stiprs un auksts lietus : Moderate or heavy freezing rain :
317: Viegls un auksts lietus : Light sleet :
320: Mērens/Stiprs un auksts lietus : Moderate or heavy sleet :
323: Vietām viegls sniegs : Patchy light snow :
326: Viegls sniegs : Light snow :
329: Vietām vidējs sniegs : Patchy moderate snow :
332: Sniegs : Moderate snow :
335: Vietām stiprs sniegs : Patchy heavy snow :
338: Stiprs sniegs : Heavy snow :
350: Krusa : Ice pellets :
353: Viegla lietus duša : Light rain shower :
356: Mērena/Stipra lietus duša : Moderate or heavy rain shower :
359: Stipra lietus duša : Torrential rain shower :
362: Viegla un auksta lietus duša : Light sleet showers :
365: Viegls sniegs : Moderate or heavy sleet showers :
368: Viegla lietus duša ar sniegu : Light snow showers :
371: Mērena/Stipra lietus duša ar sniegu : Moderate or heavy snow showers :
386: Vietām viegls lietus ar pērkona negaisu : Patchy light rain with thunder :
389: Mērens/Stiprs lietus ar pērkona negaisu : Moderate or heavy rain with thunder :
392: Vietām viegls sniegs ar pērkona negaisu : Patchy light snow with thunder :
395: Mērens/Stiprs sniegs ar pērkona negaisu : Moderate or heavy snow with thunder :

View File

@ -0,0 +1,66 @@
Bruk:
$ curl wttr.in # nåværende lokasjon
$ curl wttr.in/osl # været på Gardermoen flyplass
Støttede lokasjonsspesifiseringer:
/oslo # bynavn
/~Ullevål+stadion # valgfri lokasjon
/Москва # Unicode navn på lokasjon på alle språk
/osl # flyplasskode (3 bokstaver)
/@stackoverflow.com # domenenavn
/94107 # postnummer (bare USA)
/-78.46,106.79 # GPS-koordinater
Spesielle lokasjoner:
/moon # Månefase (legg til ,+US eller ,+France disse byene)
/moon@2016-10-25 # Månefase for spesifisert dato (@2016-10-25)
Enheter:
?m # metrisk (SI) (standard alle steder unntatt USA)
?u # USCS (standard i USA)
?M # vindstyrke i meter per sekund
Visningsvalg:
?0 # kun været nå
?1 # været nå + 1 dag
?2 # været nå + 2 dager
?n # smal visning (bare dag og natt)
?q # stille visning (ingen "Værmelding"-tekst)
?Q # superstille visning (ingen "Værmelding", ingen bynavn)
?T # ingen terminalsekvenser (ingen farger)
PNG valg:
/paris.png # generer en PNG-fil
?p # legg til ramme
?t # gjennomsiktighet 150
transparency=... # gjennomsiktighet fra 0 til 255 (255 = ikke gjennomsiktig)
Tilvalg kan kombineres:
/Paris?0pq
/Paris?0pq&lang=fr
/Paris_0pq.png # for PNG er filmodus spesifisert etter _
/Rome_0pq_lang=it.png # lange tilvalg separeres med understrek
Oversettelser:
$ curl fr.wttr.in/Paris
$ curl wttr.in/paris?lang=fr
$ curl -H "Accept-Language: fr" wttr.in/paris
Støttede språk:
FULL_TRANSLATION (støttet)
PARTIAL_TRANSLATION (under arbeid)
Spesielle URLer:
/:help # vis denne siden
/:bash.function # vis den foreslåtte bash-funksjonen wttr()
/:translation # vis informasjon om oversetterne

View File

@ -0,0 +1,60 @@
Gebruik:
$ curl wttr.in # huidige locatie
$ curl wttr.in/muc # het weer in Munic's vliegveld
Ondersteunde locatie soorten:
/paris # stadsnaam
/~Eiffel+tower # elke locatie
/Москва # Unicode naam van elke locatie in elke taal
/muc # vliegveld codes (3 letters)
/@stackoverflow.com # domeinnaam
/94107 # gebieds code
/-78.46,106.76 # GPS coördinaten
Specialen locaties:
/moon # Maanstand (voeg ,+US or ,+France voor deze plekken)
/moon@2016-10-25 # Maanstand op deze datum (@2016-10-25)
Eenheden:
?m # metriek (SI) (gebruikt als standaard overal behalve US)
?u # USCS (standaard in US)
?M # laat wind snelheid in m/s zien
Beeld opties:
?0 # alleen huidig weer
?1 # huidig weer + 1 dag
?2 # huidig weer + 2 dag
?n # smalle versie (alleen dag en nacht)
?q # stille versie (geen "Weerbericht" tekst)
?Q # superstille versie (geen " Weerbericht", geen stadsnaam)
?T # wissel terminal volgorde off (geen kleur)
PNG opties:
/paris.png # genereerd een PNG bestand
?p # voegt een frame rond de output
?t # transparantie 150
transparency=... # transparantie van 0 to 255 (255 is niet doorzichtig)
Lokalisatie:
$ curl fr.wttr.in/Paris
$ curl wttr.in/paris?lang=fr
$ curl -H "Accept-Language: fr" wttr.in/paris
Ondersteunde talen:
de fr id it nb ru (ondersteund)
ar az be bg bs ca cy cs da el eo es et fi hi hr hu hy is ja jv ka kk ko ky lt lv mk ml nl nn pt pl ro sk sl sr sr-lat sv sw th tr uk uz vi zh zu he (mee bezig)
Speciale URLs:
/:help # laat help pagina zien
/:bash.function # laat voorgestelde wttr() functie zien voor in bash
/:translation # laat the informatie van de vertalers zien

48
share/translations/nl.txt Normal file
View File

@ -0,0 +1,48 @@
113: Helder : Clear
113: Zonnig : Sunny
116: Deels bewolkt : Partly cloudy
119: Bewolkt : Cloudy
122: Bewolkt : Overcast
143: Mist : Mist
176: Mogelijk plaatselijk regen : Patchy rain possible
179: Mogelijk plaatselijk sneeuw : Patchy snow possible
182: Mogelijk plaatselijk hagel : Patchy sleet possible
185: Mogelijk plaatselijk ijzel : Patchy freezing drizzle possible
200: Mogelijk een onweersbui : Thundery outbreaks possible
227: Sneeuw winden : Blowing snow
230: Sneeuwstorm : Blizzard
248: Mist : Fog
260: Rijp : Freezing fog
263: Plaatselijk motregen : Patchy light drizzle
266: Motregen : Light drizzle
281: Ijzel : Freezing drizzle
284: Zware ijzel : Heavy freezing drizzle
293: Plaatselijk lichte regen : Patchy light rain
296: Lichte regen : Light rain
299: Af en toe regen : Moderate rain at times
302: Regen : Moderate rain
305: Af en toe zware regen : Heavy rain at times
308: Zware regen : Heavy rain
311: Lichte ijzel : Light freezing rain
314: Zware ijzel : Moderate or heavy freezing rain
317: Lichte hagel : Light sleet
320: Zware hagel : Moderate or heavy sleet
323: Plaatselijk lichte sneeuw : Patchy light snow
326: Lichte sneeuw : Light snow
329: Plaatselijke sneeuw : Patchy moderate snow
332: Sneeuw : Moderate snow
335: Plaatselijk zware sneeuw : Patchy heavy snow
338: Zware sneeuw : Heavy snow
350: Hagel : Ice pellets
353: Lichte regenbuien : Light rain shower
356: Regenbuien : Moderate or heavy rain shower
359: Extreem zware regenbuien : Torrential rain shower
362: Lichte hagelbuien : Light sleet showers
365: Hagelbuien : Moderate or heavy sleet showers
368: Lichte sneeuwbuien : Light snow showers
371: Sneeuwbuien : Moderate or heavy snow showers
386: Plaatselijk lichte regen met on: Patchy light rain with thunder weer
389: Regen met onweer : Moderate or heavy rain with thunder
392: Plaatselijk lichte sneeuw met o: Patchy light snow with thunder nweer
395: Sneeuw met onweer : Moderate or heavy snow with thunder

View File

@ -0,0 +1,66 @@
Użycie:
$ curl wttr.in # aktualna lokalizacja
$ curl wttr.in/waw # wybrana lokalizacja (WAW - Lotnisko Okęcie)
Opcje wyboru lokalizacji:
/paris # miasto
/~Eiffel+tower # miejsce
/Москва # nazwa miasta w dowolnym języku (jako Unicode string)
/waw # kod lotniska IATA (3 znaki)
/@stackoverflow.com # domena
/94107 # kod obszaru (tylko w USA)
/-78.46,106.79 # współrzędne geograficzne
Specjalne miejsca:
/moon # faza księżyca (używając n.p. ,+US lub ,+France zostanie wyświetlona faza dla podanego miejsca)
/moon@2016-10-25 # faza księżyca danego dnia (@2016-10-25)
Jednostki:
?m # system metryczny (SI) (standard poza USA)
?u # USCS (standard w USA)
?M # Prędkość wiatru w m/s
Ustawienia wyświetlania:
?0 # Pokaż jedynie aktualną pogodę
?1 # Pokaż pogodę na jutro
?2 # Pokaż pogodę na pojutrze
?n # Wersja kompaktowa (tylko noc i dzień)
?q # Wersja okrojona (bez tekstu 'Pogoda w')
?Q # Wersja bardziej okrojona (bez tekstu 'Pogoda w' i nazwy miasta)
?T # Wersja jednokolorowa
Opcje PNG:
/paris.png # generuje plik PNG
?p # dodaje obramowanie do obrazka
?t # Przezroczystość 150
transparency=... # Przezroczystość między 0 a 255 (255 = brak przezroczystości)
Opcje mogą być ze sobą łączone:
/Paris?0pq
/Paris?0pq&lang=fr
/Paris_0pq.png # jeśli generujemy obrazek PNG, to te opcje podajemy po _ (znaku podkreślenia)
/Rome_0pq_lang=it.png # _ (znakiem podkreślenia) oddzielamy opcje od siebie
Lokalizacja:
$ curl fr.wttr.in/Paris
$ curl wttr.in/paris?lang=fr
$ curl -H "Accept-Language: fr" wttr.in/paris
Obsługiwane języki:
FULL_TRANSLATION (obsługiwane)
PARTIAL_TRANSLATION (w tłumaczeniu)
Strony specjalne:
/:help # wyświetla tę stronę
/:bash.function # wyświetla proponowaną funkcję `wttr()` dla powłoki bash
/:translation # wyświetla informacje o tłumaczach

81
share/translations/pl.txt Normal file
View File

@ -0,0 +1,81 @@
113: Bezchmurnie : Clear
113: Słonecznie : Sunny
116: Lekkie zachmurzenie : Partly cloudy
119: Zachmurzenie : Cloudy
122: Całkowite zachmurzenie : Overcast
143: Zamglenie : Mist
176: Możliwe miejscowe opady deszczu : Patchy rain possible
179: Możliwe miejscowe opady śniegu : Patchy snow possible
182: Możliwe miejscowe opady deszczu ze śniegiem : Patchy sleet possible
185: Możliwe miejscowe opady marznącego deszczu : Patchy freezing drizzle possible
200: Możliwa burza : Thundery outbreaks possible
227: Zawieja śnieżna : Blowing snow
230: Śnieżyca : Blizzard
248: Mgła : Fog
260: Marznąca mgła : Freezing fog
263: Przelotna mżawka : Patchy light drizzle
266: Mżawka : Light drizzle
281: Marznąca mżawka : Freezing drizzle
284: Marznąca mżawka : Heavy freezing drizzle
293: Przelotne lekkie opady deszczu : Patchy light rain
296: Lekkie opady deszczu : Light rain
299: Przelotne umiarkowane opady deszczu : Moderate rain at times
302: Umiarkowane opady deszczu : Moderate rain
305: Przelotne silne opady deszczu : Heavy rain at times
308: Silne opady deszczu : Heavy rain
311: Lekki marznący deszcz : Light freezing rain
314: Umiarkowany lub silny marznący deszcz : Moderate or heavy freezing rain
317: Lekki deszcz ze śniegiem : Light sleet
320: Umiarkowany lub silny deszcz ze śniegiem : Moderate or heavy sleet
323: Miejscowe lekkie opady śniegu : Patchy light snow
326: Lekkie opady śniegu : Light snow
329: Miejscowe umiarkowane opady śniegu : Patchy moderate snow
332: Umiarkowane opady śniegu : Moderate snow
335: Miejscowe silne opady śniegu : Patchy heavy snow
338: Silne opady śniegu : Heavy snow
350: Gradobicie : Ice pellets
353: Lekkie opady deszczu : Light rain shower
356: Umiarkowane lub silne opady deszczu : Moderate or heavy rain shower
359: Oberwanie chmury : Torrential rain shower
362: Lekki deszcz ze śniegiem : Light sleet showers
365: Umiarkowany lub silny deszcz ze śniegiem : Moderate or heavy sleet showers
368: Lekkie opady śniegu : Light snow showers
371: Umiarkowane lub silne opady śniegu : Moderate or heavy snow showers
386: Miejscowe lekkie opady deszczu i burza z piorunami : Patchy light rain with thunder
389: Umiarkowane lub silne opady deszczu i burza z piorunami : Moderate or heavy rain with thunder
392: Miejscowe lekkie opady śniegu i burza z piorunami : Patchy light snow with thunder
395: Umiarkowane lub silne opady śniegu i burza z piorunami : Moderate or heavy snow with thunder

View File

@ -0,0 +1,67 @@
Instruções:
$ curl wttr.in # o tempo na sua localização atual
$ curl wttr.in/muc # o tempo no aeroporto de Munique
Tipos de localização suportados:
/paris # o nome de uma cidade
/~Eiffel+tower # o nome de qualquer lugar famoso
/Москва # nome Unicode de qualquer lugar em qualquer idioma
/muc # o código de um aeroporto (3 letras)
/@stackoverflow.com # o nome de um domínio web
/94107 # um código de área
/-78.46,106.79 # coordenadas do GPS
Lugares especiais:
/moon # A fase da lua (crescente ,+US ou ,+France para estas cidades)
/moon@2016-10-25 # A fase da lua em uma determinada data (@2016-10-25)
Unidades:
?m # métricas (SI) (o padrão em todos os lugares exceto nos EUA)
?u # Sistema Unificado de Clasificaçāo de Solo ou USCS (o padrão nos EUA)
?M # mostrar a velocidade do vento em m/s
Opçōes de visualização:
?0 # somente o clima atual
?1 # o clima atual + a previsão de 1 dia
?2 # o clima atual + a previsão de 2 dias
?n # versão curta (só o dia e a noite)
?q # versão quieta (sem o texto de "Previsão do Tempo")
?Q # versão superquieta (sem "Previsão do Tempo" e o nome da cidade)
?T # desliga as sequências de terminal (sem cores)
Opçōes de PNG:
/paris.png # gera uma imagem PNG
?p # acrescenta uma borda ao redor da imagem
?t # transparência 150
transparency=... # transparência de 0 a 255 (255 = sem transparência)
As opções podem ser usadas em conjunto:
/Paris?0pq
/Paris?0pq&lang=fr
/Paris_0pq.png # em PNG as opções se especificam depois do caracter _
/Rome_0pq_lang=it.png # uma longa sequência de opções podem ser separadas pelo caracter _
Localizaçāo:
$ curl fr.wttr.in/Paris
$ curl wttr.in/paris?lang=fr
$ curl -H "Accept-Language: fr" wttr.in/paris
Línguas suportadas:
FULL_TRANSLATION (suportadas)
PARTIAL_TRANSLATION (em andamento)
URLs especiais:
/:help # mostra esta página
/:bash.function # sugere uma função wttr() em bash
/:translation # mostra informação a respeito dos tradutores

View File

@ -0,0 +1,81 @@
113: Limpo : Clear
113: Ensolarado : Sunny
116: Parcialmente encoberto : Partly cloudy
119: Encoberto : Cloudy
122: Nublado : Overcast
143: Névoa : Mist
176: Possibilidade chuva fraca : Patchy rain possible
179: Possibilidade neve fraca : Patchy snow possible
182: Possibilidade granizo : Patchy sleet possible
185: Possibilidade chuvisco gelado : Patchy freezing drizzle possible
200: Possibilidade de pancadas de chuva : Thundery outbreaks possible
227: Neve com vento : Blowing snow
230: Nevasca : Blizzard
248: Nevoeiro : Fog
260: Névoa congelante : Freezing fog
263: Chuvisco irregualr : Patchy light drizzle
266: Chuvisco : Light drizzle
281: Chuvisco gelado : Freezing drizzle
284: Chuvisco muito gelado : Heavy freezing drizzle
293: Garoa irregular : Patchy light rain
296: Garoa : Light rain
299: Chuva moderada ocasional : Moderate rain at times
302: Chuva moderada : Moderate rain
305: Chuva forte ocasional : Heavy rain at times
308: Chuva forte : Heavy rain
311: Garoa gelada : Light freezing rain
314: Chuva forte ou moderada gelada : Moderate or heavy freezing rain
317: Granizo fraco : Light sleet
320: Granizo moderado ou forte : Moderate or heavy sleet
323: Neve fraca irregular : Patchy light snow
326: Neve fraca : Light snow
329: Neve moderada irregular : Patchy moderate snow
332: Neve moderada : Moderate snow
335: Neve forte irregular : Patchy heavy snow
338: Neve forte : Heavy snow
350: Pelotas de gelo : Ice pellets
353: Chuveiro de garoa : Light rain shower
356: Chuveiro de chuva moderada ou forte : Moderate or heavy rain shower
359: Chuveiro de chuva torrencial : Torrential rain shower
362: Chuveiro de granizo fraco : Light sleet showers
365: Chuveiro de granizo moderada ou forte : Moderate or heavy sleet showers
368: Chuveiro de neve fraca : Light snow showers
371: Chuveiro de neve moderada ou forte : Moderate or heavy snow showers
386: Tempestate com garoa irregular : Patchy light rain with thunder
389: Tempestade com chuva moderada ou forte : Moderate or heavy rain with thunder
392: Tempestade com neve fraca : Patchy light snow with thunder
395: Tempestade com neve moderada ou forte : Moderate or heavy snow with thunder

View File

@ -0,0 +1,67 @@
Instruções:
$ curl wttr.in # o clima na sua localização atual
$ curl wttr.in/muc # o clima no aeroporto de Munique
Tipos de localização suportados:
/paris # o nome de uma cidade
/~Eiffel+tower # o nome de qualquer lugar famoso
/Москва # nome Unicode de qualquer lugar em qualquer idioma
/muc # o código de um aeroporto (3 letras)
/@stackoverflow.com # o nome de um domínio web
/94107 # um código de área
/-78.46,106.79 # coordenadas do GPS
Lugares especiais:
/moon # A fase da lua (acrescente ,+US ou ,+France para estas cidades)
/moon@2016-10-25 # A fase da lua em uma data determinada (@2016-10-25)
Unidades:
?m # métricas (SI) (o padrão em todos os lugares exceto nos EUA)
?u # Sistema Unificado de Clasificaçāo de Solo ou USCS (o padrão nos EUA)
?M # mostrar a velocidade do vento em m/s
Opçōes de visualização:
?0 # somente o clima atual
?1 # o clima atual + a previsão de 1 dia
?2 # o clima atual + a previsão de 2 dias
?n # versão curta (só o dia e a noite)
?q # versão quieta (sem o texto de "Previsão do Tempo")
?Q # versão superquieta (sem "Previsão do Tempo" e o nome da cidade)
?T # desliga as sequências de terminal (sem cores)
Opçōes de PNG:
/paris.png # gera uma imagem PNG
?p # acrescenta uma borda ao redor da imagem
?t # transparência 150
transparency=... # transparência de 0 a 255 (255 = sem transparência)
As opções podem ser usadas em conjunto:
/Paris?0pq
/Paris?0pq&lang=fr
/Paris_0pq.png # em PNG as opções se especificam depois do caracter _
/Rome_0pq_lang=it.png # uma longa sequência de opções podem ser separadas pelo caracter _
Localizaçāo:
$ curl fr.wttr.in/Paris
$ curl wttr.in/paris?lang=fr
$ curl -H "Accept-Language: fr" wttr.in/paris
Línguas suportadas:
FULL_TRANSLATION (suportadas)
PARTIAL_TRANSLATION (em andamento)
URLs especiais:
/:help # mostra esta página
/:bash.function # sugere uma função wttr() em bash
/:translation # mostra informação a respeito dos tradutores

View File

@ -0,0 +1,67 @@
Utilizare:
$ curl wttr.in # localizare curentă
$ curl wttr.in/otp # Aeroportul Internațional Henri Coandă (OTP)
Tipuri de localizări acceptate:
/Cluj # numele localității
/~coloana+infinitului # locuri binecunoscute sau puncte de interes
/Москва # nume Unicode în orice limbă
/otp # cod aeroport (3 litere)
/@stackoverflow.com # nume de domeniu
/94107 # cod poștal (doar pentru Statele Unite)
/-78.46,106.79 # coordonate GPS
Localizări speciale:
/moon # faza lunii (adăugați ,+US sau ,+France pentru a arăta orașele cu acest nume)
/moon@2016-10-25 # faza lunii într-o anumită dată (@2016-10-25)
Unități de măsură:
?m # sistem metric (implicit, mai puțin pentru Statele Unite ale Americii)
?u # USCS (implicit pentru Statele Unite ale Americii)
?M # afișează viteza vântului în m/s
Opțiuni de afișare:
?0 # azi
?1 # azi și mâine
?2 # azi, mâine și poimâine
?n # doar ziua și noaptea
?q # fără antet "Prognoza meteo pentru"
?Q # fără antet "Prognoza meteo pentru", fără numele localității
?T # fără coduri speciale în terminal (fără culori)
Opțiuni PNG:
/Băicoi.png # generează un fișier PNG
?p # cu chenar
?t # cu transparență 150
transparency=... # cu transparență în intervalul [0-255] (255 = fără transparență)
Combinarea opțiunilor:
/Lehliu-Gară?0q
/Vaslui?0q&lang=ro
/Videle_0pq.png # în modul PNG opțiunile se specifică după _
/Roma_0pq_lang=it.png # opțiunile cu nume lung se separă prin _
Limba de afișare:
$ curl ro.wttr.in/Tărtășești
$ curl wttr.in/Paris?lang=fr
$ curl -H "Accept-Language: de" wttr.in/berlin
Limbi suportate:
FULL_TRANSLATION (Suport complet)
PARTIAL_TRANSLATION (Suport incomplet)
URL-uri speciale:
/:help # afișează această pagină
/:bash.function # funcție bash wttr()
/:translation # afișează informații despre traducerile din wttr.in

82
share/translations/ro.txt Normal file
View File

@ -0,0 +1,82 @@
113: Senin : Clear
113: Însorit : Sunny
116: Parțial înnorat : Partly cloudy
119: Înnorat : Cloudy
122: Cer acoperit : Overcast
143: Ceață : Mist
176: Posibilă ploaie pe alocuri : Patchy rain possible
179: Posibilă ninsoare pe alocuri : Patchy snow possible
182: Posibilă lapoviță pe alocuri : Patchy sleet possible
185: Posibilă burniță înghețată pe alocuri : Patchy freezing drizzle possible
200: Posibile tunete : Thundery outbreaks possible
227: Zăpadă în rafale : Blowing snow
230: Viscol : Blizzard
248: Ceață : Fog
260: Ceață înghețată : Freezing fog
263: Burniță ușoară pe alocuri : Patchy light drizzle
266: Burniță ușoară : Light drizzle
281: Burniță înghețată : Freezing drizzle
284: Burnită înghețată abundentă : Heavy freezing drizzle
293: Ploaie ușoară pe alocuri : Patchy light rain
296: Ploaie ușoară : Light rain
299: Momente de ploaie moderată : Moderate rain at times
302: Ploaie moderată : Moderate rain
305: Momente de ploaie torențială : Heavy rain at times
308: Ploaie torențială : Heavy rain
311: Ploaie înghețată ușoară : Light freezing rain
314: Ploaie înghețată moderată sau torențială : Moderate or heavy freezing rain
317: Lapoviță ușoară : Light sleet
320: Lapoviță moderată sau torențială : Moderate or heavy sleet
323: Ninsoare ușoară pe alocuri : Patchy light snow
326: Ninsoare ușoară : Light snow
329: Ninsoare moderată pe alocuri : Patchy moderate snow
332: Ninsoare moderată : Moderate snow
335: Ninsoare abundentă pe alocuri : Patchy heavy snow
338: Ninsoare abundentă : Heavy snow
350: Grindină : Ice pellets
353: Averse de ploaie ușoară : Light rain shower
356: Averse de ploaie moderată sau torențială : Moderate or heavy rain shower
359: Averse de ploaie torențială : Torrential rain shower
362: Averse de lapoviță ușoară : Light sleet showers
365: Averse de lapoviță moderată sau torențială : Moderate or heavy sleet showers
368: Averse de ninsoare ușoară : Light snow showers
371: Averse de ninsoare moderată sau torențială : Moderate or heavy snow showers
386: Ploi ușoare cu tunete pe alocuri : Patchy light rain with thunder
389: Ploaie moderată sau furtună cu tunete : Moderate or heavy rain with thunder
392: Ninsoare ușoară cu tunete pe alocuri : Patchy light snow with thunder
395: Ninsoare moderată sau abundentă cu tunete : Moderate or heavy snow with thunder

View File

@ -1,81 +1,47 @@
113: : Clear : Ясно
113: : Sunny : Солнечно
116: : Partly cloudy : Переменная облачность
119: : Cloudy : Облачно
122: : Overcast : Пасмурно
143: : Mist : Дымка
176: : Patchy rain possible : Местами дождь
179: : Patchy snow possible : Местами снег
182: : Patchy sleet possible : Местами дождь со снегом
185: : Patchy freezing drizzle possible : Местами замерзающая морось
200: : Thundery outbreaks possible : Местами грозы
227: : Blowing snow : Поземок
230: : Blizzard : Метель
248: : Fog : Туман
260: : Freezing fog : Переохлажденный туман
263: : Patchy light drizzle : Местами слабая морось
266: : Light drizzle : Слабая морось
281: : Freezing drizzle : Замерзающая морось
284: : Heavy freezing drizzle : Сильная замерзающая морось
293: : Patchy light rain : Местами небольшой дождь
296: : Light rain : Небольшой дождь
299: : Moderate rain at times : Временами умеренный дождь
302: : Moderate rain : Умеренный дождь
305: : Heavy rain at times : Временами сильный дождь
308: : Heavy rain : Сильный дождь
311: : Light freezing rain : Слабый переохлажденный дождь
314: : Moderate or heavy freezing rain : Умеренный или сильный переохлажденный дождь
317: : Light sleet : Небольшой дождь со снегом
320: : Moderate or heavy sleet : Умеренный или сильный дождь со снегом
323: : Patchy light snow : Местами небольшой снег
326: : Light snow : Небольшой снег
329: : Patchy moderate snow : Местами умеренный снег
332: : Moderate snow : Умеренный снег
335: : Patchy heavy snow : Местами сильный снег
338: : Heavy snow : Сильный снег
350: : Ice pellets : Ледяной дождь
353: : Light rain shower : Небольшой ливневый дождь
356: : Moderate or heavy rain shower : Умеренный или сильный ливневый дождь
359: : Torrential rain shower : Очень сильный ливень
362: : Light sleet showers : Небольшой ливневый дождь со снегом
365: : Moderate or heavy sleet showers : Небольшой снег
368: : Light snow showers : Небольшой ливневый дождь со снегом
371: : Moderate or heavy snow showers : Умеренный или сильный снежный ливень
386: : Patchy light rain with thunder : Местами небольшой дождь с грозой
389: : Moderate or heavy rain with thunder : Умеренный или сильный дождь с грозой
392: : Patchy light snow with thunder : Местами небольшой снег с грозой
395: : Moderate or heavy snow with thunder : Умеренный или сильный снег с грозой
113: Ясно : Clear :
113: Солнечно : Sunny :
116: Переменная облачность : Partly cloudy :
119: Облачно : Cloudy :
122: Пасмурно : Overcast :
143: Дымка : Mist :
176: Местами дождь : Patchy rain possible :
179: Местами снег : Patchy snow possible :
182: Местами дождь со снегом : Patchy sleet possible :
185: Местами замерзающая морось : Patchy freezing drizzle possible :
200: Местами грозы : Thundery outbreaks possible :
227: Поземок : Blowing snow :
230: Метель : Blizzard :
248: Туман : Fog :
260: Переохлажденный туман : Freezing fog :
263: Местами слабая морось : Patchy light drizzle :
266: Слабая морось : Light drizzle :
281: Замерзающая морось : Freezing drizzle :
284: Сильная замерзающая морось : Heavy freezing drizzle :
293: Местами небольшой дождь : Patchy light rain :
296: Небольшой дождь : Light rain :
299: Временами умеренный дождь : Moderate rain at times :
302: Умеренный дождь : Moderate rain :
305: Временами сильный дождь : Heavy rain at times :
308: Сильный дождь : Heavy rain :
311: Слабый переохлажденный дождь : Light freezing rain :
314: Умеренный или сильный переохлажденный дождь : Moderate or heavy freezing rain :
317: Небольшой дождь со снегом : Light sleet :
320: Умеренный или сильный дождь со снегом : Moderate or heavy sleet :
323: Местами небольшой снег : Patchy light snow :
326: Небольшой снег : Light snow :
329: Местами умеренный снег : Patchy moderate snow :
332: Умеренный снег : Moderate snow :
335: Местами сильный снег : Patchy heavy snow :
338: Сильный снег : Heavy snow :
350: Ледяной дождь : Ice pellets :
353: Небольшой ливневый дождь : Light rain shower :
356: Умеренный или сильный ливневый дождь : Moderate or heavy rain shower :
359: Очень сильный ливень : Torrential rain shower :
362: Небольшой ливневый дождь со снегом : Light sleet showers :
365: Небольшой снег : Moderate or heavy sleet showers :
368: Небольшой ливневый дождь со снегом : Light snow showers :
371: Умеренный или сильный снежный ливень : Moderate or heavy snow showers :
386: Местами небольшой дождь с грозой : Patchy light rain with thunder :
389: Умеренный или сильный дождь с грозой : Moderate or heavy rain with thunder :
392: Местами небольшой снег с грозой : Patchy light snow with thunder :
395: Умеренный или сильный снег с грозой : Moderate or heavy snow with thunder :

61
share/translations/te.txt Normal file
View File

@ -0,0 +1,61 @@
113: : స్పష్టం
113: : ఎండ
116: : కొంత మేఘావృతం
119: : మేఘావృతం
122: : దట్టమైన మబ్బులు
143: : పొగమంచు
176: : మందమైన వర్షం సాధ్యమవుతుంది
179: : పదునైన మంచు సాధ్యం
182: : సాధ్యమయ్యే పదునైన దుప్పటి
185: : పదునైన ఘనీభవన చినుకులు సాధ్యం
200: : Thundery వ్యాప్తి సాధ్యం
227: : మంచు వెదజల్లు
230: : మంచు తుఫాను
248: : పొగమంచు
260: : చల్లటి పొగమంచు
263: : పదునైన తేలికపాటి చిల్లు
266: : కాంతి చినుకులు
281: : ఘనీభవన చినుకులు
284: : భారీ గడ్డకట్టే చినుకులు
293: : తేలికపాటి వర్షం
296: : తేలికపాటి వర్షం
299: : సమయాల్లో మితమైన వర్షం
302: : ఆధునిక వర్షం
305: : సమయాల్లో భారీ వర్షం
308: : భారీవర్షం
311: : కాంతి ఘనీభవన వర్షం
314: : ఆధునిక లేదా భారీ ఘనీభవన వర్షం
317: : కాంతి స్లేట్
320: : ఆధునిక లేదా భారీ స్లీప్
323: : పదునైన తేలికపాటి మంచు
326: : తేలికపాటి మంచు
329: : మందమైన మోస్తరు మంచు
332: : ఆధునిక మంచు
335: : మందమైన భారీ మంచు
338: : భారీ మంచు
350: : మంచు ముక్కలు
353: : తేలికపాటి వర్షం షవర్
356: : ఆధునిక లేదా భారీ వర్షం షవర్
359: : కుండపోత వర్షం షవర్
362: : లైట్ స్లేట్ వర్షం
365: : మోడరేట్ లేదా భారీ షీట్ వర్షం
368: : తేలికపాటి మంచు వర్షం
371: : మితమైన లేదా భారీ మంచు వర్షం
386: : ఉరుములతో కూడిన తేలికపాటి వర్షం
389: : ఉరుములతో మితమైన లేదా భారీ వర్షం
392: : ఉరుములతో మందమైన తేలికపాటి మంచు
395: : ఉరుములతో మోస్తరు లేదా భారీ మంచు

View File

@ -0,0 +1,66 @@
Usage:
$ curl wttr.in # bulunduğunuz konum
$ curl wttr.in/muc # Münih havalimanında hava durumu
Desteklenen konum tipleri:
/istanbul # şehir adı
/~Eiffel+tower # herhangi bir konum
/Москва # Herhangi bir dilde herhangi bir unicode konum
/muc # havalimanı kodu (3 harfli)
/@stackoverflow.com # alan adı
/94107 # posta kodları
/-78.46,106.79 # GPS koordinatları
Özel konumlar:
/moon # Ay evresi (Şehir veya ülke için +TR veya +İstanbul ekleyin)
/moon@2016-10-25 # Belli bir tarih için ay evresi (@2016-10-25)
Ölçü birimleri:
?m # metrik sistem (SI) (ABD dışında her yer için varsayılan)
?u # USCS (ABD için varsayılan)
?M # Rüzgar hızını metre/saniye olarak göster
View options:
?0 # sadece bugün için hava durumu
?1 # Bugün ve + 1 gün sonrası için hava durumu
?2 # Bugün ve + 2 gün sonrası için hava durumu
?n # dar görünüm (sadece gece ve gündüz)
?q # sessiz görünüm ("Hava durumu" yazısı yok)
?Q # aşırı sessiz görünüm ("Hava durumu" yazısı ve şehir adı yok)
?T # teriminal geçişlerini kapatır (renkler yok)
PNG seçenekleri:
/istanbul.png # bir PNG resmi üretir
?p # resmin etrafına bir çerçeve ekler
?t # 150 birim saydamlık
transparency=... # 0 ila 255 arasında saydamlık (255 = saydam değil)
Seçenekler birleştirilebilir:
/Istanbul?0pq
/Istanbul?0pq&lang=fr
/Istanbul_0pq.png # PNG dosya modları _ karakterinden sonra belirtilir
/izmir_0pq_lang=it.png # uzun seçenekler alt çizgi ile ayrılır
Yerelleştirme:
$ curl fr.wttr.in/Istanbul
$ curl wttr.in/izmir?lang=tr
$ curl -H "Accept-Language: tr" wttr.in/izmir
Desteklenen diller:
FULL_TRANSLATION (destekleniyor)
PARTIAL_TRANSLATION (geliştirme aşamasında)
Özel adresler:
/:help # bu sayfayı göster
/:bash.function # önerilen bash fonksiyonu wttr() içeriğini göster
/:translation # çevirmenler hakkındaki bilgileri göster

47
share/translations/tr.txt Normal file
View File

@ -0,0 +1,47 @@
113: Açık : Clear
113: Günşeli : Sunny
116: Parçalı bulutlu : Partly cloudy
119: Bulutlu : Cloudy
122: Kapalı : Overcast
143: Puslu : Mist
176: Yer yer yağmur görülebilir : Patchy rain possible
179: Yer yer kar görülebilir : Patchy snow possible
182: Yer yer karla karışık yağmur görülebilir : Patchy sleet possible
185: Yer yer donan çisenti olabilir : Patchy freezing drizzle possible
200: Gök gürültülü fırtına görülebilir : Thundery outbreaks possible
227: Tipi halinde kar yağışı : Blowing snow
230: Kar fırtınası : Blizzard
248: Sisli : Fog
260: Donan sis : Freezing fog
263: Yer yer hafif donan çisenti : Patchy light drizzle
266: Yer yer donan çisenti : Light drizzle
281: Donan çisenti : Freezing drizzle
284: Kuvvetli don : Heavy freezing drizzle
293: Yer yer hafif yağmurlu : Patchy light rain
296: Hafif yağmurlu : Light rain
299: Zaman zaman orta kuvvette yağmur : Moderate rain at times
302: Orta kuvvette yağmur : Moderate rain
305: Zaman zaman şiddetli yağmur : Heavy rain at times
308: Şiddetli yağmur : Heavy rain
311: Ayaz ile hafif yağmur : Light freezing rain
314: Ayaz ile orta kuvvette veya şiddetli yağmur : Moderate or heavy freezing rain
317: Hafif karla karışık yağmur : Light sleet
320: Orta kuvvette veya şiddeli sulu kar : Moderate or heavy sleet
323: Yer yer hafif kar yağışı : Patchy light snow
326: Hafif kar yağışı : Light snow
329: Yer yer orta şiddette kar yağışı : Patchy moderate snow
332: Orta kuvvette kar yağışı : Moderate snow
335: Yer yer kuvvetli kar yağışı : Patchy heavy snow
338: Kuvvetli kar yağışı : Heavy snow
350: Dolu yağışı : Ice pellets
353: Hafif sağnak yağmur : Light rain shower
356: Orta kuvvette veya şiddetli sağnak yağmur : Moderate or heavy rain shower
359: Sel riski olan şiddetli sağnak yağmur : Torrential rain shower
362: Hafif karla karışık sağnak yağmur : Light sleet showers
365: Orta veya şiddetli karla karışık sağnak yağmur : Moderate or heavy sleet showers
368: Hafif sağnak kar yağışı : Light snow showers
371: Orta kuvvette veya şiddetli sağnak kar yağışı : Moderate or heavy snow showers
386: Yer yer gök gürültülü ve yağmurlu : Patchy light rain with thunder
389: Orta kuvvette veya şiddetli gök gürültülü yağmur : Moderate or heavy rain with thunder
392: Yer yer gök gürültülü ve karlı : Patchy light snow with thunder
395: Orta kuvvette veya şiddetli gök gürültülü kar : Moderate or heavy snow with thunder

View File

@ -0,0 +1,67 @@
Використання:
$ curl wttr.in # поточне місцеположення
$ curl wttr.in/kbp # погода в аеропорту Бориспіль (код ICAO: KBP)
Підтримуються наступні типи місцеположень:
/paris # місто
/~Eiffel+tower # будь-яке місцеположення
/Киів # юнікодне ім'я будь-якого місцеположення будь-якою мовою
/muc # код аеропорту ICAO (3 літери)
/@stackoverflow.com # доменне им'я
/94107 # поштовый індекс (тільки для США)
/-78.46,106.79 # GPS-координати
Спеціальні умовні місцеположення:
/moon # Фаза Місяця (додайте ,+US або ,+France для міста Moon у США або Франції)
/moon@2016-10-25 # Фаза Місяця для вказаної дати (@2016-10-25)
Одиниці вимірювань:
?m # метричні (СІ) (використовуються всюди крім США)
?u # USCS (використовуються у США)
?M # показувати швидкість вітру в м/с
Опції відображення:
?0 # тільки поточна погода
?1 # погода сьогодні + 1 день
?2 # погода сьогодні + 2 дня
?n # вузька версія (тільки день та ніч)
?q # тиха версія (без тексту "Прогноз погоди")
?Q # надтиха версія (без "Прогноз погоди", немає назви міста)
?T # відключити послідовності терміналу (без кольорів)
PNG-опції:
/paris.png # сгенерувати PNG-файл
?p # добавити рамку навколо
?t # transparency=150 (прозорість 150)
transparency=... # прозорість від 0 до 255 (255 = не прозорий)
Опції можна комбінувати:
/Paris?0pq
/Paris?0pq&lang=fr
/Paris_0pq.png # в PNG-запитах опції вказуються після знаку _
/Rome_0pq_lang=it.png # довгі опції розділяются знаком підкреслення _
Локалізація:
$ curl fr.wttr.in/Paris
$ curl wttr.in/paris?lang=fr
$ curl -H "Accept-Language: fr" wttr.in/paris
Мови що підтримуються:
FULL_TRANSLATION (підтримується)
PARTIAL_TRANSLATION (в процесі)
Спеціальні строрінки:
/:help # показати цю сторінку
/:bash.function # показати рекомендовану функцію wttr()
/:translation # показати список перекладачів wttr.in

47
share/translations/uk.txt Normal file
View File

@ -0,0 +1,47 @@
113: Ясно : Clear :
113: Сонячно : Sunny :
116: Змінна хмарність : Partly cloudy :
119: Хмарно : Cloudy :
122: Похмуро : Overcast :
143: Невеликий туман : Mist :
176: Місцями дощ : Patchy rain possible :
179: Місцями сніг : Patchy snow possible :
182: Місцями дощ зі снігом : Patchy sleet possible :
185: Місцями ожеледь : Patchy freezing drizzle possible :
200: Місцями грози : Thundery outbreaks possible :
227: Заметіль : Blowing snow :
230: Снігова буря : Blizzard :
248: Туман : Fog :
260: Крижаний туман : Freezing fog :
263: Місцями мряка : Patchy light drizzle :
266: Мряка : Light drizzle :
281: Ожеледь : Freezing drizzle :
284: Сильна ожеледь : Heavy freezing drizzle :
293: Місцями невеликий дощ : Patchy light rain :
296: Невеликий дощ : Light rain :
299: Часом помірний дощ : Moderate rain at times :
302: Помірний дощ : Moderate rain :
305: Часом сильний дощ : Heavy rain at times :
308: Сильний дощ : Heavy rain :
311: Слабкий крижаний дощ : Light freezing rain :
314: Крижаний дощ : Moderate or heavy freezing rain :
317: Невеликий дощ зі снігом : Light sleet :
320: Дощ зі снігом : Moderate or heavy sleet :
323: Місцями невеликий сніг : Patchy light snow :
326: Невеликий сніг : Light snow :
329: Місцями помірний сніг : Patchy moderate snow :
332: Помірний сніг : Moderate snow :
335: Місцями сильний сніг : Patchy heavy snow :
338: Сильний сніг : Heavy snow :
350: Льодяний дощ : Ice pellets :
353: Невелика злива : Light rain shower :
356: Злива : Moderate or heavy rain shower :
359: Дуже сильна злива : Torrential rain shower :
362: Невеликий мокрий сніг : Light sleet showers :
365: Мокрий сніг : Moderate or heavy sleet showers :
368: Невеликий сніг : Light snow showers :
371: Сніг : Moderate or heavy snow showers :
386: Місцями дощ з грозою : Patchy light rain with thunder :
389: Дощ з грозою : Moderate or heavy rain with thunder :
392: Місцями сніг з грозою : Patchy light snow with thunder :
395: Сніг з грозою : Moderate or heavy snow with thunder :