RandomWallpaperGnome3/randomwallpaper@iflow.space/wallpaperController.js

336 lines
8.9 KiB
JavaScript
Raw Normal View History

const Mainloop = imports.gi.GLib;
// Filesystem
const Gio = imports.gi.Gio;
2016-04-08 16:40:52 +00:00
//self
const Self = imports.misc.extensionUtils.getCurrentExtension();
const SourceAdapter = Self.imports.sourceAdapter;
const Prefs = Self.imports.settings;
2017-02-24 22:31:35 +00:00
const Timer = Self.imports.timer;
2017-07-20 11:48:13 +00:00
const HistoryModule = Self.imports.history;
2016-04-08 16:40:52 +00:00
const LoggerModule = Self.imports.logger;
var WallpaperController = class {
2017-02-24 22:31:35 +00:00
constructor() {
this.logger = new LoggerModule.Logger('RWG3', 'WallpaperController');
this.wallpaperlocation = Self.path + '/wallpapers/';
this.imageSourceAdapter = null;
this._autoFetch = {
active: false,
duration: 30,
};
// functions will be called uppon loading a new wallpaper
this._startLoadingHooks = [];
// functions will be called when loading a new wallpaper stopped. If an error occured then the error will be passed as parameter.
this._stopLoadingHooks = [];
2017-02-04 23:48:52 +00:00
2017-02-24 22:31:35 +00:00
this._timer = new Timer.AFTimer();
2017-07-20 11:48:13 +00:00
this._historyController = new HistoryModule.HistoryController(this.wallpaperlocation);
2017-02-24 22:31:35 +00:00
this._settings = new Prefs.Settings();
this._settings.observe('history-length', this._updateHistory.bind(this));
this._settings.observe('auto-fetch', this._updateAutoFetching.bind(this));
this._settings.observe('minutes', this._updateAutoFetching.bind(this));
this._settings.observe('hours', this._updateAutoFetching.bind(this));
this._desktopperAdapter = new SourceAdapter.DesktopperAdapter();
2017-07-20 15:09:44 +00:00
this._unsplashAdapter = new SourceAdapter.UnsplashAdapter();
this._wallhavenAdapter = new SourceAdapter.WallhavenAdapter();
2018-08-12 21:43:30 +00:00
this._redditAdapter = new SourceAdapter.RedditAdapter();
2017-10-07 15:08:35 +00:00
this._genericJsonAdapter = new SourceAdapter.GenericJsonAdapter();
this._updateHistory();
this._updateAutoFetching();
this.currentWallpaper = this._getCurrentWallpaper();
}
2017-02-04 23:48:52 +00:00
_updateHistory() {
2017-07-20 11:48:13 +00:00
this._historyController.load();
}
2017-02-04 23:48:52 +00:00
_updateAutoFetching() {
2017-02-04 23:48:52 +00:00
let duration = 0;
duration += this._settings.get('minutes', 'int');
duration += this._settings.get('hours', 'int') * 60;
this._autoFetch.duration = duration;
this._autoFetch.active = this._settings.get('auto-fetch', 'boolean');
if (this._autoFetch.active) {
2017-02-24 22:31:35 +00:00
this._timer.registerCallback(this.fetchNewWallpaper.bind(this));
this._timer.setMinutes(this._autoFetch.duration);
this._timer.start();
} else {
this._timer.stop();
}
}
/*
2017-07-22 19:56:17 +00:00
forwards the request to the adapter
*/
_requestRandomImageFromAdapter(callback) {
this.imageSourceAdapter = this._desktopperAdapter;
switch (this._settings.get('source', 'enum')) {
2017-07-22 19:56:17 +00:00
case 0:
this.imageSourceAdapter = this._unsplashAdapter;
2017-07-22 19:56:17 +00:00
break;
case 1:
this.imageSourceAdapter = this._desktopperAdapter;
2017-07-22 19:56:17 +00:00
break;
case 2:
this.imageSourceAdapter = this._wallhavenAdapter;
2017-07-22 19:56:17 +00:00
break;
2017-10-07 15:08:35 +00:00
case 3:
2018-08-12 21:43:30 +00:00
this.imageSourceAdapter = this._redditAdapter;
break;
case 4:
2017-10-07 15:08:35 +00:00
this.imageSourceAdapter = this._genericJsonAdapter;
break;
2017-07-22 19:56:17 +00:00
default:
this.imageSourceAdapter = this._desktopperAdapter;
break;
}
2016-04-08 16:40:52 +00:00
this.imageSourceAdapter.requestRandomImage(callback);
}
2017-07-22 19:56:17 +00:00
/**
* copy file from uri to local wallpaper directory and calls the given callback with the name and the full filepath
* of the written file as parameter.
* @param uri
* @param callback(name, path, error)
2017-07-22 19:56:17 +00:00
* @private
*/
_fetchFile(uri, callback) {
2017-07-20 11:48:13 +00:00
//extract the name from the url and
let date = new Date();
2017-07-22 19:56:17 +00:00
let name = date.getTime() + '_' + this.imageSourceAdapter.fileName(uri); // timestamp ensures uniqueness
let output_file, output_stream, input_file;
try {
output_file = Gio.file_new_for_path(this.wallpaperlocation + String(name));
output_stream = output_file.create(0, null);
input_file = Gio.file_new_for_uri(uri);
} catch (e) {
if (callback) {
callback(null, null, e);
}
return;
}
2017-07-20 11:48:13 +00:00
input_file.load_contents_async(null, (file, result) => {
let contents = null;
try {
contents = file.load_contents_finish(result)[1];
output_stream.write(contents, null);
} catch (e) {
if (callback) {
callback(null, null, e);
}
return;
}
// call callback with the name and the full filepath of the written file as parameter
if (callback) {
callback(name, output_file.get_path());
}
});
}
2017-07-22 19:56:17 +00:00
/**
* Sets the wallpaper and the lockscreen when enabled to the given path. Executes the callback on success.
* @param path
* @param callback
* @private
*/
_setBackground(path, callback) {
let background_setting = new Gio.Settings({schema: "org.gnome.desktop.background"});
2017-07-22 19:56:17 +00:00
path = "file://" + path;
this._setPictureUriOfSettingsObject(background_setting, path, () => {
if (this._settings.get('change-lock-screen', 'boolean')) {
let screensaver_setting = new Gio.Settings({schema: "org.gnome.desktop.screensaver"});
2017-07-22 19:56:17 +00:00
this._setPictureUriOfSettingsObject(screensaver_setting, path, () => {
// call callback if given
if (callback) {
callback();
}
});
} else {
// call callback if given
if (callback) {
callback();
}
}
});
}
2017-07-22 19:56:17 +00:00
/**
* Set the picture-uri property of the given settings object to the path.
* Precondition: the settings object has to be a valid Gio settings object with the picture-uri property.
* @param settings
* @param path
* @param callback
* @private
*/
_setPictureUriOfSettingsObject(settings, path, callback) {
/*
2017-07-22 19:56:17 +00:00
inspired from:
https://bitbucket.org/LukasKnuth/backslide/src/7e36a49fc5e1439fa9ed21e39b09b61eca8df41a/backslide@codeisland.org/settings.js?at=master
*/
if (settings.is_writable("picture-uri")) {
// Set a new Background-Image (should show up immediately):
let rc = settings.set_string("picture-uri", path);
if (rc) {
Gio.Settings.sync(); // Necessary: http://stackoverflow.com/questions/9985140
2017-07-22 19:56:17 +00:00
2014-10-22 13:24:55 +00:00
// call callback if given
if (callback) {
callback();
}
2017-07-22 19:56:17 +00:00
} else {
this._bailOutWithCallback("Could not set lock screen wallpaper.", callback);
}
} else {
this._bailOutWithCallback("Could not set wallpaper.", callback);
}
}
_getCurrentWallpaper() {
let background_setting = new Gio.Settings({schema: "org.gnome.desktop.background"});
return background_setting.get_string("picture-uri").replace(/^(file:\/\/)/, "");
}
setWallpaper(historyId) {
2017-07-20 11:48:13 +00:00
let historyElement = this._historyController.get(historyId);
2017-07-22 19:56:17 +00:00
if (this._historyController.promoteToActive(historyElement.id)) {
2017-07-20 11:48:13 +00:00
this._setBackground(historyElement.path);
this.currentWallpaper = this._getCurrentWallpaper();
} else {
2017-07-22 19:56:17 +00:00
this.logger.warn("The history id (" + historyElement.id + ") could not be found.")
2017-07-20 11:48:13 +00:00
// TODO: Error handling history id not found.
}
}
fetchNewWallpaper(callback) {
2017-02-24 22:31:35 +00:00
this._startLoadingHooks.forEach((element) => {
element();
});
this._timer.reset(); // reset timer
2017-02-24 22:31:35 +00:00
this._requestRandomImageFromAdapter((historyElement, error) => {
if (historyElement == null || error) {
this._bailOutWithCallback("Could not fetch wallpaper location.", callback);
this._stopLoadingHooks.map(element => element(null));
return;
}
2018-04-12 16:06:19 +00:00
this.logger.info("Requesting image: " + historyElement.source.imageDownloadUrl);
2017-07-20 11:48:13 +00:00
this._fetchFile(historyElement.source.imageDownloadUrl, (historyId, path, error) => {
if (error) {
2019-06-19 13:44:13 +00:00
this._bailOutWithCallback("Could not load new wallpaper. (" + error + ")", callback);
this._stopLoadingHooks.map(element => element(null));
return;
}
historyElement.path = path;
historyElement.id = historyId;
2017-07-20 11:48:13 +00:00
this._setBackground(path, () => {
// insert file into history
this._historyController.insert(historyElement);
this.currentWallpaper = this._getCurrentWallpaper();
this._stopLoadingHooks.map(element => element(null));
2014-10-22 13:24:55 +00:00
if (callback) {
callback();
}
2014-10-22 13:24:55 +00:00
});
});
});
}
_backgroundTimeout(delay) {
if (this.timeout) {
return;
}
delay = delay || 200;
2017-07-20 11:48:13 +00:00
this.timeout = Mainloop.timeout_add(Mainloop.PRIORITY_DEFAULT, delay, () => {
this.timeout = null;
if (this._resetWallpaper) {
this._setBackground(this.currentWallpaper);
this._resetWallpaper = false;
} else {
2017-07-20 11:48:13 +00:00
this._setBackground(this.wallpaperlocation + this.previewId);
}
return false;
});
}
previewWallpaper(historyid, delay) {
2017-10-07 12:45:38 +00:00
if (!this._settings.get('disable-hover-preview', 'boolean')) {
this.previewId = historyid;
this._resetWallpaper = false;
2017-10-07 12:45:38 +00:00
this._backgroundTimeout(delay);
}
}
resetWallpaper() {
2017-10-07 12:45:38 +00:00
if (!this._settings.get('disable-hover-preview', 'boolean')) {
this._resetWallpaper = true;
this._backgroundTimeout();
}
}
getHistoryController() {
2017-07-20 11:48:13 +00:00
return this._historyController;
}
deleteHistory() {
2017-07-20 11:48:13 +00:00
this._historyController.clear();
}
update() {
this._updateHistory();
this.currentWallpaper = this._getCurrentWallpaper();
}
registerStartLoadingHook(fn) {
2017-02-24 22:31:35 +00:00
if (typeof fn === "function") {
this._startLoadingHooks.push(fn)
}
}
2017-02-24 22:31:35 +00:00
registerStopLoadingHook(fn) {
2017-02-24 22:31:35 +00:00
if (typeof fn === "function") {
this._stopLoadingHooks.push(fn)
}
}
_bailOutWithCallback(msg, callback) {
this.logger.error(msg);
if (callback) {
callback();
}
2017-02-24 22:31:35 +00:00
}
};