Компьютерный форум OSzone.net  

Компьютерный форум OSzone.net (http://forum.oszone.net/index.php)
-   AutoIt (http://forum.oszone.net/forumdisplay.php?f=103)
-   -   Переименование имени файла fb2 в соответствии с тэгами (http://forum.oszone.net/showthread.php?t=342850)

DenchikK 07-11-2019 10:35 2895092

Переименование имени файла fb2 в соответствии с тэгами
 
Имеются множество книжек с не пронумированными сериями - ни в имени файла, ни в секции sequence.
Вручную нумировать - долго, файлов много.

Пока идея пришла такая, чтоб книги шли в порядке их выхода, считывать первые 30 строк книги, из нужных тэгов брать информацию и формировать имя файла:
Фамилия Имя - Серия 2010-02-03 - Название.fb2

<first-name>Имя</first-name>
<last-name>Фамилия</last-name>
<sequence name="Серия" />
<book-title>Название</book-title>
<date value="2010-02-03">03 February 2010</date>

Несколько дней читаю форумы, справки, но пока даже не понимаю, как подступиться к решению вопроса.

Creat0R 07-11-2019 13:22 2895122

Цитата:

Цитата DenchikK (Сообщение 2895092)
Имеются множество книжек с не пронумированными сериями - ни в имени файла, ни в секции sequence.
Вручную нумировать - долго, файлов много.

Пока идея пришла такая, чтоб книги шли в порядке их выхода, считывать первые 30 строк книги, из нужных тэгов брать информацию и формировать имя файла:
Фамилия Имя - Серия 2010-02-03 - Название.fb2

<first-name>Имя</first-name>
<last-name>Фамилия</last-name>
<sequence name="Серия" />
<book-title>Название</book-title>
<date value="2010-02-03">03 February 2010</date>

Несколько дней читаю форумы, справки, но пока даже не понимаю, как подступиться к решению вопроса.

Почему именно 30 строк, где располагаются данные теги?
Можно прикрепить пример файла такой книги?

DenchikK 07-11-2019 15:26 2895132

Цитата:

Цитата Creat0R
Почему именно 30 строк, где располагаются данные теги? »

Скрытый текст
Цитата:

<?xml version="1.0" encoding="utf-8"?>
<FictionBook xmlns="http://www.gribuser.ru/xml/fictionbook/2.0" xmlns:l="http://www.w3.org/1999/xlink">
<description>
<title-info>
<genre>detective</genre>
<author>
<first-name>Евгений</first-name>
<middle-name>Евгеньевич</middle-name>
<last-name>Сухов</last-name>
<id>1212f327-2a83-102a-9ae1-2dfe723fe7c7</id>
</author>
<book-title>Бросок на выстрел</book-title>
<annotation>
<p>Вдали от*города журналист Аристарх Русаков обнаружил труп мужчины. Убитым оказался водитель риелторской компании Василий Леваков. Журналист попытался поговорить с*важной свидетельницей*– подружкой убитого, но, как*выяснилось, девушка пару дней назад погибла при*странных обстоятельствах. Тогда Русаков отправился в*охотхозяйство, куда часто приезжал с*компанией Леваков. И*здесь всплыл один странный факт: незадолго до*убийства в*охотхозяйстве бесследно пропал заядлый охотник Востриков. Пропал он глубокой ночью, в*самом лучшем месте для*засады на*кабанов, прозванном Афонькиной протокой…</p>
</annotation>
<keywords>журналистское расследование,расследование преступлений,остросюжетные детективы</keywords>
<date value="2015-01-01">2015</date>
<coverpage>
<image l:href="#cover.jpg">
</image>
</coverpage>
<lang>ru</lang>
<sequence name="Расследования криминального репортера">
</title-info>
<document-info>
<publisher>
<first-name>
</first-name>
<last-name>Литагент «1 редакция»</last-name>

Отсмотрел несколько книг - обычно последняя из искомых строк располагается не ниже 28 строки (если нет тэга <middle-name> и проч). Я взял 30 строк с подстраховкой, но может я и не прав.

Iska 07-11-2019 17:20 2895150

DenchikK, ещё раз:
Цитата:

Цитата Creat0R
…пример файла такой книги? »

а лучше — несколько примеров (коль речь ведётся про «серии»), упакованных в архив.

Цитата:

Цитата DenchikK
но может я и не прав. »

Без «может». В xml вообще нет понятия «строка».

DenchikK 07-11-2019 21:20 2895191

Цитата:

Цитата Iska
В xml »

Что то я не подумал про xml.
Я тупо в лоб пробовал - рассматривая файл, как текстовый с разметкой, зачищая не нужный мусор.
В лоб не получилось и с xml - немного поискав, я так и не понял, как под мои нужды подставить то, что я нашёл.
Но я на одном форуме нашёл вариант с использованием функции _StringBetween.
Всё вроде здорово, всё как я и хотел, и получилось проще, чем я пытался до этого.
Но опять возникла проблема - с самым главным параметром - датой.
Я не могу пока придумать, как проще из этого:
<date value="2010-02-03">03 February 2010</date>
вычленить это:
2010-02-03
Пока в голову приходят безумные способы.

Цитата:

Цитата Iska
упакованных в архив »

Да нет никаких архивов. Есть книжки одной серии, уже отредактированных, лежащих в одной дирректории, с одним тэгом серии, которые я хочу упорядочить по дате.
Разные серии - разные дирректории.
Теперь бы понять, как дату вычленить, чтоб назначить переменной.

iglezz 07-11-2019 21:31 2895195

Вариант для переименования одного файла, прикрутить пакетную обработку, думаю, несложно будет
Скрытый текст
Код:

Local Const $APP_NAME = "fb2renamer"
Local Const $APP_VERSION = "0.1"
Local Const $APP_TITLE = $APP_NAME & " v" & $APP_VERSION

Local $g_oXML

Main()


Func _ReadXMLNodeText($oXMLobj, $sNode)
        Local $result = $oXMLobj.SelectSingleNode($sNode)
        If IsObj($result) Then
                Return $result.text
        Else
                Return ""
        EndIf
EndFunc  ;==>_ReadXMLNodeText


Func _ReadXMLNodeAttrib($oXMLobj, $sNode, $sAttrib)
        Local $sXPath = $sNode & "[@" & $sAttrib & "]"
        Local $result = $oXMLobj.SelectSingleNode($sXPath)
        If IsObj($result) Then
                Return $result.getAttribute($sAttrib)
        Else
                Return ""
        EndIf
EndFunc  ;==>_ReadXMLNodeAttrib


Func _GetParentDir($sFileName)
        Return StringLeft($sFileName, StringInStr($sFileName, "\", 0, -1) - 1)
EndFunc  ;==>_GetParentDir


Func _GetFileName($sFileName)
        Return StringTrimLeft($sFileName, StringInStr($sFileName, "\", 0, -1))
EndFunc  ;==>_GetFileName


Func _GetNewName($sFile)
        If $g_oXML.load($sFile) Then
                Local $result
                Local $sLastName, $sMiddleName, $sFirstName, $sBookTitle, $sSequenseName, $sSequenseNumber, $sDate
               
                Local $oNode = $g_oXML.SelectSingleNode("//FictionBook/description/title-info")
               
                $sLastName = _ReadXMLNodeText($oNode, "author/last-name")
                $sMiddleName = _ReadXMLNodeText($oNode, "author/middde-name")
                $sFirstName = _ReadXMLNodeText($oNode, "author/first-name")
                $sBookTitle = _ReadXMLNodeText($oNode, "book-title")
               
                $sSequenseName = _ReadXMLNodeAttrib($oNode, "sequence", "name")
                $sSequenseNumber = _ReadXMLNodeAttrib($oNode, "sequence", "number")
               
                $sDate = _ReadXMLNodeAttrib($oNode, "date", "value")
                If $sDate == "" Then
                        $oNode = $g_oXML.SelectSingleNode("//FictionBook/description/document-info")
                        $sDate = _ReadXMLNodeAttrib($oNode, "date", "value")
                EndIf
               
                ; Новое имя файла:
                Local $sNewFileName = "" _
                                & $sLastName & " " _
                                & $sFirstName & " " _
                                & $sMiddleName & " - " _
                                & $sSequenseName & " " _
                                & ($sSequenseNumber <> "" ? "(" & $sSequenseNumber & ")" : "") & " " _
                                & $sDate & " - " _
                                & $sBookTitle _
                                & ".fb2"
                $sNewFileName = StringRegExpReplace($sNewFileName, "\ +", " ")
                $sNewFileName = StringReplace($sNewFileName, " - - ", " - ")
               
                Return $sNewFileName
        Else
                SetError(1)  ; 1 == file not found
                Return ""
        EndIf
EndFunc  ;==>_GetNewName


Func _DisplayHelp()
        MsgBox(0, $APP_TITLE, "" _
                        & @ScriptName & " [ -y ] FILE1 FILE2 ... FILE(n)" & @CRLF _
                        & @CRLF _
                        & @TAB & "-y" & @TAB & "Переименовать файлы вместо тестирования" & @CRLF _
                        )
        Exit 0
EndFunc  ;==>_DisplayHelp


Func _PickUpNewName($sFileName)
        Local $sNewName = $sFileName
        Local $iCount = 1
        While True
                If FileExists($sNewName) Then
                        $sNewName = StringRegExpReplace($sNewName, " \([0-9]+\).fb2", " \(" & $iCount & "\).fb2")
                        If @extended = 0 Then $sNewName = StringReplace($sNewName, ".fb2", " (" & $iCount & ").fb2")
                Else
                        ExitLoop
                EndIf
                $iCount += 1
        WEnd
        Return $sNewName
EndFunc  ;==>_PickUpNewName


Func _RenameSingleFile($bTestMode, $sFileName)
        Local $sOldFullName = FileGetLongName($sFileName, 1)
        Local $sOldFileName = _GetFileName($sOldFullName)
        Local $sFolderName = _GetParentDir($sOldFullName)
        Local $sNewFileName = _GetNewName($sOldFullName)
        Local $sNewFullName = _PickUpNewName($sFolderName & "\" & $sNewFileName)
        $sNewFileName = _GetFileName($sNewFullName)
       
        If $bTestMode Then
                Local $iBtn = MsgBox(4, $APP_TITLE, "" _
                                & "Папка:    " & @CRLF _
                                & $sFolderName & @CRLF & @CRLF _
                                & "Имя книги:" & @CRLF _
                                & $sOldFileName & @CRLF & @CRLF _
                                & "Новое имя: " & @CRLF _
                                & $sNewFileName & @CRLF & @CRLF _
                                & @CRLF _
                                & "Переименовать?" _
                                )
                If $iBtn = 6 Then FileMove($sOldFullName, $sNewFullName)
        Else
                FileMove($sOldFullName, $sNewFullName)
        EndIf
EndFunc  ;==>_RenameSingleFile


Func _QuitWithMessage($sMessage, $iMsgBoxCode = 0, $iExitCode = 0)
        MsgBox($iMsgBoxCode, $APP_TITLE, $sMessage)
        Exit $iExitCode
EndFunc  ;==>_QuitWithMessage


Func Main()
        $g_oXML = ObjCreate("Microsoft.XMLDOM")

        If Not IsObj($g_oXML) Then _QuitWithMessage("Ошибка инициализации XML :(", 16, 1)
       
        Local $bOptTestMode = True
       
        If $CmdLine[0] = 0 Then _DisplayHelp()
       
        For $i = 1 To $CmdLine[0]
                Select
                        Case $CmdLine[$i] = "/?"
                                _DisplayHelp()
                               
                        Case $CmdLine[$i] = "-y"
                                $bOptTestMode = False
                               
                        Case FileExists($CmdLine[$i])
                                _RenameSingleFile($bOptTestMode, $CmdLine[$i])
                               
                EndSelect
        Next
EndFunc  ;==>Main


Iska 07-11-2019 22:21 2895203

Цитата:

Цитата DenchikK
Да нет никаких архивов. »

Я хотел, чтобы Вы упаковали несколько образцов файлов в архив.

oz84 17-04-2020 11:23 2917640

Какое, однако, странное решение... Хотя бы потому, что AutoIt не сможет забраться в zip-архив.

Для подобного лучше подойдёт Total Commander или Double Commander: инструмент группового переименования и один из плагинов для получения инфи из файлов FB2 (eBookInfo WDX, Fast Fb2 wdx или поновее Fast Fb2 Epub от того же автора).

Iska 17-04-2020 11:53 2917649

oz84, ну, автор хотел скрипт — он его получил.

iglezz 17-04-2020 12:34 2917660

К этому, однако, странному решению поддержку zip-архивов прикрутить - минутное дело, соответствующий UDF существует давно.


Время: 10:59.

Время: 10:59.
© OSzone.net 2001-