воскресенье, 13 ноября 2011 г.

Погода для conky с rp5.ru

Как говорит один небезызвестный государственный служащий России — буду краток.
Собственно захотелось мне выводить погоду на рабочий стол посредством conky. Стандартный weather.sh на подошел так как, ну нет в нем моей «деревни».
Поиск в гугле так-же ни к чему не привел. Есть скрипты для gismeteo, но мне нужен был именно вывод с rp5.ru, потому что прогноз с этого сайта наиболее точно совпадает с реальной погодой в моей «деревне».
Оставалось одно — слепить для этого что-то самому…
Сайт rp5.ru дает возможность получить прогноз в формате xml. Остается только «распарсить» его и подогнать в удобоваримый формат для conky.
Собственно вот сам скрипт на python.


#!/usr/bin/env python           
# -*- coding: utf-8 -*-
#########################################################################
#                                                                                                                                               #
# weathet.py - скрипт для получения прогноза погоды с rp5.ru (rp5.ua)   #
# Рекомендуется использовать совместно с системным монитором conky              #
# (http://conky.sf.net)                                                                                                 #
#                                                                                                                                               #
#########################################################################

def license():
        return """
Copyright 2011 Roman [Zloy Pingvin] <3loy.pingvin@gmail.com>
       
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 2 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.
"""       
       
import os, sys, pwd, stat, time, getoptimport socket, urllibimport xml.dom.minidom

