12
12
const { St, Soup, Gio, GLib, Clutter, GObject} = imports . gi ;
13
13
const { main, panelMenu, popupMenu, messageTray} = imports . ui ;
14
14
const Util = imports . misc . util ;
15
+ const ByteArray = imports . byteArray ;
15
16
16
17
const ExtensionUtils = imports . misc . extensionUtils ;
17
18
const Me = ExtensionUtils . getCurrentExtension ( ) ;
@@ -23,11 +24,9 @@ const Gettext = imports.gettext.domain('GoogleEarthWallpaper');
23
24
const _ = Gettext . gettext ;
24
25
25
26
const GEjsonURL = "https://www.gstatic.com/prettyearth/assets/data/v3/" ; // previously was v2
26
- const GEURL = "https://earth.google.com" ;
27
27
const IndicatorName = "GEWallpaperIndicator" ;
28
28
const TIMEOUT_SECONDS = 24 * 3600 ; // FIXME: this should use the end data from the json data
29
29
const TIMEOUT_SECONDS_ON_HTTP_ERROR = 4 * 3600 ; // retry in one hour if there is a http error
30
- const ICON = "pin" ;
31
30
32
31
const providerNames = [ 'Google Earth' , 'Google Maps' , 'Bing Maps' , 'OpenStreetMap' , 'GNOME Maps' ] ;
33
32
let googleearthWallpaperIndicator = null ;
@@ -82,21 +81,18 @@ class GEWallpaperIndicator extends panelMenu.Button {
82
81
this . link = "https://earthview.withgoogle.com/" ;
83
82
this . imageid = 0 ;
84
83
this . refreshdue = 0 ; // UNIX timestamp when next refresh is due
85
- this . httpSession = new Soup . SessionAsync ( ) ;
86
- Soup . Session . prototype . add_feature . call ( this . httpSession , new Soup . ProxyResolverDefault ( ) ) ;
84
+ this . httpSession = null ;
85
+
86
+ // create libSoup session for http requests
87
+ this . _initSoup ( ) ;
87
88
88
89
this . _settings . connect ( 'changed::hide' , ( ) => {
89
90
getActorCompat ( this ) . visible = ! this . _settings . get_boolean ( 'hide' ) ;
90
91
} ) ;
91
92
getActorCompat ( this ) . visible = ! this . _settings . get_boolean ( 'hide' ) ;
92
-
93
- this . _settings . connect ( 'changed::map-link-provider' , this . _updateProviderLink . bind ( this ) ) ;
94
- this . _settings . connect ( 'changed::notify' , this . _notifyCurrentImage . bind ( this ) ) ;
95
93
96
94
getActorCompat ( this ) . add_child ( this . icon ) ;
97
95
this . _setIcon ( ) ;
98
- // watch for indicator icon settings changes
99
- this . _settings . connect ( 'changed::icon' , this . _setIcon . bind ( this ) ) ;
100
96
101
97
this . refreshDueItem = new popupMenu . PopupMenuItem ( _ ( "<No refresh scheduled>" ) ) ;
102
98
this . descriptionItem = new popupMenu . PopupMenuItem ( _ ( "Text Location" ) ) ;
@@ -107,6 +103,8 @@ class GEWallpaperIndicator extends panelMenu.Button {
107
103
this . swallpaperItem = new popupMenu . PopupMenuItem ( _ ( "Set lockscreen image now" ) ) ;
108
104
this . refreshItem = new popupMenu . PopupMenuItem ( _ ( "Refresh Now" ) ) ;
109
105
this . settingsItem = new popupMenu . PopupMenuItem ( _ ( "Extension settings" ) ) ;
106
+
107
+ // force word wrapping for potentially long menu items
110
108
this . _wrapLabelItem ( this . descriptionItem ) ;
111
109
this . _wrapLabelItem ( this . copyrightItem ) ;
112
110
@@ -130,27 +128,25 @@ class GEWallpaperIndicator extends panelMenu.Button {
130
128
this . descriptionItem . setSensitive ( false ) ;
131
129
this . copyrightItem . setSensitive ( false ) ;
132
130
this . locationItem . setSensitive ( false ) ;
133
-
134
- this . extLinkItem . connect ( 'activate' , this . _open_link . bind ( this ) ) ;
135
- this . dwallpaperItem . connect ( 'activate' , this . _setDesktopBackground . bind ( this ) ) ;
131
+
136
132
if ( ! Convenience . currentVersionGreaterEqual ( "3.36" ) ) { // lockscreen and desktop wallpaper are the same in GNOME 3.36+
137
133
this . swallpaperItem . connect ( 'activate' , this . _setLockscreenBackground . bind ( this ) ) ;
138
134
this . menu . addMenuItem ( this . swallpaperItem ) ;
139
135
}
140
136
this . menu . addMenuItem ( new popupMenu . PopupSeparatorMenuItem ( ) ) ;
141
- this . refreshItem . connect ( 'activate' , this . _refresh . bind ( this ) ) ;
142
- this . settingsItem . connect ( 'activate' , this . _openPrefs . bind ( this ) ) ;
143
137
this . menu . addMenuItem ( new popupMenu . PopupMenuItem ( _ ( "On refresh:" ) , { reactive : false } ) ) ;
144
138
this . menu . addMenuItem ( this . wallpaperToggle ) ;
145
139
if ( ! Convenience . currentVersionGreaterEqual ( "3.36" ) ) { // lockscreen and desktop wallpaper are the same in GNOME 3.36+
146
140
this . menu . addMenuItem ( this . lockscreenToggle ) ;
147
141
}
148
142
this . menu . addMenuItem ( this . notifyToggle ) ;
149
143
this . menu . addMenuItem ( new popupMenu . PopupSeparatorMenuItem ( ) ) ;
150
- this . menu . addMenuItem ( this . settingsItem ) ;
151
-
152
- getActorCompat ( this ) . connect ( 'button-press-event' , this . _updateMenu . bind ( this ) ) ;
144
+ this . menu . addMenuItem ( this . settingsItem ) ;
145
+
146
+ // connect menu items and settings changes to functions
147
+ this . _setMenuConnections ( ) ;
153
148
149
+ // persistance of notification interval
154
150
if ( this . _settings . get_int ( 'next-refresh' ) > 0 ) {
155
151
this . _restorePreviousState ( ) ;
156
152
}
@@ -160,6 +156,33 @@ class GEWallpaperIndicator extends panelMenu.Button {
160
156
}
161
157
}
162
158
159
+ // create soup Session
160
+ _initSoup ( ) {
161
+ this . httpSession = new Soup . Session ( ) ;
162
+ this . httpSession . user_agent = 'User-Agent: Mozilla/5.0 (GNOME Shell/' + imports . misc . config . PACKAGE_VERSION + '; Linux; +https://github.com/neffo/earth-view-wallpaper-gnome-extension ) Google Earth Wallpaper Gnome Extension/' + Me . metadata . version ;
163
+
164
+ }
165
+
166
+ _setMenuConnections ( ) {
167
+ // update link to map of location
168
+ this . _settings . connect ( 'changed::map-link-provider' , this . _updateProviderLink . bind ( this ) ) ;
169
+
170
+ // on notification toggle change immediately create a notification
171
+ this . _settings . connect ( 'changed::notify' , this . _notifyCurrentImage . bind ( this ) ) ;
172
+
173
+ // watch for indicator icon settings changes (including hiding indicator)
174
+ this . _settings . connect ( 'changed::icon' , this . _setIcon . bind ( this ) ) ;
175
+
176
+ // connect menu items clicks to functions
177
+ this . extLinkItem . connect ( 'activate' , this . _open_link . bind ( this ) ) ;
178
+ this . dwallpaperItem . connect ( 'activate' , this . _setDesktopBackground . bind ( this ) ) ;
179
+ this . refreshItem . connect ( 'activate' , this . _refresh . bind ( this ) ) ;
180
+ this . settingsItem . connect ( 'activate' , this . _openPrefs . bind ( this ) ) ;
181
+
182
+ // update menu when user clicks button
183
+ getActorCompat ( this ) . connect ( 'button-press-event' , this . _updateMenu . bind ( this ) ) ;
184
+ }
185
+
163
186
_open_link ( ) {
164
187
Util . spawn ( [ "xdg-open" , this . link ] ) ;
165
188
}
@@ -201,9 +224,9 @@ class GEWallpaperIndicator extends panelMenu.Button {
201
224
// update menu text
202
225
this . refreshDueItem . label . set_text ( _ ( 'Next refresh' ) + ': ' + this . refreshdue . format ( '%X' ) + ' (' + Utils . friendly_time_diff ( this . refreshdue ) + ')' ) ;
203
226
this . locationItem . label . set_text ( Utils . friendly_coordinates ( this . lat , this . lon ) ) ;
204
- this . descriptionItem . label . set_text ( this . explanation ) ;
205
- this . copyrightItem . label . set_text ( this . copyright ) ;
206
- this . extLinkItem . label . set_text ( this . provider_text ) ;
227
+ this . descriptionItem . label . set_text ( this . _ifString ( this . explanation ) ) ;
228
+ this . copyrightItem . label . set_text ( this . _ifString ( this . copyright ) ) ;
229
+ this . extLinkItem . label . set_text ( this . _ifString ( this . provider_text ) ) ;
207
230
}
208
231
209
232
_notifyCurrentImage ( ) {
@@ -287,6 +310,9 @@ class GEWallpaperIndicator extends panelMenu.Button {
287
310
return widget ;
288
311
}
289
312
313
+ _ifString ( check ) {
314
+ return ( typeof check === 'string' || check instanceof String ) ?check :'' ;
315
+ }
290
316
291
317
_restartTimeout ( seconds = null ) {
292
318
if ( this . _timeout )
@@ -308,29 +334,50 @@ class GEWallpaperIndicator extends panelMenu.Button {
308
334
this . _restartTimeout ( 300 ) ; // in case of a timeout
309
335
this . refreshDueItem . label . set_text ( _ ( 'Fetching...' ) ) ;
310
336
337
+ // pick random image to fetch
311
338
log ( 'locations count: ' + Images . imageids . length ) ;
312
- // create an http message
313
339
let imgindex = GLib . random_int_range ( 0 , Images . imageids . length ) ;
340
+
341
+ // create an http message
314
342
let url = GEjsonURL + Images . imageids [ imgindex ] + '.json' ;
315
343
log ( "fetching: " + url ) ;
316
344
let request = Soup . Message . new ( 'GET' , url ) ;
345
+ request . request_headers . append ( 'Accept' , 'application/json' ) ;
317
346
318
347
// queue the http request
319
- this . httpSession . queue_message ( request , this . _http_process_message . bind ( this ) ) ;
348
+ if ( Soup . MAJOR_VERSION >= 3 ) { // soup3 changes this significantly
349
+ try {
350
+ this . httpSession . send_and_read_async ( request , GLib . PRIORITY_DEFAULT , null , this . _http_process_message . bind ( this ) ) ;
351
+ }
352
+ catch ( error ) {
353
+ log ( 'unable to send libsoup json message ' + error ) ;
354
+ }
355
+ }
356
+ else {
357
+ try {
358
+ this . httpSession . queue_message ( request , this . _http_process_message . bind ( this ) ) ;
359
+ }
360
+ catch ( error ) {
361
+ log ( 'unable to send libsoup json message ' + error ) ;
362
+ }
363
+ }
320
364
}
321
365
322
366
_http_process_message ( httpSession , message ) {
323
- if ( message . status_code == 200 ) {
324
- log ( "Datatype: " + message . response_headers . get_content_type ( ) ) ;
325
- let data = message . response_body . data ;
367
+ try {
368
+ let data ;
369
+ if ( Soup . MAJOR_VERSION >= 3 ) {
370
+ data = ByteArray . toString ( this . httpSession . send_and_read_finish ( message ) . get_data ( ) ) ;
371
+ }
372
+ else {
373
+ log ( "Datatype: " + message . response_headers . get_content_type ( ) ) ;
374
+ data = message . response_body . data ;
375
+ }
326
376
log ( "Recieved " + data . length + " bytes" ) ;
327
377
this . _parseData ( data ) ;
328
- } else if ( message . status_code == 403 ) {
329
- log ( "Access denied: " + message . status_code ) ;
330
- this . _updatePending = false ;
331
- this . _restartTimeout ( TIMEOUT_SECONDS_ON_HTTP_ERROR ) ;
332
- } else {
333
- log ( "Network error occured: " + message . status_code ) ;
378
+ }
379
+ catch ( error ) {
380
+ log ( "Network error occured: " + error ) ;
334
381
this . _updatePending = false ;
335
382
this . _restartTimeout ( TIMEOUT_SECONDS_ON_HTTP_ERROR ) ;
336
383
}
@@ -342,13 +389,14 @@ class GEWallpaperIndicator extends panelMenu.Button {
342
389
if ( imagejson . id != '' ) {
343
390
this . title = _ ( "Google Earth Wallpaper" ) ;
344
391
let location = "" ;
392
+
345
393
if ( 'geocode' in imagejson ) {
346
394
//location = imagejson.geocode.administrative_area_level_1 +', '+imagejson.geocode.country;
347
395
location = Object . values ( imagejson . geocode ) . join ( ", " ) ;
348
396
} else {
349
397
location = [ imagejson . region , imagejson . country ] . filter ( Boolean ) . join ( ', ' ) ;
350
398
}
351
- let coordinates = Utils . friendly_coordinates ( imagejson . lat , imagejson . lng ) ;
399
+
352
400
this . explanation = location . trim ( ) ; // + '\n'+ coordinates;
353
401
this . copyright = imagejson . attribution ;
354
402
this . lat = imagejson . lat ;
@@ -359,6 +407,7 @@ class GEWallpaperIndicator extends panelMenu.Button {
359
407
360
408
let GEWallpaperDir = this . _settings . get_string ( 'download-folder' ) ;
361
409
let userPicturesDir = GLib . get_user_special_dir ( GLib . UserDirectory . DIRECTORY_PICTURES ) ; // XDG pictures directory
410
+
362
411
if ( GEWallpaperDir == '' ) {
363
412
GEWallpaperDir = userPicturesDir + "/GoogleEarthWallpaper/" ;
364
413
this . _settings . set_string ( 'download-folder' , GEWallpaperDir ) ;
@@ -386,19 +435,23 @@ class GEWallpaperIndicator extends panelMenu.Button {
386
435
this . _setBackground ( ) ;
387
436
this . _updatePending = false ;
388
437
}
438
+
389
439
this . _settings . set_string ( 'image-details' , [
390
440
this . explanation . replace ( / \| / gm, '' ) , // just incase (see below)
391
441
this . copyright . replace ( / \| / gm, '&' ) , // i think copyright info uses | instead of &
392
442
this . lat . toString ( ) ,
393
443
this . lon . toString ( ) ,
394
444
this . zoom . toString ( ) ] . join ( '|' ) ) ;
395
445
this . _settings . set_int ( 'image-id' , imagejson . id ) ;
396
- } else {
446
+ }
447
+ else {
448
+ log ( 'refresh failed, no valid image returned' ) ;
397
449
this . title = _ ( "No wallpaper available" ) ;
398
450
this . explanation = _ ( "Something went wrong..." ) ;
399
451
this . filename = "" ;
400
452
this . _updatePending = false ;
401
453
}
454
+
402
455
this . _updateMenu ( ) ;
403
456
this . _notifyCurrentImage ( ) ;
404
457
this . _restartTimeout ( this . _settings . get_int ( 'refresh-interval' ) ) ;
@@ -407,7 +460,9 @@ class GEWallpaperIndicator extends panelMenu.Button {
407
460
_delete_previous ( to_delete ) {
408
461
if ( to_delete == '' )
409
462
return ;
463
+
410
464
let deletepictures = this . _settings . get_boolean ( 'delete-previous' ) ;
465
+
411
466
if ( deletepictures ) {
412
467
let oldfile = Gio . file_new_for_path ( to_delete ) ;
413
468
if ( oldfile . query_exists ( null ) ) {
0 commit comments