5077 сомнений.

5077 сомнений.

Ну вот. Начала, наконец, прожевываться перловка, скрипты хоть кое-как зафурычили, стремительным домкратом наросла библиотечка полезных сабрутинок, и в тумане перспективы стал вырисовываться первый результат: 5077.

5077 - это число книжек из AldLit (это, совместно, Альдебаран36163 и Литрес4415), которых, по нынешнему мнению скрипта-сравнилки, нет в Либрусеке.

На самом деле множество из них таки в Либрусеке есть, и я хотел бы уменьшить это число 5077 - более правильным сравнением книг из AldLit и из Либрусека. Но тут я теряюсь в сомнениях. Помогите соображениями о возможных подводных камнях, братие и сестрие! По вот этим поводам.

Деёфикация:
Сейчас "Звездная тень" и "Звёздная тень" считаются разными книгами. Может быть, превратить все "ё" в "е", и только после этого сравнивать?

Декавычкизация:
Сейчас "«Л» – значит люди" и "Л – значит люди" считаются разными книгами. Может быть, уничтожить все виды кавычек, и только после этого сравнивать?

Детирезация:
Сейчас "Звезды — холодные игрушки" (тут имеется в виду en dash, em dash, etc.) и "Звезды – холодные игрушки" (minus sign, hyphen) считаются разными книгами. Может быть, привести все виды тире к дефису (minus sign, hyphen), и только после этого сравнивать?

Ещё я хочу спросить уважаемое сообщество про этавот, о книгах из AldLit, стоящих в первой очереди к заливке на Либрусек:

1. Конвертировать ли в UTF-8 те книги, которые сейчас в другой кодировке?
2. Писать ли в history, и если писать, то что?
3. Прошу прокомментировать предполагаемый порядок предзаливочной обработки, может я чего упустил.
4. Самый кривой вопрос... как, черт побери, формируются зипы, которые на http://lib.rus.ec/allbooks и http://lib.rus.ec/all/daily/ ? Я имею в виду... скажем, если книгу из Либрусека удалили или заменили на лучший вариант, в зипах ведь она всё равно остаётся, зипы ведь не переформировываются заново?

Предполагаемый порядок предзаливочной обработки:
1. Записать в history предлибрусечное происхождение - Альдебаран36163 или Литрес4415 (?)
2. Конвертировать все файлы в кодировку UTF-8 (и записать это действие в history?).
3. Прогнать через FB2Fix - это также приподнимет версию на 0.01
4. Прогнать через fb2-renaming, по схеме: Familiya_Imya_Otchestvo_(Niknejm)_(Serial-#)_Nazvanie_knigi.fb2 . При этом _Otchestvo, _(Niknejm), и _(Serial-#) - опциональны, вставляются только при наличии таковых в дескрипшне. Если авторов много, автор берется только первый.

Updated: Предполагаемый порядок предзаливочной обработки (именно в изложенном порядке):

1. Записать в custom-info (не в history) предлибрусечное происхождение - Aldebaran36163 или Litres4415 (Perl script)

2. Инкрементировать версию на 0.01 0.001 (по просьбе Bullfear) (Perl script, поскольку FB2Fix на этой операции иногда пропускает файлы)

3. Прогнать через FB2Fix (попутно конвертировать все файлы в кодировку UTF-8, конвертирование никуда не записывать) (FB2Fix) Используемая версия Fb2Fix 1.0.8. Содержимое options-файла:
/compress-
/indentheader+
/indentbody-
/incversion-
/mapgenres-
/validate-
/rename-
/loglevel:Verbose
/logfile:F:\5525-NEW-step03-fb2fixed-fb2fix.log.txt
/output:F:\5525-NEW-step03-fb2fixed
/encoding:UTF-8
/recurse-
/force-

4. Прогнать через fb2-renaming, по схеме: Familiya_Imya_(Serial-#)_Nazvanie_knigi.fb2 . При этом _(Serial-#) - опционально, вставляются только при наличии таковых в дескрипшне. Если авторов много, автор берется только первый. (Perl script)

Updated: новое магическое число, после улучшения логики сравнивалки - 4511.

Updated: Самое-самое последнее магическое число - 4509. Да и то благополучно закончилось :))

