Копирование файлов с временной панели с сохранение структуры папок

Здесь обсуждается всё, что касается макросов.
buniak_a_h
Posts: 896
Joined: Sat 20 Apr, 2013 00:17
Location: Питер
Has thanked: 77 times
Been thanked: 28 times
Contact:

Копирование файлов с временной панели с сохранение структуры папок

Post by buniak_a_h » Tue 24 Apr, 2018 20:12

Предлагаю небольшой макрос, копирующий файлы с временной панели, открытой на активной панели (извините за тавтологию) в директорий, открытый на неактивной панели. Макрос "рассовывает" копируемые файлы по подкаталогам в соответствии с их расположением в исходной структуре (относительно "корневой" папки). Особенно полезна для копирования результатов поиска файлов, помещённых на временную панель.
  1. --[[ Тест
  2. Macro{
  3. --  id="";
  4.   area="Shell";
  5.   key="AltCtrlF2";
  6. --  description="";
  7. --  filemask="";
  8.   flags="";
  9. --  priority=50;
  10. --  sortpriority=50;
  11. --  condition=function(key) return true end;
  12. action=function()
  13.  far.Show(Panel.FExist(0, APanel.Current))
  14. end;
  15. }
  16. --]]
  17.  
  18. --[[
  19. CopyFiles.TempPanel.lua, Версия 4
  20. Макрос, реализующий копирование файлов из временной панели в папку, открытую
  21. на неактивной панели, с сохранением структуры каталогов.
  22. 1. Макрос повешен на AltCtrlF5
  23. 2. Макрос не обрабатывает каталоги (только файлы)
  24. 3. Макрос не запрашивает путь к приёмному каталогу. Строго в каталог неактивной панели.
  25. 4. При наличии в приемном каталоге файла запрашивает, что делать. Варианты:
  26.    - переписать \  как для одного файла,
  27.    - пропустить /  так и для всех оставшихся
  28.    - обновить - переписать только если исходный файл новее приёмного.
  29.                 Действует на все оставшиеся
  30.    - прекратить копирование.
  31. 5. Визуализации процесса не предусмотрено. Желающие могут сделать сами...
  32. Версия 4:
  33. 5.a. Предусмотен вывод копируемого файла, обновление содержимого приёмной (пассивной) панели и
  34.      возможность прерывания копирования оставшихся (не скопированных) файлов. Увы, прерывание
  35.      копирования текущего файла не предусмотрено .
  36. Версия 5:
  37. 6. Путь к "корню" запоминается при начале поиска из диалога поиска файла (AltF7).
  38. 7. Если после копирования остались не скопированные файлы, то предлагается "докопировать" их обычным копирование
  39.    в папку, открытую на пассивной панели без сохранения структуры каталогов.
  40. --
  41. © Буняк А.Х.
  42. --]]
  43. local ReWriteMode=0
  44. Macro {
  45.     area = "Shell";
  46.     key = 'AltCtrlF5';
  47.     description = 'Копирование файла из временной панели с учётом вложенных каталогов';
  48.     flags = ""; -- EnableOutput не помогает
  49.     condition=function()
  50.      --local PanGuid=win.Uuid(_G.panel.GetPanelInfo(0).OwnerGuid):upper()
  51.      return band(panel.GetPanelInfo(nil, 1).Flags, far.Flags.PFLAGS_REALNAMES) == far.Flags.PFLAGS_REALNAMES
  52.             --or
  53.             --PanGuid=='B77C964B-E31E-4D4C-8FE5-D6B0C6853E7C' or -- TempPanel
  54.             --PanGuid=='8E11EA75-0303-4374-AC60-D1E38F865449' or -- LF Search: temporary panel
  55.             --PanGuid=='F250C12A-78E2-4ABC-A784-3FDD3156E415' or -- RESearch
  56.             --PanGuid=='E2500D1C-D1D2-4C4C-91C0-6864F2AAF5E8'    -- LF TmpPanel
  57.     end;
  58.     action = function()
  59.      -- Получение имени "корневого" каталога (того, что на ..)
  60.      ReWriteMode = 0
  61.      local function _RootDir()
  62.       local ItemInfo=panel.GetPanelInfo(0)
  63.       local iItem, iTop=ItemInfo.CurrentItem, ItemInfo.TopPanelItem
  64.       Panel.SetPosIdx(0, 1)
  65.       local sRes=APanel.Path0
  66.       panel.RedrawPanel(nil, 1, {CurrentItem=iItem; TopPanelItem=iTop})
  67.       return sRes
  68.      end
  69.      -- Копирование одного файла
  70.      local function _CopyF(Src, Dst, Root)
  71.       -- Заменяю корневой каталог на приемный в исходном файле
  72.       local bRes=false
  73.       if Src:sub(1, Root:len()):upper() == Root:upper() then
  74.        local _Dst = Dst .. Src:sub(Root:len()+1)
  75.        local _DstPath = mf.fsplit(_Dst, 3)
  76.        if mf.fexist(_Dst) then
  77.         if ReWriteMode < 3 then
  78.          ReWriteMode = far.Message( _Dst..'\nФайл Существует. Что делаем?',
  79.                                     'Копирование файлов со структурой каталогов',
  80.                                     'Переписать;Пропустить;Переписать все;Пропустить все;Обновить все;Отменить' )
  81.          if ReWriteMode == 6 then ReWriteMode = -1 end
  82.         end
  83.         if ReWriteMode == 1 or ReWriteMode == 3 or
  84.            (ReWriteMode == 5 and win.GetFileInfo(Src).LastWriteTime > win.GetFileInfo(_Dst).LastWriteTime) then
  85.          win.DeleteFile(_Dst)
  86.         end
  87.        elseif not mf.fexist(_DstPath) then
  88.         if not win.CreateDir(_DstPath) then return end
  89.        end
  90.        if not mf.fexist(_Dst) and mf.fexist(_DstPath) then
  91.         far.Message('Копируется '..Src..'\nв '.._DstPath, '', '')
  92.         bRes = win.CopyFile(Src, _Dst)
  93.         far.AdvControl("ACTL_REDRAWALL")
  94.         --panel.RedrawPanel(nil, 0)
  95.         panel.UpdatePanel(nil, 0, true)
  96.        end
  97.       end -- if Src:sub(1, Root:len()):upper() == Root:upper()
  98.       return bRes
  99.      end -- _CopyF
  100.      local RootDir=_RootDir()
  101.      local aItems={}
  102.      if APanel.Selected then
  103.       -- Цикл по отмеченным
  104.       for i=1,APanel.SelCount do
  105.        table.insert(aItems, panel.GetSelectedPanelItem(nil, 1, i))
  106.       end
  107.       -- Список отмеченных элементов, которые надо будет потом погасить одной командой,
  108.       -- чтобы была возможность восстановить отметку по CtrlM
  109.       local aDone={}
  110.       local anDone, i0={}, 2 -- Для обхода ошибки ФАРа в Panel.Select (временно)
  111.       for _, Item in ipairs(aItems) do
  112.        --[[*D*]]local sBreak=mf.waitkey(1,0); if sBreak=='Esc' and far.Message('Прервать?','Копирование файлов с временной панели', ';YesNo','w') == 1 then break end
  113.        --if (mf.waitkey(1,0) == 'Esc') then break end;
  114.        if not Item.FileAttributes:match('d') and
  115.           mf.fexist(Item.FileName) -- При режиме :any на временной панели могут быть не только реальные файлы
  116.        then
  117.         if _CopyF(Item.FileName, PPanel.Path, RootDir) then
  118.          table.insert(aDone, Item.FileName)
  119.          -- Т.к. Panel.FExist не работает, ищу итем перебором.
  120.          -- Т.к. обработка итемов происходит в порядке их повления на панели, можно искать
  121.          -- не каждый раз от начала, а со следующего за предыдущим.
  122.          for i=i0,APanel.ItemCount do
  123.           if panel.GetPanelItem(nil, 1, i).FileName == Item.FileName then
  124.            table.insert(anDone, i)
  125.            i0 = i + 1
  126.            break
  127.           end
  128.          end
  129.          --table.insert(anDone, Panel.FExist(0, Item.FileName)) - Panel.FExist не работает на плагиновой панели...
  130.         end
  131.         if ReWriteMode == -1 then break end -- Был отказ (снятие)
  132.        end
  133.       end
  134.       -- Снятие отметок с файлов, которые были скопированы
  135.       if #aDone > 0 then
  136.        --Panel.Select( 0, 0, 2,  table.concat(aDone, '\n'))
  137.        panel.SetSelection(nil, 1, anDone, false)
  138.        Panel.SetPosIdx(0, APanel.CurPos)
  139.       end
  140.      else
  141.       local Item = panel.GetCurrentPanelItem(nil, 1)
  142.       if not Item.FileAttributes:match('d') then
  143.        _CopyF(Item.FileName, PPanel.Path, RootDir)
  144.       end
  145.      end
  146.     end;
  147. }

