diff --git a/%1 b/%1
new file mode 100644
index 0000000..e69de29
diff --git a/api.go b/api.go
index f8067a4..e01920f 100644
--- a/api.go
+++ b/api.go
@@ -839,10 +839,20 @@ type dateToParse struct {
Parsed time.Time `json:"parseme"`
}
-// json magically parses datetimes so why not
-func parseDt(date string) time.Time {
+func parseDT(date string) time.Time {
+ // decent method
+ dt, err := time.Parse("2006-01-02T15:04:05.000000", date)
+ if err == nil {
+ return dt
+ }
+ // magic method
+ // some stored dates from jellyfin have no timezone at the end, if not we assume UTC
+ if date[len(date)-1] != 'Z' {
+ date += "Z"
+ }
timeJSON := []byte("{ \"parseme\": \"" + date + "\" }")
var parsed dateToParse
+ // Magically turn it into a time.Time
json.Unmarshal(timeJSON, &parsed)
return parsed.Parsed
}
@@ -869,8 +879,9 @@ func (app *appContext) GetUsers(gc *gin.Context) {
var user respUser
user.LastActive = "n/a"
if jfUser["LastActivityDate"] != nil {
- date := parseDt(jfUser["LastActivityDate"].(string))
+ date := parseDT(jfUser["LastActivityDate"].(string))
user.LastActive = app.formatDatetime(date)
+ // fmt.Printf("%s: %s, %s, %+v\n", jfUser["Name"].(string), jfUser["LastActivityDate"].(string), user.LastActive, date)
}
user.ID = jfUser["Id"].(string)
user.Name = jfUser["Name"].(string)
diff --git a/nohup.out b/nohup.out
new file mode 100644
index 0000000..8d292ec
--- /dev/null
+++ b/nohup.out
@@ -0,0 +1,8 @@
+Nov 29 23:37 : exception: Failed to bind to '[::]:6600'; Failed to bind socket: Address already in use
+/usr/bin/mpDris2:1367: DeprecationWarning: The SafeConfigParser class has been renamed to ConfigParser in Python 3.2. This alias will be removed in future versions. Use ConfigParser directly instead.
+ config = configparser.SafeConfigParser()
+2020-11-29 23:37:53,454 mpDris2 INFO: Using file:///home/hrfee/Music as music library path.
+2020-11-29 23:37:53,454 mpDris2 INFO: Using Mutagen to read covers from music files.
+2020-11-29 23:37:53,456 base INFO: Calling MPD connect('localhost', '6600', timeout=None)
+2020-11-29 23:37:57,776 mpDris2 INFO: Replaced by :1.24 (PID 1128)
+2020-11-29 23:37:57,777 base INFO: Calling MPD disconnect()
diff --git a/ts/accounts.ts b/ts/accounts.ts
index 6f74a7e..5955537 100644
--- a/ts/accounts.ts
+++ b/ts/accounts.ts
@@ -1,7 +1,7 @@
-import { checkCheckboxes, populateUsers, populateRadios } from "./modules/accounts.js";
-import { _post, _get, _delete, rmAttr, addAttr } from "./modules/common.js";
+import { checkCheckboxes, populateUsers, populateRadios, changeEmail, validateEmail } from "./modules/accounts.js";
+import { _post, _get, _delete, rmAttr, addAttr, createEl } from "./modules/common.js";
import { populateProfiles } from "./modules/settings.js";
-import { Focus, Unfocus, createEl, storeDefaults } from "./modules/admin.js";
+import { Focus, Unfocus, storeDefaults } from "./modules/admin.js";
interface aWindow extends Window {
changeEmail(icon: HTMLElement, id: string): void;
@@ -9,67 +9,7 @@ interface aWindow extends Window {
declare var window: aWindow;
-const validateEmail = (email: string): boolean => /\S+@\S+\.\S+/.test(email);
-
-window.changeEmail = (icon: HTMLElement, id: string): void => {
- const iconContent = icon.outerHTML;
- icon.setAttribute('class', '');
- const entry = icon.nextElementSibling as HTMLInputElement;
- const ogEmail = entry.value;
- entry.readOnly = false;
- entry.classList.remove('form-control-plaintext');
- entry.classList.add('form-control');
- if (ogEmail == "") {
- entry.placeholder = 'Address';
- }
- const tick = createEl(`
-
- `);
- tick.onclick = (): void => {
- const newEmail = entry.value;
- if (!validateEmail(newEmail) || newEmail == ogEmail) {
- return;
- }
- cross.remove();
- const spinner = createEl(`
-
- Saving...
-
- `);
- tick.replaceWith(spinner);
- let send = {};
- send[id] = newEmail;
- _post("/users/emails", send, function (): void {
- if (this.readyState == 4) {
- if (this.status == 200 || this.status == 204) {
- entry.nextElementSibling.remove();
- } else {
- entry.value = ogEmail;
- }
- }
- });
- icon.outerHTML = iconContent;
- entry.readOnly = true;
- entry.classList.remove('form-control');
- entry.classList.add('form-control-plaintext');
- entry.placeholder = '';
- };
- const cross = createEl(`
-
- `);
- cross.onclick = (): void => {
- tick.remove();
- cross.remove();
- icon.outerHTML = iconContent;
- entry.readOnly = true;
- entry.classList.remove('form-control');
- entry.classList.add('form-control-plaintext');
- entry.placeholder = '';
- entry.value = ogEmail;
- };
- icon.parentNode.appendChild(tick);
- icon.parentNode.appendChild(cross);
-};
+window.changeEmail = changeEmail;
(document.getElementById('selectAll')).onclick = function (): void {
const checkboxes: NodeListOf = document.getElementById('accountsList').querySelectorAll('input[type=checkbox]');
diff --git a/ts/modules/accounts.ts b/ts/modules/accounts.ts
index e72243c..1d5e661 100644
--- a/ts/modules/accounts.ts
+++ b/ts/modules/accounts.ts
@@ -1,4 +1,4 @@
-import { _get, _post, _delete } from "../modules/common.js";
+import { _get, _post, _delete, createEl } from "../modules/common.js";
import { Focus, Unfocus } from "../modules/admin.js";
interface aWindow extends Window {
@@ -7,6 +7,8 @@ interface aWindow extends Window {
declare var window: aWindow;
+export const validateEmail = (email: string): boolean => /\S+@\S+\.\S+/.test(email);
+
export const checkCheckboxes = (): void => {
const defaultsButton = document.getElementById('accountsTabSetDefaults');
const deleteButton = document.getElementById('accountsTabDelete');
@@ -28,6 +30,66 @@ export const checkCheckboxes = (): void => {
window.checkCheckboxes = checkCheckboxes;
+export function changeEmail(icon: HTMLElement, id: string): void {
+ const iconContent = icon.outerHTML;
+ icon.setAttribute('class', '');
+ const entry = icon.nextElementSibling as HTMLInputElement;
+ const ogEmail = entry.value;
+ entry.readOnly = false;
+ entry.classList.remove('form-control-plaintext');
+ entry.classList.add('form-control');
+ if (ogEmail == "") {
+ entry.placeholder = 'Address';
+ }
+ const tick = createEl(`
+
+ `);
+ tick.onclick = (): void => {
+ const newEmail = entry.value;
+ if (!validateEmail(newEmail) || newEmail == ogEmail) {
+ return;
+ }
+ cross.remove();
+ const spinner = createEl(`
+
+ Saving...
+
+ `);
+ tick.replaceWith(spinner);
+ let send = {};
+ send[id] = newEmail;
+ _post("/users/emails", send, function (): void {
+ if (this.readyState == 4) {
+ if (this.status == 200 || this.status == 204) {
+ entry.nextElementSibling.remove();
+ } else {
+ entry.value = ogEmail;
+ }
+ }
+ });
+ icon.outerHTML = iconContent;
+ entry.readOnly = true;
+ entry.classList.remove('form-control');
+ entry.classList.add('form-control-plaintext');
+ entry.placeholder = '';
+ };
+ const cross = createEl(`
+
+ `);
+ cross.onclick = (): void => {
+ tick.remove();
+ cross.remove();
+ icon.outerHTML = iconContent;
+ entry.readOnly = true;
+ entry.classList.remove('form-control');
+ entry.classList.add('form-control-plaintext');
+ entry.placeholder = '';
+ entry.value = ogEmail;
+ };
+ icon.parentNode.appendChild(tick);
+ icon.parentNode.appendChild(cross);
+};
+
export function populateUsers(): void {
const acList = document.getElementById('accountsList');
acList.innerHTML = `
@@ -53,10 +115,6 @@ export function populateUsers(): void {
return entry.outerHTML;
};
const template = (id: string, username: string, email: string, lastActive: string, admin: boolean): string => {
- let isAdmin = "No";
- if (admin) {
- isAdmin = "Yes";
- }
let fci = "form-check-input";
if (window.bsVersion != 5) {
fci = "";
diff --git a/ts/modules/admin.ts b/ts/modules/admin.ts
index 7fb983d..ade7cb8 100644
--- a/ts/modules/admin.ts
+++ b/ts/modules/admin.ts
@@ -1,14 +1,8 @@
-import { rmAttr, addAttr, _post, _get, _delete } from "../modules/common.js";
+import { rmAttr, addAttr, _post, _get, _delete, createEl } from "../modules/common.js";
export const Focus = (el: HTMLElement): void => rmAttr(el, 'unfocused');
export const Unfocus = (el: HTMLElement): void => addAttr(el, 'unfocused');
-export function createEl(html: string): HTMLElement {
- let div = document.createElement('div') as HTMLDivElement;
- div.innerHTML = html;
- return div.firstElementChild as HTMLElement;
-}
-
export function storeDefaults(users: string | Array): void {
const button = document.getElementById('storeDefaults') as HTMLButtonElement;
button.disabled = true;
diff --git a/ts/modules/common.ts b/ts/modules/common.ts
index c6b25be..39ba0d2 100644
--- a/ts/modules/common.ts
+++ b/ts/modules/common.ts
@@ -1,5 +1,11 @@
declare var window: Window;
+export function createEl(html: string): HTMLElement {
+ let div = document.createElement('div') as HTMLDivElement;
+ div.innerHTML = html;
+ return div.firstElementChild as HTMLElement;
+}
+
export function serializeForm(id: string): Object {
const form = document.getElementById(id) as HTMLFormElement;
let formData = {};