http://lib.rus.ec/sites/default/files/4509-list-by-title.txt 805.48 кб
http://lib.rus.ec/sites/default/files/4509-list-by-author.txt 805.48 кб

---------------------------------
Для справки и прояснения о чем, собственно, речь:
Что такое Альдебаран36163: http://lib.rus.ec/node/107093
Что такое Литрес4415: http://lib.rus.ec/node/105819
AldLit = Альдебаран36163 плюс Литрес4415 минус внутренние дубли и некоторые проблемные файлы.
AldLit готовится к заливке на Либрусек.
5077 (на сегодняшний день) - это часть AldLit, первая очередь к заливке на Либрусек, книги, которых (условно) на Либрусеке нет вовсе.
Вторая и последующие очереди к заливке будут состоять из книг из AldLit, которые на Либрусеке есть, но сделаны LibRusEcKit или eBookDownLoader.

Комментарии

4509 благополучно кончились :))

Интересный глюк случился при заливке этой коллекции.
У книги Меня зовут "Бендер" аннотация от Наполеон. Последняя любовь
При попытке исправить аннотацию, оказалась, что она общая для обеих книг, изменения происходят сразу и в той и в другой! Как случилось такое объединение и как его отменить?
Удалось исправить: скачал, удалил из библиотеки, залил по-новой.

sd написал:
Интересный глюк случился при заливке этой коллекции.
У книги Меня зовут "Бендер" аннотация от Наполеон. Последняя любовь
При попытке исправить аннотацию, оказалась, что она общая для обеих книг, изменения происходят сразу и в той и в другой! Как случилось такое объединение и как его отменить?
Удалось исправить: скачал, удалил из библиотеки, залил по-новой.

Пока я дрых уже исправили... а глюк и правда интересный, я такого и не припомню.