CopyFiles.TempPanel.lua.7z
CopyFiles.TempPanel.lua, версия 4
(2.77 KiB) Downloaded 94 times
Опубликовал версию 5 (с которой работаю уже пару месяцев). Только во вложении, т.к. используется пара моих модулей.
CopyFiles.TempPanel.v5.lua.7z
CopyFiles.TempPanel.lua, версия 5
(13.03 KiB) Downloaded 62 times
Last edited by buniak_a_h on Fri 30 Nov, 2018 11:09, edited 1 time in total.

buniak_a_h
Posts: 896
Joined: Sat 20 Apr, 2013 00:17
Location: Питер
Has thanked: 77 times
Been thanked: 28 times
Contact:

Копирование файлов с временной панели с сохранение структуры папок

Post by buniak_a_h » Wed 25 Apr, 2018 16:04

Latest post of the previous page:

Сделал 3-ю версию макроса. Changelog:
  • Версия 2
    1. Первая версия работала только во временной панели, созданной плагином TempPanel. Во вторую версию добавлены временные панели от плагинов LuaFAR Search и RESearch
  • Версия 3
    • По рекомендации John Doe заменил проверку GUID-а на флаг файловой панели
    • Добавил проверку, что исходный файл - реальный, т.к. TmpPanel в режиме :any может отображать на панели что угодно
    • Сделан обход ошибки ФАРа в функции Panel.Select для гашения отметок

