1
0
mirror of https://github.com/chylex/Discord-History-Tracker.git synced 2024-11-25 14:42:44 +01:00

Compare commits

..

2 Commits

Author SHA1 Message Date
will-ca
da72649247
Merge 21490dd69e into ce87901088 2023-11-23 14:51:45 +01:00
will-ca
21490dd69e
Refactor to match code from the app version (PR #237) 2023-11-23 14:48:09 +01:00
16 changed files with 1477 additions and 4404 deletions

View File

@ -31,6 +31,7 @@ After you've done changes to the source code, you will need to build it. Before
Now open the folder that contains `build.py` in a command line, and run `python build.py` to create a build with default settings. The following files will be created: Now open the folder that contains `build.py` in a command line, and run `python build.py` to create a build with default settings. The following files will be created:
* `bld/track.js` is the raw tracker script that can be pasted into a browser console * `bld/track.js` is the raw tracker script that can be pasted into a browser console
* `bld/track.html` is the tracker script but sanitized for inclusion in HTML (see `web/index.php` for examples)
* `bld/viewer.html` is the complete offline viewer * `bld/viewer.html` is the complete offline viewer
You can tweak the build process using the following flags: You can tweak the build process using the following flags:

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

View File

@ -11,8 +11,8 @@ import distutils.dir_util
VERSION_SHORT = "v.31f" VERSION_SHORT = "v.31f"
VERSION_FULL = VERSION_SHORT + ", released 20 November 2023" VERSION_FULL = VERSION_SHORT + ", released 20 November 2023"
EXEC_UGLIFYJS_WIN = "{2}/lib/uglifyjs.cmd --parse bare_returns --compress --mangle toplevel --mangle-props keep_quoted,reserved=[{3}] --output \"{1}\" \"{0}\"" EXEC_UGLIFYJS_WIN = "{2}/lib/uglifyjs.cmd --parse bare_returns --compress --output \"{1}\" \"{0}\""
EXEC_UGLIFYJS_AUTO = "uglifyjs --parse bare_returns --compress --mangle toplevel --mangle-props keep_quoted,reserved=[{3}] --output \"{1}\" \"{0}\"" EXEC_UGLIFYJS_AUTO = "uglifyjs --parse bare_returns --compress --output \"{1}\" \"{0}\""
USE_UGLIFYJS = "--nominify" not in sys.argv USE_UGLIFYJS = "--nominify" not in sys.argv
USE_MINIFICATION = "--nominify" not in sys.argv USE_MINIFICATION = "--nominify" not in sys.argv
@ -32,17 +32,13 @@ else:
USE_UGLIFYJS = False USE_UGLIFYJS = False
print("Could not find 'uglifyjs', JS minification will be disabled") print("Could not find 'uglifyjs', JS minification will be disabled")
if USE_UGLIFYJS:
with open("reserve.txt", "r") as reserved:
RESERVED_PROPS = ",".join(line.strip() for line in reserved.readlines())
# File Utilities # File Utilities
def combine_files(input_pattern, output_file): def combine_files(input_pattern, output_file):
is_first_file = True is_first_file = True
with fileinput.input(sorted(glob.glob(input_pattern, recursive=True))) as stream: with fileinput.input(sorted(glob.glob(input_pattern))) as stream:
for line in stream: for line in stream:
if stream.isfirstline(): if stream.isfirstline():
if is_first_file: if is_first_file:
@ -53,6 +49,23 @@ def combine_files(input_pattern, output_file):
output_file.write(line.replace("{{{version:full}}}", VERSION_FULL)) output_file.write(line.replace("{{{version:full}}}", VERSION_FULL))
def combine_files_to_str(input_pattern):
is_first_file = True
output = []
with fileinput.input(sorted(glob.glob(input_pattern))) as stream:
for line in stream:
if stream.isfirstline():
if is_first_file:
is_first_file = False
else:
output.append("\n")
output.append(line.replace("{{{version:full}}}", VERSION_FULL))
return "".join(output)
def minify_css(input_file, output_file): def minify_css(input_file, output_file):
if not USE_MINIFICATION: if not USE_MINIFICATION:
if input_file != output_file: if input_file != output_file:
@ -77,24 +90,34 @@ def minify_css(input_file, output_file):
# Build System # Build System
def build_tracker_html(): def build_tracker():
output_file_raw = "bld/track.js" output_file_raw = "bld/track.js"
output_file_html = "bld/track.html" output_file_html = "bld/track.html"
output_file_userscript = "bld/track.user.js"
output_file_tmp = "bld/track.tmp.js" with open("src/tracker/styles/controller.css", "r") as f:
input_pattern = "src/tracker/**/*.js" controller_css = f.read()
with open("src/tracker/styles/settings.css", "r") as f:
settings_css = f.read()
with open("src/tracker/bootstrap.js", "r") as f:
bootstrap_js = f.read()
combined_tracker_js = combine_files_to_str("src/tracker/scripts/*.js")
combined_tracker_js = combined_tracker_js.replace("/*[CSS-CONTROLLER]*/", controller_css)
combined_tracker_js = combined_tracker_js.replace("/*[CSS-SETTINGS]*/", settings_css)
full_tracker_js = bootstrap_js.replace("/*[IMPORTS]*/", combined_tracker_js)
minified_tracker_js = full_tracker_js
with open(output_file_raw, "w") as out: with open(output_file_raw, "w") as out:
if not USE_UGLIFYJS: out.write(full_tracker_js)
out.write("(function(){\n")
combine_files(input_pattern, out)
if not USE_UGLIFYJS:
out.write("})()")
if USE_UGLIFYJS: if USE_UGLIFYJS:
os.system(EXEC_UGLIFYJS.format(output_file_raw, output_file_tmp, WORKING_DIR, RESERVED_PROPS)) output_file_tmp = "bld/track.tmp.js"
os.system(EXEC_UGLIFYJS.format(output_file_raw, output_file_tmp, WORKING_DIR))
with open(output_file_raw, "w") as out: with open(output_file_raw, "w") as out:
out.write("javascript:(function(){") out.write("javascript:(function(){")
@ -107,25 +130,28 @@ def build_tracker_html():
os.remove(output_file_tmp) os.remove(output_file_tmp)
with open(output_file_raw, "r") as raw: with open(output_file_raw, "r") as raw:
script_contents = raw.read().replace("&", "&amp;").replace('"', "&quot;").replace("'", "&#x27;").replace("<", "&lt;").replace(">", "&gt;") minified_tracker_js = raw.read()
with open(output_file_html, "w") as out: write_tracker_html(output_file_html, minified_tracker_js)
out.write(script_contents) write_tracker_userscript(output_file_userscript, full_tracker_js)
def build_tracker_userscript(): def write_tracker_html(output_file, tracker_js):
output_file = "bld/track.user.js" tracker_js = tracker_js.replace("&", "&amp;").replace('"', "&quot;").replace("'", "&#x27;").replace("<", "&lt;").replace(">", "&gt;")
input_pattern = "src/tracker/**/*.js"
userscript_base = "src/base/track.user.js"
with open(userscript_base, "r") as base:
userscript_contents = base.read().replace("{{{version}}}", VERSION_SHORT).split("{{{contents}}}")
with open(output_file, "w") as out: with open(output_file, "w") as out:
out.write(userscript_contents[0]) out.write(tracker_js)
combine_files(input_pattern, out)
out.write(userscript_contents[1])
def write_tracker_userscript(output_file, full_tracker_js):
with open("src/base/track.user.js", "r") as f:
userscript_js = f.read()
userscript_js = userscript_js.replace("{{{version}}}", VERSION_SHORT)
userscript_js = userscript_js.replace("{{{contents}}}", full_tracker_js)
with open(output_file, "w") as out:
out.write(userscript_js)
def build_viewer(): def build_viewer():
@ -150,7 +176,7 @@ def build_viewer():
combine_files(input_js_pattern, out) combine_files(input_js_pattern, out)
if USE_UGLIFYJS: if USE_UGLIFYJS:
os.system(EXEC_UGLIFYJS.format(tmp_js_file_combined, tmp_js_file_minified, WORKING_DIR, RESERVED_PROPS)) os.system(EXEC_UGLIFYJS.format(tmp_js_file_combined, tmp_js_file_minified, WORKING_DIR))
else: else:
shutil.copyfile(tmp_js_file_combined, tmp_js_file_minified) shutil.copyfile(tmp_js_file_combined, tmp_js_file_minified)
@ -202,11 +228,8 @@ def build_website():
os.makedirs("bld", exist_ok = True) os.makedirs("bld", exist_ok = True)
print("Building tracker html...") print("Building tracker...")
build_tracker_html() build_tracker()
print("Building tracker userscript...")
build_tracker_userscript()
print("Building viewer...") print("Building viewer...")
build_viewer() build_viewer()

View File

@ -1,74 +0,0 @@
autoscroll
_autoscroll
afterFirstMsg
_afterFirstMsg
afterSavedMsg
_afterSavedMsg
enableImagePreviews
_enableImagePreviews
enableFormatting
_enableFormatting
enableAnimatedEmoji
_enableAnimatedEmoji
enableUserAvatars
_enableUserAvatars
DHT_LOADED
DHT_EMBEDDED
meta
data
users
userindex
servers
channels
u
t
m
f
e
a
t
te
d
r
re
c
n
an
tag
avatar
author
type
state
name
position
topic
nsfw
id
username
bot
discriminator
timestamp
content
editedTimestamp
mentions
embeds
attachments
title
description
reply
reactions
emoji
count
animated
ext
toDate
memoizedProps
props
children
channel
messages
msSaveBlob
messageReference
message_id
guild_id
guild

View File

@ -1,5 +0,0 @@
**STOP!**
These files must be kept in sync with the upstream desktop app branch in order for future changes/fixes to the desktop script to be cleanly merged here.
Changes for the browser version should be done in another file to maintain mergeablity.

View File

@ -1,28 +1,23 @@
// NOTE: STOP! This file must be kept in sync with the upstream desktop app branch in order for future changes/fixes to the desktop script to be cleanly merged here. // noinspection JSAnnotator
// Changes for the browser version should be done in another file to maintain mergeablity.
(function() {
const url = window.location.href;
if (!url.includes("discord.com/") && !url.includes("discordapp.com/") && !confirm("Could not detect Discord in the URL, do you want to run the script anyway?")) { const url = window.location.href;
if (!url.includes("discord.com/") && !url.includes("discordapp.com/") && !confirm("Could not detect Discord in the URL, do you want to run the script anyway?")) {
return; return;
} }
if (window.DHT_LOADED) { if (window.DHT_LOADED) {
alert("Discord History Tracker is already loaded."); alert("Discord History Tracker is already loaded.");
return; return;
} }
window.DHT_LOADED = true; window.DHT_LOADED = true;
window.DHT_ON_UNLOAD = []; window.DHT_ON_UNLOAD = [];
/*[IMPORTS]*/ /*[IMPORTS]*/
const port = 0; /*[PORT]*/ let delayedStopRequests = 0;
const token = "/*[TOKEN]*/"; const stopTrackingDelayed = function(callback) {
STATE.setup(port, token);
let delayedStopRequests = 0;
const stopTrackingDelayed = function(callback) {
delayedStopRequests++; delayedStopRequests++;
window.setTimeout(() => { window.setTimeout(() => {
@ -33,22 +28,22 @@
callback(); callback();
} }
}, 200); // give the user visual feedback after clicking the button before switching off }, 200); // give the user visual feedback after clicking the button before switching off
}; };
let hasJustStarted = false; let hasJustStarted = false;
let isSending = false; let isSending = false;
const onError = function(e) { const onError = function(e) {
console.log(e); console.log(e);
GUI.setStatus(e.status === "DISCONNECTED" ? "Disconnected" : "Error"); GUI.setStatus(e.status === "DISCONNECTED" ? "Disconnected" : "Error");
stopTrackingDelayed(() => isSending = false); stopTrackingDelayed(() => isSending = false);
}; };
const isNoAction = function(action) { const isNoAction = function(action) {
return action === null || action === CONSTANTS.AUTOSCROLL_ACTION_NOTHING; return action === null || action === CONSTANTS.AUTOSCROLL_ACTION_NOTHING;
}; };
const onTrackingContinued = function(anyNewMessages) { const onTrackingContinued = function(anyNewMessages) {
if (!STATE.isTracking()) { if (!STATE.isTracking()) {
return; return;
} }
@ -80,11 +75,11 @@
STATE.setIsTracking(false); STATE.setIsTracking(false);
} }
} }
}; };
let waitUntilSendingFinishedTimer = null; let waitUntilSendingFinishedTimer = null;
const onMessagesUpdated = async messages => { const onMessagesUpdated = async messages => {
if (!STATE.isTracking() || delayedStopRequests > 0) { if (!STATE.isTracking() || delayedStopRequests > 0) {
return; return;
} }
@ -123,17 +118,17 @@
onTrackingContinued(false); onTrackingContinued(false);
} }
else { else {
const anyNewMessages = await STATE.addDiscordMessages(messages); const anyNewMessages = STATE.addDiscordMessages(messages);
onTrackingContinued(anyNewMessages); onTrackingContinued(anyNewMessages);
} }
} catch (e) { } catch (e) {
onError(e); onError(e);
} }
}; };
DISCORD.setupMessageCallback(onMessagesUpdated); DISCORD.setupMessageCallback(onMessagesUpdated);
STATE.onTrackingStateChanged(enabled => { STATE.onTrackingStateChanged(enabled => {
if (enabled) { if (enabled) {
const messages = DISCORD.getMessages(); const messages = DISCORD.getMessages();
@ -150,12 +145,10 @@
else { else {
isSending = false; isSending = false;
} }
}); });
GUI.showController(); GUI.showController();
if (IS_FIRST_RUN) { if (IS_FIRST_RUN) {
GUI.showSettings(); GUI.showSettings();
} }
})();
/*[DEBUGGER]*/

