[Plugin Request] WLX: MAFF

Обсуждение только плагинов и утилит для Total Commander.

Модераторы: Моторокер, Avada, CaptainFlint, Nik, d-view

Alkaline
Сообщения: 5
Зарегистрирован: Пт янв 24, 2014 13:13

[Plugin Request] WLX: MAFF

Сообщение Alkaline »

Реквестую листерный плагин для формата maff - Mozilla Archive Format. Готов спонсировать создание в размере $ 30.

Общее описание формата. Maff - это по сути zip-архив с одной или несколькими папками с длинным цифровым именем (одна папка - одна вкладка firefox), каждая из которых содержит главный файл index.html, папку с прочими файлами index_html и информационный файл index.rdf. (Но в принципе можно и все в куче иметь, без подпапки). Файл создается соответствующим плагином для firefox - можно посмотреть структуру. Формат открытый.

Требования к плагину такие. По F3 если внутри одна папка - распаковывать все содержимое в память или в Temp и открывать на просмотр index.html. При закрытии листера - удалять временные файлы. Если в maff-файле несколько подпапок (сохранено несколько вкладок) - выводить список с именами из всех index.rdf с возможностью выбора уже для просмотра конкретной заметки по F3. При нажатии ENTER на maff-файле - стандартное поведение (запуск ассоциированной программы, т.е. firefox), но вход в архив по Ctrl+PgDown. Поддержка Unicode.

Создание архиваторного плагина не желательно, но возможно, если будут соблюдены все условия выше для комфортного просмотра. Хотя плюсом в этом подходе могло бы стать создание maff-файлов из папок с сохраненными html. Но главное - удобный просмотр.

Условия размещения: пишете плагин, высылаете мне, я подтверждаю и перечисляю деньги на мобилу или еще как. Дальше плагин становится свободным (за вашим авторством, разумеется) и размещается здесь на сайте как обычно.
Аватара пользователя
Avada
Сообщения: 10543
Зарегистрирован: Пт авг 01, 2008 16:17
Откуда: Россия, Саратов

Сообщение Avada »

Оставляю в стороне просмотр, но обращаю внимание на следующее:
Alkaline писал(а):Maff - это по сути zip-архив
Alkaline писал(а): При нажатии ENTER на maff-файле - стандартное поведение (запуск ассоциированной программы, т.е. firefox), но вход в архив по Ctrl+PgDown.
Alkaline писал(а):Создание архиваторного плагина не желательно
Оно не то что нежелательно, а пока что непонятно зачем вообще нужно. Если это действительно по факту ZIP-архив, то вход в него по Ctrl+PgDn уже прямо сейчас должен быть доступен в TC с помощью внутреннего ZIP-распаковщика.
Даже самая богатая фантазия
Не представит себе наши безобразия.
Alkaline
Сообщения: 5
Зарегистрирован: Пт янв 24, 2014 13:13

Сообщение Alkaline »

У меня были мысли организовать это с помощью MultiArc, но в итоге мне не понравилась эта затея. Однако плюсом было бы, как я уже написал, создание maff-файлов из html-файлов и папок просто по Alt+F5.

Лучше не уводите мысли от темы. А тема в том, что смотреть я хочу по F3 (а не с помощью Firefox), и смотреть хочу всю страницу с картинками, а не только html, поэтому распаковывать надо все.
Аватара пользователя
wdx
Сообщения: 7
Зарегистрирован: Вс июл 08, 2012 22:18

Сообщение wdx »

Присоединюсь к просьбе Alkaline. Я тоже давно уже работаю с maff-ми в тотале. Но это не удобно: каждый раз заходить внутрь архива, потом морочаться с картинками, которые не отображаются и т. п.
Так что голосую двумя руками за идею плагина.
Аватара пользователя
MVV
Сообщения: 4815
Зарегистрирован: Чт окт 15, 2009 10:58
Откуда: Ростов-Дон

Сообщение MVV »

вход в архив по Ctrl+PgDown
Создание архиваторного плагина не желательно
Ахтунг, взаимоисключающие параграфы!

Вход по Ctrl+Enter как раз и реализуется за счёт архиваторных плагинов. А просмотр по F3 - за счет плагинов просмотрщика. Поэтому это уже два плагина.
Skif_off
Сообщения: 1257
Зарегистрирован: Ср ноя 28, 2012 13:44

Сообщение Skif_off »