buniak_a_h
Posts: 896
Joined: Sat 20 Apr, 2013 00:17
Location: Питер
Has thanked: 77 times
Been thanked: 28 times
Contact:

Копирование файлов с временной панели с сохранение структуры папок

Post by buniak_a_h » Thu 10 May, 2018 07:12

Обновил скрипт в первом посте темы. Добавлена простейшая визуализация и прерывание по [Esc].
Господа гуру! Может, кто читает эту тему и сможет ответить на "смежный" вопрос: есть ли возможность как-то визуализировать в макросе процесс копирования одного файла (без программирования самого процесса копирования)? Варианты:
(а) вызов внутренней процедуры копирования файла ФАРа с параметрами (Source, Destination, RewriteMode) и кодом возврата
(б) может, посоветуете плагин с аналогичными возможностями
Просто вызов диалога копирования с последовательностью Keys не очень подходит: не определить, что копирование было прервано. Подозреваю, что меня бы устроила export.GetFiles, но примера использования не нашёл.

User avatar
HaRT
Moderator
Posts: 8944
Joined: Tue 30 Aug, 2005 17:21
Location: Санкт-Петербург
Has thanked: 87 times
Been thanked: 155 times

Копирование файлов с временной панели с сохранение структуры папок

Post by HaRT » Thu 10 May, 2018 11:57

buniak_a_h wrote:
Thu 10 May, 2018 07:12
вызов диалога копирования с последовательностью Keys не очень подходит: не определить, что копирование было прервано
Я не гуру, но подозреваю, что прерывание копирования в стандартном диалоге можно отловить, повесив обработчик на соответствующее диалоговое событие. Костыль, конечно, но всё же лучше, чем ничего. Вот тут есть некий пример обработчика (правда, инициализации диалога, притом на Moon Script): viewtopic.php?p=146816#p146816.
Фар есть инструмент, а не нянька. © 2009 DrKnS

