mirror of
https://github.com/hrfee/jfa-go.git
synced 2024-12-22 09:00:10 +00:00
fix/improve parsing of last active dates
parseDT only uses the magic json.Unmarshal method if theres an error with the better version. Error came from some times being sent without a "Z" at the end denoting UTC.
This commit is contained in:
parent
3c952d21f7
commit
a1e30ff5db
17
api.go
17
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)
|
||||
|
8
nohup.out
Normal file
8
nohup.out
Normal file
@ -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()
|
@ -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(`
|
||||
<i class="fa fa-check d-inline-block icon-button text-success" style="margin-left: 0.5rem; margin-right: 0.5rem;"></i>
|
||||
`);
|
||||
tick.onclick = (): void => {
|
||||
const newEmail = entry.value;
|
||||
if (!validateEmail(newEmail) || newEmail == ogEmail) {
|
||||
return;
|
||||
}
|
||||
cross.remove();
|
||||
const spinner = createEl(`
|
||||
<div class="spinner-border spinner-border-sm" role="status" style="width: 1rem; height: 1rem; margin-left: 0.5rem;">
|
||||
<span class="sr-only">Saving...</span>
|
||||
</div>
|
||||
`);
|
||||
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(`
|
||||
<i class="fa fa-close d-inline-block icon-button text-danger"></i>
|
||||
`);
|
||||
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;
|
||||
|
||||
(<HTMLInputElement>document.getElementById('selectAll')).onclick = function (): void {
|
||||
const checkboxes: NodeListOf<HTMLInputElement> = document.getElementById('accountsList').querySelectorAll('input[type=checkbox]');
|
||||
|
@ -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(`
|
||||
<i class="fa fa-check d-inline-block icon-button text-success" style="margin-left: 0.5rem; margin-right: 0.5rem;"></i>
|
||||
`);
|
||||
tick.onclick = (): void => {
|
||||
const newEmail = entry.value;
|
||||
if (!validateEmail(newEmail) || newEmail == ogEmail) {
|
||||
return;
|
||||
}
|
||||
cross.remove();
|
||||
const spinner = createEl(`
|
||||
<div class="spinner-border spinner-border-sm" role="status" style="width: 1rem; height: 1rem; margin-left: 0.5rem;">
|
||||
<span class="sr-only">Saving...</span>
|
||||
</div>
|
||||
`);
|
||||
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(`
|
||||
<i class="fa fa-close d-inline-block icon-button text-danger"></i>
|
||||
`);
|
||||
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 = "";
|
||||
|
@ -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<string>): void {
|
||||
const button = document.getElementById('storeDefaults') as HTMLButtonElement;
|
||||
button.disabled = true;
|
||||
|
@ -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 = {};
|
||||
|
Loading…
Reference in New Issue
Block a user