К сожалению, я не кот :(
Голову было нечем занять, а надо было и
вот что получилось из любопытства
кнопка

Код: Выделить всё

TOTALCMD#BAR#DATA
%COMMANDER_PATH%\AutoIt.exe %COMMANDER_PATH%\UTILITIES\MAFF.au3
"%P%N" "%P"
AutoIt3_v10.ico
MAFF
%COMMANDER_PATH%\UTILITIES\
-1
Второй параметр %P для того, чтобы не искать путь к файлу *.maff (одна строка + скопипастить функцию, но просто лень:))
AutoIt.exe отсюда (можно 3.3.8.1, поменьше чуток).
Скрипт:

Код: Выделить всё

#NoTrayIcon

;Пишем в переменную %COMMANDER_PATH%
$COMMANDER_PATH = EnvGet("COMMANDER_PATH")
;Запускаем 7-zip с командой list и ловим все, что она выдаст
$sOut = ""
$iPID = Run($COMMANDER_PATH & '\PLUGINS\WCX\TOTAL7ZIP\7Z.EXE l "' & $CmdLine[1] & '"', $COMMANDER_PATH & '\PLUGINS\WCX\TOTAL7ZIP', @SW_HIDE, 2)
While 1
    $sOut &= StdoutRead($iPID)
    If @error Then ExitLoop
WEnd
;Проверяем конец строки - DOS/Unix/Mac
Select
    Case StringInStr($sOut, @CRLF) > 0
        $sDelimiter = @CRLF
    Case StringInStr($sOut, @LF) > 0
        $sDelimiter = @LF
    Case Else
        $sDelimiter = @CR
