local F = far.Flags
local aMenuItem
local Info = package.loaded.regscript or function(...) return ... end
local nfo = Info {_filename or ...,
name = "FindDup";
description = "Поиск дубликатов текущего файла";
version = "1.1.2"; --http://semver.org/lang/ru/
author = "BAX";
url = "https://forum.farmanager.com/viewtopic.php?p=174413#p174413";
id = "2B01CDB2-E9E6-4E8C-95E0-C3C7BD5C9730";
history = [[
18.04.2023 v1.1.1 - стартовая версия
18.05.2023 v1.1.2:
1. Оформление для Scripts Browser-а.
2. Исправлена неточность, из-за которой при наличии на временной панели одноимённых файлов (расположенных
в разных папках) неправильно отмечались файлы-дубликаты (см. https://forum.farmanager.com/viewtopic.php?t=13212).
3. В случае нахождения дубликатов предоставляется на выбор кничожить все, кроме текущего, заменить все на
жесткие, символические ссылки либо только отметить.
]];
--files = "*.cfg;*.ru.lng";
--config = function(nfo,name) end;
--help =
execute = function(nfo,name) aMenuItem.action() end;
--disabled = false;
--options = {};
}
if not nfo then return end
--local O = nfo.options
local IntheckerGuid = "E186306E-3B0D-48C1-9668-ED7CF64C0E65"
local ClearBefore = true
aMenuItem = {
description="Поиск дубликатов текущего файла";
menu='Plugins';
area='Shell';
guid="837A4BAD-A88A-4EDF-8743-D0C400399378";
text=function() return not APanel.Folder and "BAX - Поиск дублей текущего файла" end;
action=function()
local function CheckSum(fn)
local crc = Plugin.SyncCall(IntheckerGuid, "gethash", "md5", fn)
return type(crc) == 'string' and crc:upper()
end
local i0, l0, md5_0 = APanel.CurPos, panel.GetCurrentPanelItem(nil, 1).FileSize, CheckSum(APanel.Path0.."\\"..APanel.Current)
local aSel, aiSel = {}, {}
for i=1,APanel.ItemCount do
local PanItem = panel.GetPanelItem(nil, 1, i)
if not PanItem.FileAttributes:match"d" and
PanItem.FileSize == l0 and
CheckSum(APanel.Path0 .. '\\' .. PanItem.FileName) == md5_0 then
if i ~= i0 then aSel[#aSel+1] = PanItem.FileName end
aiSel[#aiSel+1] = i
end
end
if #aiSel > 1 then
local iCh = mf.mload('BAX','FindDup.iCh') or 0
if iCh > 1 then
mf.postmacro(Keys, tostring(iCh-1) .. '*Tab')
end
iCh = far.Message("Что делать с найденными дубликатами?\n\1\n(для создания символических ссылок требуются права администратора)",
"Поиск дублей текущего файла",
"Отметить;Удалить;Создать жёсткие ссылки;Создать символические ссылки")
if iCh > 0 then
mf.msave('BAX','FindDup.iCh', iCh)
end
if iCh == 1 then
if ClearBefore then Panel.Select(0, 0) end
panel.SetSelection(nil, 1, aiSel, true)
elseif iCh > 1 then -- Удалить или ссылки
local function FullName(fn)
if fn:match"%c:\\" then return fn
else
local res=APanel.Path0 .. (APanel.Path0:sub(-1) == '\\' and '' or '\\') .. fn
return res
end
end
local fn0 = FullName(APanel.Current)
for _,v in ipairs(aSel) do
v = FullName(v)
win.DeleteFile(v)
if iCh >= 3 then
far.MkLink(fn0, v, iCh == 3 and F.LINK_HARDLINK or F.LINK_SYMLINKFILE, F.MLF_DONOTUPDATEPANEL)
end
end
end
else
far.Message"Дубликатов не найдено"
end
end;
}
MenuItem(aMenuItem)