На "Списке проектов" появилось сообщение еще об одном таком баге. Исправлять не стал, посмотрите в чем там дело.
(http://lib.rus.ec/b/117281) получтил аннотацию от (http://lib.rus.ec/b/117183)

> На "Списке проектов" появилось сообщение еще об одном таком баге. Исправлять не стал, посмотрите в чем там дело.

Сначала подумал, что заблуждаетесь. Но оказались правы. Кусочки для прояснения (комментарии мои):

<?php
Global $PD; // если несколько книжек, то сия штука сохраняется (глобальная переменная)
.
.
function
parse_fb2_document_info($f) {
  unset (
$GLOBALS['PD']); // тут верно, обнуляют все разом
 
Global $PD;
.
.
function
parsefb2($fb2, $f1 = 'libParserStart', $f2 = 'libParserEnd', $f3 = 'libParserData') {
  Global
$PD, $user; // но в этой функции обнуления нет, а вроде как она вызывается в остальных скриптах-модулях
?>

Возможно, повторяю возможно, поможет простое unset в parsefb2. Нужно обращаться к создателю.

Я правильно понимаю, что ошибка появляется при закачке сразу нескольких книг, в некоторых из которых нет annotation?

Нет, промах. Действительно одна аннотация на две книги. Я пас.

Если книгу с бОльшим номером удалить, а потом залить ее по новой, то ошибка исчезает и у книги появляется аннотация выдернутая из описания. Если востановить удаленную - ошибка появляется вновь. Т.е. ошибка привязана к определенному номеру файла.

Pavel_V написал:
Возможно, повторяю возможно, поможет простое unset в parsefb2. Нужно обращаться к создателю.

Внутри parsefb2 нельзя делать unset. В $PD передаются некоторые параметры для парсера.

Ковыряясь в результатах заливки, кажется, понял поведение Либрусека при разметке сериалов. В fb2-схеме тег sequence может присутствовать аж в трех местах: в title-info, в src-title-info и в publish-info.

Пример: http://lib.rus.ec/b/114885 (Азимов, Логика есть логика)

1. В title-info <sequence name="Рассказы о демоне Азазеле" />
2. src-title-info отсутствут целиком
3. В publish-info <sequence name="Миры Айзека Азимова" number="12" />

При заливке победил sequence из publish-info, что, в общем, логично. А я при fb2-переименовании ориентировался только на sequence из title-info. Надо будет сделать учет всех трех, с приоритетом publish-info - старший, title-info - самый младший.

Кстати, в Либрусеке на страничке редактирования книги теги sequence не показываются (баг?).

pkn написал:
Ковыряясь в результатах заливки, кажется, понял поведение Либрусека при разметке сериалов. В fb2-схеме тег sequence может присутствовать аж в трех местах: в title-info, в src-title-info и в publish-info.

Серия к которой относится произведение автора это одно, а издательская серия - это совсем другое :-)
И они вполне могут быть разными

> При заливке победил sequence из publish-info, что, в общем, логично.

Баг из той же серии, что и этот. Толко хуже - одно строчкой не обойтись уже. Не предусмотрено было несколько sequence изначально. Вот отрывок из того же parse.inc:

<?php
  
case 'SEQUENCE':
     
$PD->sequencenumber = $attrs['number'];
     
$PD->sequencename = $attrs['name'];
    return;
?>

Т.е. здесь используется не массив, как в случае с авторами, а строка. Но я плохо знаю как устроены внутренности lib.rus.ec, и вообще ничего не знаю про Drupal. Но полагаю, что нужно сделать по образу и подобию с author, типа так:
<?php
  
case 'SEQUENCE':
     
$PD->sequences[] = AddSeqId($attrs['name'], $attrs['number']);
    return;
?>

Естественно, нужна новая функция AddSeqId, кою ещё нужно встроить в двух-трех местах, убрать лишнее. Много кода перетрясти придеться - новые глюки вылезти могут.

Где багтрекер?

Багтрекер нашел, вот:
http://lib.rus.ec/forums-6

Pavel_V написал:
>
Естественно, нужна новая функция AddSeqId, кою ещё нужно встроить в двух-трех местах, убрать лишнее. Много кода перетрясти придеться - новые глюки вылезти могут.

Кода перетрясти придётся пол библиотеки.
SeqId сидит в libbook, отдельной таблицы нет. На наличии нескольких сериалов у одной книги совершенно не расчитано. Придётся пересматривать все места где есть SELECT FROM libbook, заменяя на libbook LEFT JOIN libseq USING(BookId), их сотни, перепрограммировать все списки книг с учётом многосериальности. Да и скорости лишний JOIN не добавит.
Не уверен, что оно того стоит. Несколько авторов бывает часто, а вот несколько сериалов - это уже редкость.

> Кода перетрясти придётся пол библиотеки.
Хорошо, тогда следует вставить костыли в парсере. Как уже говорили - выставить приоритеты. Серия книги приоритетней серии бумажного издания (автор для нас важнее издательских крыс!). Все просто думаю - если уже есть - не переписывать (if(empty($seria)) $seria=$tomy_to). Ведь вначале идет именно серия книги.

> Внутри parsefb2 нельзя делать unset.
Хорошо, но можно удалить тот же annotation ($PD['ann']). И по возможности удалить все, что относиться к книге. Иначе, если в последующей книжке в цикле чего-то не хватает, то копируется из предыдущей. Конечно, опять костыль, не совсем верно. Ох уж эти глобальные переменные.

Но не понятно мне, почему одна аннотация на две книги? Связанно ли это с тем, что "случайно" оказались одинаковые аннотации. Магия друпала?

Нужно разговор на форум перенести. Уже несколько подобных багов поднакопилось.

Bullfear, тут готовятся к заливке вторая и третья очереди из AldLit - подтверди, пожалуйста, что версию нужно приподнимать на 0.001, а не 0.01. Спрашиваю на всякий случай, а то может ты передумал. А то меня немножко сомнения берут что 0.001 будет достаточно чтобы заливочный скрипт убедить в старшинстве заливаемой версии.

Цитата:
подтверди, пожалуйста, что версию нужно приподнимать на 0.001, а не 0.01. Спрашиваю на всякий случай, а то может ты передумал.

Подтверждаю :) Кстати все равно я отсеивал книги в архивах либрусека по дате. За 18-е число добавлять не стал.
Цитата:
меня немножко сомнения берут что 0.001 будет достаточно чтобы заливочный скрипт убедить в старшинстве заливаемой версии.

Скрипт железный. Сравнивает больше\меньше. Для такого сравнения даже 0.00000001 достаточно будет, чтобы его убедить. В принципе можно проверить :)