View File

@ -84,14 +84,7 @@ var GUI = (function(){
// styles // styles
controller.styles = DOM.createStyle(` controller.styles = DOM.createStyle(`/*[CSS-CONTROLLER]*/`);
#app-mount div[class*="app-"] { margin-bottom: 48px !important; }
#dht-ctrl { position: absolute; bottom: 0; width: 100%; height: 48px; background-color: #FFF; z-index: 1000000; }
#dht-ctrl button { height: 32px; margin: 8px 0 8px 8px; font-size: 16px; padding: 0 12px; background-color: #7289DA; color: #FFF; text-shadow: 1px 1px 2px rgba(0, 0, 0, 0.75); }
#dht-ctrl button:disabled { background-color: #7A7A7A; cursor: default; }
#dht-ctrl-close { margin: 8px 8px 8px 0 !important; float: right; }
#dht-ctrl p { display: inline-block; margin: 14px 12px; }
#dht-ctrl input { display: none; }`);
// main // main
@ -104,7 +97,7 @@ ${btn("track", "")}
${btn("download", "Download")} ${btn("download", "Download")}
${btn("reset", "Reset")} ${btn("reset", "Reset")}
<p id='dht-ctrl-status'></p> <p id='dht-ctrl-status'></p>
<input id='dht-ctrl-upload-input' type='file' multiple> <input id='dht-ctrl-upload-input' type='file' multiple style="display: none">
${btn("close", "X")}`); ${btn("close", "X")}`);
// elements // elements
@ -193,11 +186,7 @@ ${btn("close", "X")}`);
// styles // styles
settings.styles = DOM.createStyle(` settings.styles = DOM.createStyle(`/*[CSS-SETTINGS]*/`);
#dht-cfg-overlay { position: absolute; left: 0; top: 0; width: 100%; height: 100%; background-color: #000; opacity: 0.5; display: block; z-index: 1000001; }
#dht-cfg { position: absolute; left: 50%; top: 50%; width: 800px; height: 262px; margin-left: -400px; margin-top: -131px; padding: 8px; background-color: #fff; z-index: 1000002; }
#dht-cfg-note { margin-top: 22px; }
#dht-cfg sub { color: #666; font-size: 13px; }`);
// overlay // overlay
@ -274,10 +263,7 @@ It is recommended to disable link and image previews to avoid putting unnecessar
} }
}, },
setStatus: function(state){ setStatus: function(status) {}
console.log("Status: " + state)
// TODO I guess.
}
}; };
return root; return root;

