Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /*
- * Weather extension for Gnome shell
- * - Displays a small weather information on the top panel
- * - On click, gives a popup with details about the weather
- Copyright (C) 2011
- ecyrbe <[email protected]>
- Timur Kristóf <[email protected]>,
- Elad Alfassa <[email protected]>,
- Simon Legner <[email protected]>
- This file is part of gnome-shell-extension-weather.
- gnome-shell-extension-weather 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.
- gnome-shell-extension-weather 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 gnome-shell-extension-weather. If not, see <http://www.gnu.org/licenses/>.
- */
- const GLib = imports.gi.GLib;
- const Gio = imports.gi.Gio;
- const Lang = imports.lang;
- const Mainloop = imports.mainloop;
- const Cairo = imports.cairo;
- const Clutter = imports.gi.Clutter;
- const Shell = imports.gi.Shell;
- const St = imports.gi.St;
- const Gettext = imports.gettext.domain('gnome-shell');
- const _ = Gettext.gettext;
- const Json = imports.gi.Json;
- const Main = imports.ui.main;
- const PanelMenu = imports.ui.panelMenu;
- const PopupMenu = imports.ui.popupMenu;
- const Soup = imports.gi.Soup;
- const Util = imports.misc.util;
- const UNITS = 'c'; // Units for temperature (case sensitive). f: Fahrenheit. c: Celsius
- const YAHOO_ID = 'FRXX6724'; // PUT your YAHOO ZIP code here
- const WEATHER_URL = 'http://weather.yahooapis.com/forecastjson?u=' + UNITS + '&p=' + YAHOO_ID;
- const FORECAST_URL = 'http://query.yahooapis.com/v1/public/yql?format=json&q=select%20item.forecast%20from%20weather.forecast%20where%20location%3D%22' + YAHOO_ID + '%22%20%20and%20u="' + UNITS + '"';
- function WeatherMenuButton() {
- this._init();
- }
- WeatherMenuButton.prototype = {
- __proto__: PanelMenu.Button.prototype,
- _init: function() {
- // Panel icon
- this._weatherIcon = new St.Icon({
- icon_type: St.IconType.FULLCOLOR,
- icon_size: Main.panel.button.get_child().height - 4,
- icon_name: 'view-refresh-symbolic',
- style_class: 'weather-icon' + (Main.panel.actor.get_direction() == St.TextDirection.RTL ? '-rtl' : '')
- });
- // Label
- this._weatherInfo = new St.Label({ text: _('...') });
- // Panel menu item - the current class
- let menuAlignment = 0.25;
- if (St.Widget.get_default_direction() == St.TextDirection.RTL)
- menuAlignment = 1.0 - menuAlignment;
- PanelMenu.Button.prototype._init.call(this, menuAlignment);
- // Putting the panel item together
- let topBox = new St.BoxLayout();
- topBox.add_actor(this._weatherIcon);
- topBox.add_actor(this._weatherInfo);
- this.actor.set_child(topBox);
- Main.panel._centerBox.add(this.actor, { y_fill: true });
- // Current weather
- this._currentWeather = new St.Bin({style_class: 'current'});
- // Future weather
- this._futureWeather = new St.Bin({style_class: 'forecast'/*, x_align: St.Align.START*/});
- // Separator (copied from Gnome shell's popupMenu.js)
- this._separatorArea = new St.DrawingArea({ style_class: 'popup-separator-menu-item' });
- this._separatorArea.width = 200;
- this._separatorArea.connect('repaint', Lang.bind(this, this._onSeparatorAreaRepaint));
- // Putting the popup item together
- let mainBox = new St.BoxLayout({vertical: true});
- mainBox.add_actor(this._currentWeather);
- mainBox.add_actor(this._separatorArea);
- mainBox.add_actor(this._futureWeather);
- this.menu.addActor(mainBox);
- // Items
- this.showLoadingUi();
- this.rebuildCurrentWeatherUi();
- this.rebuildFutureWeatherUi();
- // Show weather
- here = this;
- Mainloop.timeout_add(3000, function() {
- here.refreshWeather();
- });
- },
- get_weather_icon: function(code) {
- switch (parseInt(code, 10)){
- case 4:
- return 'weather-storm';
- case 5:
- case 10:
- case 11:
- case 12:
- case 39:
- case 40:
- return 'weather-showers';
- case 26:
- return 'weather-overcast';
- case 28:
- case 30:
- case 44:
- return 'weather-few-clouds';
- case 32:
- case 34:
- case 36:
- return 'weather-clear';
- default:
- return 'weather-snow';
- }
- },
- get_weather_condition: function(code) {
- switch (parseInt(code,10)){
- case 0 : return 'Tornade';
- case 1 : return 'Tempete tropicale';
- case 2 : return 'Ouragan';
- case 3 : return 'Orage severe';
- case 4 : return 'Orage';
- case 5 : return 'Neige et pluie';
- case 6 : return 'Pluie et grele';
- case 7 : return 'Neige et grele';
- case 8 : return 'Pluie fine froides';
- case 9 : return 'Pluie fine';
- case 10: return 'Pluie verglassante';
- case 11 :
- case 12 : return 'Averses';
- case 13 :
- case 14 :
- case 15 :
- case 16 : return 'Neige';
- case 17 : return 'Grele';
- case 18 : return 'Neige fondue';
- case 19 : return 'Poussière';
- case 20 : return 'Brouillard';
- case 21 : return 'Brume';
- case 22 : return 'Polution';
- case 23 : return 'Bourrasques de vent';
- case 24 : return 'Venteux';
- case 25 : return 'Froid';
- case 26 :
- case 27 :
- case 28 :
- case 29 :
- case 30 : return 'Nuageux';
- case 31 : return 'Degage';
- case 32 : return 'Ensoleille'
- case 33 :
- case 34 : return 'Beau temps'
- case 35 : return 'Pluie et grele'
- case 36 : return 'Chaud';
- case 37 :
- case 38 :
- case 39 : return 'Eclairs orageux';
- case 40 : return 'Pluie et Eclaicies';
- case 41 :
- case 42 :
- case 43 : return 'Tempete de neige';
- case 44 : return 'Eclaicies';
- case 45 : return 'Orages';
- case 46 : return 'Tempête de neige';
- case 47 : return 'Orages intermittant';
- default: return 'Inconnu';
- }
- },
- load_json: function(url) {
- var session = new Soup.SessionSync();
- var message = Soup.Message.new('GET', url);
- stat = session.send_message(message);
- jp = new Json.Parser();
- jp.load_from_data(message.response_body.data, -1);
- return jp.get_root();
- },
- load_json_async: function(url, fun) {
- here = this;
- let session = new Soup.SessionAsync();
- let message = Soup.Message.new('GET', url);
- session.queue_message(message, function(session, message) {
- jp = new Json.Parser();
- jp.load_from_data(message.response_body.data, -1);
- fun.call(here, jp.get_root().get_object());
- });
- },
- refreshWeather: function() {
- // Refresh current weather
- this.load_json_async(WEATHER_URL, function(weather) {
- let location = weather.get_object_member('location').get_string_member('city');
- let comment = this.get_weather_condition(weather.get_object_member('condition').get_string_member('code')); //weather.get_object_member('condition').get_string_member('text');
- let temperature = weather.get_object_member('condition').get_double_member('temperature');
- let temperature_unit = weather.get_object_member('units').get_string_member('temperature');
- let humidity = weather.get_object_member('atmosphere').get_string_member('humidity') + ' %';
- let pressure = weather.get_object_member('atmosphere').get_double_member('pressure');
- pressure_unit = weather.get_object_member('units').get_string_member('pressure');
- let wind_direction = weather.get_object_member('wind').get_string_member('direction');
- let wind = weather.get_object_member('wind').get_double_member('speed');
- wind_unit = weather.get_object_member('units').get_string_member('speed');
- let iconname = this.get_weather_icon(weather.get_object_member('condition').get_string_member('code'));
- this._currentWeatherIcon.icon_name = this._weatherIcon.icon_name = iconname;
- this._weatherInfo.text = (temperature + ' ' + temperature_unit);
- this._currentWeatherSummary.text = comment;
- this._currentWeatherLocation.text = location;
- this._currentWeatherTemperature.text = temperature + ' ' + temperature_unit;
- this._currentWeatherHumidity.text = humidity;
- this._currentWeatherPressure.text = pressure + ' ' + pressure_unit;
- this._currentWeatherWind.text = wind + ' ' + wind_unit;
- });
- // Refresh forecast
- this.load_json_async(FORECAST_URL, function(forecast) {
- date_string = ['Ajourd\'hui', 'Demain'];
- forecast2 = forecast.get_object_member('query').get_object_member('results').get_array_member('channel').get_elements();
- for (let i = 0; i <= 1; i++) {
- let forecastUi = this._forecast[i];
- let forecastData = forecast2[i].get_object().get_object_member('item').get_object_member('forecast');
- let code = forecastData.get_string_member('code');
- let comment = this.get_weather_condition(code);//forecastData.get_string_member('text');
- let t_low = forecastData.get_string_member('low');
- let t_high = forecastData.get_string_member('high');
- forecastUi.Day.text = date_string[i]; //+ ' (' + forecastData.get_string_member('day') + ')';
- forecastUi.Temperature.text = t_low + '\u2013' + t_high + ' ' + UNITS.toUpperCase();
- forecastUi.Summary.text = comment;
- forecastUi.Icon.icon_name = this.get_weather_icon(code);
- }
- });
- // Repeatedly refresh weather
- Mainloop.timeout_add_seconds(60*4, Lang.bind(this, this.refreshWeather));
- },
- destroyCurrentWeather: function() {
- if (this._currentWeather.get_child() != null)
- this._currentWeather.get_child().destroy();
- },
- destroyFutureWeather: function() {
- if (this._futureWeather.get_child() != null)
- this._futureWeather.get_child().destroy();
- },
- showLoadingUi: function() {
- this.destroyCurrentWeather();
- this.destroyFutureWeather();
- this._currentWeather.set_child(new St.Label({ text: _('Loading current weather ...') }));
- this._futureWeather.set_child(new St.Label({ text: _('Loading future weather ...') }));
- },
- rebuildCurrentWeatherUi: function() {
- this.destroyCurrentWeather();
- // This will hold the icon for the current weather
- this._currentWeatherIcon = new St.Icon({
- icon_type: St.IconType.FULLCOLOR,
- icon_size: 64,
- icon_name: 'view-refresh-symbolic',
- style_class: 'weather-current-icon'
- });
- // The summary of the current weather
- this._currentWeatherSummary = new St.Label({
- text: _('Loading ...'),
- style_class: 'weather-current-summary'
- });
- this._currentWeatherLocation = new St.Label({ text: _('Please wait') });
- let bb = new St.BoxLayout({vertical: true, style_class: 'weather-current-summarybox'});
- bb.add_actor(this._currentWeatherLocation);
- bb.add_actor(this._currentWeatherSummary);
- // Other labels
- this._currentWeatherTemperature = new St.Label({ text: '...' });
- this._currentWeatherHumidity = new St.Label({ text: '...' });
- this._currentWeatherPressure = new St.Label({ text: '...' });
- this._currentWeatherWind = new St.Label({ text: '...' });
- let rb = new St.BoxLayout({style_class: 'weather-current-databox'});
- rb_captions = new St.BoxLayout({vertical: true, style_class: 'weather-current-databox-captions'});
- rb_values = new St.BoxLayout({vertical: true, style_class: 'weather-current-databox-values'});
- rb.add_actor(rb_captions);
- rb.add_actor(rb_values);
- rb_captions.add_actor(new St.Label({text: _('Temperature:')}));
- rb_values.add_actor(this._currentWeatherTemperature);
- rb_captions.add_actor(new St.Label({text: _('Humidite:')}));
- rb_values.add_actor(this._currentWeatherHumidity);
- rb_captions.add_actor(new St.Label({text: _('Pression:')}));
- rb_values.add_actor(this._currentWeatherPressure);
- rb_captions.add_actor(new St.Label({text: _('Vent:')}));
- rb_values.add_actor(this._currentWeatherWind);
- let xb = new St.BoxLayout();
- xb.add_actor(bb);
- xb.add_actor(rb);
- let box = new St.BoxLayout({style_class: 'weather-current-iconbox'});
- box.add_actor(this._currentWeatherIcon);
- box.add_actor(xb);
- this._currentWeather.set_child(box);
- },
- rebuildFutureWeatherUi: function() {
- this.destroyFutureWeather();
- this._forecast = [];
- this._forecastBox = new St.BoxLayout();
- this._futureWeather.set_child(this._forecastBox);
- for (let i = 0; i <= 1; i++) {
- let forecastWeather = {};
- forecastWeather.Icon = new St.Icon({
- icon_type: St.IconType.FULLCOLOR,
- icon_size: 48,
- icon_name: 'view-refresh-symbolic',
- style_class: 'weather-forecast-icon'
- });
- forecastWeather.Day = new St.Label({style_class: 'weather-forecast-day'});
- forecastWeather.Summary = new St.Label({style_class: 'weather-forecast-summary'});
- forecastWeather.Temperature = new St.Label({style_class: 'weather-forecast-temperature'});
- let by = new St.BoxLayout({vertical: true, style_class: 'weather-forecast-databox'});
- by.add_actor(forecastWeather.Day);
- by.add_actor(forecastWeather.Summary);
- by.add_actor(forecastWeather.Temperature);
- let bb = new St.BoxLayout({style_class: 'weather-forecast-box'});
- bb.add_actor(forecastWeather.Icon);
- bb.add_actor(by);
- this._forecast[i] = forecastWeather;
- this._forecastBox.add_actor(bb);
- }
- },
- // Copied from Gnome shell's popupMenu.js
- _onSeparatorAreaRepaint: function(area) {
- let cr = area.get_context();
- let themeNode = area.get_theme_node();
- let [width, height] = area.get_surface_size();
- let margin = themeNode.get_length('-margin-horizontal');
- let gradientHeight = themeNode.get_length('-gradient-height');
- let startColor = themeNode.get_color('-gradient-start');
- let endColor = themeNode.get_color('-gradient-end');
- let gradientWidth = (width - margin * 2);
- let gradientOffset = (height - gradientHeight) / 2;
- let pattern = new Cairo.LinearGradient(margin, gradientOffset, width - margin, gradientOffset + gradientHeight);
- pattern.addColorStopRGBA(0, startColor.red / 255, startColor.green / 255, startColor.blue / 255, startColor.alpha / 255);
- pattern.addColorStopRGBA(0.5, endColor.red / 255, endColor.green / 255, endColor.blue / 255, endColor.alpha / 255);
- pattern.addColorStopRGBA(1, startColor.red / 255, startColor.green / 255, startColor.blue / 255, startColor.alpha / 255);
- cr.setSource(pattern);
- cr.rectangle(margin, gradientOffset, gradientWidth, gradientHeight);
- cr.fill();
- }
- };
- function main() {
- this._weatherMenu = new WeatherMenuButton();
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement