mirror of
https://github.com/weyne85/chaturbate-dvr.git
synced 2025-10-29 16:58:56 +00:00
Updates and refactors
Channel_file.go - fix issue with segments not correctly ending when they were supposed to Log_type.go - moved log type to it's own file, setup global logging (touches on issue #47) Main.go - added update_log_level handler, setting global log level Channel.go, channel_internal.go, channel_util.go - updated to use new log_type Manager.go - updated to use new log_type, update from .com to .global (issue #74) Channel_update.go, create_channel.go, delete_channel.go, get_channel.go, get_settings.go, listen_update.go, pause_channel.go, resume_channel.go, terminal_program.go - go fmt / go vet Chaturbate_channels.json.sample - added sample json of the channels file, for mapping in docker config List_channels.go - refactored to sort by online status, so online is always at the first ones you see Script.js - adjust default settings, added pagination, added global log logic Index.html - updated to use online version of tocas ui, added pagination, added global log logic, visual improvements Removal of local tocas folder since using online version
This commit is contained in:
@@ -1,212 +1,254 @@
|
||||
function data() {
|
||||
return {
|
||||
settings: {},
|
||||
channels: [],
|
||||
is_updating_channels: false,
|
||||
form_data: {
|
||||
username: "",
|
||||
resolution: "1080",
|
||||
resolution_fallback: "up",
|
||||
framerate: "30",
|
||||
filename_pattern: "{{.Username}}_{{.Year}}-{{.Month}}-{{.Day}}_{{.Hour}}-{{.Minute}}-{{.Second}}{{if .Sequence}}_{{.Sequence}}{{end}}",
|
||||
split_filesize: 0,
|
||||
split_duration: 0,
|
||||
interval: 1,
|
||||
},
|
||||
return {
|
||||
settings: {},
|
||||
channels: [],
|
||||
currentPage: 1,
|
||||
itemsPerPage: 5,
|
||||
is_updating_channels: false,
|
||||
form_data: {
|
||||
username: "",
|
||||
resolution: "1080",
|
||||
resolution_fallback: "down",
|
||||
framerate: "30",
|
||||
filename_pattern: "{{.Username}}/{{.Year}}-{{.Month}}-{{.Day}}/{{.Username}}_{{.Hour}}-{{.Minute}}-{{.Second}}{{if .Sequence}}_{{.Sequence}}{{end}}",
|
||||
split_filesize: 0,
|
||||
split_duration: 0,
|
||||
interval: 1,
|
||||
},
|
||||
|
||||
// openCreateDialog
|
||||
openCreateDialog() {
|
||||
document.getElementById("create-dialog").showModal()
|
||||
},
|
||||
// Watch for changes in LogLevel
|
||||
watchLogLevel() {
|
||||
this.$watch("settings.log_level", async (newVal, oldVal) => {
|
||||
if (newVal !== oldVal) {
|
||||
await this.updateLogLevel();
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
// closeCreateDialog
|
||||
closeCreateDialog() {
|
||||
document.getElementById("create-dialog").close()
|
||||
this.resetCreateDialog()
|
||||
},
|
||||
// Compute the channels to display for the current page
|
||||
get paginatedChannels() {
|
||||
const start = (this.currentPage - 1) * this.itemsPerPage;
|
||||
return this.channels.slice(start, start + this.itemsPerPage);
|
||||
},
|
||||
|
||||
// submitCreateDialog
|
||||
submitCreateDialog() {
|
||||
this.createChannel()
|
||||
this.closeCreateDialog()
|
||||
},
|
||||
// Calculate total pages
|
||||
get totalPages() {
|
||||
return Math.ceil(this.channels.length / this.itemsPerPage);
|
||||
},
|
||||
|
||||
// error
|
||||
error() {
|
||||
alert("Error occurred, please refresh the page if something is wrong.")
|
||||
},
|
||||
// Change page on click
|
||||
goToPage(page) {
|
||||
if (page >= 1 && page <= this.totalPages) {
|
||||
this.currentPage = page;
|
||||
}
|
||||
},
|
||||
// openCreateDialog
|
||||
openCreateDialog() {
|
||||
document.getElementById("create-dialog").showModal();
|
||||
},
|
||||
|
||||
//
|
||||
async call(path, body) {
|
||||
try {
|
||||
var resp = await fetch(`/api/${path}`, {
|
||||
body: JSON.stringify(body),
|
||||
method: "POST",
|
||||
})
|
||||
if (resp.status !== 200) {
|
||||
this.error()
|
||||
return [null, true]
|
||||
}
|
||||
return [await resp.json(), false]
|
||||
} catch {
|
||||
this.error()
|
||||
return [null, true]
|
||||
}
|
||||
},
|
||||
// closeCreateDialog
|
||||
closeCreateDialog() {
|
||||
document.getElementById("create-dialog").close();
|
||||
this.resetCreateDialog();
|
||||
},
|
||||
|
||||
// getSettings
|
||||
async getSettings() {
|
||||
var [resp, err] = await this.call("get_settings", {})
|
||||
if (!err) {
|
||||
this.settings = resp
|
||||
this.resetCreateDialog()
|
||||
}
|
||||
},
|
||||
// submitCreateDialog
|
||||
submitCreateDialog() {
|
||||
this.createChannel();
|
||||
this.closeCreateDialog();
|
||||
},
|
||||
|
||||
// init
|
||||
async init() {
|
||||
document.getElementById("create-dialog").addEventListener("close", () => this.resetCreateDialog())
|
||||
// error
|
||||
error() {
|
||||
alert("Error occurred, please refresh the page if something is wrong.");
|
||||
},
|
||||
|
||||
await this.getSettings()
|
||||
await this.listChannels()
|
||||
this.listenUpdate()
|
||||
},
|
||||
//
|
||||
async call(path, body) {
|
||||
try {
|
||||
var resp = await fetch(`/api/${path}`, {
|
||||
body: JSON.stringify(body),
|
||||
method: "POST",
|
||||
});
|
||||
if (resp.status !== 200) {
|
||||
this.error();
|
||||
return [null, true];
|
||||
}
|
||||
return [await resp.json(), false];
|
||||
} catch {
|
||||
this.error();
|
||||
return [null, true];
|
||||
}
|
||||
},
|
||||
|
||||
// resetCreateDialog
|
||||
resetCreateDialog() {
|
||||
document.getElementById("splitting-accordion").open = false
|
||||
// getSettings
|
||||
async getSettings() {
|
||||
var [resp, err] = await this.call("get_settings", {});
|
||||
if (!err) {
|
||||
this.settings = resp;
|
||||
this.resetCreateDialog();
|
||||
await this.updateLogLevel();
|
||||
}
|
||||
},
|
||||
|
||||
this.form_data = {
|
||||
username: "",
|
||||
resolution: this.settings.resolution.toString(),
|
||||
resolution_fallback: this.settings.resolution_fallback,
|
||||
framerate: this.settings.framerate.toString(),
|
||||
filename_pattern: this.settings.filename_pattern,
|
||||
split_filesize: this.settings.split_filesize.toString(),
|
||||
split_duration: this.settings.split_duration.toString(),
|
||||
interval: this.settings.interval.toString(),
|
||||
}
|
||||
},
|
||||
// init
|
||||
async init() {
|
||||
document
|
||||
.getElementById('create-dialog')
|
||||
.addEventListener('close', () => this.resetCreateDialog());
|
||||
|
||||
// createChannel
|
||||
async createChannel() {
|
||||
await this.call("create_channel", {
|
||||
username: this.form_data.username,
|
||||
resolution: parseInt(this.form_data.resolution),
|
||||
resolution_fallback: this.form_data.resolution_fallback,
|
||||
framerate: parseInt(this.form_data.framerate),
|
||||
filename_pattern: this.form_data.filename_pattern,
|
||||
split_filesize: parseInt(this.form_data.split_filesize),
|
||||
split_duration: parseInt(this.form_data.split_duration),
|
||||
interval: parseInt(this.form_data.interval),
|
||||
})
|
||||
},
|
||||
await this.getSettings(); // Ensure settings are loaded
|
||||
this.watchLogLevel(); // Start watching LogLevel after settings load
|
||||
await this.listChannels();
|
||||
this.listenUpdate();
|
||||
},
|
||||
|
||||
// deleteChannel
|
||||
async deleteChannel(username) {
|
||||
if (!confirm(`Are you sure you want to delete the channel "${username}"?`)) {
|
||||
return
|
||||
}
|
||||
var [_, err] = await this.call("delete_channel", { username })
|
||||
if (!err) {
|
||||
this.channels = this.channels.filter(ch => ch.username !== username)
|
||||
}
|
||||
},
|
||||
async updateLogLevel() {
|
||||
const [_, err] = await this.call('update_log_level', {
|
||||
log_level: this.settings.log_level,
|
||||
});
|
||||
|
||||
// pauseChannel
|
||||
async pauseChannel(username) {
|
||||
await this.call("pause_channel", { username })
|
||||
},
|
||||
if (err) {
|
||||
this.error();
|
||||
}
|
||||
},
|
||||
|
||||
// terminateProgram
|
||||
async terminateProgram() {
|
||||
if (confirm("Are you sure you want to terminate the program?")) {
|
||||
alert("The program is terminated, any error messages are safe to ignore.")
|
||||
await this.call("terminate_program", {})
|
||||
}
|
||||
},
|
||||
// resetCreateDialog
|
||||
resetCreateDialog() {
|
||||
document.getElementById("splitting-accordion").open = false;
|
||||
|
||||
// resumeChannel
|
||||
async resumeChannel(username) {
|
||||
await this.call("resume_channel", { username })
|
||||
},
|
||||
// Ensure settings are loaded before resetting form_data
|
||||
this.form_data = {
|
||||
username: "",
|
||||
resolution: this.settings.resolution?.toString() || "1080",
|
||||
resolution_fallback: this.settings.resolution_fallback || "down",
|
||||
framerate: this.settings.framerate?.toString() || "30",
|
||||
filename_pattern: this.settings.filename_pattern || "{{.Username}}/{{.Year}}-{{.Month}}-{{.Day}}/{{.Username}}_{{.Hour}}-{{.Minute}}-{{.Second}}{{if .Sequence}}_{{.Sequence}}{{end}}",
|
||||
split_filesize: this.settings.split_filesize?.toString() || "0",
|
||||
split_duration: this.settings.split_duration?.toString() || "30",
|
||||
interval: this.settings.interval?.toString() || "1",
|
||||
};
|
||||
},
|
||||
|
||||
// listChannels
|
||||
async listChannels() {
|
||||
if (this.is_updating_channels) {
|
||||
return
|
||||
}
|
||||
var [resp, err] = await this.call("list_channels", {})
|
||||
if (!err) {
|
||||
this.channels = resp.channels
|
||||
this.channels.forEach(ch => {
|
||||
this.scrollLogs(ch.username)
|
||||
})
|
||||
}
|
||||
this.is_updating_channels = false
|
||||
},
|
||||
// createChannel
|
||||
async createChannel() {
|
||||
await this.call("create_channel", {
|
||||
username: this.form_data.username,
|
||||
resolution: parseInt(this.form_data.resolution),
|
||||
resolution_fallback: this.form_data.resolution_fallback,
|
||||
framerate: parseInt(this.form_data.framerate),
|
||||
filename_pattern: this.form_data.filename_pattern,
|
||||
split_filesize: parseInt(this.form_data.split_filesize),
|
||||
split_duration: parseInt(this.form_data.split_duration),
|
||||
interval: parseInt(this.form_data.interval),
|
||||
});
|
||||
},
|
||||
|
||||
// listenUpdate
|
||||
listenUpdate() {
|
||||
var source = new EventSource("/api/listen_update")
|
||||
// deleteChannel
|
||||
async deleteChannel(username) {
|
||||
if (!confirm(`Are you sure you want to delete the channel "${username}"?`)) {
|
||||
return;
|
||||
}
|
||||
var [_, err] = await this.call("delete_channel", { username });
|
||||
if (!err) {
|
||||
this.channels = this.channels.filter((ch) => ch.username !== username);
|
||||
}
|
||||
},
|
||||
|
||||
source.onmessage = event => {
|
||||
var data = JSON.parse(event.data)
|
||||
// pauseChannel
|
||||
async pauseChannel(username) {
|
||||
await this.call("pause_channel", { username });
|
||||
},
|
||||
|
||||
// If the channel is not in the list or is stopped, refresh the list.
|
||||
if (!this.channels.some(ch => ch.username === data.username) || data.is_stopped) {
|
||||
this.listChannels()
|
||||
return
|
||||
}
|
||||
// terminateProgram
|
||||
async terminateProgram() {
|
||||
if (confirm("Are you sure you want to terminate the program?")) {
|
||||
alert("The program is terminated, any error messages are safe to ignore.");
|
||||
await this.call("terminate_program", {});
|
||||
}
|
||||
},
|
||||
|
||||
var index = this.channels.findIndex(ch => ch.username === data.username)
|
||||
// resumeChannel
|
||||
async resumeChannel(username) {
|
||||
await this.call("resume_channel", { username });
|
||||
},
|
||||
|
||||
if (index === -1) {
|
||||
return
|
||||
}
|
||||
// listChannels
|
||||
async listChannels() {
|
||||
if (this.is_updating_channels) {
|
||||
return;
|
||||
}
|
||||
var [resp, err] = await this.call("list_channels", {});
|
||||
if (!err) {
|
||||
this.channels = resp.channels;
|
||||
this.currentPage = 1;
|
||||
this.channels.forEach((ch) => {
|
||||
this.scrollLogs(ch.username);
|
||||
});
|
||||
}
|
||||
this.is_updating_channels = false;
|
||||
},
|
||||
|
||||
this.channels[index].segment_duration = data.segment_duration
|
||||
this.channels[index].segment_filesize = data.segment_filesize
|
||||
this.channels[index].filename = data.filename
|
||||
this.channels[index].last_streamed_at = data.last_streamed_at
|
||||
this.channels[index].is_online = data.is_online
|
||||
this.channels[index].is_paused = data.is_paused
|
||||
this.channels[index].logs = [...this.channels[index].logs, data.log]
|
||||
// listenUpdate
|
||||
listenUpdate() {
|
||||
var source = new EventSource("/api/listen_update");
|
||||
|
||||
if (this.channels[index].logs.length > 100) {
|
||||
this.channels[index].logs = this.channels[index].logs.slice(-100)
|
||||
}
|
||||
source.onmessage = (event) => {
|
||||
var data = JSON.parse(event.data);
|
||||
|
||||
this.scrollLogs(data.username)
|
||||
}
|
||||
// If the channel is not in the list or is stopped, refresh the list.
|
||||
if (!this.channels.some((ch) => ch.username === data.username) || data.is_stopped) {
|
||||
this.listChannels();
|
||||
return;
|
||||
}
|
||||
|
||||
source.onerror = err => {
|
||||
source.close()
|
||||
}
|
||||
},
|
||||
var index = this.channels.findIndex((ch) => ch.username === data.username);
|
||||
|
||||
downloadLogs(username) {
|
||||
var a = window.document.createElement("a")
|
||||
a.href = window.URL.createObjectURL(
|
||||
new Blob([this.channels[this.channels.findIndex(ch => ch.username === username)].logs.join("\n")], { type: "text/plain", oneTimeOnly: true })
|
||||
)
|
||||
a.download = `${username}_logs.txt`
|
||||
document.body.appendChild(a)
|
||||
a.click()
|
||||
document.body.removeChild(a)
|
||||
},
|
||||
if (index === -1) {
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
scrollLogs(username) {
|
||||
// Wait for the DOM to update.
|
||||
setTimeout(() => {
|
||||
var logs_element = document.getElementById(`${username}-logs`)
|
||||
this.channels[index].segment_duration = data.segment_duration;
|
||||
this.channels[index].segment_filesize = data.segment_filesize;
|
||||
this.channels[index].filename = data.filename;
|
||||
this.channels[index].last_streamed_at = data.last_streamed_at;
|
||||
this.channels[index].is_online = data.is_online;
|
||||
this.channels[index].is_paused = data.is_paused;
|
||||
this.channels[index].logs = [...this.channels[index].logs, data.log];
|
||||
|
||||
if (!logs_element) {
|
||||
return
|
||||
}
|
||||
logs_element.scrollTop = logs_element.scrollHeight
|
||||
}, 1)
|
||||
},
|
||||
}
|
||||
if (this.channels[index].logs.length > 100) {
|
||||
this.channels[index].logs = this.channels[index].logs.slice(-100);
|
||||
}
|
||||
|
||||
this.scrollLogs(data.username);
|
||||
};
|
||||
|
||||
source.onerror = (err) => {
|
||||
source.close();
|
||||
};
|
||||
},
|
||||
|
||||
downloadLogs(username) {
|
||||
var a = window.document.createElement("a");
|
||||
a.href = window.URL.createObjectURL(new Blob([this.channels[this.channels.findIndex((ch) => ch.username === username)].logs.join("\n")], { type: "text/plain", oneTimeOnly: true }));
|
||||
a.download = `${username}_logs.txt`;
|
||||
document.body.appendChild(a);
|
||||
a.click();
|
||||
document.body.removeChild(a);
|
||||
},
|
||||
|
||||
//
|
||||
scrollLogs(username) {
|
||||
// Wait for the DOM to update.
|
||||
setTimeout(() => {
|
||||
var logs_element = document.getElementById(`${username}-logs`);
|
||||
|
||||
if (!logs_element) {
|
||||
return;
|
||||
}
|
||||
logs_element.scrollTop = logs_element.scrollHeight;
|
||||
}, 1);
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user