EndSelect
;и разбиваем на строки, в качестве разделителя - конец строки
$aLines = StringSplit($sOut, $sDelimiter, 1)
;Рег. выражением находим имя каталога в *.maff (это точно всегда будет 13я строка вывода?)
$MaffPath = StringRegExpReplace($aLines[13], '(\d{4}.*?\s+0\s+0\s+)([a-z0-9_]+)', '\2')
;Распаковываем *.maff в %Temp%
RunWait($COMMANDER_PATH & '\PLUGINS\WCX\TOTAL7ZIP\7Z.EXE x "' & $CmdLine[1] & '" -o"' & @TempDir & '" -aoa', $COMMANDER_PATH & '\PLUGINS\WCX\TOTAL7ZIP', @SW_HIDE)
;Ищем окно ТС
$hWnd = WinWait("[CLASS:TTOTAL_CMD]", "", 3)
;Делаем активным на всякий случай и
WinActivate($hWnd)
;с помощью TCFS2 посылаем команду открыть в активной панели каталог с распакованным *.maff
RunWait($COMMANDER_PATH & '\UTILITIES\TCFS2\TCFS2.EXE /ef "tem(`em_CD ' & @TempDir & '\' & $MaffPath & '\`)"', $COMMANDER_PATH & '\UTILITIES\TCFS2', @SW_HIDE)
;Ждем появления окна листера
$hWndL = WinWait("[Class:TLister]", "")
;и после ждем его закрытия
While WinExists("[Class:TLister]")
    Sleep(500)
WEnd
;Ищем окно ТС
$hWnd = WinWait("[CLASS:TTOTAL_CMD]", "", 3)
;Делаем активным на всякий случай и
WinActivate($hWnd)
;с помощью TCFS2 посылаем команду вернуться в каталог с *.maff
RunWait($COMMANDER_PATH & '\UTILITIES\TCFS2\TCFS2.EXE /ef "tem(`em_CD ' & $CmdLine[2] & '\`)"', $COMMANDER_PATH & '\UTILITIES\TCFS2', @SW_HIDE)
;Грохаем папку с распакованным *.maff
If FileExists(@TempDir & '\' & $MaffPath) Then DirRemove(@TempDir & '\' & $MaffPath, 1)
Из комментариев вроде все понятно, нужна утилита TCFS2 и пользовательская команда

Код: Выделить всё

[em_CD]
cmd=CD
param=%A
menu=Переход
Открыть в неактивной панели у меня не получилось.
Аватара пользователя
MVV
Сообщения: 4815
Зарегистрирован: Чт окт 15, 2009 10:58
Откуда: Ростов-Дон

Сообщение MVV »

Через TCFS2 можно и без em_CD, там же есть tcd, заодно умеет в неактивной. Да и сам тотал умеет через /O /S /R=.
Skif_off
Сообщения: 1257
Зарегистрирован: Ср ноя 28, 2012 13:44

Сообщение Skif_off »

MVV
Я бы не стал называть это готовым решением :) Просто набросок размышления для.
MVV писал(а):Через TCFS2 можно и без em_CD, там же есть tcd, заодно умеет в неактивной.
Сначала не работало с tcd, как позже выяснилось, из-за ошибки в регулярном выражении, потом уже не стал возвращаться.
AlexBiggest
Сообщения: 9
Зарегистрирован: Сб апр 19, 2014 05:37

Сообщение AlexBiggest »

Skif_off
Опубликуйте, пожалуйста, решение без TCFS2.
Аватара пользователя
Avada
Сообщения: 10543
Зарегистрирован: Пт авг 01, 2008 16:17
Откуда: Россия, Саратов

Сообщение Avada »

AlexBiggest
Во-первых, разве кто-то тут обещал такое решение?
Во-вторых, читаем правила форума про оверквотинг Лишнее удалено.
Даже самая богатая фантазия
Не представит себе наши безобразия.
Skif_off
Сообщения: 1257
Зарегистрирован: Ср ноя 28, 2012 13:44

Сообщение Skif_off »

AlexBiggest
Ну, "решение" - это слишком громко :)
Просто пришла в голову мысль автоматизировать:
- распаковать maff-файл в %temp%, при этом читая вывод 7z (внутри maff-файла папка, нам нужно её имя);
- перейти на неактивную пенель;
- создать вкладку (решил усложнить, мало ли что открыто - вдруг нужное), открыть в ней каталог распакованного maff-файла;
- дальше уже самому нужно нажать Просмотр по html-файлу.
Скрипт ждет появления и закрытия окна Lister (проверяет с интервалом 500 мс), потом закрывает вкладку, возвращает активность рабочей файловой панели и удаляет в %temp% распакованный maff-файл.
Т.к. используются дескрипторы, а не заголовки окон, гипотетически: несколько открытых для просмотра файлов (и окон Lister) не должны быть проблемой.
Утилита TCFS2 заменена на ключи запуска ТС.
В папку плагина Total7zip необходимо добавить файл 7z.exe из дистрибутива 7-Zip (забыл упомянуть в первый раз - давно у меня, привык). Или положить его куда угодно (хоть установленный), только поправить путь.
Кнопка

Код: Выделить всё

TOTALCMD#BAR#DATA
"%COMMANDER_PATH%\AutoIt.exe" "%COMMANDER_PATH%\UTILITIES\MAFF.au3"
%P%N "%P"
AutoIt3_v10.ico
MAFF
%COMMANDER_PATH%\UTILITIES\
-1
Скрипт

Код: Выделить всё

#NoTrayIcon

;Изменяет продолжительность паузы после успешных оконных функций. Время в миллисекундах (по умолчанию=250)
Opt("WinWaitDelay", 100)

Global Const $WM_TC_COMMAND = 0x0433

;Проверяем количество параметров
If $CmdLine[0] <> '2' Then 
    MsgBox(4096, 'MAFF.au3', 'Проверьте параметры запуска.') 
    Exit 
EndIf
;Получаем дескриптор окна ТС
$hWnd = WinGetHandle('[CLASS:TTOTAL_CMD]')
;Пишем в переменную %COMMANDER_PATH% и %COMMANDER_EXE%
$COMMANDER_PATH = EnvGet('COMMANDER_PATH')
$COMMANDER_EXE = EnvGet('COMMANDER_EXE')
;Запускаем 7-zip с командой list и ловим все, что она выдаст
$sOut = ''
$iPID = Run('"' & $COMMANDER_PATH & '\PLUGINS\WCX\Total7zip\7z.exe" l "' & $CmdLine[1] & '"', $COMMANDER_PATH & '\PLUGINS\WCX\Total7zip', @SW_HIDE, 2)
While 1
    $sOut &= StdoutRead($iPID)
    If @error Then ExitLoop
WEnd
;Проверяем конец строки - DOS/Unix/Mac
Select
    Case StringInStr($sOut, @CRLF) > 0
        $sDelimiter = @CRLF
    Case StringInStr($sOut, @LF) > 0
        $sDelimiter = @LF
    Case Else
        $sDelimiter = @CR
EndSelect
;и разбиваем на строки, в качестве разделителя - конец строки
$aLines = StringSplit($sOut, $sDelimiter, 1)
;Рег. выражением находим имя каталога в *.maff (это точно всегда будет 13я строка вывода?)
$MaffPath = StringRegExpReplace($aLines[13], '(\d{4}.*?\s+0\s+0\s+)([a-z0-9_]+)', '\2')
;Распаковываем *.maff в %Temp%
RunWait('"' & $COMMANDER_PATH & '\PLUGINS\WCX\Total7zip\7z.exe" x "' & $CmdLine[1] & '" -o"' & @TempDir & '" -aoa', $COMMANDER_PATH & '\PLUGINS\WCX\Total7zip', @SW_HIDE)
;Делаем активным окно ТС на всякий случай и
WinActivate($hWnd)
;далаем активной неактивную панель
Send('{TAB}')
;Открываем новую вкладку
_SendMessage($hWnd, $WM_TC_COMMAND, 3001, 0)
If @error Then
    MsgBox(4096, 'MAFF.au3', '_SendMessage Error: ' & @error)
    Exit
EndIf
;Открываем папку распакованного maff-файла
RunWait('"' & $COMMANDER_EXE & '" /O /S /L="' & @TempDir & '\' & $MaffPath & '"', '', @SW_HIDE)

;Тут нужно запустить Lister

;Ждем появления окна Lister
$hWndL = WinWait('[Class:TLister]', '')
;Закрываем вкладку
_SendMessage($hWnd, $WM_TC_COMMAND, 3007, 0)
If @error Then
    MsgBox(4096, 'MAFF.au3', '_SendMessage Error: ' & @error)
    Exit
EndIf
;возвращаем активность панели, в которой работали (закомментировать/убрать, если не нравится, как дергается окно Lister)
_SendMessage($hWnd, 0x6, 0x1)
ControlSend($hWnd, '', '', '{TAB}')
WinActivate($hWndL)
;и после ждем закрытия Lister
While WinExists($hWndL)
    Sleep(500)
WEnd
;Грохаем папку с распакованным *.maff
If FileExists(@TempDir & '\' & $MaffPath) Then DirRemove(@TempDir & '\' & $MaffPath, 1)

Func _SendMessage($hWnd, $iMsg, $wParam = 0, $lParam = 0, $iReturn = 0, $wParamType = 'wparam', $lParamType = 'lparam', $sReturnType = 'lresult')
    Local $aResult = DllCall('user32.dll', $sReturnType, 'SendMessageW', 'hwnd', $hWnd, 'uint', $iMsg, $wParamType, $wParam, $lParamType, $lParam)
    If @error Then Return SetError(@error, @extended, '')
    If $iReturn >= 0 And $iReturn <= 4 Then Return $aResult[$iReturn]
    Return $aResult
EndFunc   ;==>_SendMessage
Если не нравится дерганье окна Lister, убрать/закомментировать

Код: Выделить всё

_SendMessage($hWnd, 0x6, 0x1)
ControlSend($hWnd, '', '', '{TAB}')
WinActivate($hWndL) 
Хотя так получается быстрее, чем делать окно ТС активным, посылать Send('{TAB}') и потом уже активировать окно Lister.

З.Ы. Кстати,
Показать

Код: Выделить всё

_SendMessage($hWnd, $WM_TC_COMMAND, NNNN, 0)
отлично работает с ТС: NNNN - команда TC в десятичном формате (список), в начале скрипта нужно добавить

Код: Выделить всё

Global Const $WM_TC_COMMAND = 0x0433
Еще раз, уже публично, спасибо MVV за подсказку :)
З.З.Ы. Размышления/мысли вслух убраны, оставлен окончательный вариант. "As is", как говорится. Работает в AutoIt 3.3.8.1 и 3.3.12.0, MAFF не пользуюсь, поддержку (хотя тут всё просто в общем) не обещаю.

Добавлено:
Косметика: исправлен заголовок окна ошибки _SendMessage(), поленился набирать и скопировал из скрипта FastCopy :) Исправлено.
Добавлена проверка параметров запуска (только количество).
Skif_off
Сообщения: 1257
Зарегистрирован: Ср ноя 28, 2012 13:44

Сообщение Skif_off »

Что меня несколько напрягает в последнее время, так это то, что я пишу: почему-то частенько решение оказывается громоздким и всё можно сделать заметно проще.
Итого, новая версия, внезапно пришло в голову:
кнопка

Код: Выделить всё

TOTALCMD#BAR#DATA
"%COMMANDER_PATH%\AutoIt.exe" "%COMMANDER_PATH%\UTILITIES\MAFF.au3"
%P%N
AutoIt3_v10.ico
MAFF
%COMMANDER_PATH%\UTILITIES\
-1
сам скрипт

Код: Выделить всё

;Проверяем количество параметров
If $CmdLine[0] <> '1' Then
    MsgBox(4096, 'MAFF.au3', 'Проверьте параметры запуска.')
    Exit
EndIf
;Пишем в переменную %COMMANDER_PATH% и %COMMANDER_EXE%
$COMMANDER_PATH = EnvGet('COMMANDER_PATH')
$COMMANDER_EXE = EnvGet('COMMANDER_EXE')
;Запускаем 7-zip с командой list и ловим все, что она выдаст
$sOut = ''
$iPID = Run('"' & $COMMANDER_PATH & '\PLUGINS\WCX\Total7zip\7z.exe" l "' & $CmdLine[1] & '"', $COMMANDER_PATH & '\PLUGINS\WCX\Total7zip', @SW_HIDE, 2)
While 1
    $sOut &= StdoutRead($iPID)
    If @error Then ExitLoop
WEnd
;Проверяем конец строки - DOS/Unix/Mac
Select
    Case StringInStr($sOut, @CRLF) > 0
        $sDelimiter = @CRLF
    Case StringInStr($sOut, @LF) > 0
        $sDelimiter = @LF
    Case Else
        $sDelimiter = @CR
EndSelect
;и разбиваем на строки, в качестве разделителя - конец строки
$aLines = StringSplit($sOut, $sDelimiter, 1)
;Рег. выражением находим имя каталога в *.maff (это точно всегда будет 13я строка вывода?)
$MaffPath = StringRegExpReplace($aLines[13], '(\d{4}.*?\s+0\s+0\s+)([a-z0-9_]+)', '\2')
;Распаковываем *.maff в %Temp%
RunWait('"' & $COMMANDER_PATH & '\PLUGINS\WCX\Total7zip\7z.exe" x "' & $CmdLine[1] & '" -o"' & @TempDir & '" -aoa', $COMMANDER_PATH & '\PLUGINS\WCX\Total7zip', @SW_HIDE)
;Открываем index.html в Lister отдельным процессом и ждем, пока завершится
RunWait('"' & $COMMANDER_EXE & '" /S=L "' & @TempDir & '\' & $MaffPath & '\index.html"', $COMMANDER_PATH)
;Грохаем папку с распакованным *.maff
If FileExists(@TempDir & '\' & $MaffPath) Then DirRemove(@TempDir & '\' & $MaffPath, 1)
Существенно подсократил и упростил, окна и дескрипторы - на фиг (+ скорость работы, по идее, увеличится, но с таймером ломает возиться).
Комментарии исчерпывающие, не буду тратить ваше и своё время дополнительным расписыванием.

Добавлено:
Добавлена проверка параметров запуска (только количество), чтобы AutoIt не ругался непонятно и на английском на необъявленную переменную.
Dec
Сообщения: 466
Зарегистрирован: Чт сен 07, 2006 18:56

Сообщение Dec »

Первые наброски плагина decMaffWLX. Работает без распаковки maff-файла на жесткий диск. Показывает первый попавшийся index.html в maff файле.

Update

Можно выбрать любой index файл из maff-файла.
Skif_off
Сообщения: 1257
Зарегистрирован: Ср ноя 28, 2012 13:44

Сообщение Skif_off »

х64 планируется? Размерчик, правда, х64 под 3.5 метров получится, наверное. Но мой скрипт не очень удобен - HTMLView почему-то подтормаживает при закрытии, а его будущее в тумане.
А как технически выглядит "без распаковки"? Архив монтируется как папка?

Только хотел попросить возможность указать путь к 7z.dll (она есть в Total7zip), а её уже нет в плагине :)
Dec
Сообщения: 466
Зарегистрирован: Чт сен 07, 2006 18:56

Сообщение Dec »

Skif_off писал(а):х64 планируется?
Да.
Skif_off писал(а):А как технически выглядит "без распаковки"? Архив монтируется как папка?
В TC регистрируется новый протокол, и простому WebBrowser передаются URL вида maff://c:\path\filename.maff/27864278647264728/index.html. Протокол реализуется в плагине. WebBrowser при чтении данных с протокола maff:// обращается к процедурам плагина, а плагин в свою очередь анализирует запрос и распаковывает запрашиваемые данные в память и отдает их WebBrowser.
Ответить