[gnome-shell/wip/fmuellner/calendar-refresh: 3/15] weather: Add WeatherClient
- From: Florian Müllner <fmuellner src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-shell/wip/fmuellner/calendar-refresh: 3/15] weather: Add WeatherClient
- Date: Mon, 27 Feb 2017 21:38:55 +0000 (UTC)
commit 666cb7250904f221f0e5425ba4a27e06a5974720
Author: Florian Müllner <fmuellner gnome org>
Date: Thu Feb 23 22:55:33 2017 +0100
weather: Add WeatherClient
In preparation of integrating GNOME Weather, add a helper class that
retrieves weather information according to Weather's configuration
if the application is installed.
https://bugzilla.gnome.org/show_bug.cgi?id=754031
js/js-resources.gresource.xml | 1 +
js/ui/weather.js | 178 +++++++++++++++++++++++++++++++++++++++++
2 files changed, 179 insertions(+), 0 deletions(-)
---
diff --git a/js/js-resources.gresource.xml b/js/js-resources.gresource.xml
index 72cc4f8..0a70b3a 100644
--- a/js/js-resources.gresource.xml
+++ b/js/js-resources.gresource.xml
@@ -96,6 +96,7 @@
<file>ui/unlockDialog.js</file>
<file>ui/userWidget.js</file>
<file>ui/viewSelector.js</file>
+ <file>ui/weather.js</file>
<file>ui/windowAttentionHandler.js</file>
<file>ui/windowMenu.js</file>
<file>ui/windowManager.js</file>
diff --git a/js/ui/weather.js b/js/ui/weather.js
new file mode 100644
index 0000000..5a621a2
--- /dev/null
+++ b/js/ui/weather.js
@@ -0,0 +1,178 @@
+// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
+
+const Geoclue = imports.gi.Geoclue;
+const Gio = imports.gi.Gio;
+const GWeather = imports.gi.GWeather;
+const Lang = imports.lang;
+const Signals = imports.signals;
+
+const Util = imports.misc.util;
+
+const WeatherClient = new Lang.Class({
+ Name: 'WeatherClient',
+
+ _init: function() {
+ this._loading = false;
+
+ this._useAutoLocation = false;
+ this._mostRecentLocation = null;
+
+ this._gclueService = null;
+ this._gclueStarted = false;
+ this._gclueFailed = false;
+ this._gclueLocationChangedId = 0;
+
+ this._world = GWeather.Location.get_world();
+
+ let providers = GWeather.Provider.METAR |
+ GWeather.Provider.YR_NO |
+ GWeather.Provider.OWM;
+ this._weatherInfo = new GWeather.Info({ enabled_providers: providers });
+ this._weatherInfo.connect('updated', () => { this.emit('changed'); });
+
+ this._weatherAppMon = new Util.AppSettingsMonitor('org.gnome.Weather.Application.desktop',
+ 'org.gnome.Weather.Application');
+ this._weatherAppMon.connect('available-changed', () => { this.emit('changed'); });
+ this._weatherAppMon.watchSetting('automatic-location',
+ Lang.bind(this, this._onAutomaticLocationChanged));
+ this._weatherAppMon.watchSetting('locations',
+ Lang.bind(this, this._onLocationsChanged));
+ },
+
+ get available() {
+ return this._weatherAppMon.available;
+ },
+
+ get loading() {
+ return this._loading;
+ },
+
+ get info() {
+ return this._weatherInfo;
+ },
+
+ activateApp: function() {
+ this._weatherAppMon.activateApp();
+ },
+
+ update: function() {
+ this._loadInfo();
+ },
+
+ _loadInfo: function() {
+ let id = this._weatherInfo.connect('updated', () => {
+ this._weatherInfo.disconnect(id);
+
+ this._loading = false;
+ this.emit('changed');
+ });
+
+ this._loading = true;
+ this.emit('changed');
+
+ this._weatherInfo.update();
+ },
+
+ _locationsEqual: function(loc1, loc2) {
+ if (loc1 == loc2)
+ return true;
+
+ if (loc1 == null || loc2 == null)
+ return false;
+
+ return loc1.equal(loc2);
+ },
+
+ _setLocation: function(location) {
+ if (this._locationsEqual(this._weatherInfo.location, location))
+ return;
+
+ this._weatherInfo.abort();
+ this._weatherInfo.set_location(location);
+
+ if (location)
+ this._loadInfo();
+ else
+ this.emit('changed');
+ },
+
+ _updateLocationMonitoring: function() {
+ if (this._useAutoLocation) {
+ if (this._gclueLocationChangedId != 0 || this._gclueService == null)
+ return;
+
+ this._gclueLocationChangedId =
+ this._gclueService.connect('notify::location',
+ Lang.bind(this, this._onGClueLocationChanged));
+ this._onGClueLocationChanged();
+ } else {
+ if (this._gclueLocationChangedId)
+ this._gclueService.disconnect(this._gclueLocationChangedId);
+ this._gclueLocationChangedId = 0;
+ }
+ },
+
+ _startGClueService: function() {
+ if (this._gclueStarted)
+ return;
+
+ this._gclueStarted = true;
+ Geoclue.Simple.new('org.gnome.Shell', Geoclue.AccuracyLevel.CITY, null,
+ (o, res) => {
+ try {
+ this._gclueService = Geoclue.Simple.new_finish(res);
+ } catch(e) {
+ log('Failed to connect to Geoclue2 service: ' + e.message);
+ this._gclueFailed = true;
+ this._setLocation(this._mostRecentLocation);
+ return;
+ }
+
+ this._gclueService.get_client().distance_threshold = 100;
+ this._updateLocationMonitoring();
+ });
+ },
+
+ _onGClueLocationChanged: function() {
+ let geoLocation = this._gclueService.location;
+ let location = GWeather.Location.new_detached(geoLocation.description,
+ null,
+ geoLocation.latitude,
+ geoLocation.longitude);
+ this._setLocation(location);
+ },
+
+ _onAutomaticLocationChanged: function(settings, key) {
+ let useAutoLocation = settings.get_boolean(key);
+ if (this._useAutoLocation == useAutoLocation)
+ return;
+
+ this._useAutoLocation = useAutoLocation;
+
+ this._updateLocationMonitoring();
+
+ if (this._useAutoLocation) {
+ if (!this._gclueStarted)
+ this._startGClueService();
+ } else {
+ this._setLocation(this._mostRecentLocation);
+ }
+ },
+
+ _onLocationsChanged: function(settings, key) {
+ let serialized = settings.get_value(key).deep_unpack().shift();
+ let mostRecentLocation = null;
+
+ if (serialized)
+ mostRecentLocation = this._world.deserialize(serialized);
+
+ if (this._locationsEqual(this._mostRecentLocation, mostRecentLocation))
+ return;
+
+ this._mostRecentLocation = mostRecentLocation;
+
+ if (!this._useAutoLocation || this._gclueFailed)
+ this._setLocation(this._mostRecentLocation);
+ }
+});
+Signals.addSignalMethods(WeatherClient.prototype);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]