Skip to content

Commit

Permalink
Version 16 (#37)
Browse files Browse the repository at this point in the history
* initial gnome 43+ support, add CodeQL
* fix lint errors and warnings, and metadata
* SessionAsync is deprecated
* wrap some first run errors
  • Loading branch information
neffo authored Nov 20, 2022
1 parent 9991b4b commit 869b0f4
Show file tree
Hide file tree
Showing 8 changed files with 242 additions and 95 deletions.
3 changes: 2 additions & 1 deletion .eslintrc.yml
Original file line number Diff line number Diff line change
Expand Up @@ -197,7 +197,8 @@ rules:
prefer-arrow-callback: 'off'
prefer-const: 'off'
prefer-destructuring: 'off'
prefer-named-capture-group: error
prefer-named-capture-group: 'warn'
no-cond-assign: 'warn'
prefer-numeric-literals: error
prefer-object-spread: error
prefer-promise-reject-errors: error
Expand Down
74 changes: 74 additions & 0 deletions .github/workflows/codeql-analysis.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
# For most projects, this workflow file will not need changing; you simply need
# to commit it to your repository.
#
# You may wish to alter this file to override the set of languages analyzed,
# or to provide custom queries or build logic.
#
# ******** NOTE ********
# We have attempted to detect the languages in your repository. Please check
# the `language` matrix defined below to confirm you have the correct set of
# supported CodeQL languages.
#
name: "CodeQL"

on:
push:
branches: [ "master" ]
pull_request:
# The branches below must be a subset of the branches above
branches: [ "master" ]
schedule:
- cron: '15 1 * * 2'

jobs:
analyze:
name: Analyze
runs-on: ubuntu-latest
permissions:
actions: read
contents: read
security-events: write

strategy:
fail-fast: false
matrix:
language: [ 'javascript' ]
# CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python', 'ruby' ]
# Learn more about CodeQL language support at https://aka.ms/codeql-docs/language-support

steps:
- name: Checkout repository
uses: actions/checkout@v3

# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
uses: github/codeql-action/init@v2
with:
languages: ${{ matrix.language }}
# If you wish to specify custom queries, you can do so here or in a config file.
# By default, queries listed here will override any specified in a config file.
# Prefix the list here with "+" to use these queries and those in the config file.

# Details on CodeQL's query packs refer to : https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning#using-queries-in-ql-packs
# queries: security-extended,security-and-quality


# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
# If this step fails, then you should remove it and run the build manually (see below)
- name: Autobuild
uses: github/codeql-action/autobuild@v2

# ℹ️ Command-line programs to run using the OS shell.
# 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun

# If the Autobuild fails above, remove it and uncomment the following three lines.
# modify them (or add more) to build your code if your project, please refer to the EXAMPLE below for guidance.

# - run: |
# echo "Run, Build Application using script"
# ./location_of_script_within_repo/buildscript.sh

- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v2
with:
category: "/language:${{matrix.language}}"
2 changes: 1 addition & 1 deletion convenience.js
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ function versionSmaller(a, b) {
}

function currentVersion() {
return ''+Config.PACKAGE_VERSION.replace(/(alpha|beta)/,'0');
return String(Config.PACKAGE_VERSION.replace(/(alpha|beta|rc)/,'0'));
}

function currentVersionEqual(v) {
Expand Down
121 changes: 88 additions & 33 deletions extension.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
const {St, Soup, Gio, GLib, Clutter, GObject} = imports.gi;
const {main, panelMenu, popupMenu, messageTray} = imports.ui;
const Util = imports.misc.util;
const ByteArray = imports.byteArray;

const ExtensionUtils = imports.misc.extensionUtils;
const Me = ExtensionUtils.getCurrentExtension();
Expand All @@ -23,11 +24,9 @@ const Gettext = imports.gettext.domain('GoogleEarthWallpaper');
const _ = Gettext.gettext;

const GEjsonURL = "https://www.gstatic.com/prettyearth/assets/data/v3/"; // previously was v2
const GEURL = "https://earth.google.com";
const IndicatorName = "GEWallpaperIndicator";
const TIMEOUT_SECONDS = 24 * 3600; // FIXME: this should use the end data from the json data
const TIMEOUT_SECONDS_ON_HTTP_ERROR = 4 * 3600; // retry in one hour if there is a http error
const ICON = "pin";

const providerNames = ['Google Earth', 'Google Maps', 'Bing Maps', 'OpenStreetMap' , 'GNOME Maps'];
let googleearthWallpaperIndicator=null;
Expand Down Expand Up @@ -82,21 +81,18 @@ class GEWallpaperIndicator extends panelMenu.Button {
this.link = "https://earthview.withgoogle.com/";
this.imageid = 0;
this.refreshdue = 0; // UNIX timestamp when next refresh is due
this.httpSession = new Soup.SessionAsync();
Soup.Session.prototype.add_feature.call(this.httpSession, new Soup.ProxyResolverDefault());
this.httpSession = null;

// create libSoup session for http requests
this._initSoup();

this._settings.connect('changed::hide', () => {
getActorCompat(this).visible = !this._settings.get_boolean('hide');
});
getActorCompat(this).visible = !this._settings.get_boolean('hide');

this._settings.connect('changed::map-link-provider', this._updateProviderLink.bind(this));
this._settings.connect('changed::notify', this._notifyCurrentImage.bind(this));

getActorCompat(this).add_child(this.icon);
this._setIcon();
// watch for indicator icon settings changes
this._settings.connect('changed::icon', this._setIcon.bind(this));

this.refreshDueItem = new popupMenu.PopupMenuItem(_("<No refresh scheduled>"));
this.descriptionItem = new popupMenu.PopupMenuItem(_("Text Location"));
Expand All @@ -107,6 +103,8 @@ class GEWallpaperIndicator extends panelMenu.Button {
this.swallpaperItem = new popupMenu.PopupMenuItem(_("Set lockscreen image now"));
this.refreshItem = new popupMenu.PopupMenuItem(_("Refresh Now"));
this.settingsItem = new popupMenu.PopupMenuItem(_("Extension settings"));

// force word wrapping for potentially long menu items
this._wrapLabelItem(this.descriptionItem);
this._wrapLabelItem(this.copyrightItem);

Expand All @@ -130,27 +128,25 @@ class GEWallpaperIndicator extends panelMenu.Button {
this.descriptionItem.setSensitive(false);
this.copyrightItem.setSensitive(false);
this.locationItem.setSensitive(false);

this.extLinkItem.connect('activate', this._open_link.bind(this));
this.dwallpaperItem.connect('activate', this._setDesktopBackground.bind(this));

if (!Convenience.currentVersionGreaterEqual("3.36")) { // lockscreen and desktop wallpaper are the same in GNOME 3.36+
this.swallpaperItem.connect('activate', this._setLockscreenBackground.bind(this));
this.menu.addMenuItem(this.swallpaperItem);
}
this.menu.addMenuItem(new popupMenu.PopupSeparatorMenuItem());
this.refreshItem.connect('activate', this._refresh.bind(this));
this.settingsItem.connect('activate', this._openPrefs.bind(this));
this.menu.addMenuItem(new popupMenu.PopupMenuItem(_("On refresh:"), {reactive : false} ));
this.menu.addMenuItem(this.wallpaperToggle);
if (!Convenience.currentVersionGreaterEqual("3.36")) { // lockscreen and desktop wallpaper are the same in GNOME 3.36+
this.menu.addMenuItem(this.lockscreenToggle);
}
this.menu.addMenuItem(this.notifyToggle);
this.menu.addMenuItem(new popupMenu.PopupSeparatorMenuItem());
this.menu.addMenuItem(this.settingsItem);

getActorCompat(this).connect('button-press-event', this._updateMenu.bind(this));
this.menu.addMenuItem(this.settingsItem);

// connect menu items and settings changes to functions
this._setMenuConnections();

// persistance of notification interval
if (this._settings.get_int('next-refresh') > 0 ) {
this._restorePreviousState();
}
Expand All @@ -160,6 +156,33 @@ class GEWallpaperIndicator extends panelMenu.Button {
}
}

// create soup Session
_initSoup() {
this.httpSession = new Soup.Session();
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;

}

_setMenuConnections() {
// update link to map of location
this._settings.connect('changed::map-link-provider', this._updateProviderLink.bind(this));

// on notification toggle change immediately create a notification
this._settings.connect('changed::notify', this._notifyCurrentImage.bind(this));

// watch for indicator icon settings changes (including hiding indicator)
this._settings.connect('changed::icon', this._setIcon.bind(this));

// connect menu items clicks to functions
this.extLinkItem.connect('activate', this._open_link.bind(this));
this.dwallpaperItem.connect('activate', this._setDesktopBackground.bind(this));
this.refreshItem.connect('activate', this._refresh.bind(this));
this.settingsItem.connect('activate', this._openPrefs.bind(this));

// update menu when user clicks button
getActorCompat(this).connect('button-press-event', this._updateMenu.bind(this));
}

_open_link () {
Util.spawn(["xdg-open", this.link]);
}
Expand Down Expand Up @@ -201,9 +224,9 @@ class GEWallpaperIndicator extends panelMenu.Button {
// update menu text
this.refreshDueItem.label.set_text(_('Next refresh')+': '+this.refreshdue.format('%X')+' ('+Utils.friendly_time_diff(this.refreshdue)+')');
this.locationItem.label.set_text(Utils.friendly_coordinates(this.lat, this.lon));
this.descriptionItem.label.set_text(this.explanation);
this.copyrightItem.label.set_text(this.copyright);
this.extLinkItem.label.set_text(this.provider_text);
this.descriptionItem.label.set_text(this._ifString(this.explanation));
this.copyrightItem.label.set_text(this._ifString(this.copyright));
this.extLinkItem.label.set_text(this._ifString(this.provider_text));
}

_notifyCurrentImage() {
Expand Down Expand Up @@ -287,6 +310,9 @@ class GEWallpaperIndicator extends panelMenu.Button {
return widget;
}

_ifString(check) {
return (typeof check === 'string' || check instanceof String)?check:'';
}

_restartTimeout(seconds = null) {
if (this._timeout)
Expand All @@ -308,29 +334,50 @@ class GEWallpaperIndicator extends panelMenu.Button {
this._restartTimeout(300); // in case of a timeout
this.refreshDueItem.label.set_text(_('Fetching...'));

// pick random image to fetch
log('locations count: '+Images.imageids.length);
// create an http message
let imgindex = GLib.random_int_range(0,Images.imageids.length);

// create an http message
let url = GEjsonURL+Images.imageids[imgindex]+'.json';
log("fetching: " + url);
let request = Soup.Message.new('GET', url);
request.request_headers.append('Accept', 'application/json');

// queue the http request
this.httpSession.queue_message(request, this._http_process_message.bind(this));
if (Soup.MAJOR_VERSION >= 3) { // soup3 changes this significantly
try {
this.httpSession.send_and_read_async(request, GLib.PRIORITY_DEFAULT, null, this._http_process_message.bind(this));
}
catch(error) {
log('unable to send libsoup json message '+error);
}
}
else {
try {
this.httpSession.queue_message(request, this._http_process_message.bind(this));
}
catch(error) {
log('unable to send libsoup json message '+error);
}
}
}

_http_process_message(httpSession, message) {
if (message.status_code == 200) {
log("Datatype: "+message.response_headers.get_content_type());
let data = message.response_body.data;
try {
let data;
if (Soup.MAJOR_VERSION >= 3) {
data = ByteArray.toString(this.httpSession.send_and_read_finish(message).get_data());
}
else {
log("Datatype: "+message.response_headers.get_content_type());
data = message.response_body.data;
}
log("Recieved "+data.length+" bytes");
this._parseData(data);
} else if (message.status_code == 403) {
log("Access denied: "+message.status_code);
this._updatePending = false;
this._restartTimeout(TIMEOUT_SECONDS_ON_HTTP_ERROR);
} else {
log("Network error occured: "+message.status_code);
}
catch (error) {
log("Network error occured: "+error);
this._updatePending = false;
this._restartTimeout(TIMEOUT_SECONDS_ON_HTTP_ERROR);
}
Expand All @@ -342,13 +389,14 @@ class GEWallpaperIndicator extends panelMenu.Button {
if (imagejson.id != '') {
this.title = _("Google Earth Wallpaper");
let location = "";

if ('geocode' in imagejson) {
//location = imagejson.geocode.administrative_area_level_1 +', '+imagejson.geocode.country;
location = Object.values(imagejson.geocode).join(", ");
} else {
location = [imagejson.region,imagejson.country].filter(Boolean).join(', ');
}
let coordinates = Utils.friendly_coordinates(imagejson.lat,imagejson.lng);

this.explanation = location.trim(); // + '\n'+ coordinates;
this.copyright = imagejson.attribution;
this.lat = imagejson.lat;
Expand All @@ -359,6 +407,7 @@ class GEWallpaperIndicator extends panelMenu.Button {

let GEWallpaperDir = this._settings.get_string('download-folder');
let userPicturesDir = GLib.get_user_special_dir(GLib.UserDirectory.DIRECTORY_PICTURES); // XDG pictures directory

if (GEWallpaperDir == '') {
GEWallpaperDir = userPicturesDir + "/GoogleEarthWallpaper/";
this._settings.set_string('download-folder',GEWallpaperDir);
Expand Down Expand Up @@ -386,19 +435,23 @@ class GEWallpaperIndicator extends panelMenu.Button {
this._setBackground();
this._updatePending = false;
}

this._settings.set_string('image-details',[
this.explanation.replace(/\|/gm, ''), // just incase (see below)
this.copyright.replace(/\|/gm, '&'), // i think copyright info uses | instead of &
this.lat.toString(),
this.lon.toString(),
this.zoom.toString()].join('|'));
this._settings.set_int('image-id',imagejson.id);
} else {
}
else {
log('refresh failed, no valid image returned');
this.title = _("No wallpaper available");
this.explanation = _("Something went wrong...");
this.filename = "";
this._updatePending = false;
}

this._updateMenu();
this._notifyCurrentImage();
this._restartTimeout(this._settings.get_int('refresh-interval'));
Expand All @@ -407,7 +460,9 @@ class GEWallpaperIndicator extends panelMenu.Button {
_delete_previous(to_delete) {
if (to_delete == '')
return;

let deletepictures = this._settings.get_boolean('delete-previous');

if (deletepictures) {
let oldfile = Gio.file_new_for_path(to_delete);
if (oldfile.query_exists(null)) {
Expand Down
Loading

0 comments on commit 869b0f4

Please sign in to comment.