User avatar
John Doe
Бюрократ
Posts: 12363
Joined: Wed 27 Apr, 2005 20:42
Has thanked: 33 times
Been thanked: 171 times

Копирование файлов с временной панели с сохранение структуры папок

Post by John Doe » Thu 10 May, 2018 12:21

buniak_a_h wrote:
Thu 10 May, 2018 07:12
не определить, что копирование было прервано.
Проверить существование целевого файла?

buniak_a_h
Posts: 896
Joined: Sat 20 Apr, 2013 00:17
Location: Питер
Has thanked: 77 times
Been thanked: 28 times
Contact:

Копирование файлов с временной панели с сохранение структуры папок

Post by buniak_a_h » Thu 10 May, 2018 12:27

Спасибо всем. Метод реализуемый, но какой-то... чрезвычайный. Через выю, короче. Не люблю я клавиатурные макросы вперемешку с процедурами на языках программирования. Подожду ещё; если никто не присоветует - буду думать в направлении клавимакроса... :-(

User avatar
John Doe
Бюрократ
Posts: 12363
Joined: Wed 27 Apr, 2005 20:42
Has thanked: 33 times
Been thanked: 171 times

Копирование файлов с временной панели с сохранение структуры папок

Post by John Doe » Thu 10 May, 2018 12:39

Альтернативно, можно было бы целиком переложить копирование на какой-либо сторонний компонент (xcopy, robocopy, fastcopy, teracopy, etc), а функции макроса ограничить подготовкой файла с заданием.

User avatar
zg
zero-gravity
Posts: 5585
Joined: Tue 15 Mar, 2005 17:36
Location: riga
Been thanked: 91 times
Contact:

Копирование файлов с временной панели с сохранение структуры папок

Post by zg » Thu 10 May, 2018 13:57

CopyFileEx есть же. там может в самом начеале чуть посложнее, и то не факт, но в перспективе — самый нормальный метод.

buniak_a_h
Posts: 896
Joined: Sat 20 Apr, 2013 00:17
Location: Питер
Has thanked: 77 times
Been thanked: 28 times
Contact:

Копирование файлов с временной панели с сохранение структуры папок

Post by buniak_a_h » Thu 10 May, 2018 16:18

zg wrote:
Thu 10 May, 2018 13:57
CopyFileEx
1. Уж не стал писать... У меня CopyFileEx - персона non grata. Несколько раз копирование обрывалось без всякой диагностики. Т.е. пока скопированным файлом не воспользуешься - об ошибке не узнаешь. Ошибка абсолютно случайная, устойчиво повторить не могу.
2. абсолютно не предусмотрен интерфейс для использования из скрипта. Я имею в виду - нет ни вызова нужной функции через Plugin.Call, ни через командную строку. Или есть, но в документации не описано. А значит - опять Keys...

User avatar
HaRT
Moderator
Posts: 8944
Joined: Tue 30 Aug, 2005 17:21
Location: Санкт-Петербург
Has thanked: 87 times
Been thanked: 155 times

Копирование файлов с временной панели с сохранение структуры папок

Post by HaRT » Thu 10 May, 2018 16:23

buniak_a_h wrote:
Thu 10 May, 2018 16:18
У меня CopyFileEx - персона non grata. Несколько раз копирование обрывалось без всякой диагностики.
Вы про плагин? Я подозреваю, что zg имел в виду ф-ю WinAPI.
Фар есть инструмент, а не нянька. © 2009 DrKnS

User avatar
zg
zero-gravity
Posts: 5585
Joined: Tue 15 Mar, 2005 17:36
Location: riga
Been thanked: 91 times
Contact:

Копирование файлов с временной панели с сохранение структуры папок

Post by zg » Thu 10 May, 2018 17:57

тем более плагин немного не так называется.

buniak_a_h
Posts: 896
Joined: Sat 20 Apr, 2013 00:17
Location: Питер
Has thanked: 77 times
Been thanked: 28 times
Contact:

Копирование файлов с временной панели с сохранение структуры папок

Post by buniak_a_h » Thu 10 May, 2018 19:11

zg wrote:
Thu 10 May, 2018 17:57
тем более плагин немного не так называется.
Да, извините, плагин - FileCopyEx.
HaRT wrote:
Thu 10 May, 2018 16:23
zg имел в виду ф-ю WinAPI
И что мне с ней делать? писать вставку на СИ для вызова функции? Я этим не занимался пока, и не уверен, что овчинка выделки стоит. Если только написать "универсальный" макрос, вызывающий эту функцию. Для одной задачи - стрельба из пушки по воробьям. Я надеялся, что такое могло уже кому-то понадобиться, и кно-нить уже реализовал. Видимо, нет.

User avatar
HaRT
Moderator
Posts: 8944
Joined: Tue 30 Aug, 2005 17:21
Location: Санкт-Петербург
Has thanked: 87 times
Been thanked: 155 times

Копирование файлов с временной панели с сохранение структуры папок

Post by HaRT » Thu 10 May, 2018 19:31

buniak_a_h wrote:
Thu 10 May, 2018 19:11
что мне с ней делать? писать вставку на СИ для вызова функции?
FFI
Фар есть инструмент, а не нянька. © 2009 DrKnS

buniak_a_h
Posts: 896
Joined: Sat 20 Apr, 2013 00:17
Location: Питер
Has thanked: 77 times
Been thanked: 28 times
Contact:

Копирование файлов с временной панели с сохранение структуры папок

Post by buniak_a_h » Thu 10 May, 2018 22:51

HaRT wrote:
Thu 10 May, 2018 19:31
buniak_a_h wrote:
Thu 10 May, 2018 19:11
что мне с ней делать? писать вставку на СИ для вызова функции?
FFI
Это я и имел в виду под "вставкой на СИ".

buniak_a_h
Posts: 896
Joined: Sat 20 Apr, 2013 00:17
Location: Питер
Has thanked: 77 times
Been thanked: 28 times
Contact:

Копирование файлов с временной панели с сохранение структуры папок

Post by buniak_a_h » Fri 11 May, 2018 02:14

HaRT, с ffi возникли проблемы. Посмотрите, пожалуйста, вопрос на форуме, посвящённом ffi

Shtirla
Posts: 108
Joined: Wed 04 Mar, 2009 20:09
Has thanked: 8 times
Been thanked: 2 times

Копирование файлов с временной панели с сохранение структуры папок

Post by Shtirla » Fri 30 Nov, 2018 06:44

Во первых Спасибо автору ! помог решить задачку быстрее.
во вторых выкладываю модификацию текущего макроса, замена идет поиском первых слэшей в пути, а не из Panel0, ибо накиданные с разных ресурсов файлы так не копировались


buniak_a_h
Posts: 896
Joined: Sat 20 Apr, 2013 00:17
Location: Питер
Has thanked: 77 times
Been thanked: 28 times
Contact:

Копирование файлов с временной панели с сохранение структуры папок

Post by buniak_a_h » Fri 30 Nov, 2018 10:58

Shtirla wrote:
Fri 30 Nov, 2018 06:44
замена идет поиском первых слэшей в пути, а не из Panel0, ибо накиданные с разных ресурсов файлы так не копировались
Я, конечно, в курсе. Но тут тоже проблема возникает: если поиск привёл к тому, что все найденные файлы расположены в одном подкаталоге (и его вложенных), то в качестве "корня" будет именно этот общий каталог. Меня это не устраивало. Поэтому я сделал макрос, "заточенный" под поиск по AltF7: при закрытии диалога поиска я запоминаю текущий каталог в локальную переменную, а при копировании использую это значение. Плюс - ясно. Минус - именно "заточенность" на поиск файла. Т.е. при занесении на временную панель файла, не находящегося в каталоге, бывшем текущим при начале поиска этот файл не будет найден. В связи с этим добавил следующее: если после копирования остались не скопированные файлы, то инициируется обычный поиск (F5).
Пример переделанного макроса будет помещён в первый пост темы чуть позже.

Shtirla
Posts: 108
Joined: Wed 04 Mar, 2009 20:09
Has thanked: 8 times
Been thanked: 2 times

Копирование файлов с временной панели с сохранение структуры папок

Post by Shtirla » Fri 30 Nov, 2018 11:00

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

Post Reply

Return to “Обсуждение макросов”