UPDATE_TIME = 600
class Weather:
        def __init__(self,url):
                socket.setdefaulttimeout(10)
                self.map = []
                self.wind = []
                self.rain = []
                self.xmlurl = url
                self.itemrss = None
                self.day = -1
                self.temp_file = "/tmp/weather." + pwd.getpwuid(os.getuid())[0] + ".tmp"

                params = ("time_step", "datetime", "G", "HHii", "cloud_cover", 
                          "ccloud_cover","precipitation", "pressure", "temperature", 
                          "humidity","wind_direction","wwind_direction","wind_velocity", "falls","ffalls", "drops")
                # Таблица направления ветра
                self.wind.append (                      
                        {u"С":          "9",
                         u"С-В":        ";",
                         u"В":          "=",
                         u"Ю-В":        "?",
                         u"Ю":          "1",
                         u"Ю-З":        "?",
                         u"З":          "5",
                         u"С-З":        "7",
                         u"ШТЛ":        "%",
                        })
                # Таблица вида осадков
                self.rain.append (
                        {"0":   "Без осадков",
                         "1":   "Дождь",
                         "2":   "Снег с дождем",
                         "3":   "Снег"
                        })
                
                try:
                        opts, args = getopt.getopt(sys.argv[1:], "ht:d:", ["help","day="])
                except getopt.GetoptError, err:
                        print str(err)
                        print "Используйте -h или --help для получения справки"
                        sys.exit(2)
                                
                for o, a in opts:
                        if o in ("-h", "--help"):
                                self.help()
                                sys.exit()
                                                                
                        elif o in ("-d", "--day"):
                                try:
                                        self.day = int(a)
                                        if self.day < 0 or self.day > 3:
                                                raise
                                except:
                                        print "Неверное значение параметра '--day', должно быть от 0 до 3\nИспользуйте -h или --help для получения справки"
                                        sys.exit(2)
                                        
                param = sys.argv[len(sys.argv)-1]
                if param in params:
                        self.forecast(self.day,param)
                else:
                        print "Не верно заданы параметры!\nИспользуйте -h или --help для получения справки"
                        sys.exit(2)
                
        def loadxml(self):
                data = urllib.urlopen(self.xmlurl)
                tmp = open(self.temp_file, "w")
                tmp.write(data.read())
                tmp.close()
                
        def load(self):
                if os.path.isfile(self.temp_file):
                        if (int(time.time()) - int(os.stat(self.temp_file)[stat.ST_MTIME])) < UPDATE_TIME :
                                return self.temp_file
                        else:
                                self.loadxml()
                                return self.temp_file
                else:
                        self.loadxml()
                        return self.temp_file
        
        def parse(self):

                self.dom = xml.dom.minidom.parse(self.load())
                self.dom.normalize()
                self.itemrss = self.dom.getElementsByTagName('timestep')
                
                for item in self.itemrss:
                        self.time_step = item.getElementsByTagName('time_step')[0].childNodes[0].data
                        self.datetime = item.getElementsByTagName('datetime')[0].childNodes[0].data
                        self.G = item.getElementsByTagName('G')[0].childNodes[0].data
                        self.HHii = item.getElementsByTagName('HHii')[0].childNodes[0].data
                        self.cloud_cover = item.getElementsByTagName('cloud_cover')[0].childNodes[0].data
                        self.precipitation = item.getElementsByTagName('precipitation')[0].childNodes[0].data
                        self.pressure = item.getElementsByTagName('pressure')[0].childNodes[0].data
                        self.temperature = item.getElementsByTagName('temperature')[0].childNodes[0].data
                        self.humidity = item.getElementsByTagName('humidity')[0].childNodes[0].data
                        self.wind_direction = item.getElementsByTagName('wind_direction')[0].childNodes[0].data
                        self.wind_velocity = item.getElementsByTagName('wind_velocity')[0].childNodes[0].data
                        self.falls = item.getElementsByTagName('falls')[0].childNodes[0].data
                        self.drops = int(float(item.getElementsByTagName('drops')[0].childNodes[0].data)*2)

                        # Преобразование облачности
                        if int(self.cloud_cover) <= 20:
                                self.ccloud_cover = "a"
                        elif int(self.cloud_cover) > 20 and int(self.cloud_cover) <= 40:
                                self.ccloud_cover = "b"
                        elif int(self.cloud_cover) > 40 and int(self.cloud_cover) <= 60:
                                self.ccloud_cover = "c"
                        elif int(self.cloud_cover) > 60 and int(self.cloud_cover) <= 80:
                                self.ccloud_cover = "d"
                        elif int(self.cloud_cover) > 80:
                                self.ccloud_cover = "e"
                                

                        self.map.append (
                                {"time_step":           self.time_step,
                                 "datetime":            self.datetime,
                                 "G":                           self.G,
                                 "HHii":                        self.HHii,
                                 "cloud_cover":         self.cloud_cover,
                                 "ccloud_cover":        self.ccloud_cover,
                                 "precipitation":       self.precipitation,
                                 "pressure":            self.pressure,
                                 "temperature":         self.temperature,
                                 "humidity":            self.humidity,
                                 "wind_direction":      self.wind_direction,
                                 "wwind_direction":     self.wind[0][self.wind_direction],
                                 "wind_velocity":       self.wind_velocity,
                                 "falls":                       self.falls,
                                 "ffalls":                      self.rain[0][self.falls],
                                 "drops":                       self.drops
                                })

        def forecast(self,day,key):
                self.parse()
                print self.map[day][key]

        def help(self):
                print""
                print "weathet.py - скрипт для получения прогноза погоды с rp5.ru (rp5.ua)\nПредназначен для использования совместно с системным монитором conky (http://conky.sf.net)"
                print license()
                print ""
                print "Запуск: weather.py [ОПЦИИ] [ПАРАМЕТР]"
                print ""
                print "Опции :"
                print "  -h, --help                     Выводит эту справку"
                print "  -d, --day                      Смещение времени прогноза, значение от 0 до 3"
                print ""
                print "Параметры :\n"
                print "time_step - смещение указанного ниже момента прогноза (datetime) в часах относительно 0 час Гринвичского времени в день составления прогноза. time_step соответствует русскому термину 'заблаговременность прогноза'. Например, если time_step = 48 - это прогноз на момент времени, отстоящий на 48 часов от момента составления прогноза (0 ГМТ)\n"
                print "datetime - момент прогноза по местному времени (дата час:минута)\n"
                print "G - момент прогноза по местному времени в часах. Например, '15'\n"
                print "HHiii - момент прогноза по местному времени в часах и минутах. Например, '15:00'\n"
                print "cloud_cover облачность (%)\n"
                print "ccloud_cover - нормализованный для шрифта ConkyWeather cloud_cover\n"
                print "precipitation n - толщина осадков (мм), накопленных в течение 4 часов перед указанным выше моментом времени. Например, если G = 15 час, то осадки накапливались с 11 до 15 час.\n"
                print "pressure - атмосферное давление (мм. рт. ст.)\n"
                print "temperature - температура воздуха (град. Цельсия)\n"
                print "humidity - относительная влажность воздуха (%)\n"
                print "wind_direction - направление ветра (С-северный, СВ-северо-восточный и т.д.). Направление указывает ОТКУДА дует ветер. Например, северный ветер дует с севера\n"
                print "wwind_direction - нормализованный для шрифта ConkyWind wind_direction\n"
                print "wind_velocity - скорость ветра (м/сек)\n"
                print "falls - тип осадков (0 - отсутствие осадков, 1 - дождь, 2 - дождь со снегом, 3 - снег)\n"
                print "ffalls - нормализованный для шрифта ConkyWeather falls\n"
                print "drops - коэффициент количества снежинок или капель дождя для визуализации. Возможные значения: 0.5, 1, 2, 3, 4, 5, 6, 7, 8. На сайте rp5.ua drops умножается на 2. Тогда при drops = 0.5 нужно изобразить одну каплю или снежинку, при drops = 8 - шестнадцать капель или снежинок"
def main():
        Weather("http://rp5.ua/xml/528/00000/ru")

if __name__ == '__main__':
        main()
 
 
 
ConkyWeather.tar.bz2 (3.8 КБ)  

Комментариев нет:

Отправить комментарий