Bullfear написал:

Скрипт железный. Сравнивает больше\меньше. Для такого сравнения даже 0.00000001 достаточно

Это я тоже так думал, пока не начал в Перле версии сравнивать... ну будем надеяться, что php (Либрусек вроде на php написан) поумнее Перла в этом деле. Все таки следующее поколение. ОК, 0.001 it is.

Заметка для отметки.

В процессе ковыряния нащупал баг в скриптах (включая kop-fb2-split-copy-by-lang.pl_.txt)... точнее, в модуле File::Find. (ActivePerl perl, v5.8.7 built for MSWin32-x86-multi-thread)

Перловый модуль File::Find не находит файлы, у которых в имени есть кириллические буквы. Например:
Vonnegut_Kurt__Dolgaya_progulka_тАФ_navsegda.fb2

С одной стороны - это хорошо, я теперь понимаю почему у меня из сравнилки и вылезает постоянно так много "отсутствующих на Либрусеке" книг.

С другой - плохо: я как-то не могу придумать как этот баг обойти. DIR в cmd.exe тоже выдает ??? вместо кириллицы...

pkn написал:

Перловый модуль File::Find не находит файлы, у которых в имени есть кириллические буквы.

В конечном счете "и одолел" ©. Как обычно (гребаный перл!) действовать пришлось через ухо.

Сначала, после долгих мытарств с unzip-режимом 7zip-а и попыток (безуспешных) припахать умный UnRar, пришлось таки научиться залезать в зипы из перла. Оказалось, что оно того стоило - перловый unzip неплох.

Затем пришлось вплотную познакомиться со структурой fb2-файлов (якобы fb2), залитых на Либрусек на ранних этапах. Тут я обрел понимание отчего и почему хлипкий перловый модулёк XML::Parser падал в обморок от одного вида этих файлов. Заодно очередной раз приподнялся мой градус уважения к Ларину, но это мы спишем на подхалимаж.

В общем, процедура такова:
use Archive::Zip qw( :ERROR_CODES :CONSTANTS );
- и все мои проблемы с Compress::Zlib отпадают. Оно таки работает, просто я не тот модуль пытался подключить.

Затем собираем в список все либрусечьи зипы, извлекаем списки мемберов, отсекаем (по расширению, увы) не-fb2, и начинаем их распаковывать... в память, только в память! Если распаковка не произошла - безжалостно бросаем, это файло безнадежно.

А вот если произошла... тут начинаем пытаться создать ASCII-валидное имя файла извлекая из у неё внутре fb2-шные теги. Именно так, и никак иначе - проверено Электроником. Ларин при этом, если я правильно понимаю, если в кривом дескрипшне вообще отсутствует book-title и/или author, идёт в body и берет нужное прямо оттуда. А то и тег FictionBook парсит на предмет наличия... (см. Hitman: Enemy Within ) ...но у меня, слава богам задача попроще: если из fb2-файла нельзя извлечь имя, то это не fb2-файл, и пусть его автор повесится.

Теперь, если удалось извлечь из (якобы) fb2 имя-файла (пусть сто раз корявое, но валидное) - сплёвываем память в это имя-файла (естественно, проверившись и обезопасившись на предмет дупликатов), и весело насвистывая, переходим к следующему. Если не удалось (что-то около 80 файлов из 103202) - рапортуем файл как извлекаемый, но fb2-безнадежный. Сравнилка сочтет его несуществующим, но, может, где-то потом пригодится.

Собствено, все. Таким макаром удалось извлечь из librusec-zips-original 102431 файла (из 103202) - тысячи на три больше, чем удавалось многомудрому WinRar-у, кстати.

Теперь зарядить изготовление хешей, и завтра, с новыми силами - уля-улю! - сравнилку гонять во все гривы.

Страницы

X