You are not logged in.
YAWS last update: 2014-10-21 (v1.6.2)
I built the following script to use with my Conky setup. This script, which I called YAWS (Yet Another Weather Script), uses the REST style API of the Norwegian Meteorological institute to get weather forecasts for practically any location on this planet.
YAWS was built with/for Python 2.7. The previous posted version is/was bugged and needed an upgrade. I saw a couple of posts on the New Monster Conky thread about another weather script, conkyForecast, which stopped working. Instead of fixing conkyForecast, I decided to update my own script, using the syntax and parameters of conkyForecast. Five days later, I can now post a working, almost complete, script.
Version 1.6.2
Version 1.6.2 fixes a couple of bugs, caused by some poorly written code and the Norwegian Meteorological Institute updating their API.
Version 1.6
Version 1.6 adds proxy support, cached files, timezones and a configuration file. Instead of specifying the location in the parameters, it is now set inside the configuration file. The file is by default located at $HOME/.config/YAWS/YAWS.cfg, but can be changed with the -C or --config parameter. There is a sample configuration included with the script.
More information about the configuration can be found near the bottom of this post.
Download link (1.6.2): http://hubsec.eu/files/yaws-1.6.2.tar.gz
Download link (1.6.1): http://hubsec.eu/files/yaws-1.6.1.tar.gz
Download link (1.5.3): http://hubsec.eu/files/yaws-1.5.3.tar.gz
Requirements:
- Python 2.7
- Requests (apt-get install python-requests)
(Note: the version delivered by aptitude, might give problems. Use the 2.2.1 or later requests version when this occurs)
Installation instructions for Requests, if the Aptitude version gives errors:
Download version 2.2.1 or later. Untar it and execute in the created directory the command
python setup.py install
as root (for example by using sudo).
Usage:
usage: yaws.py [-h] [-C FILE] [-t FILE] [-L LOCALE] [-d DATATYPE] [-s NUMBER]
[-e NUMBER] [-i] [-b] [-M] [-n] [-r] [-x] [-u] [-w] [--version]
YAWS: Yet Another Weather Script
optional arguments:
-h, --help show this help message and exit
-C FILE, --config FILE
[default: $HOME/.config/YAWS/YAWS.cfg] The
path to the configuration file, allowing multiple
config files to be used.
-t FILE, --template FILE
define a template file to generate output in one call.
A displayable item in the file is in the form
[--datatype=HT --startday=1]. The following are
possible options within each item: --datatype,
--startday, --endday, --imperial, --beaufort,
--metrespersecond, --shortweekday, --hideunits,
--hidedegreesymbol, --night. Note that the short forms
of the options are not supported! If any of these
options is set from the commandline, it sets the
default value of the option for all template items.
-L LOCALE, --locale LOCALE
override the system locale for language output
(en=english, nl=dutch, fr=french, more to come)
-d DATATYPE, --datatype DATATYPE
[default: HT] The data type options are: DW (Day of
Week), WI (Weather Icon Path), LT (Low Temp), HT (High
Temp), CC (Current Conditions), CT (Conditions Text),
HM (Humidity), WD (Wind Direction), WA (Wind Angle -
in degrees), WS (Wind Speed), CN (City Name), CO
(Country), SR (SunRise), SS (SunSet), DL (DayLight),
MP (Moon Phase), BR (Barometer Reading), BD (Barometer
Description), DP (Dew Point), WM (weather map fetch
and image path returned), LU (Last Update), LF (Last
Fetch), SC (Spam Counter), TZ (Time Zone). Not
applicable at command line when using templates.
-s NUMBER, --startday NUMBER
define the starting day number, if omitted current
conditions are output. Not applicable at command line
when using templates.
-e NUMBER, --endday NUMBER
define the ending day number, with a maximum of 9, if
omitted only starting day data is output. Not
applicable at command line when using templates.
-i, --imperial request imperial units, if omitted output is in
metric.
-b, --beaufort request beaufort scale for wind speeds, if omitted
output is either metric/imperial.
-M, --metrespersecond
request metres per second for wind speeds, if omitted
output is either metric/imperial.
-n, --night switch output to night data, if omitted day output
will be output.
-r, --refetch Fetch data regardless of data expiry.
-x, --hidedegreesymbol
Hide the degree symbol used with temperature output
-u, --hideunits Hide units such as mph or C, degree symbols (°) are
still shown.
-w, --shortweekday Shorten the day of week data type to 3 characters.
--version show program's version number and exit
Configuration file
The configuration file is split up in sections. All sections but the proxy settings are mandatory.
The sections are: 'general', 'location', 'datetime', 'locale' and 'proxy'.
General
cache_path: path to a folder where the cache can be saved. Downloaded weathermaps are saved there as well.
expiry_minutes: time in minutes how long the cached data remains valid.
Location
lat: latitude of the location
lon: longitude of the location
msl: (optional) meters above sea level of the location
Datetime
All options use the Python format to display date-time information. See the Python docs for the formats.
time_format: format to display time without seconds
time_format_full: format to display time including seconds
date_format: format to display dates
locale
time_zone: 0 = GMT, negative is west of GMT, positive is east of GMT. For example: GMT-5 translates as -5
dst: (optional) adding this option defines Day Saving Time. When omitted, DST is not used in the when displaying times.
locale: (optional) locale to use, the locales currently supported are listed against the --locale option in the command options help.
proxy
host: hostname of the proxy
port: (optional) port of the proxy
username: (optional) username used with the proxy
password: (optional) password used with the proxy
Last edited by boisei0 (2014-11-06 18:57:43)
YAWS (cli weather script with conkyForecast syntax) | Bitbucket | Github | Blog
Member of the Unofficial #! Emergency Tinfoil Hat Distribution Center
Emergency Tinfoil Hat Conky Alert System development team
Offline
Hi ... I had to try it.
$ python3 weather-yaws.py --help
usage: weather-yaws.py [-h] [--msl MSL] [--hours HOURS] [--version] lat lon
YAWS: Yet Another Weather Script
positional arguments:
lat Latitude of the location
lon Longitude of the location
optional arguments:
-h, --help show this help message and exit
--msl MSL Meters above sea level of the location
--hours HOURS Hours from now, up to 240; expects 0 if not given
--version show program's version number and exit
$ python3 weather-yaws.py lat -34.26 lon -58.28 --msl 25
usage: weather-yaws.py [-h] [--msl MSL] [--hours HOURS] [--version] lat lon
weather-yaws.py: error: argument lat: invalid float value: 'lat'
$
OK, from here lat|lon to 2 decimals.
$ python3 weather-yaws.py lat -34.26 lon -58.28 --msl 25
usage: weather-yaws.py [-h] [--msl MSL] [--hours HOURS] [--version] lat lon
weather-yaws.py: error: argument lat: invalid float value: 'lat'
this works "http://api.met.no/weatherapi/locationforecast/1.8/?lat=-34.26;lon=-58.28;msl=25" although I cannot check the actual location .. pretty close to my other weather scripts though.
Can you see what I missed? I named the script ~/bin/weather-yaws.py
· ↓ ↓ ↓ ↓ ↓ ↓ ·
BunsenLabs Forums now Open for Registration
· ↑ ↑ ↑ ↑ ↑ ↑ · BL ModSquad
Offline
To fix: remove the name of lat and lon, just put
$ python3 weather-yaws.py -34.56 -58.48 --msl 25
in there. I should have mentioned in the first post, that 'lat' and 'lon' are posititheonal arguments, so overwrite their name with the value. I'm not too happy with that behavior, but did not find another way to do it yet. I'll update the first post with a working example for the arguments.
boisei0@inchiquin:~/workspace/WeatherForecast/NorskMet$ python3 weather.py -34.56 -58.48 --msl 25
Now:
Temperature: 8.5°C
Wind: NW 4 Beaufort
Humidity: 47.5%
Pressure: 1020.9 hPa
YAWS (cli weather script with conkyForecast syntax) | Bitbucket | Github | Blog
Member of the Unofficial #! Emergency Tinfoil Hat Distribution Center
Emergency Tinfoil Hat Conky Alert System development team
Offline
Modified and slightly delayed cross-post from the New Monster Conky Thread:
Deegan wrote:Thanks #! CrunchBanger
![]()
How come this error with conkyforecast?
![]()
Conky forecast has pretty well stopped working - and unless a python coder wants to pick up where Mark lets off it will stay that way.
Sites make changes ... Mark has left Linux for work related reasons so cF sits unsupported.
Check out v9000 or Teo's scripts in my sig.
Inspired by this post and the conkyForecast script, I spent the last four five days (including Christmas) updating my own weather script (when I look back, I did not use more than a few lines of my original code) to the cF syntax. I now have a working script, omitting only a few functions of cF. I'm using the API of the Norwegian Meteorological institute for this script. There are a few thing I can/will not add due to the limitations of the API I use.
I'll update the first post with the new script. Please not that it may (or shall) contain bugs.
Options not (yet) included:
--config (no configuration file yet)
--spaces
--locale (still working on the translation(s))
--minuteshide
--centeredwidth
--refetch (will be adding this in the next version)
--verbose
--errorlogfile
--infologfile
Datatypes not (yet) included:
OB (no support in the API)
PC (no support in the API, however it supports precipitation in mm; I still have to think about this option)
UI (no support in the API, Norway only)
UT (no support in the API, Norway only)
WG (no support in the API)
VI (no support in the API)
BF
BS
MF
WF
BI
MI
YAWS (cli weather script with conkyForecast syntax) | Bitbucket | Github | Blog
Member of the Unofficial #! Emergency Tinfoil Hat Distribution Center
Emergency Tinfoil Hat Conky Alert System development team
Offline
Updated YAWS to 1.5.3: minor bugfixes and support for
'The official revised O#!ETHDC Emergency Tinfoil Hat Conky Alert System, V2.x'
Download: YAWS 1.5.3
Currently working on 1.6. Functions to include: configuration file, timezone support and file cache.
YAWS (cli weather script with conkyForecast syntax) | Bitbucket | Github | Blog
Member of the Unofficial #! Emergency Tinfoil Hat Distribution Center
Emergency Tinfoil Hat Conky Alert System development team
Offline
I'm still having a problem getting this working
I just download the latest ...
03 Apr 14 | 16:52:20 ~
$ python3 /media/5/Conky/YAWS/yaws.py --help
Traceback (most recent call last):
File "/media/5/Conky/YAWS/yaws.py", line 35, in <module>
import requests
ImportError: No module named 'requests'
03 Apr 14 | 16:53:27 ~
$ cd /media/5/Conky/YAWS
03 Apr 14 | 16:53:41 /media/5/Conky/YAWS
$ python3 yaws.py --help
Traceback (most recent call last):
File "yaws.py", line 35, in <module>
import requests
ImportError: No module named 'requests'
03 Apr 14 | 16:53:50 /media/5/Conky/YAWS
$
Yup, it's 'executable'.
· ↓ ↓ ↓ ↓ ↓ ↓ ·
BunsenLabs Forums now Open for Registration
· ↑ ↑ ↑ ↑ ↑ ↑ · BL ModSquad
Offline
@Sector11: apt-get install python-requests installs Requests for Python 2. This version of YAWS, in contrary to the first version, is not (yet) compatible with Python 3. This is not clear at all, so I'll understand the confusion. To execute, run
python yaws.py
On my TODO-list for today: make YAWS compatible with Python 3 and push it towards 1.6.
YAWS (cli weather script with conkyForecast syntax) | Bitbucket | Github | Blog
Member of the Unofficial #! Emergency Tinfoil Hat Distribution Center
Emergency Tinfoil Hat Conky Alert System development team
Offline
04 Apr 14 | 11:09:56 ~
$ python /media/5/Conky/YAWS/yaws.py --help
Traceback (most recent call last):
File "/media/5/Conky/YAWS/yaws.py", line 36, in <module>
import requests
ImportError: No module named requests
04 Apr 14 | 11:10:00 ~
$ cd /media/5/Conky/YAWS
04 Apr 14 | 11:10:02 /media/5/Conky/YAWS
$ python /media/5/Conky/YAWS/yaws.py --help
Traceback (most recent call last):
File "/media/5/Conky/YAWS/yaws.py", line 36, in <module>
import requests
ImportError: No module named requests
04 Apr 14 | 11:10:04 /media/5/Conky/YAWS
$
I guess my Debian SID doesn't like it.
04 Apr 14 | 11:25:01 /media/5/Conky/YAWS
$ python2 /media/5/Conky/YAWS/yaws.py --help
Traceback (most recent call last):
File "/media/5/Conky/YAWS/yaws.py", line 36, in <module>
import requests
ImportError: No module named requests
· ↓ ↓ ↓ ↓ ↓ ↓ ·
BunsenLabs Forums now Open for Registration
· ↑ ↑ ↑ ↑ ↑ ↑ · BL ModSquad
Offline
Did you try the (somewhere today added) approach from the first post?
Installation instructions for Requests, if the Aptitude version gives errors:
Download version 2.2.1 or later. Untar it and execute in the created directory the commandpython setup.py install
as root (for example by using sudo).
YAWS (cli weather script with conkyForecast syntax) | Bitbucket | Github | Blog
Member of the Unofficial #! Emergency Tinfoil Hat Distribution Center
Emergency Tinfoil Hat Conky Alert System development team
Offline
Did you try the (somewhere today added) approach from the first post?
Installation instructions for Requests, if the Aptitude version gives errors:
Download version 2.2.1 or later. Untar it and execute in the created directory the commandpython setup.py install
as root (for example by using sudo).
:8 ummm ... :8 ...errrrr .... yup, that did it... :8
I should wake up fully before doing things.
Now I have python2.6, python2.7 and python3.3 installed. 8) ->0¿0
Would you be so kind as to show the portion of your conky from TEXT down that shows this output..
How close are the yaws.po files to the ones that cF uses?
ie: here's /media/5/Conky/conkyForecast-2.24/locale/fr - for French
# i18n translation template file for conkyForecast.py
# The msgstr values require defining for the require language, once populated
# pass the file back so it can be compiled and used in the script.
# Copyright (C) 2008 Kaivalagi
# Kaivalagi <m_buck@hotmail.com>, 2008.
#
msgid ""
msgstr ""
"Project-Id-Version: conkyForecast.py 1.0\n"
"POT-Creation-Date: 2008-08-19 19:02+BST\n"
"PO-Revision-Date: 2011-08-07 22:30+0100\n"
"Last-Translator: Kaivalagi <m_buck@hotmail.com>\n"
"Language-Team: Kaivalagi <m_buck@hotmail.com>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Generated-By: pygettext.py 1.5\n"
"X-Poedit-Language: French\n"
"X-Poedit-Country: FRANCE\n"
"X-Poedit-SourceCharset: utf-8\n"
msgid "falling"
msgstr "couchant"
msgid "rising"
msgstr "levant"
msgid "steady"
msgstr "stable"
msgid "calm"
msgstr "calme"
#: conkyForecast.py:157
msgid "Tornado"
msgstr "Tornade"
#: conkyForecast.py:158
msgid "Tropical Storm"
msgstr "Tempête Tropicale"
#: conkyForecast.py:159
msgid "Hurricane"
msgstr "Ouragan"
#: conkyForecast.py:160
msgid "Severe Thunderstorms"
msgstr "Orages Violents"
#: conkyForecast.py:161
msgid "Thunderstorms"
msgstr "Orageux"
#: conkyForecast.py:162
msgid "Mixed Rain and Snow"
msgstr "Pluie et Neige"
#: conkyForecast.py:163
msgid "Mixed Rain and Sleet"
msgstr "Pluie et Neige Mouillée"
#: conkyForecast.py:164
msgid "Mixed Precipitation"
msgstr "Variable avec averses"
#: conkyForecast.py:165
msgid "Freezing Drizzle"
msgstr "Bruine Givrante"
#: conkyForecast.py:166
msgid "Drizzle"
msgstr "Bruine"
#: conkyForecast.py:167
msgid "Freezing Rain"
msgstr "Pluie Glaçante"
#: conkyForecast.py:168
msgid "Light Rain"
msgstr "Pluie Légère"
#: conkyForecast.py:169
msgid "Rain"
msgstr "Pluie"
#: conkyForecast.py:170
msgid "Snow Flurries"
msgstr "Bourrasques de neige"
#: conkyForecast.py:171
msgid "Light Snow Showers"
msgstr "Légère Neige"
#: conkyForecast.py:172
msgid "Drifting Snow"
msgstr "Tempête de Neige"
#: conkyForecast.py:173
msgid "Snow"
msgstr "Neige"
#: conkyForecast.py:174
msgid "Hail"
msgstr "Grêle"
#: conkyForecast.py:175
msgid "Sleet"
msgstr "Neige fondue"
#: conkyForecast.py:176
msgid "Dust"
msgstr "Nuage de poussière"
#: conkyForecast.py:177
msgid "Fog"
msgstr "Brouillard"
#: conkyForecast.py:178
msgid "Haze"
msgstr "Brume"
#: conkyForecast.py:179
msgid "Smoke"
msgstr "Fumée"
#: conkyForecast.py:180
msgid "Blustery"
msgstr "Très Venteux"
#: conkyForecast.py:181
msgid "Windy"
msgstr "Venteux"
#: conkyForecast.py:182
#: conkyForecast.py:201
#: conkyForecast.py:205
#: conkyForecast.py:206
#: conkyForecast.py:248
#: conkyForecast.py:258
msgid "N/A"
msgstr "N/A"
#: conkyForecast.py:183
msgid "Cloudy"
msgstr "Nuageux"
#: conkyForecast.py:184
#: conkyForecast.py:185
msgid "Mostly Cloudy"
msgstr "Très Nuageux"
#: conkyForecast.py:186
#: conkyForecast.py:187
msgid "Partly Cloudy"
msgstr "Nuages Disséminés"
#: conkyForecast.py:188
#: conkyForecast.py:189
msgid "Clear"
msgstr "Beau"
#: conkyForecast.py:190
#: conkyForecast.py:191
msgid "Fair"
msgstr "Belles Éclaircies"
#: conkyForecast.py:192
msgid "Mixed Rain and Hail"
msgstr "Pluie avec Grêle"
#: conkyForecast.py:193
msgid "Hot"
msgstr "Chaleur"
#: conkyForecast.py:194
#: conkyForecast.py:204
msgid "Isolated Thunderstorms"
msgstr "Orages Isolés"
#: conkyForecast.py:195
msgid "Scattered Thunderstorms"
msgstr "Orages Localisés"
#: conkyForecast.py:196
#: conkyForecast.py:202
msgid "Scattered Showers"
msgstr "Averses Localisées"
#: conkyForecast.py:197
msgid "Heavy Rain"
msgstr "Pluie battante"
#: conkyForecast.py:198
msgid "Scattered Snow Showers"
msgstr "Tempêtes de Neige Localisées"
#: conkyForecast.py:199
#: conkyForecast.py:200
msgid "Heavy Snow"
msgstr "Fortes chutes de neige"
#: conkyForecast.py:203
msgid "Snow Showers"
msgstr "Tempêtes de neige"
#: conkyForecast.py:210
msgid "Today"
msgstr "Aujourd'hui"
#: conkyForecast.py:211
msgid "Monday"
msgstr "Lundi"
#: conkyForecast.py:212
msgid "Tuesday"
msgstr "Mardi"
#: conkyForecast.py:213
msgid "Wednesday"
msgstr "Mercredi"
#: conkyForecast.py:214
msgid "Thursday"
msgstr "Jeudi"
#: conkyForecast.py:215
msgid "Friday"
msgstr "Vendredi"
#: conkyForecast.py:216
msgid "Saturday"
msgstr "Samedi"
#: conkyForecast.py:217
msgid "Sunday"
msgstr "Dimanche"
#: conkyForecast.py:221
msgid "Now"
msgstr "Auj"
#: conkyForecast.py:222
msgid "Mon"
msgstr "Lun"
#: conkyForecast.py:223
msgid "Tue"
msgstr "Mar"
#: conkyForecast.py:224
msgid "Wed"
msgstr "Mer"
#: conkyForecast.py:225
msgid "Thu"
msgstr "Jeu"
#: conkyForecast.py:226
msgid "Fri"
msgstr "Ven"
#: conkyForecast.py:227
msgid "Sat"
msgstr "Sam"
#: conkyForecast.py:228
msgid "Sun"
msgstr "Dim"
#: conkyForecast.py:232
msgid "N"
msgstr "N"
#: conkyForecast.py:233
msgid "NNE"
msgstr "NNE"
#: conkyForecast.py:234
msgid "NE"
msgstr "NE"
#: conkyForecast.py:235
msgid "ENE"
msgstr "ENE"
#: conkyForecast.py:236
msgid "E"
msgstr "E"
#: conkyForecast.py:237
msgid "ESE"
msgstr "ESE"
#: conkyForecast.py:238
msgid "SE"
msgstr "SE"
#: conkyForecast.py:239
msgid "SSE"
msgstr "SSE"
#: conkyForecast.py:240
msgid "S"
msgstr "S"
#: conkyForecast.py:241
msgid "SSW"
msgstr "SSO"
#: conkyForecast.py:242
msgid "SW"
msgstr "SO"
#: conkyForecast.py:243
msgid "WSW"
msgstr "OSO"
#: conkyForecast.py:244
msgid "W"
msgstr "O"
#: conkyForecast.py:245
msgid "WNW"
msgstr "ONO"
#: conkyForecast.py:246
msgid "NW"
msgstr "NO"
#: conkyForecast.py:247
msgid "NNW"
msgstr "NNO"
#: conkyForecast.py:252
msgid "Very Low"
msgstr "Très Bas"
#: conkyForecast.py:253
msgid "Low"
msgstr "Bas"
#: conkyForecast.py:254
msgid "Moderate"
msgstr "Modéré"
#: conkyForecast.py:255
msgid "High"
msgstr "Haut"
#: conkyForecast.py:256
msgid "Very High"
msgstr "Très haut"
#: conkyForecast.py:257
msgid "Extreme"
msgstr "Extrême"
#: conkyForecast.py:407
msgid "New"
msgstr "Nouvelle"
#: conkyForecast.py:408
msgid "First Quarter"
msgstr "Premier quartier"
#: conkyForecast.py:409
msgid "Full"
msgstr "Pleine"
#: conkyForecast.py:410
msgid "Last Quarter"
msgstr "Dernier quartier"
#: conkyForecast.py:411
msgid "Waning Crescent"
msgstr "Dernier croissant"
#: conkyForecast.py:412
msgid "Waning Gibbous"
msgstr "Gibbeuse décroissante"
#: conkyForecast.py:413
msgid "Waxing Crescent"
msgstr "Premier croissant"
#: conkyForecast.py:414
msgid "Waxing Gibbous"
msgstr "Gibbeuse croissante"
#~ msgid "Showers"
#~ msgstr "Averses"
#~ msgid "Cold"
#~ msgstr "Froid"
#~ msgid "Thunder Showers"
#~ msgstr "Neige Lourde"
Lot's already done:
/media/5/Conky/conkyForecast-2.24/locale/bg
/media/5/Conky/conkyForecast-2.24/locale/cs
/media/5/Conky/conkyForecast-2.24/locale/de
/media/5/Conky/conkyForecast-2.24/locale/es
/media/5/Conky/conkyForecast-2.24/locale/fj
/media/5/Conky/conkyForecast-2.24/locale/fr
/media/5/Conky/conkyForecast-2.24/locale/it
/media/5/Conky/conkyForecast-2.24/locale/lt
/media/5/Conky/conkyForecast-2.24/locale/nl
/media/5/Conky/conkyForecast-2.24/locale/pl
/media/5/Conky/conkyForecast-2.24/locale/ro
/media/5/Conky/conkyForecast-2.24/locale/sk
/media/5/Conky/conkyForecast-2.24/locale/sv
/media/5/Conky/conkyForecast-2.24/locale/zh
Last edited by Sector11 (2014-04-04 18:15:41)
· ↓ ↓ ↓ ↓ ↓ ↓ ·
BunsenLabs Forums now Open for Registration
· ↑ ↑ ↑ ↑ ↑ ↑ · BL ModSquad
Offline
Would you be so kind as to show the portion of your conky from TEXT down that shows this output..
TEXT
${execpi 3600 python ~/workspace/WeatherForecast/NorskMet/yaws.py 51.9280 6.3447 --msl 15 --template=/home/boisei0/Scripts-Snippets/lua/conkyrc/default/weather.template}
weather.template looks like this:
${time %T} | [--datatype=CN]
${color4}${font monospace:bold:size=9}[--datatype=CC]${font}${color}
${voffset 3}${color3}Wind: ${color}[--datatype=WA]([--datatype=WD]) ${color3}@ ${color}[--datatype=WS --beaufort]${goto 235}${color3}FL: ${color}[--datatype=LT]${image [--datatype=WI] -p 15,45 -s 48x48}
${goto 100}${font Zekton:size=20}${color}${voffset 10}[--datatype=HT]${font}${voffset -15}${goto 235}${color3}Max: ${color}[--datatype=HT --startday=0]
${goto 235}${color3}Min: ${color}[--datatype=LT --startday=0]
${voffset 5}${goto 235}${color3}Hum: ${color}[--datatype=HM]
${goto 235}${color3}DP: ${color}[--datatype=DP]
${color3}Pressure: ${color}[--datatype=BR] - [--datatype=BD]${color}
${color3}Moon Phase: ${color}[--datatype=MP]${color}
${voffset 5} ${color3}Sunrise:${color} [--datatype=SR]
${color3}Sunset:${color} [--datatype=SS]
${color3}Daylight:${color} [--datatype=DL]
${voffset 3}${color3}Alert Level:${color} SPAMCON [--datatype=SC]
It's a slightly modified version of what I've included in the examples directory. I found that one over at the Ubuntu forums, made by someone with the name 'Sector11'. Not sure if I added proper credits to that example...
Edit: :8 woops :8 that's a no... Updated the templates, will upload the version with original authors names with 1.6
How close are the yaws.po files to the ones that cF uses?
ie: here's /media/5/Conky/conkyForecast-2.24/locale/fr - for French
I had to use a dictionary for about 4 words for the French locale. The rest I took from the cF source / locales. I know about the other po-files, but I'm not that multi-lingual to check if what I write is correct
Last edited by boisei0 (2014-04-04 19:00:58)
YAWS (cli weather script with conkyForecast syntax) | Bitbucket | Github | Blog
Member of the Unofficial #! Emergency Tinfoil Hat Distribution Center
Emergency Tinfoil Hat Conky Alert System development team
Offline
It's a slightly modified version of what I've included in the examples directory. I found that one over at the Ubuntu forums, made by someone with the name 'Sector11'. Not sure if I added proper credits to that example...
Edit: :8 woops :8 that's a no... Updated the templates, will upload the version with original authors names with 1.6
Sector who? Never heard of him.
My problem wasn't that I had the
${execpi 600 python /media/5/Conky/YAWS/yaws.py --msl 6 --template /media/5/Conky/YAWS/example/test.template}
command wrong, I figured that would be like the old cF line.
I had the lats and longs wrong :8
Once I stopped using conkyLatLong - it has an error now and has me someplace in the northern hemisphere and zoomed in on the 'satellite' image to my roof top here: Find Latitude and Longitude
.. put UVI in there and YAWS a winner ... it is now but I just had to say that about the UVI.
Sector11 wrote:How close are the yaws.po files to the ones that cF uses?
ie: here's /media/5/Conky/conkyForecast-2.24/locale/fr - for FrenchI had to use a dictionary for about 4 words for the French locale. The rest I took from the cF source / locales. I know about the other po-files, but I'm not that multi-lingual to check if what I write is correct
All of the .po files were done by users who used the languages in question and submitted them to Mark to include them.
Pretty safe bet if you used them ... would capture the interest of others ...
No I'll have to test ... play with the all the example templates now ... and come up with some new ones.
One "execpi" call to get all that info and uses conky commands as well in the template is just too good to stay away from.
· ↓ ↓ ↓ ↓ ↓ ↓ ·
BunsenLabs Forums now Open for Registration
· ↑ ↑ ↑ ↑ ↑ ↑ · BL ModSquad
Offline
This has potential like crazy .... I've been playing and enjoying ...
I got that far and it hit me ... those sun rise and set times are way off!
Should look something like this:
Any idea how to fix this?
Looks like there is a MR and MS time too:
def parse_data(self, args, model):
if args.datatype == 'DL':
return self.get_daylight(model.sun_rise, model.sun_set)
elif args.datatype == 'MP':
return model.moon_phase
elif args.datatype == 'MR':
return datetime.datetime.strptime(model.moon_rise, '%Y-%m-%dT%H:%M:%SZ').strftime('%H:%M')
elif args.datatype == 'MS':
return datetime.datetime.strptime(model.moon_set, '%Y-%m-%dT%H:%M:%SZ').strftime('%H:%M')
elif args.datatype == 'SR':
return datetime.datetime.strptime(model.sun_rise, '%Y-%m-%dT%H:%M:%SZ').strftime('%H:%M')
elif args.datatype == 'SS':
return datetime.datetime.strptime(model.sun_set, '%Y-%m-%dT%H:%M:%SZ').strftime('%H:%M')
else:
raise Exception
Last edited by Sector11 (2014-04-05 01:32:03)
· ↓ ↓ ↓ ↓ ↓ ↓ ·
BunsenLabs Forums now Open for Registration
· ↑ ↑ ↑ ↑ ↑ ↑ · BL ModSquad
Offline
This has potential like crazy .... I've been playing and enjoying ...
http://s20.postimg.org/okboe1imh/2014_04_04_22_16_20_541x342_Sector11.jpg
I got that far and it hit me ... those sun rise and set times are way off!
Should look something like this:
http://s20.postimg.org/a2eh61rbd/2014_04_04_22_17_23_1132x437_Sector11.jpgAny idea how to fix this?
Looks like there is a MR and MS time too:
Working on the timezone support now (should have implemented that months ago, but with me being the only user, it wasn't that high on my todo-list). All times displayed are the UTC values. So the 10.09 is 10.09 UTC = 7.09 GMT minus 3.
Python is a really nice language, but there are a couple of things I really hate. One of them is timezones. It's a load of (difficult) work to do calculations on time when it involves this. One of the main reasons I didn't implement it yet.
About the UVI part, I'm afraid that's a bit harder to implement. As I only use the met.no API for the weather data, the UVI is only available for Scandinavia, as can be seen on this image:
Might use a different API for stuff like UVI, but not sure about the implementation yet.
YAWS (cli weather script with conkyForecast syntax) | Bitbucket | Github | Blog
Member of the Unofficial #! Emergency Tinfoil Hat Distribution Center
Emergency Tinfoil Hat Conky Alert System development team
Offline
Working on the timezone support now (should have implemented that months ago, but with me being the only user, it wasn't that high on my todo-list). All times displayed are the UTC values. So the 10.09 is 10.09 UTC = 7.09 GMT minus 3.
Python is a really nice language, but there are a couple of things I really hate. One of them is timezones. It's a load of (difficult) work to do calculations on time when it involves this. One of the main reasons I didn't implement it yet.
That makes sense. Maybe a user set variable that sets the timezone? ie: mine would be:
UserTZ -3
hmmmmmmmm not so simple ... 1 + -3 = -2 not 22:00
sorry
About the UVI part, I'm afraid that's a bit harder to implement. As I only use the met.no API for the weather data, the UVI is only available for Scandinavia, as can be seen on this image:
http://i.imgur.com/0AmttbN.png
Might use a different API for stuff like UVI, but not sure about the implementation yet.
I think you mentioned something about UVI before. For most in the northern hemisphere it's not a big issue ... here it is.
I don't know any programming languages so I'm at the mercy of developers. See time stuff above.
· ↓ ↓ ↓ ↓ ↓ ↓ ·
BunsenLabs Forums now Open for Registration
· ↑ ↑ ↑ ↑ ↑ ↑ · BL ModSquad
Offline
I know this suggestion is far too late and would require a complete re write of your script but the wunderground API is really easy to work with and has near global coverage if you were thinking of expanding your data
Last edited by mrpeachy (2014-04-05 13:12:36)
Offline
Timezones seem to work in alpha version of 1.6.
Added configuration files, timezones, filecache and proxy support. Still testing though, will upload a working version when I think it's free of bugs.
Just made this Conky using timezone GMT-3 combined with the coordinates supplied by Sector 11 in post #2
Template is a slightly modified version of details.template, provided with the script
@mrpeachy: might add a WU version later. Somewhere on my todo-list now.
YAWS (cli weather script with conkyForecast syntax) | Bitbucket | Github | Blog
Member of the Unofficial #! Emergency Tinfoil Hat Distribution Center
Emergency Tinfoil Hat Conky Alert System development team
Offline
Updated top post with information about version 1.6. If someone encounters weird bugs, let me know and I'll try to fix them.
YAWS (cli weather script with conkyForecast syntax) | Bitbucket | Github | Blog
Member of the Unofficial #! Emergency Tinfoil Hat Distribution Center
Emergency Tinfoil Hat Conky Alert System development team
Offline
sun_moon.template
[--datatype=CN], [--datatype=CO] ${color8}${time %a. %d %b. %Y} at: ${time %T}${color}
${color3}Alert Level:${color} SPAMCON [--datatype=SC]
${goto 90} | Day |
Sun:${goto 90} Rise | Light | Set | High${goto 320}| Low
${execi 600 echo `date --date="0 day" | awk '{print $1" "$3" "$2}'`}${goto 90}[--startday=0 --datatype=SR] | [--startday=0 --datatype=DL] | [--startday=0 --datatype=SS] | [--startday=0 --datatype=HT]${goto 320}| [--startday=0 --datatype=LT] [--startday=0 --datatype=CT]
${execi 600 echo `date --date="1 day" | awk '{print $1" "$3" "$2}'`}${goto 90}[--startday=1 --datatype=SR] | [--startday=1 --datatype=DL] | [--startday=1 --datatype=SS] | [--startday=1 --datatype=HT]${goto 320}| [--startday=1 --datatype=LT] [--startday=1 --datatype=CT]
${execi 600 echo `date --date="2 day" | awk '{print $1" "$3" "$2}'`}${goto 90}[--startday=2 --datatype=SR] | [--startday=2 --datatype=DL] | [--startday=2 --datatype=SS] | [--startday=2 --datatype=HT]${goto 320}| [--startday=2 --datatype=LT] [--startday=2 --datatype=CT]
${execi 600 echo `date --date="3 day" | awk '{print $1" "$3" "$2}'`}${goto 90}[--startday=3 --datatype=SR] | [--startday=3 --datatype=DL] | [--startday=3 --datatype=SS] | [--startday=3 --datatype=HT]${goto 320}| [--startday=3 --datatype=LT] [--startday=3 --datatype=CT]
${execi 600 echo `date --date="4 day" | awk '{print $1" "$3" "$2}'`}${goto 90}[--startday=4 --datatype=SR] | [--startday=4 --datatype=DL] | [--startday=4 --datatype=SS] | [--startday=4 --datatype=HT]${goto 320}| [--startday=4 --datatype=LT] [--startday=4 --datatype=CT]
${execi 600 echo `date --date="5 day" | awk '{print $1" "$3" "$2}'`}${goto 90}[--startday=5 --datatype=SR] | [--startday=5 --datatype=DL] | [--startday=5 --datatype=SS] | [--startday=5 --datatype=HT]${goto 320}| [--startday=5 --datatype=LT] [--startday=5 --datatype=CT]
${execi 600 echo `date --date="6 day" | awk '{print $1" "$3" "$2}'`}${goto 90}[--startday=6 --datatype=SR] | [--startday=6 --datatype=DL] | [--startday=6 --datatype=SS] | [--startday=6 --datatype=HT]${goto 320}| [--startday=6 --datatype=LT] [--startday=6 --datatype=CT]
${execi 600 echo `date --date="7 day" | awk '{print $1" "$3" "$2}'`}${goto 90}[--startday=7 --datatype=SR] | [--startday=7 --datatype=DL] | [--startday=7 --datatype=SS] | [--startday=7 --datatype=HT]${goto 320}| [--startday=7 --datatype=LT] [--startday=7 --datatype=CT]
${execi 600 echo `date --date="8 day" | awk '{print $1" "$3" "$2}'`}${goto 90}[--startday=8 --datatype=SR] | [--startday=8 --datatype=DL] | [--startday=8 --datatype=SS] | [--startday=8 --datatype=HT]${goto 320}| [--startday=8 --datatype=LT] [--startday=8 --datatype=CT]
${execi 600 echo `date --date="9 day" | awk '{print $1" "$3" "$2}'`}${goto 90}[--startday=9 --datatype=SR] | [--startday=9 --datatype=DL] | [--startday=9 --datatype=SS] | [--startday=9 --datatype=HT]${goto 320}| [--startday=9 --datatype=LT] [--startday=9 --datatype=CT]
Moon: Rise | Set | Phase
${execi 600 echo `date --date="0 day" | awk '{print $1" "$3" "$2}'`}${goto 90}[--startday=0 --datatype=MR] | [--startday=0 --datatype=MS] | [--startday=0 --datatype=MP]
${execi 600 echo `date --date="1 day" | awk '{print $1" "$3" "$2}'`}${goto 90}[--startday=1 --datatype=MR] | [--startday=1 --datatype=MS] | [--startday=1 --datatype=MP]
${execi 600 echo `date --date="2 day" | awk '{print $1" "$3" "$2}'`}${goto 90}[--startday=2 --datatype=MR] | [--startday=2 --datatype=MS] | [--startday=2 --datatype=MP]
${execi 600 echo `date --date="3 day" | awk '{print $1" "$3" "$2}'`}${goto 90}[--startday=3 --datatype=MR] | [--startday=3 --datatype=MS] | [--startday=3 --datatype=MP]
${execi 600 echo `date --date="4 day" | awk '{print $1" "$3" "$2}'`}${goto 90}[--startday=4 --datatype=MR] | [--startday=4 --datatype=MS] | [--startday=4 --datatype=MP]
${execi 600 echo `date --date="5 day" | awk '{print $1" "$3" "$2}'`}${goto 90}[--startday=5 --datatype=MR] | [--startday=5 --datatype=MS] | [--startday=5 --datatype=MP]
${execi 600 echo `date --date="6 day" | awk '{print $1" "$3" "$2}'`}${goto 90}[--startday=6 --datatype=MR] | [--startday=6 --datatype=MS] | [--startday=6 --datatype=MP]
${execi 600 echo `date --date="7 day" | awk '{print $1" "$3" "$2}'`}${goto 90}[--startday=7 --datatype=MR] | [--startday=7 --datatype=MS] | [--startday=7 --datatype=MP]
${execi 600 echo `date --date="8 day" | awk '{print $1" "$3" "$2}'`}${goto 90}[--startday=8 --datatype=MR] | [--startday=8 --datatype=MS] | [--startday=8 --datatype=MP]
${execi 600 echo `date --date="9 day" | awk '{print $1" "$3" "$2}'`}${goto 90}[--startday=9 --datatype=MR] | [--startday=9 --datatype=MS] | [--startday=9 --datatype=MP]
Fetched: [--datatype=LF]
· ↓ ↓ ↓ ↓ ↓ ↓ ·
BunsenLabs Forums now Open for Registration
· ↑ ↑ ↑ ↑ ↑ ↑ · BL ModSquad
Offline
My latest as seen in the SPAM Alert thread:
The conky:
TEXT
${execpi 600 python /media/5/Conky/YAWS/yaws-1.6/yaws.py --config /media/5/Conky/YAWS/yaws-1.6/YAWS.cfg --template /media/5/Conky/YAWS/yaws-1.6/example/9days.template}
9days.template
${time %T}${alignr 5}${color8}SPAMCON: [--datatype=SC]${color}
${execi 600 echo `date --date="0 day" | awk '{print $1" "$3" "$2}'`} ${color6}[--datatype=MP --startday=0]${color}
Max: [--datatype=HT --startday=0]${image [--datatype=WI] -p 0,15 -s 38x38}
Min: [--datatype=LT --startday=0]${image [--datatype=WI --startday=0] -p 0,75 -s 38x38}
Now: ${color5}[--datatype=CC]${color}
[--datatype=HT --hideunits]${goto 130}± [--datatype=LT --hideunits]
Hum: [--datatype=HM]${goto 130}Dew: [--datatype=DP --hideunits]
Bar: [--datatype=BR] - [--datatype=BD]
Wind: [--hideunits --datatype=WS] km/h | [--datatype=WA] | [--datatype=WD]
Sun: [--startday=0 --datatype=SR] ${color5}| [--startday=0 --datatype=DL] |${color} [--startday=0 --datatype=SS]
Moon: [--startday=0 --datatype=MR] | | [--startday=0 --datatype=MS]
${membar 0,240}
${execi 600 echo `date --date="1 day" | awk '{print $1" "$3" "$2}'`} ${color6}[--datatype=MP --startday=1]
${color5}[--datatype=CC --startday=1]${color}${image [--datatype=WI --startday=1] -p 0,168 -s 38x38}
${color9}[--datatype=HT --startday=1 --hideunits]${goto 130}${color3}[--datatype=LT --startday=1 --hideunits]${color}
Sun: [--startday=1 --datatype=SR] ${color5}| [--startday=1 --datatype=DL] |${color} [--startday=1 --datatype=SS]
Moon: [--startday=1 --datatype=MR] | | [--startday=1 --datatype=MS]
${membar 0,240}
${execi 600 echo `date --date="2 day" | awk '{print $1" "$3" "$2}'`} ${color6}[--datatype=MP --startday=2]${color}
${color5}[--datatype=CC --startday=2]${color}${image [--datatype=WI --startday=2] -p 0,254 -s 38x38}
${color9}[--datatype=HT --startday=2 --hideunits]${goto 130}${color3}[--datatype=LT --startday=2 --hideunits]${color}
Sun: [--startday=2 --datatype=SR] ${color5}| [--startday=2 --datatype=DL] |${color} [--startday=2 --datatype=SS]
Moon: [--startday=2 --datatype=MR] | | [--startday=2 --datatype=MS]
${membar 0,240}
${execi 600 echo `date --date="3 day" | awk '{print $1" "$3" "$2}'`} ${color6}[--datatype=MP --startday=3]${color}
${color5}[--datatype=CC --startday=3]${color}${image [--datatype=WI --startday=3] -p 0,337 -s 38x38}
${color9}[--datatype=HT --startday=3 --hideunits]${goto 130}${color3}[--datatype=LT --startday=3 --hideunits]${color}
Sun: [--startday=3 --datatype=SR] ${color5}| [--startday=3 --datatype=DL] |${color} [--startday=3 --datatype=SS]
Moon: [--startday=3 --datatype=MR] | | [--startday=3 --datatype=MS]
${membar 0,240}
${execi 600 echo `date --date="4 day" | awk '{print $1" "$3" "$2}'`} ${color6}[--datatype=MP --startday=4]${color}
${color5}[--datatype=CC --startday=4]${color}${image [--datatype=WI --startday=4] -p 0,422 -s 38x38}
${color9}[--datatype=HT --startday=4 --hideunits]${goto 130}${color3}[--datatype=LT --startday=4 --hideunits]${color}
Sun: [--startday=4 --datatype=SR] ${color5}| [--startday=4 --datatype=DL] |${color} [--startday=4 --datatype=SS]
Moon: [--startday=4 --datatype=MR] | | [--startday=4 --datatype=MS]
${membar 0,240}
${execi 600 echo `date --date="5 day" | awk '{print $1" "$3" "$2}'`} ${color6}[--datatype=MP --startday=5]${color}
${color5}[--datatype=CC --startday=5]${color}${image [--datatype=WI --startday=5] -p 0,505 -s 38x38}
${color9}[--datatype=HT --startday=5 --hideunits]${goto 130}${color3}[--datatype=LT --startday=5 --hideunits]${color}
Sun: [--startday=5 --datatype=SR] ${color5}| [--startday=5 --datatype=DL] |${color} [--startday=5 --datatype=SS]
Moon: [--startday=5 --datatype=MR] | | [--startday=5 --datatype=MS]
${membar 0,240}
${execi 600 echo `date --date="6 day" | awk '{print $1" "$3" "$2}'`} ${color6}[--datatype=MP --startday=6]${color}
${color5}[--datatype=CC --startday=6]${color}${image [--datatype=WI --startday=6] -p 0,590 -s 38x38}
${color9}[--datatype=HT --startday=6 --hideunits]${goto 130}${color3}[--datatype=LT --startday=6 --hideunits]${color}
Sun: [--startday=6 --datatype=SR] ${color5}| [--startday=6 --datatype=DL] |${color} [--startday=6 --datatype=SS]
Moon: [--startday=6 --datatype=MR] | | [--startday=6 --datatype=MS]
${membar 0,240}
${execi 600 echo `date --date="7 day" | awk '{print $1" "$3" "$2}'`} ${color6}[--datatype=MP --startday=7]${color}
${color5}[--datatype=CC --startday=7]${color}${image [--datatype=WI --startday=7] -p 0,673 -s 38x38}
${color9}[--datatype=HT --startday=7 --hideunits]${goto 130}${color3}[--datatype=LT --startday=7 --hideunits]${color}
Sun: [--startday=7 --datatype=SR] ${color5}| [--startday=7 --datatype=DL] |${color} [--startday=7 --datatype=SS]
Moon: [--startday=7 --datatype=MR] | | [--startday=7 --datatype=MS]
${membar 0,240}
${execi 600 echo `date --date="8 day" | awk '{print $1" "$3" "$2}'`} ${color6}[--datatype=MP --startday=8]${color}
${color5}[--datatype=CC --startday=8]${color}${image [--datatype=WI --startday=8] -p 0,757 -s 38x38}
${color9}[--datatype=HT --startday=8 --hideunits]${goto 130}${color3}[--datatype=LT --startday=8 --hideunits]${color}
Sun: [--startday=8 --datatype=SR] ${color5}| [--startday=8 --datatype=DL] |${color} [--startday=8 --datatype=SS]
Moon: [--startday=8 --datatype=MR] | | [--startday=8 --datatype=MS]
${membar 0,240}
${execi 600 echo `date --date="9 day" | awk '{print $1" "$3" "$2}'`} ${color6}[--datatype=MP --startday=9]${color}
${color5}[--datatype=CC --startday=9]${color}${image [--datatype=WI --startday=9] -p 0,840 -s 38x38}
${color9}[--datatype=HT --startday=9 --hideunits]${goto 130}${color3}[--datatype=LT --startday=9 --hideunits]${color}
Sun: [--startday=9 --datatype=SR] ${color5}| [--startday=9 --datatype=DL] |${color} [--startday=9 --datatype=SS]
Moon: [--startday=9 --datatype=MR] | | [--startday=9 --datatype=MS]
${membar 0,240}
Updated: [--datatype=LU]
Fetched: [--datatype=LF]
· ↓ ↓ ↓ ↓ ↓ ↓ ·
BunsenLabs Forums now Open for Registration
· ↑ ↑ ↑ ↑ ↑ ↑ · BL ModSquad
Offline
And then, there's that moment when you see a screenshot of your program and you spot a bug in it :8. Just uploaded 1.6.1. Datatypes 'LU' and 'LF' should now have timezone support, as well as the ability to display a custom format, as specified in the configuration.
YAWS (cli weather script with conkyForecast syntax) | Bitbucket | Github | Blog
Member of the Unofficial #! Emergency Tinfoil Hat Distribution Center
Emergency Tinfoil Hat Conky Alert System development team
Offline
And then, there's that moment when you see a screenshot of your program and you spot a bug in it :8. Just uploaded 1.6.1. Datatypes 'LU' and 'LF' should now have timezone support, as well as the ability to display a custom format, as specified in the configuration.
Got it ... will tackle it shortly. I meant to ask about that TZ in there too. I forgot. :8
· ↓ ↓ ↓ ↓ ↓ ↓ ·
BunsenLabs Forums now Open for Registration
· ↑ ↑ ↑ ↑ ↑ ↑ · BL ModSquad
Offline
OK ... I'm revisiting "YAWS" 1.6.1 and it doesn't like me.
06 Nov 14 | 14:01:00 ~
$ conky -c /home/sector11/yaws-1.6/yaws.conky &
[1] 11519
06 Nov 14 | 14:01:06 ~
$ Conky: forked to background, pid is 11524
Conky: desktop window (264) is root window
Conky: window type - normal
Conky: drawing to created window (0x2e00001)
Conky: drawing to double buffer
Traceback (most recent call last):
File "/home/sector11/yaws-1.6/yaws.py", line 1086, in <module>
main()
File "/home/sector11/yaws-1.6/yaws.py", line 1055, in main
forecast = WeatherForecast(config)
File "/home/sector11/yaws-1.6/yaws.py", line 530, in __init__
raise Exception
Exception
~/yaws-1.6/YAWS.cfg
[general]
#cache_path = /tmp/yaws/
cache_path = /home/sector11/yaws-1.6/cache/
expiry_minutes = 60
[location]
lat = -34.563285
lon = -58.489036
#lat = 50.0000
#lon = 4.0000
#msl = 15
[datetime]
time_format = %H:%M
time_format_full = %T
date_format = %Y-%m-%d
[locale]
time_zone = 0
#dst
#locale = fr
#[proxy]
#host = example.com
#port = 8080
#username = user
#password = pass
This: time_zone = 0 should be: time_zone = -3 - but should not stop it from working. (I think)
in the conky:
update_interval 1
TEXT
Hello ...
this is a conky
${execpi 600 python /home/sector11/yaws-1.6/yaws.py --config /home/sector11/yaws-1.6/YAWS.cfg --template /home/sector11/yaws-1.6/example/9days.template}
Although I'm sure you have it: yaws.py
#/!usr/bin/python
# -*- coding: utf-8 -*-
#================================================================================#
# yaws.py #
# Yet Another Weather Script #
# !!! WORKS ONLY OUTSIDE NORWAY !!! # TODO: FIX THIS!!! #
# Script for weather forecasts using the REST style API from The Norwegian #
# Meteorological institute, outputs to command line. #
#--------------------------------------------------------------------------------#
# This program is free software; you can redistribute it and/or #
# modify it under the terms of the GNU General Public License #
# as published by the Free Software Foundation; either version 3 #
# of the License, or (at your option) any later version. #
# #
# This program is distributed in the hope that it will be useful, #
# but WITHOUT ANY WARRANTY; without even the implied warranty of #
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
# GNU General Public License for more details. #
# #
# You should have received a copy of the GNU General Public License #
# along with this program; if not, write to the Free Software #
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #
#================================================================================#
__appname__ = 'YAWS'
__author__ = 'Boisei0'
__version__ = '1.6.1'
import argparse
import ConfigParser
import cPickle
import datetime
import gettext
#import locale
import operator
import os
import requests
import sys
import xml.etree.ElementTree
reload(sys)
sys.setdefaultencoding('utf-8')
# default to standard locale translation
domain = __file__.replace(os.path.dirname(__file__) + "/", "").replace(".py", "")
locale_directory = os.path.dirname(os.path.abspath(__file__)) + "/locale"
gettext.bindtextdomain(domain, locale_directory)
gettext.textdomain(domain)
gettext.install(domain)
max_days = 9 # Hardcoded detail from the API documentation
class CommandlineParser:
def __init__(self):
self.parser = argparse.ArgumentParser(description=u'YAWS: Yet Another Weather Script')
#self.parser.add_argument('lat', type=float, help=u'latitude of the location')
#self.parser.add_argument('lon', type=float, help=u'longitude of the location')
#self.parser.add_argument('--msl', type=int, help=u'meters above sea level of the location')
self.parser.add_argument("-C", "--config", dest="config", default="{0}/.config/{1}/{1}.cfg".format(os.environ['HOME'], __appname__), metavar="FILE", help=u"[default: {0}/.config/{1}/{1}.cfg] The path to the configuration file, allowing multiple config files to be used.".format(os.environ['HOME'], __appname__))
self.parser.add_argument("-t", "--template", dest="template", metavar="FILE", help=u"define a template file to generate output in one call. A displayable item in the file is in the form [--datatype=HT --startday=1]. The following are possible options within each item: --datatype, --startday, --endday, --imperial, --beaufort, --metrespersecond, --shortweekday, --hideunits, --hidedegreesymbol, --night. Note that the short forms of the options are not supported! If any of these options is set from the commandline, it sets the default value of the option for all template items.")
self.parser.add_argument("-L", "--locale", dest="locale", help=u"override the system locale for language output (en=english, nl=dutch, more to come)")
self.parser.add_argument('-d', '--datatype', dest='datatype', default='HT', help=u"[default: HT] The data type options are: DW (Day of Week), WI (Weather Icon Path), LT (Low Temp), HT (High Temp), CC (Current Conditions), CT (Conditions Text), HM (Humidity), WD (Wind Direction), WA (Wind Angle - in degrees), WS (Wind Speed), CN (City Name), CO (Country), SR (SunRise), SS (SunSet), DL (DayLight), MP (Moon Phase), BR (Barometer Reading), BD (Barometer Description), DP (Dew Point), WM (weather map fetch and image path returned), LU (Last Update), LF (Last Fetch), SC (Spam Counter), TZ (Time Zone). Not applicable at command line when using templates.")
self.parser.add_argument('-s', "--startday", dest="startday", type=int, metavar="NUMBER", help=u"define the starting day number, if omitted current conditions are output. Not applicable at command line when using templates.")
self.parser.add_argument("-e", "--endday", dest='endday', type=int, metavar='NUMBER', help=u"define the ending day number, with a maximum of {}, if omitted only starting day data is output. Not applicable at command line when using templates.".format(max_days))
self.parser.add_argument('-i', '--imperial', dest='imperial', default=False, action='store_true', help=u'request imperial units, if omitted output is in metric.')
self.parser.add_argument('-b', '--beaufort', dest='beaufort', default=False, action='store_true', help=u'request beaufort scale for wind speeds, if omitted output is either metric/imperial.')
self.parser.add_argument("-M", "--metrespersecond", dest="metrespersecond", default=False, action="store_true", help=u"request metres per second for wind speeds, if omitted output is either metric/imperial.")
self.parser.add_argument("-n", "--night", dest="night", default=False, action="store_true", help=u"switch output to night data, if omitted day output will be output.")
self.parser.add_argument("-r", "--refetch", dest="refetch", default=False, action="store_true", help=u"Fetch data regardless of data expiry.")
self.parser.add_argument("-x", "--hidedegreesymbol", dest="hidedegreesymbol", default=False, action="store_true", help=u"Hide the degree symbol used with temperature output")
self.parser.add_argument("-u", "--hideunits", dest="hideunits", default=False, action="store_true", help=u"Hide units such as mph or C, degree symbols (°) are still shown.")
self.parser.add_argument("-w", "--shortweekday", dest="shortweekday", default=False, action="store_true", help=u"Shorten the day of week data type to 3 characters.")
self.parser.add_argument('--version', action='version', version='{} v{} by {}'.format(__appname__, __version__,
__author__))
def parse_args(self):
return self.parser.parse_args()
class YAWSConfigParser:
def __init__(self, config_path):
self._config = ConfigParser.ConfigParser(allow_no_value=True)
try:
self._config.readfp(open(config_path))
except IOError:
raise Exception('Configuration file is missing. Specify a location with -C or place it on the default\
\nlocation: {0}/.config/{1}/{1}.cfg'.format(os.environ['HOME'], __appname__))
try:
self._config_model = self._config_to_model()
except (ConfigParser.NoOptionError, ConfigParser.NoSectionError):
raise Exception('Configuration file is incomplete or malformed. Minimal settings should be:\
\ncache_path, expiry_minutes, lat, lon, time_format, time_format_full, date_format and time_zone.\
\nSee the example configuration for details.')
def _config_to_model(self):
cache_path = self._config.get('general', 'cache_path')
expiry_minutes = int(self._config.get('general', 'expiry_minutes'))
lat = self._config.get('location', 'lat')
lon = self._config.get('location', 'lon')
try:
msl = self._config.get('location', 'msl')
except ConfigParser.NoOptionError:
msl = None
time_format = self._config.get('datetime', 'time_format')
time_format_full = self._config.get('datetime', 'time_format_full')
date_format = self._config.get('datetime', 'date_format')
try:
cfg_locale = self._config.get('locale', 'locale')
except ConfigParser.NoOptionError:
cfg_locale = 'en'
time_zone = int(self._config.get('locale', 'time_zone'))
try:
if self._config.get('locale', 'dst') is not None:
dst = True
else:
dst = False
except ConfigParser.NoOptionError:
dst = False
try:
proxy_host = self._config.get('proxy', 'proxy_host')
except (ConfigParser.NoOptionError, ConfigParser.NoSectionError):
proxy_host = None
try:
proxy_port = self._config.get('proxy', 'proxy_port')
except (ConfigParser.NoOptionError, ConfigParser.NoSectionError):
proxy_port = None
try:
proxy_user = self._config.get('proxy', 'proxy_user')
except (ConfigParser.NoOptionError, ConfigParser.NoSectionError):
proxy_user = None
try:
proxy_pass = self._config.get('proxy', 'proxy_pass')
except (ConfigParser.NoOptionError, ConfigParser.NoSectionError):
proxy_pass = None
return ConfigModel(cache_path, expiry_minutes, lat, lon, time_format, time_format_full, date_format, cfg_locale,
time_zone, dst, msl, proxy_host, proxy_port, proxy_user, proxy_pass)
def get_config_model(self):
return self._config_model
class ConfigModel:
def __init__(self, cache_path, expiry_minutes, lat, lon, time_format, time_format_full, date_format, cfg_locale,
time_zone, dst, msl, proxy_host, proxy_port, proxy_user, proxy_pass):
self.cache_path = cache_path
self.expiry_minutes = expiry_minutes
self.lat = lat
self.lon = lon
self.msl = msl
self.time_format = time_format
self.time_format_full = time_format_full
self.date_format = date_format
self.locale = cfg_locale
self.time_zone = time_zone
self.dst = dst
self.proxy_host = proxy_host
self.proxy_port = proxy_port
self.proxy_user = proxy_user
self.proxy_pass = proxy_pass
if self.proxy_host is not None:
self.use_proxy = True
else:
self.use_proxy = False
class Converter:
def __init__(self):
pass
@staticmethod
def celcius_to_fahrenheit(celcius, dp=0):
celcius = float(celcius)
return round(((celcius * 9.0) / 5.0) + 32, dp)
@staticmethod
def mps_to_kph(mps, dp=0):
mps = float(mps)
return round(mps * 3.6, dp)
@staticmethod
def mps_to_mph(mps, dp=0):
mps = float(mps)
return round(mps * 2.237, dp)
class Sunrise:
"""Module for sun- and moonrise using the REST style API from The Norwegian Meteorological institute"""
def __init__(self, cfg, date=None, date_from=None, date_to=None):
if date is not None:
url = 'http://api.met.no/weatherapi/sunrise/1.0/?lat={};lon={};date={}'.format(cfg.lat, cfg.lon, date)
resp = requests.get(url, proxies=get_proxies(cfg))
elif date_from is not None and date_to is not None:
url = 'http://api.met.no/weatherapi/sunrise/1.0/?lat={};lon={};from={};to={}'.format(cfg.lat, cfg.lon,
date_from, date_to)
resp = requests.get(url, proxies=get_proxies(cfg))
else:
today = datetime.datetime.today()
date = today.strftime('%Y-%m-%d')
url = 'http://api.met.no/weatherapi/sunrise/1.0/?lat={};lon={};date={}'.format(cfg.lat, cfg.lon, date)
resp = requests.get(url, proxies=get_proxies(cfg))
if resp.status_code == 200:
self.root = xml.etree.ElementTree.fromstring(resp.text)
else:
raise Exception
self._cfg = cfg
def list_dates(self):
dates = []
for child in self.root:
if child.tag != 'meta':
dates.append(child.attrib['date'])
return dates
def get_index_by_date(self, date):
if date in self.list_dates():
index = 0
for child in self.root:
if child.tag == 'meta':
index += 1
elif child.attrib['date'] == date:
return index
else:
index += 1
def fill_model_by_date(self, date):
if date in self.list_dates():
index = self.get_index_by_date(date)
sun_rise = self.root[index][0][0].attrib['rise']
sun_set = self.root[index][0][0].attrib['set']
moon_rise = self.root[index][0][1].attrib['rise']
moon_set = self.root[index][0][1].attrib['set']
moon_phase = self.root[index][0][1].attrib['phase']
model = SunriseModel(date, sun_rise, sun_set, moon_rise, moon_set, moon_phase)
return model
else:
raise Exception
def parse_data(self, args, model):
if args.datatype == 'DL':
return self.get_daylight(model.sun_rise, model.sun_set)
elif args.datatype == 'MP':
return model.moon_phase
elif args.datatype == 'MR':
return self.get_tz_time(model.moon_rise)
elif args.datatype == 'MS':
return self.get_tz_time(model.moon_set)
elif args.datatype == 'SR':
return self.get_tz_time(model.sun_rise)
elif args.datatype == 'SS':
return self.get_tz_time(model.sun_set)
else:
raise Exception
def get_tz_time(self, dt):
dt_delta = datetime.datetime.strptime(dt, '%Y-%m-%dT%H:%M:%SZ')
dt_delta += TimeZone(self._cfg.time_zone, self._cfg.dst).get_timedelta()
return dt_delta.strftime(self._cfg.time_format)
@staticmethod
def get_daylight(sun_rise, sun_set):
sun_set = datetime.datetime.strptime(sun_set, '%Y-%m-%dT%H:%M:%SZ')
sun_rise = datetime.datetime.strptime(sun_rise, '%Y-%m-%dT%H:%M:%SZ')
return timedelta_dl_to_time((sun_set - sun_rise))
class SunriseModel:
def __init__(self, date, sun_rise, sun_set, moon_rise, moon_set, moon_phase):
self.date = date
self.sun_rise = sun_rise
self.sun_set = sun_set
self.moon_rise = moon_rise
self.moon_set = moon_set
self.moon_phase = moon_phase
class Template:
def __init__(self, config, forecast, sunrise, template):
self._cfg = config
self.forecast = forecast
self.sunrise = sunrise
self.template = template
def parse(self):
for command in self.get_all_commands():
command = command.strip()
output = self.parse_command(command)
try:
self.template = self.template.replace(command, str(output))
except TypeError:
pass
return self.template
def parse_command(self, full_command):
full_command = full_command[1:-1]
full_args = full_command.split(' ')
datatype = None
startday = None
endday = None
imperial = None
beaufort = None
metrespersecond = None
shortweekday = None
hideunits = None
hidedegreesymbol = None
night = None
for argument in full_args:
if argument[:-2] == '--datatype=':
datatype = argument[-2:]
elif argument[:-1] == '--startday=':
startday = int(argument[-1:])
elif argument[:-1] == '--endday=':
endday = int(argument[-1:])
if endday > max_days:
endday = max_days
elif argument == '--imperial':
imperial = True
elif argument == '--beaufort':
beaufort = True
elif argument == '--metrespersecond':
metrespersecond = True
elif argument == '--shortweekday':
shortweekday = True
elif argument == '--hideunits':
hideunits = True
elif argument == '--hidedegreesymbol':
hidedegreesymbol = True
elif argument == '--night':
night = True
elif argument == '':
pass
else:
raise Exception
if datatype is None:
datatype = 'HT'
if startday is None:
startday = 0
if endday is None:
endday = startday
if imperial is None:
imperial = False
if beaufort is None:
beaufort = False
if metrespersecond is None:
metrespersecond = False
if shortweekday is None:
shortweekday = False
if hideunits is None:
hideunits = False
if hidedegreesymbol is None:
hidedegreesymbol = False
if night is None:
night = False
args = TemplateArgs(self._cfg.lat, self._cfg.lon, self._cfg.msl, datatype, startday, endday, imperial, beaufort,
metrespersecond, shortweekday, hideunits, hidedegreesymbol, night)
if range(startday, endday) == list():
output = parse_forecast_arguments(args, self.forecast, self.sunrise, self._cfg, days=startday)
return output
else:
output = []
for day in range(startday, endday):
output.append(parse_forecast_arguments(args, self.forecast, self.sunrise, self._cfg, days=day))
return output
def get_all_commands(self):
commands = []
current_pos = 0
while self.template.find('[', current_pos) != -1: # commands left in file
pos_command_start = self.template.find('[', current_pos)
pos_command_end = self.template.find(']', current_pos)
if pos_command_end == -1: # malformed command
raise Exception
command = self.template[pos_command_start:pos_command_end + 1]
commands.append(command)
current_pos = pos_command_end + 1
return commands
class TemplateArgs:
def __init__(self, lat, lon, msl, datatype, startday, endday, imperial, beaufort, metrespersecond, shortweekday,
hideunits, hidedegreesymbol, night):
self.lat = lat
self.lon = lon
self.msl = msl
self.datatype = datatype
self.startday = startday
self.endday = endday
self.imperial = imperial
self.beaufort = beaufort
self.metrespersecond = metrespersecond
self.shortweekday = shortweekday
self.hideunits = hideunits
self.hidedegreesymbol = hidedegreesymbol
self.night = night
# start ignoring translations required at runtime
def _(text):
return text
class TextData:
def __init__(self):
pass
barometric_description = {
0: _('Stormy'),
1: _('Rain'),
2: _('Change'),
3: _('Fair'),
4: _('Very dry')
}
weekdays = {
0: _('Monday'),
1: _('Tuesday'),
2: _('Wednesday'),
3: _('Thursday'),
4: _('Friday'),
5: _('Saturday'),
6: _('Sunday')
}
weekdays_short = {
0: _('Mon'),
1: _('Tue'),
2: _('Wed'),
3: _('Thu'),
4: _('Fri'),
5: _('Sat'),
6: _('Sun')
}
weather_conditions = {
1: _('Sunny'),
2: _('Light cloudy'),
3: _('Partly cloudy'),
4: _('Cloudy'),
5: _('Light rain and sun'),
6: _('Light rain with thunder and sun'),
7: _('Sleet and sun'),
8: _('Snow and sun'),
9: _('Light rain'),
10: _('Rain'),
11: _('Rain and thunder'),
12: _('Sleet'),
13: _('Snow'),
14: _('Snow and thunder'),
15: _('Fog'),
16: _('Sunny'),
17: _('Light cloudy'),
18: _('Light rain and sun'),
19: _('Snow and sun'),
20: _('Sleet with sun and thunder'),
21: _('Snow with sun and thunder'),
22: _('Light rain and thunder'),
23: _('Sleet and thunder')
}
# end ignoring translations
del _
class TimeZone:
def __init__(self, offset=0, dst=False):
self._offset = offset
self._dst = dst
def tzname(self):
if self._offset == 0 and not self._dst:
return 'UTC'
else:
name = 'GMT'
if self._offset < 0:
name += str(self._offset)
else:
name += '+{}'.format(self._offset)
if self._dst:
name += ' DST'
return name
def get_timedelta(self):
if not self._dst:
return datetime.timedelta(hours=self._offset)
else:
return datetime.timedelta(hours=(self._offset + 1))
class WeatherForecast:
"""Module for weather forecasts using the REST style API from The Norwegian Meteorological institute"""
#def __init__(self, lat, lon, msl=None):
def __init__(self, cfg):
if not cfg.msl:
url = 'http://api.met.no/weatherapi/locationforecast/1.8/?lat={};lon={}'.format(cfg.lat, cfg.lon)
resp = requests.get(url, proxies=get_proxies(cfg))
else:
url = 'http://api.met.no/weatherapi/locationforecast/1.8/?lat={};lon={};msl={}'.format(cfg.lat, cfg.lon,
cfg.msl)
resp = requests.get(url, proxies=get_proxies(cfg))
if resp.status_code == 200:
self.root = xml.etree.ElementTree.fromstring(resp.text)
else:
raise Exception
self._cfg = cfg
def list_precipitation_times(self):
times = []
for child in self.root[1]:
if child.attrib['from'] != child.attrib['to']: # only precipitation forecasts
times.append(child.attrib['from'])
return times
def list_all_times(self):
times = []
for child in self.root[1]:
times.append(child.attrib['from'])
return times
def list_times(self):
times = []
for child in self.root[1]:
if child.attrib['from'] == child.attrib['to']: # full forecast
times.append(child.attrib['from'])
return times
@staticmethod
def get_barometric_description(pressure):
pressure = float(pressure)
if pressure < 965:
return _(TextData.barometric_description[0])
elif pressure < 980:
return _(TextData.barometric_description[1])
elif pressure < 1015:
return _(TextData.barometric_description[2])
elif pressure < 1030:
return _(TextData.barometric_description[3])
else:
return _(TextData.barometric_description[4])
def get_forecast_index_t12_by_date(self, date):
timestamp = '{}T12:00:00Z'.format(date)
return self.get_index_by_timestamp(timestamp)
def get_indices_by_date(self, date):
indices = []
index = 0
for child in self.root[1]:
full_date = datetime.datetime.strptime(child.attrib['from'], '%Y-%m-%dT%H:%M:%SZ')
if full_date.strftime('%Y-%m-%d') == date and child.attrib['from'] != child.attrib['to']:
indices.append(index)
index += 1
return indices
def get_forecast_indices_by_date(self, date):
indices = []
index = 0
for child in self.root[1]:
full_date = datetime.datetime.strptime(child.attrib['from'], '%Y-%m-%dT%H:%M:%SZ')
if full_date.strftime('%Y-%m-%d') == date and child.attrib['from'] == child.attrib['to']:
indices.append(index)
index += 1
return indices
def get_index_by_timestamp(self, timestamp):
if timestamp in self.list_times():
index = 0
for child in self.root[1]:
if child.attrib['from'] == timestamp:
return index
else:
index += 1
def get_low_temperature_by_date(self, date):
indices = self.get_forecast_indices_by_date(date)
temperature_list = []
for index in indices:
for i in range(0, 11):
try:
if self.root[1][index][0][i].tag == 'temperature':
temperature_list.append(self.root[1][index][0][i].attrib['value'])
except IndexError:
pass
return min(temperature_list)
def get_mean_weather_symbol_by_date(self, date):
indices = self.get_indices_by_date(date)
symbol_list = []
for index in indices:
try:
symbol_list.append(self.root[1][index][0][1].attrib['number'])
except IndexError:
pass
return self.get_mean_weather_symbol(symbol_list)
@staticmethod
def get_mean_weather_symbol(symbol_list):
symbol_count_dict = {
0: 0,
1: 0,
2: 0,
3: 0,
4: 0,
5: 0,
6: 0,
7: 0,
8: 0,
9: 0,
10: 0,
11: 0,
12: 0,
13: 0,
14: 0,
15: 0,
16: 0,
17: 0,
18: 0,
19: 0,
20: 0,
21: 0,
22: 0,
23: 0
}
for item in symbol_list:
symbol_count_dict[int(item)] += 1
return max(symbol_count_dict.iteritems(), key=operator.itemgetter(1))[0]
def get_last_update(self):
return self.get_tz_date_time(self.root[0][0].attrib['runended'])
def get_tz_date_time(self, dt):
dt_delta = datetime.datetime.strptime(dt, '%Y-%m-%dT%H:%M:%SZ')
dt_delta += TimeZone(self._cfg.time_zone, self._cfg.dst).get_timedelta()
return dt_delta.strftime('{} {}'.format(self._cfg.date_format, self._cfg.time_format))
def fill_model_by_timestamp(self, timestamp):
if timestamp in self.list_times():
index = self.get_index_by_timestamp(timestamp)
temperature = 0
wind_angle = 0
wind_direction = 0
wind_speed_mps = 0
wind_speed_bft = 0
humidity = 0
pressure = 0
cloudiness = 0
fog = 0
low_clouds = 0
medium_clouds = 0
high_clouds = 0
dewpoint = 0
for i in range(0, 11):
try:
item = self.root[1][index][0][i]
tag = item.tag
if tag == 'temperature':
temperature = item.attrib['value']
elif tag == 'windDirection':
wind_angle = item.attrib['deg']
wind_direction = item.attrib['name']
elif tag == 'windSpeed':
wind_speed_mps = item.attrib['mps']
wind_speed_bft = item.attrib['beaufort']
elif tag == 'humidity':
humidity = item.attrib['value']
elif tag == 'pressure':
pressure = item.attrib['value']
elif tag == 'cloudiness':
cloudiness = item.attrib['percent']
elif tag == 'fog':
fog = item.attrib['percent']
elif tag == 'lowClouds':
low_clouds = item.attrib['percent']
elif tag == 'mediumClouds':
medium_clouds = item.attrib['percent']
elif tag == 'highClouds':
high_clouds = item.attrib['percent']
elif tag == 'dewpointTemperature':
dewpoint = item.attrib['value']
else:
# do not raise exception; add Norway only items later
pass
except IndexError:
pass
date = datetime.datetime.strptime(timestamp, '%Y-%m-%dT%H:%M:%SZ').strftime('%Y-%m-%d')
low_temperature = self.get_low_temperature_by_date(date)
model = ForecastModel(timestamp, temperature, wind_angle, wind_direction, wind_speed_mps, wind_speed_bft,
humidity, pressure, cloudiness, fog, low_clouds, medium_clouds, high_clouds,
dewpoint, low_temperature)
return model
else:
raise Exception
def parse_forecast(self, args, model, date):
if args.datatype == 'BR':
if args.hideunits:
return '{}'.format(model.pressure)
else:
return '{} hPa'.format(model.pressure)
elif args.datatype == 'BD':
return self.get_barometric_description(model.pressure)
elif args.datatype in ['CC', 'CT']:
return _(TextData.weather_conditions[self.get_mean_weather_symbol_by_date(date)])
elif args.datatype == 'DP':
if args.imperial:
if args.hidedegreesymbol:
if args.hideunits:
return u'{}'.format(Converter.celcius_to_fahrenheit(model.dewpoint, 1))
else:
return u'{}F'.format(Converter.celcius_to_fahrenheit(model.dewpoint, 1))
else:
if args.hideunits:
return u'{}°'.format(Converter.celcius_to_fahrenheit(model.dewpoint, 1))
else:
return u'{}°F'.format(Converter.celcius_to_fahrenheit(model.dewpoint, 1))
else:
if args.hidedegreesymbol:
if args.hideunits:
return u'{}'.format(model.dewpoint)
else:
return u'{}C'.format(model.dewpoint)
else:
if args.hideunits:
return u'{}°'.format(model.dewpoint)
else:
return u'{}°C'.format(model.dewpoint)
elif args.datatype == 'HM':
if args.hideunits:
return '{}'.format(model.humidity)
else:
return '{}%'.format(model.humidity)
elif args.datatype == 'HT':
if args.imperial:
if args.hidedegreesymbol:
if args.hideunits:
return u'{}'.format(Converter.celcius_to_fahrenheit(model.temperature, 1))
else:
return u'{}F'.format(Converter.celcius_to_fahrenheit(model.temperature, 1))
else:
if args.hideunits:
return u'{}°'.format(Converter.celcius_to_fahrenheit(model.temperature, 1))
else:
return u'{}°F'.format(Converter.celcius_to_fahrenheit(model.temperature, 1))
else:
if args.hidedegreesymbol:
if args.hideunits:
return u'{}'.format(model.temperature)
else:
return u'{}C'.format(model.temperature)
else:
if args.hideunits:
return u'{}°'.format(model.temperature)
else:
return u'{}°C'.format(model.temperature)
elif args.datatype == 'LU':
return self.get_last_update()
elif args.datatype == 'LT':
if args.imperial:
if args.hidedegreesymbol:
if args.hideunits:
return u'{}'.format(Converter.celcius_to_fahrenheit(model.low_temperature, 1))
else:
return u'{}F'.format(Converter.celcius_to_fahrenheit(model.low_temperature, 1))
else:
if args.hideunits:
return u'{}°'.format(Converter.celcius_to_fahrenheit(model.low_temperature, 1))
else:
return u'{}°F'.format(Converter.celcius_to_fahrenheit(model.low_temperature, 1))
else:
if args.hidedegreesymbol:
if args.hideunits:
return u'{}'.format(model.low_temperature)
else:
return u'{}C'.format(model.low_temperature)
else:
if args.hideunits:
return u'{}°'.format(model.low_temperature)
else:
return u'{}°C'.format(model.low_temperature)
elif args.datatype == 'PC':
pass
elif args.datatype == 'WA':
if args.hidedegreesymbol:
return u'{}'.format(model.wind_angle)
else:
return u'{}°'.format(model.wind_angle)
elif args.datatype == 'WD':
return model.wind_direction
elif args.datatype == 'WI':
if args.night:
return '{}/night-{}.png'.format(os.path.join(os.path.dirname(os.path.abspath(__file__)), 'images'),
self.get_mean_weather_symbol_by_date(date))
else:
return '{}/day-{}.png'.format(os.path.join(os.path.dirname(os.path.abspath(__file__)), 'images'),
self.get_mean_weather_symbol_by_date(date))
elif args.datatype == 'WS':
if args.beaufort:
if args.hideunits:
return '{}'.format(model.wind_speed_bft)
else:
return '{} Bft'.format(model.wind_speed_bft)
elif args.imperial:
if args.hideunits:
return '{}'.format(Converter.mps_to_mph(model.wind_speed_mps))
else:
return '{} mph'.format(Converter.mps_to_mph(model.wind_speed_mps))
else:
if args.hideunits:
return '{}'.format(Converter.mps_to_kph(model.wind_speed_mps))
else:
return '{} kph'.format(Converter.mps_to_kph(model.wind_speed_mps))
else:
raise Exception
class ForecastModel:
def __init__(self, timestamp, temperature, wind_angle, wind_direction, wind_speed_mps, wind_speed_bft, humidity,
pressure, cloudiness, fog, low_clouds, medium_clouds, high_clouds, dewpoint, low_temperature):
self.timestamp = timestamp
self.temperature = temperature
self.wind_angle = wind_angle
self.wind_direction = wind_direction
self.wind_speed_mps = wind_speed_mps
self.wind_speed_bft = wind_speed_bft
self.humidity = humidity
self.pressure = pressure
self.cloudiness = cloudiness
self.fog = fog
self.low_clouds = low_clouds
self.medium_clouds = medium_clouds
self.high_clouds = high_clouds
self.dewpoint = dewpoint
self.low_temperature = low_temperature
def parse_forecast_arguments(args, forecast, sunrise, cfg, days=0):
date_delta = datetime.datetime.utcnow() + datetime.timedelta(days=days)
date = timedelta_to_date(date_delta)
if args.datatype in ['BR', 'BD', 'CC', 'CT', 'DP', 'HM', 'HT', 'LU', 'LT', 'PC', 'WA', 'WD', 'WI', 'WS']:
index = forecast.get_forecast_index_t12_by_date(date)
if index is None:
index = 0
model = forecast.fill_model_by_timestamp(forecast.list_all_times()[index])
return forecast.parse_forecast(args, model, date)
elif args.datatype in ['DL', 'MP', 'MR', 'MS', 'SR', 'SS']:
# sunrise = Sunrise(cfg, date)
model = sunrise.fill_model_by_date(date)
return sunrise.parse_data(args, model)
elif args.datatype == 'DW':
date_dt = datetime.datetime.strptime(date, '%Y-%m-%d')
if args.shortweekday:
return _(TextData.weekdays_short[date_dt.weekday()])
else:
return _(TextData.weekdays[date_dt.weekday()])
elif args.datatype == 'LF':
return datetime.datetime.now().strftime('{} {}'.format(cfg.date_format, cfg.time_format_full))
elif args.datatype in ['CN', 'CO']:
city, country = reverse_geocode(cfg)
if args.datatype == 'CN':
return city
elif args.datatype == 'CO':
return country
else:
raise Exception
elif args.datatype == 'WM':
return get_weather_map(800, 400, cfg)
elif args.datatype == 'SC':
counter = int(requests.get('http://hubsec.eu:8145/spam/', proxies=get_proxies(cfg)).text)
if counter < 5:
return 5
elif counter < 15:
return 4
elif counter < 40:
return 3
elif counter < 60:
return 2
else:
return 1
elif args.datatype == 'TZ':
return TimeZone(cfg.time_zone, cfg.dst).tzname()
def reverse_geocode(config):
url = 'http://maps.googleapis.com/maps/api/geocode/json?latlng={},{}&sensor=false'.format(config.lat, config.lon)
resp = requests.get(url, proxies=get_proxies(config))
if resp.status_code != 200:
raise Exception
try:
try:
data = resp.json()
except TypeError:
try:
data = resp.json
except Exception:
return 'N/A', 'N/A'
city = 'N/A'
country = 'N/A'
for item in data['results'][0]['address_components']:
if 'locality' in item['types']:
city = item['long_name']
elif 'country' in item['types']:
country = item['long_name']
return city, country
except KeyError:
return 'N/A', 'N/A'
def get_proxies(config):
if config.proxy_host is None:
return dict()
if config.proxy_port is not None and config.proxy_user is not None and config.proxy_pass is not None:
return {'http': 'http://{}:{}@{}:{}'.format(config.proxy_user, config.proxy_pass, config.proxy_host,
config.proxy_port)}
elif config.proxy_user is None and config.proxy_port is not None:
return {'http': 'http://{}:{}'.format(config.proxy_host, config.proxy_port)}
elif config.proxy_port is None and config.proxy_user is not None:
return {'http': 'http://{}:{}@{}'.format(config.proxy_user, config.proxy_pass, config.proxy_host)}
elif config.proxy_port is None and config.proxy_user is None:
return {'http': 'http://{}'.format(config.proxy_host)}
def get_weather_map(width, height, config):
url = 'http://api.met.no/weatherapi/geosatellite/1.3/?area=global;width={};height={}'.format(width, height)
resp = requests.get(url, stream=True, proxies=get_proxies(config))
if resp.status_code != 200:
raise Exception
image_path = os.path.join(config.cache_path, 'weathermap.jpg')
with open(image_path, 'wb') as image_file:
image_file.write(resp.content)
return image_path
def timedelta_to_date(delta):
full_date = datetime.datetime.strptime(str(delta), '%Y-%m-%d %H:%M:%S.%f')
return full_date.strftime('%Y-%m-%d')
def timedelta_dl_to_time(delta, hide_seconds=True):
full_date = datetime.datetime.strptime(str(delta), '%H:%M:%S')
if hide_seconds:
return full_date.strftime('%H:%M')
else:
return str(delta)
def main():
try:
parser = CommandlineParser()
args = parser.parse_args()
config = YAWSConfigParser(args.config).get_config_model()
except Exception as ex:
sys.exit(ex)
try:
# set the locale
if not args.locale:
#language = locale.getdefaultlocale()[0][0:2]
language = config.locale
else:
language = args.locale
if language != 'en':
if gettext.find(domain, locale_directory, languages=[language]) is not None:
try:
trans = gettext.translation(domain, locale_directory, languages=[language])
trans.install(unicode=True)
except Exception:
pass
except Exception:
pass
if args.startday is None:
startday = 0
else:
startday = int(args.startday)
if args.endday is None:
endday = startday
else:
endday = int(args.endday)
if endday > max_days:
endday = max_days
today = datetime.datetime.utcnow().strftime('%Y-%m-%d')
last_date = timedelta_to_date(datetime.datetime.utcnow() + datetime.timedelta(days=max_days))
if os.path.exists(config.cache_path):
if os.path.exists(os.path.join(config.cache_path, 'data.pkl')):
# pickle data if new enough
f = open(os.path.join(config.cache_path, 'data.pkl'), 'rb')
last_fetch = cPickle.load(f)
if datetime.datetime.utcnow() - last_fetch > datetime.timedelta(minutes=config.expiry_minutes):
forecast = WeatherForecast(config)
sunrise = Sunrise(config, date_from=today, date_to=last_date)
refetched = True
else:
if args.refetch is not None:
forecast = WeatherForecast(config)
sunrise = Sunrise(config, date_from=today, date_to=last_date)
refetched = True
else:
forecast = cPickle.load(f)
sunrise = cPickle.load(f)
refetched = False
f.close()
else:
forecast = WeatherForecast(config)
sunrise = Sunrise(config, date_from=today, date_to=last_date)
refetched = True
else:
os.mkdir(config.cache_path)
forecast = WeatherForecast(config)
sunrise = Sunrise(config, date_from=today, date_to=last_date)
refetched = True
if args.template is not None:
with open(args.template, 'r') as f:
template_text = f.read()
template = Template(config, forecast, sunrise, template_text)
print(template.parse())
else:
if range(startday, endday) == list():
print(parse_forecast_arguments(args, forecast, sunrise, config, days=startday))
else:
for day in range(startday, endday):
print(parse_forecast_arguments(args, forecast, sunrise, config, days=day))
if refetched:
output = open(os.path.join(config.cache_path, 'data.pkl'), 'wb')
cPickle.dump(datetime.datetime.utcnow(), output)
cPickle.dump(forecast, output)
cPickle.dump(sunrise, output)
output.close()
if __name__ == '__main__':
main()
sys.exit(0)
EDIT: This: time_zone = -3 didn't help.
Last edited by Sector11 (2014-11-06 17:15:51)
· ↓ ↓ ↓ ↓ ↓ ↓ ·
BunsenLabs Forums now Open for Registration
· ↑ ↑ ↑ ↑ ↑ ↑ · BL ModSquad
Offline
No it's not you... It's a bug I fixed in my local version, but I forgot to update this topic as well (for about a couple of months)... The Norwegian Meteorological Institute updated their version and I hardcoded excepted a particular type of response, which it didn't get after the update. A quick fix: search for http://api.met.no/weatherapi/locationforecast/1.8/ and replace it by http://api.met.no/weatherapi/locationforecast/1.9/. I'll update the first post with the new version later tonight, dinner time right now.
YAWS (cli weather script with conkyForecast syntax) | Bitbucket | Github | Blog
Member of the Unofficial #! Emergency Tinfoil Hat Distribution Center
Emergency Tinfoil Hat Conky Alert System development team
Offline
AHA! No din-din for you!
Mrs. boisei0 send him to bed ... directly to bed, do not pass go, do not collect 200 guilder
OOPS my age is showing ... 200€
That's for the fix - 2 changed.
... OOPS!
Different errors ...
06 Nov 14 | 14:55:24 ~
$ conky -c /home/sector11/yaws-1.6/yaws.conky &
[1] 13003
06 Nov 14 | 14:55:38 ~
$ Conky: forked to background, pid is 13008
Conky: desktop window (264) is root window
Conky: window type - normal
Conky: drawing to created window (0x2800001)
Conky: drawing to double buffer
Traceback (most recent call last):
File "/home/sector11/yaws-1.6/yaws.py", line 1086, in <module>
main()
File "/home/sector11/yaws-1.6/yaws.py", line 1069, in main
print(template.parse())
File "/home/sector11/yaws-1.6/yaws.py", line 306, in parse
output = self.parse_command(command)
File "/home/sector11/yaws-1.6/yaws.py", line 381, in parse_command
output = parse_forecast_arguments(args, self.forecast, self.sunrise, self._cfg, days=startday)
File "/home/sector11/yaws-1.6/yaws.py", line 880, in parse_forecast_arguments
return forecast.parse_forecast(args, model, date)
File "/home/sector11/yaws-1.6/yaws.py", line 829, in parse_forecast
self.get_mean_weather_symbol_by_date(date))
File "/home/sector11/yaws-1.6/yaws.py", line 621, in get_mean_weather_symbol_by_date
return self.get_mean_weather_symbol(symbol_list)
File "/home/sector11/yaws-1.6/yaws.py", line 653, in get_mean_weather_symbol
symbol_count_dict[int(item)] += 1
KeyError: 46
· ↓ ↓ ↓ ↓ ↓ ↓ ·
BunsenLabs Forums now Open for Registration
· ↑ ↑ ↑ ↑ ↑ ↑ · BL ModSquad
Offline
Copyright © 2012 CrunchBang Linux.
Proudly powered by Debian. Hosted by Linode.
Debian is a registered trademark of Software in the Public Interest, Inc.
Server: acrobat