mirror of
https://github.com/loot/libloot.git
synced 2026-07-27 14:16:01 -07:00
Add update checking to UI
Unblock most http(s) requests to allow usage of the GitHub API. Requests to fonts.googleapis.com are still blocked to prevent Polymer trying to load the fonts from there when they're already present locally.
This commit is contained in:
+2
-1
@@ -34,6 +34,7 @@
|
||||
"Jed": "SlexAxton/Jed#^1.1.1",
|
||||
"jed-gettext-parser": "^1.0.0",
|
||||
"marked": "^0.3.2",
|
||||
"lodash": "^4.3.0"
|
||||
"lodash": "^4.3.0",
|
||||
"octokat": "^0.4.18"
|
||||
}
|
||||
}
|
||||
|
||||
+16
-20
@@ -8,7 +8,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: LOOT 0.10.0\n"
|
||||
"Report-Msgid-Bugs-To: https://github.com/loot/loot/issues\n"
|
||||
"POT-Creation-Date: 2016-10-15 12:29+0100\n"
|
||||
"POT-Creation-Date: 2016-11-02 23:09+0000\n"
|
||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||
@@ -628,7 +628,7 @@ msgstr ""
|
||||
msgid "Loading plugin contents..."
|
||||
msgstr ""
|
||||
|
||||
#: src/gui/query/sort_plugins_query.h:68
|
||||
#: src/gui/query/sort_plugins_query.h:70
|
||||
msgid "Sorting load order..."
|
||||
msgstr ""
|
||||
|
||||
@@ -652,60 +652,56 @@ msgstr ""
|
||||
msgid "None of the supported games were detected."
|
||||
msgstr ""
|
||||
|
||||
#: src/backend/game/game.cpp:61
|
||||
msgid "Invalid game ID supplied."
|
||||
msgstr ""
|
||||
|
||||
#: src/backend/game/game.cpp:68
|
||||
#: src/backend/game/game.cpp:64
|
||||
msgid "Game path could not be detected."
|
||||
msgstr ""
|
||||
|
||||
#: src/backend/game/game.cpp:78
|
||||
#: src/backend/game/game.cpp:74
|
||||
msgid "Could not create LOOT folder for game. Details:"
|
||||
msgstr ""
|
||||
|
||||
#: src/backend/game/load_order_handler.cpp:49
|
||||
msgid "Unsupported game ID supplied."
|
||||
#: src/backend/game/game_cache.cpp:119
|
||||
msgid "You have not sorted your load order this session."
|
||||
msgstr ""
|
||||
|
||||
#: src/backend/game/load_order_handler.cpp:54
|
||||
#: src/backend/game/load_order_handler.cpp:46
|
||||
msgid "Game path is not initialised."
|
||||
msgstr ""
|
||||
|
||||
#: src/backend/game/load_order_handler.cpp:88
|
||||
#: src/backend/game/load_order_handler.cpp:82
|
||||
msgid ""
|
||||
"libloadorder failed to create a game handle. Details could not be fetched."
|
||||
msgstr ""
|
||||
|
||||
#: src/backend/game/load_order_handler.cpp:91
|
||||
#: src/backend/game/load_order_handler.cpp:85
|
||||
msgid "libloadorder failed to create a game handle. Details:"
|
||||
msgstr ""
|
||||
|
||||
#: src/backend/game/load_order_handler.cpp:109
|
||||
#: src/backend/game/load_order_handler.cpp:103
|
||||
msgid ""
|
||||
"libloadorder failed to check if a plugin is active. Details could not be "
|
||||
"fetched."
|
||||
msgstr ""
|
||||
|
||||
#: src/backend/game/load_order_handler.cpp:112
|
||||
#: src/backend/game/load_order_handler.cpp:106
|
||||
msgid "libloadorder failed to check if a plugin is active. Details:"
|
||||
msgstr ""
|
||||
|
||||
#: src/backend/game/load_order_handler.cpp:134
|
||||
#: src/backend/game/load_order_handler.cpp:128
|
||||
msgid ""
|
||||
"libloadorder failed to get the load order. Details could not be fetched."
|
||||
msgstr ""
|
||||
|
||||
#: src/backend/game/load_order_handler.cpp:137
|
||||
#: src/backend/game/load_order_handler.cpp:131
|
||||
msgid "libloadorder failed to get the load order. Details:"
|
||||
msgstr ""
|
||||
|
||||
#: src/backend/game/load_order_handler.cpp:160
|
||||
#: src/backend/game/load_order_handler.cpp:154
|
||||
msgid ""
|
||||
"libloadorder failed to set the load order. Details could not be fetched."
|
||||
msgstr ""
|
||||
|
||||
#: src/backend/game/load_order_handler.cpp:163
|
||||
#: src/backend/game/load_order_handler.cpp:157
|
||||
msgid "libloadorder failed to set the load order. Details:"
|
||||
msgstr ""
|
||||
|
||||
@@ -728,7 +724,7 @@ msgstr ""
|
||||
msgid "Unable to open \"%1%\" for CRC calculation."
|
||||
msgstr ""
|
||||
|
||||
#: src/backend/helpers/helpers.cpp:122 src/backend/helpers/helpers.cpp:125
|
||||
#: src/backend/helpers/helpers.cpp:103 src/backend/helpers/helpers.cpp:106
|
||||
msgid "Failed to open file in its default application."
|
||||
msgstr ""
|
||||
|
||||
|
||||
@@ -450,6 +450,7 @@
|
||||
<script src="../../../bower_components/Jed/jed.js"></script>
|
||||
<script src="../../../bower_components/jed-gettext-parser/jedGettextParser.js"></script>
|
||||
<script src="../../../bower_components/lodash/dist/lodash.core.min.js"></script>
|
||||
<script src="../../../bower_components/octokat/dist/octokat.js"></script>
|
||||
<script src="js/dialog.js"></script>
|
||||
<script src="js/dom.js"></script>
|
||||
<script src="js/events.js"></script>
|
||||
@@ -461,6 +462,7 @@
|
||||
<script src="js/filters.js"></script>
|
||||
<script src="js/state.js"></script>
|
||||
<script src="js/translator.js"></script>
|
||||
<script src="js/updateExists.js"></script>
|
||||
<script src="js/initialise.js"></script>
|
||||
<script>
|
||||
'use strict';
|
||||
|
||||
+18
-7
@@ -34,11 +34,11 @@
|
||||
return item;
|
||||
}
|
||||
|
||||
function createMessageItem(message) {
|
||||
function createMessageItem(type, content) {
|
||||
const li = document.createElement('li');
|
||||
li.className = 'error';
|
||||
li.className = type;
|
||||
/* Use the Marked library for Markdown formatting support. */
|
||||
li.innerHTML = marked(message);
|
||||
li.innerHTML = marked(content);
|
||||
|
||||
return li;
|
||||
}
|
||||
@@ -166,15 +166,26 @@
|
||||
forceSelectDefaultValue(messageLangSelect);
|
||||
}
|
||||
|
||||
static appendGeneralMessages(messages) {
|
||||
if (!messages) {
|
||||
return;
|
||||
}
|
||||
|
||||
const generalMessagesList = document.getElementById('summary').getElementsByTagName('ul')[0];
|
||||
messages.forEach((message) => {
|
||||
generalMessagesList.appendChild(createMessageItem(message.type, message.content));
|
||||
});
|
||||
}
|
||||
|
||||
static listInitErrors(errorMessages) {
|
||||
if (!errorMessages) {
|
||||
return;
|
||||
}
|
||||
const generalMessagesList = document.getElementById('summary').getElementsByTagName('ul')[0];
|
||||
|
||||
errorMessages.forEach((message) => {
|
||||
generalMessagesList.appendChild(createMessageItem(message));
|
||||
});
|
||||
DOM.appendGeneralMessages(errorMessages.map((element) => ({
|
||||
type: 'error',
|
||||
content: element,
|
||||
})));
|
||||
|
||||
document.getElementById('filterTotalMessageNo').textContent = errorMessages.length;
|
||||
document.getElementById('totalMessageNo').textContent = errorMessages.length;
|
||||
|
||||
@@ -37,7 +37,8 @@
|
||||
root.loot.translateStaticText,
|
||||
root.loot.Plugin,
|
||||
root.loot.query,
|
||||
root.loot.Translator);
|
||||
root.loot.Translator,
|
||||
root.loot.updateExists);
|
||||
}
|
||||
}(this, (Dialog,
|
||||
dom,
|
||||
@@ -47,7 +48,8 @@
|
||||
translateStaticText,
|
||||
Plugin,
|
||||
query,
|
||||
Translator) => {
|
||||
Translator,
|
||||
updateExists) => {
|
||||
function setupEventHandlers() {
|
||||
/* Set up handlers for filters. */
|
||||
document.getElementById('hideVersionNumbers').addEventListener('change', onSidebarFilterToggle);
|
||||
@@ -235,6 +237,19 @@
|
||||
dom.openDialog('firstRun');
|
||||
}
|
||||
})
|
||||
.then(() => loot.query('getVersion'))
|
||||
.then(JSON.parse)
|
||||
.then((version) => updateExists(version.release, version.build))
|
||||
.then((isUpdateAvailable) => {
|
||||
if (!isUpdateAvailable) {
|
||||
return;
|
||||
}
|
||||
|
||||
dom.appendGeneralMessages([{
|
||||
type: 'warn',
|
||||
content: loot.l10n.translate('A [new release](%s) of LOOT is available.', 'https://github.com/loot/loot/releases/latest'),
|
||||
}]);
|
||||
})
|
||||
.catch(handlePromiseError);
|
||||
};
|
||||
}));
|
||||
|
||||
@@ -0,0 +1,60 @@
|
||||
'use strict';
|
||||
(function exportModule(root, factory) {
|
||||
if (typeof define === 'function' && define.amd) {
|
||||
// AMD. Register as an anonymous module.
|
||||
define(['bower_components/octokat/dist/octokat.js'], factory);
|
||||
} else {
|
||||
// Browser globals
|
||||
root.loot = root.loot || {};
|
||||
root.loot.updateExists = factory(root.Octokat);
|
||||
}
|
||||
}(this, (Octokat) => {
|
||||
const versionRegex = /^(\d+)\.(\d+)\.(\d+)$/;
|
||||
|
||||
function compare(lhs, rhs) {
|
||||
if (!versionRegex.test(lhs) || !versionRegex.test(rhs)) {
|
||||
throw new Error(`versions to compare are of unexpected format: ${lhs}, ${rhs}`);
|
||||
}
|
||||
|
||||
const lhsNumbers = lhs.split('.');
|
||||
const rhsNumbers = rhs.split('.');
|
||||
|
||||
for (let i = 0; i < lhsNumbers.length; i += 1) {
|
||||
const lhsNumber = Number(lhsNumbers[i]);
|
||||
const rhsNumber = Number(rhsNumbers[i]);
|
||||
|
||||
if (lhsNumber < rhsNumber) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (rhsNumber < lhsNumber) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
return (currentVersion, currentBuild) => {
|
||||
if (currentVersion === undefined || currentBuild === undefined) {
|
||||
return Promise.reject(new Error('Invalid arguments, both version and build must be given'));
|
||||
}
|
||||
|
||||
const repo = (new Octokat()).repos('loot', 'loot');
|
||||
|
||||
return repo.releases.latest.fetch().then((latestRelease) => {
|
||||
const comparison = compare(currentVersion, latestRelease.tagName);
|
||||
if (comparison === -1) {
|
||||
return true;
|
||||
} else if (comparison === 1) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return repo.tags.fetch().then((tags) => {
|
||||
const tag = tags.find((element) => element.name === latestRelease.tagName);
|
||||
|
||||
return !tag.commit.sha.startsWith(currentBuild);
|
||||
});
|
||||
});
|
||||
};
|
||||
}));
|
||||
@@ -239,8 +239,10 @@ CefRequestHandler::ReturnValue LootHandler::OnBeforeResourceLoad(CefRefPtr<CefBr
|
||||
CefRefPtr<CefFrame> frame,
|
||||
CefRefPtr<CefRequest> request,
|
||||
CefRefPtr<CefRequestCallback> callback) {
|
||||
if (boost::starts_with(request->GetURL().ToString(), "http"))
|
||||
if (boost::starts_with(request->GetURL().ToString(), "https://fonts.googleapis.com")) {
|
||||
BOOST_LOG_TRIVIAL(warning) << "Blocking load of resource at " << request->GetURL().ToString();
|
||||
return RV_CANCEL;
|
||||
}
|
||||
|
||||
return RV_CONTINUE;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
'use strict';
|
||||
|
||||
/* Mock the octokat methods used. */
|
||||
function Octokat() {
|
||||
this.repos = function(owner, repo) {
|
||||
return {
|
||||
releases: {
|
||||
latest: {
|
||||
fetch() {
|
||||
return Promise.resolve({
|
||||
tagName: '0.9.2',
|
||||
});
|
||||
},
|
||||
},
|
||||
},
|
||||
tags: {
|
||||
fetch() {
|
||||
return Promise.resolve([{
|
||||
name: '0.9.2',
|
||||
commit: {
|
||||
sha: '6b58f92a5d41f5d7f149a1263dac78687a065ff5',
|
||||
},
|
||||
}, {
|
||||
name: '0.9.1',
|
||||
commit: {
|
||||
sha: 'dc24e10a4774903ede4e94165e7d6fa806466e4a',
|
||||
},
|
||||
}, {
|
||||
name: '0.9.0',
|
||||
commit: {
|
||||
sha: '44a0d8505d5402dd24cf0fda9540da9557866c80',
|
||||
},
|
||||
}]);
|
||||
},
|
||||
},
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -13,18 +13,21 @@
|
||||
|
||||
<script>mocha.setup('bdd')</script>
|
||||
<script src="mock_dom.js"></script>
|
||||
<script src="mock_octokat.js"></script>
|
||||
<script src="../../../../gui/html/js/filters.js"></script>
|
||||
<script src="../../../../gui/html/js/plugin.js"></script>
|
||||
<script src="../../../../gui/html/js/game.js"></script>
|
||||
<script src="../../../../gui/html/js/query.js"></script>
|
||||
<script src="../../../../gui/html/js/state.js"></script>
|
||||
<script src="../../../../gui/html/js/translator.js"></script>
|
||||
<script src="../../../../gui/html/js/updateExists.js"></script>
|
||||
<script src="test_filters.js"></script>
|
||||
<script src="test_game.js"></script>
|
||||
<script src="test_plugin.js"></script>
|
||||
<script src="test_query.js"></script>
|
||||
<script src="test_state.js"></script>
|
||||
<script src="test_translator.js"></script>
|
||||
<script src="test_updateExists.js"></script>
|
||||
<script>
|
||||
onload = function(){
|
||||
mocha.checkLeaks();
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
'use strict';
|
||||
|
||||
describe('updateExists()', () => {
|
||||
it('should reject if no arguments are passed', () => {
|
||||
return loot.updateExists().should.be.rejected();
|
||||
});
|
||||
|
||||
it('should reject if one argument is passed', () => {
|
||||
return loot.updateExists('1.0.0').should.be.rejected();
|
||||
});
|
||||
|
||||
it('should reject if passed a version number has less than three parts', () => {
|
||||
return loot.updateExists('1.0', 'deadbeef').should.be.rejected();
|
||||
});
|
||||
|
||||
it('should reject if passed a version number has more than three parts', () => {
|
||||
return loot.updateExists('1.0.0.0', 'deadbeef').should.be.rejected();
|
||||
});
|
||||
|
||||
it('should reject if the version number given contains non-digit, non-period characters', () => {
|
||||
return loot.updateExists('1.0a.0', 'deadbeef').should.be.rejected();
|
||||
});
|
||||
|
||||
it('should resolve to true if the given version is less than the latest version', () => {
|
||||
return loot.updateExists('0.9.1', 'deadbeef').should.be.fulfilledWith(true);
|
||||
});
|
||||
|
||||
it('should resolve to false if the given version is greater than the latest version', () => {
|
||||
return loot.updateExists('0.10.0', 'deadbeef').should.be.fulfilledWith(false);
|
||||
});
|
||||
|
||||
it('should resolve to true if the given version equals the latest version but the short build SHAs are unequal', () => {
|
||||
return loot.updateExists('0.9.2', 'deadbeef').should.be.fulfilledWith(true);
|
||||
});
|
||||
|
||||
it('should resolve to false if the given version equals the latest version and the short build SHAs are equal', () => {
|
||||
return loot.updateExists('0.9.2', '6b58f92').should.be.fulfilledWith(false);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user