Работа над вкладкой "Конвертирование"
This commit is contained in:
@@ -318,6 +318,7 @@ class Reader extends Vue {
|
|||||||
this.enableSitesFilter = settings.enableSitesFilter;
|
this.enableSitesFilter = settings.enableSitesFilter;
|
||||||
this.showNeedUpdateNotify = settings.showNeedUpdateNotify;
|
this.showNeedUpdateNotify = settings.showNeedUpdateNotify;
|
||||||
this.splitToPara = settings.splitToPara;
|
this.splitToPara = settings.splitToPara;
|
||||||
|
this.djvuQuality = settings.djvuQuality;
|
||||||
|
|
||||||
this.readerActionByKeyCode = utils.userHotKeysObjectSwap(settings.userHotKeys);
|
this.readerActionByKeyCode = utils.userHotKeysObjectSwap(settings.userHotKeys);
|
||||||
this.$root.readerActionByKeyEvent = (event) => {
|
this.$root.readerActionByKeyEvent = (event) => {
|
||||||
@@ -973,10 +974,11 @@ class Reader extends Vue {
|
|||||||
if (!book) {
|
if (!book) {
|
||||||
book = await readerApi.loadBook({
|
book = await readerApi.loadBook({
|
||||||
url,
|
url,
|
||||||
|
uploadFileName,
|
||||||
|
enableSitesFilter: this.enableSitesFilter,
|
||||||
skipHtmlCheck: (this.splitToPara ? true : false),
|
skipHtmlCheck: (this.splitToPara ? true : false),
|
||||||
isText: (this.splitToPara ? true : false),
|
isText: (this.splitToPara ? true : false),
|
||||||
enableSitesFilter: this.enableSitesFilter,
|
djvuQuality: this.djvuQuality,
|
||||||
uploadFileName
|
|
||||||
},
|
},
|
||||||
(state) => {
|
(state) => {
|
||||||
progress.setState(state);
|
progress.setState(state);
|
||||||
|
|||||||
@@ -549,7 +549,7 @@ class SettingsPage extends Vue {
|
|||||||
margin-bottom: 5px;
|
margin-bottom: 5px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.label-1 {
|
.label-1, .label-7 {
|
||||||
width: 75px;
|
width: 75px;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -561,7 +561,7 @@ class SettingsPage extends Vue {
|
|||||||
width: 100px;
|
width: 100px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.label-1, .label-2, .label-3, .label-4, .label-5, .label-6 {
|
.label-1, .label-2, .label-3, .label-4, .label-5, .label-6, .label-7 {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
|
|||||||
@@ -3,10 +3,25 @@
|
|||||||
<span>Настройки конвертирования применяются ко всем</span>
|
<span>Настройки конвертирования применяются ко всем</span>
|
||||||
<span>вновь открываемым или обновляемым файлам</span>
|
<span>вновь открываемым или обновляемым файлам</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<!---------------------------------------------->
|
||||||
<div class="part-header">HTML, XML, TXT</div>
|
<div class="part-header">HTML, XML, TXT</div>
|
||||||
|
|
||||||
<div class="item row">
|
<div class="item row">
|
||||||
<div class="label-6">Сайты</div>
|
<div class="label-7">Текст</div>
|
||||||
|
<div class="col row">
|
||||||
|
<q-checkbox v-model="splitToPara" @input="needTextReload" size="xs" label="Попытаться разбить текст на параграфы">
|
||||||
|
<q-tooltip :delay="1000" anchor="top middle" self="bottom middle" content-style="font-size: 80%">
|
||||||
|
Опция принудительно включает эвристику разбиения текста на<br>
|
||||||
|
параграфы в случае, если формат файла определен как html,<br>
|
||||||
|
xml или txt. Возможна нечитабельная разметка текста.
|
||||||
|
</q-tooltip>
|
||||||
|
</q-checkbox>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="item row">
|
||||||
|
<div class="label-7">Сайты</div>
|
||||||
<div class="col row">
|
<div class="col row">
|
||||||
<q-checkbox v-model="enableSitesFilter" @input="needTextReload" size="xs" label="Включить html-фильтр для сайтов">
|
<q-checkbox v-model="enableSitesFilter" @input="needTextReload" size="xs" label="Включить html-фильтр для сайтов">
|
||||||
<q-tooltip :delay="1000" anchor="top middle" self="bottom middle" content-style="font-size: 80%">
|
<q-tooltip :delay="1000" anchor="top middle" self="bottom middle" content-style="font-size: 80%">
|
||||||
@@ -21,19 +36,21 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<!---------------------------------------------->
|
||||||
|
<div class="part-header">PDF</div>
|
||||||
|
|
||||||
|
<!---------------------------------------------->
|
||||||
|
<div class="part-header">DJVU</div>
|
||||||
<div class="item row">
|
<div class="item row">
|
||||||
<div class="label-6">Текст</div>
|
<div class="label-7">Качество</div>
|
||||||
<div class="col row">
|
<div class="col row">
|
||||||
<q-checkbox v-model="splitToPara" @input="needTextReload" size="xs" label="Попытаться разбить текст на параграфы">
|
<NumInput class="col-5" v-model="djvuQuality" :min="10" :max="100">
|
||||||
<q-tooltip :delay="1000" anchor="top middle" self="bottom middle" content-style="font-size: 80%">
|
<q-tooltip :delay="1000" anchor="top middle" self="bottom middle" content-style="font-size: 80%">
|
||||||
Опция принудительно включает эвристику разбиения текста на<br>
|
Качество конвертирования Djvu в Fb2. Чем значение выше, тем больше<br>
|
||||||
параграфы в случае, если формат файла определен как html,<br>
|
размер итогового файла. Если сервер отказывается конвертировать<br>
|
||||||
xml или txt. Возможна нечитабельная разметка текста.
|
слишком большой файл, то попробуйте понизить качество.
|
||||||
</q-tooltip>
|
</q-tooltip>
|
||||||
</q-checkbox>
|
</NumInput>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="part-header">PDF</div>
|
|
||||||
|
|
||||||
<div class="part-header">DJVU</div>
|
|
||||||
|
|||||||
@@ -253,6 +253,7 @@ const settingDefaults = {
|
|||||||
imageFitWidth: true,
|
imageFitWidth: true,
|
||||||
enableSitesFilter: true,
|
enableSitesFilter: true,
|
||||||
splitToPara: false,
|
splitToPara: false,
|
||||||
|
djvuQuality: 20,
|
||||||
|
|
||||||
showServerStorageMessages: true,
|
showServerStorageMessages: true,
|
||||||
showWhatsNewDialog: true,
|
showWhatsNewDialog: true,
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ class ReaderController extends BaseController {
|
|||||||
skipHtmlCheck: (request.hasOwnProperty('skipHtmlCheck') ? request.skipHtmlCheck : false),
|
skipHtmlCheck: (request.hasOwnProperty('skipHtmlCheck') ? request.skipHtmlCheck : false),
|
||||||
isText: (request.hasOwnProperty('isText') ? request.isText : false),
|
isText: (request.hasOwnProperty('isText') ? request.isText : false),
|
||||||
uploadFileName: (request.hasOwnProperty('uploadFileName') ? request.uploadFileName : false),
|
uploadFileName: (request.hasOwnProperty('uploadFileName') ? request.uploadFileName : false),
|
||||||
|
djvuQuality: (request.hasOwnProperty('djvuQuality') ? request.djvuQuality : false),
|
||||||
});
|
});
|
||||||
const state = this.workerState.getState(workerId);
|
const state = this.workerState.getState(workerId);
|
||||||
return (state ? state : {});
|
return (state ? state : {});
|
||||||
|
|||||||
@@ -16,7 +16,12 @@ class ConvertDjvu extends ConvertJpegPng {
|
|||||||
if (!this.check(data, opts))
|
if (!this.check(data, opts))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
const {inputFiles, callback, abort} = opts;
|
let {inputFiles, callback, abort, djvuQuality} = opts;
|
||||||
|
|
||||||
|
djvuQuality = (djvuQuality && djvuQuality <= 100 && djvuQuality >= 10 ? djvuQuality : 20);
|
||||||
|
let jpegQuality = djvuQuality;
|
||||||
|
let tiffQuality = djvuQuality + 30;
|
||||||
|
tiffQuality = (tiffQuality < 85 ? tiffQuality : 85);
|
||||||
|
|
||||||
const ddjvuPath = '/usr/bin/ddjvu';
|
const ddjvuPath = '/usr/bin/ddjvu';
|
||||||
if (!await fs.pathExists(ddjvuPath))
|
if (!await fs.pathExists(ddjvuPath))
|
||||||
@@ -40,7 +45,7 @@ class ConvertDjvu extends ConvertJpegPng {
|
|||||||
|
|
||||||
//конвертируем в tiff
|
//конвертируем в tiff
|
||||||
let perc = 0;
|
let perc = 0;
|
||||||
await this.execConverter(ddjvuPath, ['-format=tiff', '-quality=50', '-verbose', inputFiles.sourceFile, tifFile], () => {
|
await this.execConverter(ddjvuPath, ['-format=tiff', `-quality=${tiffQuality}`, '-verbose', inputFiles.sourceFile, tifFile], () => {
|
||||||
perc = (perc < 100 ? perc + 1 : 40);
|
perc = (perc < 100 ? perc + 1 : 40);
|
||||||
callback(perc);
|
callback(perc);
|
||||||
}, abort);
|
}, abort);
|
||||||
@@ -57,16 +62,24 @@ class ConvertDjvu extends ConvertJpegPng {
|
|||||||
await fs.remove(tifFile);
|
await fs.remove(tifFile);
|
||||||
|
|
||||||
//конвертируем в jpg
|
//конвертируем в jpg
|
||||||
await this.execConverter(mogrifyPath, ['-quality', '20', '-scale', '2048>', '-verbose', '-format', 'jpg', `${dir}*.tif`], () => {
|
await this.execConverter(mogrifyPath, ['-quality', jpegQuality, '-scale', '2048>', '-verbose', '-format', 'jpg', `${dir}*.tif`], () => {
|
||||||
perc = (perc < 100 ? perc + 1 : 40);
|
perc = (perc < 100 ? perc + 1 : 40);
|
||||||
callback(perc);
|
callback(perc);
|
||||||
}, abort);
|
}, abort);
|
||||||
|
|
||||||
|
limitSize = 2*this.config.maxUploadFileSize;
|
||||||
|
let jpgFilesSize = 0;
|
||||||
//ищем изображения
|
//ищем изображения
|
||||||
let files = [];
|
let files = [];
|
||||||
await utils.findFiles(async(file) => {
|
await utils.findFiles(async(file) => {
|
||||||
if (path.extname(file) == '.jpg')
|
if (path.extname(file) == '.jpg') {
|
||||||
|
jpgFilesSize += (await fs.stat(file)).size;
|
||||||
|
if (jpgFilesSize > limitSize) {
|
||||||
|
throw new Error(`Файл для конвертирования слишком большой|FORLOG| jpgFilesSize: ${jpgFilesSize} > ${limitSize}`);
|
||||||
|
}
|
||||||
|
|
||||||
files.push({name: file, base: path.basename(file)});
|
files.push({name: file, base: path.basename(file)});
|
||||||
|
}
|
||||||
}, dir);
|
}, dir);
|
||||||
|
|
||||||
files.sort((a, b) => a.base.localeCompare(b.base));
|
files.sort((a, b) => a.base.localeCompare(b.base));
|
||||||
|
|||||||
Reference in New Issue
Block a user