253 lines
5.3 KiB
TypeScript
253 lines
5.3 KiB
TypeScript
/* eslint-disable @typescript-eslint/camelcase */
|
|
"use strict";
|
|
// License: MIT
|
|
|
|
import { parsePath, sanitizePath } from "../util";
|
|
import { _ } from "../i18n";
|
|
|
|
const REPLACE_EXPR = /\*\w+\*/gi;
|
|
|
|
const BATCH_FORMATTER = new Intl.NumberFormat(undefined, {
|
|
style: "decimal",
|
|
useGrouping: false,
|
|
minimumIntegerDigits: 3,
|
|
maximumFractionDigits: 0
|
|
});
|
|
|
|
const DATE_FORMATTER = new Intl.NumberFormat(undefined, {
|
|
style: "decimal",
|
|
useGrouping: false,
|
|
minimumIntegerDigits: 2,
|
|
maximumFractionDigits: 0
|
|
});
|
|
|
|
export default class Renamer {
|
|
private readonly d: any;
|
|
|
|
constructor(download: any) {
|
|
this.d = download;
|
|
}
|
|
|
|
get nameinfo() {
|
|
return parsePath(this.d.finalName);
|
|
}
|
|
|
|
get ref() {
|
|
return this.d.uReferrer;
|
|
}
|
|
|
|
|
|
get p_name() {
|
|
return this.nameinfo.base;
|
|
}
|
|
|
|
get p_ext() {
|
|
return this.nameinfo.ext;
|
|
}
|
|
|
|
get p_text() {
|
|
return this.d.description;
|
|
}
|
|
|
|
get p_title() {
|
|
return this.d.title;
|
|
}
|
|
|
|
get p_host() {
|
|
return this.d.uURL.host;
|
|
}
|
|
|
|
get p_domain() {
|
|
return this.d.uURL.domain;
|
|
}
|
|
|
|
get p_subdirs() {
|
|
return parsePath(this.d.uURL).path;
|
|
}
|
|
|
|
get p_qstring() {
|
|
const {search} = this.d.uURL;
|
|
return search && search.substr(1).replace(/\/+/g, "-");
|
|
}
|
|
|
|
get p_url() {
|
|
return this.d.usable.substr(this.d.uURL.protocol.length + 2);
|
|
}
|
|
|
|
get p_batch() {
|
|
return BATCH_FORMATTER.format(this.d.batch);
|
|
}
|
|
|
|
get p_num() {
|
|
return BATCH_FORMATTER.format(this.d.batch);
|
|
}
|
|
|
|
get p_idx() {
|
|
return BATCH_FORMATTER.format(this.d.idx);
|
|
}
|
|
|
|
get p_date() {
|
|
return `${this.p_y}${this.p_m}${this.p_d}T${this.p_hh}${this.p_mm}${this.p_ss}`;
|
|
}
|
|
|
|
get p_refname() {
|
|
const {ref} = this;
|
|
if (!ref) {
|
|
return null;
|
|
}
|
|
return parsePath(ref).base;
|
|
}
|
|
|
|
get p_refext() {
|
|
const {ref} = this;
|
|
if (!ref) {
|
|
return null;
|
|
}
|
|
return parsePath(ref).ext;
|
|
}
|
|
|
|
get p_refhost() {
|
|
const {ref} = this;
|
|
if (!ref) {
|
|
return null;
|
|
}
|
|
return ref.host;
|
|
}
|
|
|
|
get p_refdomain() {
|
|
const {ref} = this;
|
|
if (!ref) {
|
|
return null;
|
|
}
|
|
return ref.domain;
|
|
}
|
|
|
|
get p_refsubdirs() {
|
|
const {ref} = this;
|
|
if (!ref) {
|
|
return null;
|
|
}
|
|
return parsePath(ref).path;
|
|
}
|
|
|
|
get p_refqstring() {
|
|
const {ref} = this;
|
|
if (!ref) {
|
|
return null;
|
|
}
|
|
const {search} = ref;
|
|
return search && search.substr(1).replace(/\/+/g, "-");
|
|
}
|
|
|
|
get p_refurl() {
|
|
return this.d.usableReferrer.substr(
|
|
this.d.uReferrer.protocol.length + 2);
|
|
}
|
|
|
|
get p_hh() {
|
|
return DATE_FORMATTER.format(this.d.startDate.getHours());
|
|
}
|
|
|
|
get p_mm() {
|
|
return DATE_FORMATTER.format(this.d.startDate.getMinutes());
|
|
}
|
|
|
|
get p_ss() {
|
|
return DATE_FORMATTER.format(this.d.startDate.getSeconds());
|
|
}
|
|
|
|
get p_d() {
|
|
return DATE_FORMATTER.format(this.d.startDate.getDate());
|
|
}
|
|
|
|
get p_m() {
|
|
return DATE_FORMATTER.format(this.d.startDate.getMonth() + 1);
|
|
}
|
|
|
|
get p_y() {
|
|
return DATE_FORMATTER.format(this.d.startDate.getFullYear());
|
|
}
|
|
|
|
toString() {
|
|
const {mask} = this.d;
|
|
// eslint-disable-next-line @typescript-eslint/no-this-alias
|
|
const self: any = this;
|
|
// XXX flat
|
|
return sanitizePath(mask.replace(REPLACE_EXPR, function(type: string) {
|
|
let prop = type.substr(1, type.length - 2);
|
|
const flat = prop.startsWith("flat");
|
|
if (flat) {
|
|
prop = prop.substr(4);
|
|
}
|
|
prop = `p_${prop}`;
|
|
const rv = (prop in self) ?
|
|
(self[prop] || "").trim() :
|
|
type;
|
|
if (flat) {
|
|
return rv.replace(/\/+/g, "-");
|
|
}
|
|
return rv;
|
|
}));
|
|
}
|
|
}
|
|
|
|
export const SUPPORTED =
|
|
Object.keys(Object.getOwnPropertyDescriptors(Renamer.prototype)).
|
|
filter(k => k.startsWith("p_")).
|
|
map(k => k.slice(2));
|
|
|
|
function makeHTMLMap() {
|
|
const e = document.createElement("section");
|
|
e.className = "renamer-map";
|
|
|
|
const head = document.createElement("h2");
|
|
head.className = "renamer-head";
|
|
head.textContent = _("renamer-tags");
|
|
e.appendChild(head);
|
|
|
|
const tags = SUPPORTED;
|
|
const mid = Math.ceil(tags.length / 2);
|
|
for (const half of [tags.slice(0, mid), tags.slice(mid)]) {
|
|
const cont = document.createElement("div");
|
|
cont.className = "renamer-half";
|
|
for (const k of half) {
|
|
const tag = document.createElement("code");
|
|
tag.className = "renamer-tag";
|
|
tag.textContent = `*${k}*`;
|
|
cont.appendChild(tag);
|
|
|
|
const label = document.createElement("label");
|
|
label.className = "renamer-label";
|
|
label.textContent = _(`renamer-${k}`);
|
|
cont.appendChild(label);
|
|
}
|
|
e.appendChild(cont);
|
|
}
|
|
const info = document.createElement("em");
|
|
info.className = "renamer-info";
|
|
info.textContent = _("renamer-info");
|
|
e.appendChild(info);
|
|
return e;
|
|
}
|
|
|
|
export function hookButton(maskButton: HTMLElement) {
|
|
let maskMap: HTMLElement;
|
|
maskButton.addEventListener("click", (evt: MouseEvent) => {
|
|
evt.preventDefault();
|
|
evt.stopPropagation();
|
|
|
|
const {top, right} = maskButton.getBoundingClientRect();
|
|
if (!maskMap) {
|
|
maskMap = makeHTMLMap();
|
|
document.body.appendChild(maskMap);
|
|
maskMap.classList.add("hidden");
|
|
}
|
|
maskMap.classList.toggle("hidden");
|
|
if (!maskMap.classList.contains("hidden")) {
|
|
const maskRect = maskMap.getBoundingClientRect();
|
|
maskMap.style.top = `${top - maskRect.height - 10}px`;
|
|
maskMap.style.left = `${right - maskRect.width}px`;
|
|
}
|
|
});
|
|
}
|