Перенос на сервер работы с именами файлов при скачивании
This commit is contained in:
@@ -231,12 +231,12 @@ class Api {
|
|||||||
return await this.request({action: 'get-genre-tree'});
|
return await this.request({action: 'get-genre-tree'});
|
||||||
}
|
}
|
||||||
|
|
||||||
async getBookLink(params) {
|
async getBookLink(bookId) {
|
||||||
return await this.request(Object.assign({action: 'get-book-link'}, params), 120);
|
return await this.request({action: 'get-book-link', bookId}, 120);
|
||||||
}
|
}
|
||||||
|
|
||||||
async getBookInfo(params) {
|
async getBookInfo(bookId) {
|
||||||
return await this.request(Object.assign({action: 'get-book-info'}, params), 120);
|
return await this.request({action: 'get-book-info', bookId}, 120);
|
||||||
}
|
}
|
||||||
|
|
||||||
async getConfig() {
|
async getConfig() {
|
||||||
|
|||||||
@@ -129,31 +129,8 @@ export default class BaseList {
|
|||||||
})();
|
})();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const makeValidFilenameOrEmpty = (s) => {
|
|
||||||
try {
|
|
||||||
return utils.makeValidFilename(s);
|
|
||||||
} catch(e) {
|
|
||||||
return '';
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
//имя файла
|
|
||||||
let downFileName = 'default-name';
|
|
||||||
const author = book.author.split(',');
|
|
||||||
const at = [author[0], book.title];
|
|
||||||
downFileName = makeValidFilenameOrEmpty(at.filter(r => r).join(' - '))
|
|
||||||
|| makeValidFilenameOrEmpty(at[0])
|
|
||||||
|| makeValidFilenameOrEmpty(at[1])
|
|
||||||
|| downFileName;
|
|
||||||
downFileName = downFileName.substring(0, 100);
|
|
||||||
|
|
||||||
const ext = `.${book.ext}`;
|
|
||||||
if (downFileName.substring(downFileName.length - ext.length) != ext)
|
|
||||||
downFileName += ext;
|
|
||||||
|
|
||||||
const bookPath = `${book.folder}/${book.file}${ext}`;
|
|
||||||
//подготовка
|
//подготовка
|
||||||
const response = await this.api.getBookLink({bookPath, downFileName});
|
const response = await this.api.getBookLink(book.id);
|
||||||
|
|
||||||
const link = response.link;
|
const link = response.link;
|
||||||
const href = `${window.location.origin}${link}`;
|
const href = `${window.location.origin}${link}`;
|
||||||
@@ -162,7 +139,7 @@ export default class BaseList {
|
|||||||
//скачивание
|
//скачивание
|
||||||
const d = this.$refs.download;
|
const d = this.$refs.download;
|
||||||
d.href = href;
|
d.href = href;
|
||||||
d.download = downFileName;
|
d.download = response.downFileName;
|
||||||
|
|
||||||
d.click();
|
d.click();
|
||||||
} else if (action == 'copyLink') {
|
} else if (action == 'copyLink') {
|
||||||
@@ -187,7 +164,7 @@ export default class BaseList {
|
|||||||
}
|
}
|
||||||
} else if (action == 'bookInfo') {
|
} else if (action == 'bookInfo') {
|
||||||
//информация о книге
|
//информация о книге
|
||||||
const response = await this.api.getBookInfo({bookPath, downFileName});
|
const response = await this.api.getBookInfo(book.id);
|
||||||
this.$emit('listEvent', {action: 'bookInfo', data: response.bookInfo});
|
this.$emit('listEvent', {action: 'bookInfo', data: response.bookInfo});
|
||||||
}
|
}
|
||||||
} catch(e) {
|
} catch(e) {
|
||||||
|
|||||||
@@ -87,18 +87,6 @@ export async function copyTextToClipboard(text) {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function makeValidFilename(filename, repl = '_') {
|
|
||||||
let f = filename.replace(/[\x00\\/:*"<>|]/g, repl); // eslint-disable-line no-control-regex
|
|
||||||
f = f.trim();
|
|
||||||
while (f.length && (f[f.length - 1] == '.' || f[f.length - 1] == '_')) {
|
|
||||||
f = f.substring(0, f.length - 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (f)
|
|
||||||
return f;
|
|
||||||
else
|
|
||||||
throw new Error('Invalid filename');
|
|
||||||
}
|
|
||||||
/*
|
/*
|
||||||
export function formatDate(d, format = 'normal') {
|
export function formatDate(d, format = 'normal') {
|
||||||
switch (format) {
|
switch (format) {
|
||||||
|
|||||||
@@ -165,23 +165,19 @@ class WebSocketController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async getBookLink(req, ws) {
|
async getBookLink(req, ws) {
|
||||||
if (!utils.hasProp(req, 'bookPath'))
|
if (!utils.hasProp(req, 'bookId'))
|
||||||
throw new Error(`bookPath is empty`);
|
throw new Error(`bookId is empty`);
|
||||||
if (!utils.hasProp(req, 'downFileName'))
|
|
||||||
throw new Error(`downFileName is empty`);
|
|
||||||
|
|
||||||
const result = await this.webWorker.getBookLink({bookPath: req.bookPath, downFileName: req.downFileName});
|
const result = await this.webWorker.getBookLink(req.bookId);
|
||||||
|
|
||||||
this.send(result, req, ws);
|
this.send(result, req, ws);
|
||||||
}
|
}
|
||||||
|
|
||||||
async getBookInfo(req, ws) {
|
async getBookInfo(req, ws) {
|
||||||
if (!utils.hasProp(req, 'bookPath'))
|
if (!utils.hasProp(req, 'bookId'))
|
||||||
throw new Error(`bookPath is empty`);
|
throw new Error(`bookId is empty`);
|
||||||
if (!utils.hasProp(req, 'downFileName'))
|
|
||||||
throw new Error(`downFileName is empty`);
|
|
||||||
|
|
||||||
const result = await this.webWorker.getBookInfo({bookPath: req.bookPath, downFileName: req.downFileName});
|
const result = await this.webWorker.getBookInfo(req.bookId);
|
||||||
|
|
||||||
this.send(result, req, ws);
|
this.send(result, req, ws);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -400,17 +400,36 @@ class WebWorker {
|
|||||||
return link;
|
return link;
|
||||||
}
|
}
|
||||||
|
|
||||||
async getBookLink(params) {
|
async getBookLink(bookId) {
|
||||||
this.checkMyState();
|
this.checkMyState();
|
||||||
|
|
||||||
const {bookPath, downFileName} = params;
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const db = this.db;
|
const db = this.db;
|
||||||
let link = '';
|
let link = '';
|
||||||
|
|
||||||
|
//найдем bookPath и downFileName
|
||||||
|
let rows = await db.select({table: 'book', where: `@@id(${db.esc(bookId)})`});
|
||||||
|
if (!rows.length)
|
||||||
|
throw new Error('404 Файл не найден');
|
||||||
|
|
||||||
|
const book = rows[0];
|
||||||
|
let downFileName = book.file;
|
||||||
|
const author = book.author.split(',');
|
||||||
|
const at = [author[0], book.title];
|
||||||
|
downFileName = utils.makeValidFileNameOrEmpty(at.filter(r => r).join(' - '))
|
||||||
|
|| utils.makeValidFileNameOrEmpty(at[0])
|
||||||
|
|| utils.makeValidFileNameOrEmpty(at[1])
|
||||||
|
|| downFileName;
|
||||||
|
downFileName = downFileName.substring(0, 100);
|
||||||
|
|
||||||
|
const ext = `.${book.ext}`;
|
||||||
|
if (downFileName.substring(downFileName.length - ext.length) != ext)
|
||||||
|
downFileName += ext;
|
||||||
|
|
||||||
|
const bookPath = `${book.folder}/${book.file}${ext}`;
|
||||||
|
|
||||||
//найдем хеш
|
//найдем хеш
|
||||||
const rows = await db.select({table: 'file_hash', where: `@@id(${db.esc(bookPath)})`});
|
rows = await db.select({table: 'file_hash', where: `@@id(${db.esc(bookPath)})`});
|
||||||
if (rows.length) {//хеш найден по bookPath
|
if (rows.length) {//хеш найден по bookPath
|
||||||
const hash = rows[0].hash;
|
const hash = rows[0].hash;
|
||||||
const bookFile = `${this.config.filesDir}/${hash}`;
|
const bookFile = `${this.config.filesDir}/${hash}`;
|
||||||
@@ -428,7 +447,7 @@ class WebWorker {
|
|||||||
if (!link)
|
if (!link)
|
||||||
throw new Error('404 Файл не найден');
|
throw new Error('404 Файл не найден');
|
||||||
|
|
||||||
return {link};
|
return {link, bookPath, downFileName};
|
||||||
} catch(e) {
|
} catch(e) {
|
||||||
log(LM_ERR, `getBookLink error: ${e.message}`);
|
log(LM_ERR, `getBookLink error: ${e.message}`);
|
||||||
if (e.message.indexOf('ENOENT') >= 0)
|
if (e.message.indexOf('ENOENT') >= 0)
|
||||||
@@ -437,18 +456,20 @@ class WebWorker {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async getBookInfo(params) {
|
async getBookInfo(bookId) {
|
||||||
this.checkMyState();
|
this.checkMyState();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
//const db = this.db;
|
const db = this.db;
|
||||||
let link = await this.getBookLink(params);
|
|
||||||
const hash = path.basename(link.link);
|
|
||||||
|
|
||||||
/*const bookFile = `${this.config.filesDir}/${hash}`;
|
const bookInfo = await this.getBookLink(bookId);
|
||||||
const bookInfo = await fb2parser*/
|
|
||||||
|
|
||||||
return {hash};
|
const rows = await db.select({table: 'book', where: `@@id(${db.esc(bookId)})`});
|
||||||
|
bookInfo.book = rows[0];
|
||||||
|
bookInfo.fb2 = {};
|
||||||
|
bookInfo.cover = '';
|
||||||
|
|
||||||
|
return {bookInfo};
|
||||||
} catch(e) {
|
} catch(e) {
|
||||||
log(LM_ERR, `getBookInfo error: ${e.message}`);
|
log(LM_ERR, `getBookInfo error: ${e.message}`);
|
||||||
if (e.message.indexOf('ENOENT') >= 0)
|
if (e.message.indexOf('ENOENT') >= 0)
|
||||||
@@ -457,48 +478,6 @@ class WebWorker {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
async restoreBookFile(publicPath) {
|
|
||||||
this.checkMyState();
|
|
||||||
|
|
||||||
try {
|
|
||||||
const db = this.db;
|
|
||||||
const hash = path.basename(publicPath);
|
|
||||||
|
|
||||||
//найдем bookPath и downFileName
|
|
||||||
const rows = await db.select({table: 'file_hash', where: `@@id(${db.esc(hash)})`});
|
|
||||||
if (rows.length) {//нашли по хешу
|
|
||||||
const rec = rows[0];
|
|
||||||
await this.restoreBook(rec.bookPath, rec.downFileName);
|
|
||||||
|
|
||||||
return rec.downFileName;
|
|
||||||
} else {//bookPath не найден
|
|
||||||
throw new Error('404 Файл не найден');
|
|
||||||
}
|
|
||||||
} catch(e) {
|
|
||||||
log(LM_ERR, `restoreBookFile error: ${e.message}`);
|
|
||||||
if (e.message.indexOf('ENOENT') >= 0)
|
|
||||||
throw new Error('404 Файл не найден');
|
|
||||||
throw e;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async getDownFileName(publicPath) {
|
|
||||||
this.checkMyState();
|
|
||||||
|
|
||||||
const db = this.db;
|
|
||||||
const hash = path.basename(publicPath);
|
|
||||||
|
|
||||||
//найдем downFileName
|
|
||||||
const rows = await db.select({table: 'file_hash', where: `@@id(${db.esc(hash)})`});
|
|
||||||
if (rows.length) {//downFileName найден по хешу
|
|
||||||
return rows[0].downFileName;
|
|
||||||
} else {//bookPath не найден
|
|
||||||
throw new Error('404 Файл не найден');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
async getInpxFile(params) {
|
async getInpxFile(params) {
|
||||||
let data = null;
|
let data = null;
|
||||||
if (params.inpxFileHash && this.inpxFileHash && params.inpxFileHash === this.inpxFileHash) {
|
if (params.inpxFileHash && this.inpxFileHash && params.inpxFileHash === this.inpxFileHash) {
|
||||||
|
|||||||
@@ -119,6 +119,27 @@ function toUnixPath(dir) {
|
|||||||
return dir.replace(/\\/g, '/');
|
return dir.replace(/\\/g, '/');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function makeValidFileName(fileName, repl = '_') {
|
||||||
|
let f = fileName.replace(/[\x00\\/:*"<>|]/g, repl); // eslint-disable-line no-control-regex
|
||||||
|
f = f.trim();
|
||||||
|
while (f.length && (f[f.length - 1] == '.' || f[f.length - 1] == '_')) {
|
||||||
|
f = f.substring(0, f.length - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (f)
|
||||||
|
return f;
|
||||||
|
else
|
||||||
|
throw new Error('Invalid filename');
|
||||||
|
}
|
||||||
|
|
||||||
|
function makeValidFileNameOrEmpty(fileName) {
|
||||||
|
try {
|
||||||
|
return makeValidFileName(fileName);
|
||||||
|
} catch(e) {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
sleep,
|
sleep,
|
||||||
processLoop,
|
processLoop,
|
||||||
@@ -133,4 +154,6 @@ module.exports = {
|
|||||||
randomHexString,
|
randomHexString,
|
||||||
gzipFile,
|
gzipFile,
|
||||||
toUnixPath,
|
toUnixPath,
|
||||||
|
makeValidFileName,
|
||||||
|
makeValidFileNameOrEmpty,
|
||||||
};
|
};
|
||||||
Reference in New Issue
Block a user