View File

@ -167,15 +167,15 @@ class SAVEFILE{
channelObj.name = channelName; channelObj.name = channelName;
if (extraInfo.position){ if (extraInfo.position) {
channelObj.position = extraInfo.position; channelObj.position = extraInfo.position;
} }
if (extraInfo.topic){ if (extraInfo.topic) {
channelObj.topic = extraInfo.topic; channelObj.topic = extraInfo.topic;
} }
if (extraInfo.nsfw){ if (extraInfo.nsfw) {
channelObj.nsfw = extraInfo.nsfw; channelObj.nsfw = extraInfo.nsfw;
} }

View File

@ -110,11 +110,12 @@ const STATE = (function() {
* Registers a Discord server and channel. * Registers a Discord server and channel.
*/ */
addDiscordChannel(serverInfo, channelInfo){ addDiscordChannel(serverInfo, channelInfo){
let serverName = serverInfo.name var serverName = serverInfo.name;
let serverType = serverInfo.type var serverType = serverInfo.type;
let channelId = channelInfo.id var channelId = channelInfo.id;
let channelName = channelInfo.name var channelName = channelInfo.name;
let extraInfo = channelInfo.extra var extraInfo = channelInfo.extra || {};
var serverIndex = this.getSavefile().findOrRegisterServer(serverName, serverType); var serverIndex = this.getSavefile().findOrRegisterServer(serverName, serverType);
if (this.getSavefile().tryRegisterChannel(serverIndex, channelId, channelName, extraInfo) === true){ if (this.getSavefile().tryRegisterChannel(serverIndex, channelId, channelName, extraInfo) === true){
@ -150,13 +151,6 @@ const STATE = (function() {
this._trackingStateChangedListeners.push(callback); this._trackingStateChangedListeners.push(callback);
callback(this._isTracking); callback(this._isTracking);
} }
/*
* Shim for code from the desktop app.
*/
setup(port, token) {
console.log("Placeholder port and token: " + port + " " + token);
}
} }
return new CLS(); return new CLS();

View File

@ -1,6 +1,3 @@
// NOTE: Currently unused. See `.createStyle()` calls in `gui.js`.
/*
const css_controller = `
#app-mount { #app-mount {
height: calc(100% - 48px) !important; height: calc(100% - 48px) !important;
} }
@ -33,5 +30,8 @@ const css_controller = `
display: inline-block; display: inline-block;
margin: 14px 12px; margin: 14px 12px;
} }
`
*/ #dht-ctrl-close {
margin: 8px 8px 8px 0 !important;
float: right;
}

View File

@ -1,6 +1,3 @@
// NOTE: Currently unused. See `.createStyle()` calls in `gui.js`.
/*
const css_settings = `
#dht-cfg-overlay { #dht-cfg-overlay {
position: absolute; position: absolute;
left: 0; left: 0;
@ -29,5 +26,8 @@ const css_settings = `
#dht-cfg-note { #dht-cfg-note {
margin-top: 22px; margin-top: 22px;
} }
`
*/ #dht-cfg sub {
color: #666;
font-size: 13px;
}