- add name expansion gh:po5/thumbfast -> https://github.com/po5/thumbfast - allow multiple files to be downloaded to one dir - add pin option to stop updates on specific plugins
222 lines
5.7 KiB
Lua
222 lines
5.7 KiB
Lua
--[[
|
|
Eat It - a Mpv plugin manager
|
|
|
|
Copyright © 2023 squibid
|
|
|
|
This program is free software: you can redistribute it and/or modify
|
|
it under the terms of the GNU General Public License as published by
|
|
the Free Software Foundation, either version 3 of the License, or
|
|
(at your option) any later version.
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU General Public License for more details.
|
|
]]
|
|
|
|
local mp = require('mp')
|
|
|
|
-- load the config file
|
|
dofile(mp.command_native({'expand-path', '~~/eatit-cfg.lua'}))
|
|
|
|
-- helper functions --
|
|
local function tablelength(T)
|
|
local count = 0
|
|
for _ in pairs(T) do count = count + 1 end
|
|
return count
|
|
end
|
|
|
|
local function fileexists(name)
|
|
local ok, err, code = os.rename(name, name)
|
|
if not ok then
|
|
if code == 13 then
|
|
-- Permission denied, but it exists
|
|
return true
|
|
end
|
|
end
|
|
return ok, err
|
|
end
|
|
|
|
local function testforslash(str)
|
|
if string.match(str, '/') then
|
|
return string.match(str, '/([^/]+)$')
|
|
else
|
|
return str
|
|
end
|
|
end
|
|
|
|
local function run(cmd)
|
|
local x = io.popen(cmd)
|
|
if not x then return 1 end
|
|
local y = x:read("*a")
|
|
x:close()
|
|
return y
|
|
end
|
|
|
|
local function cp(a, b)
|
|
local i = io.open(a, 'r')
|
|
if not i then return 1 end
|
|
local o = io.open(b, 'w')
|
|
if not o then return 2 end
|
|
o:write(i:read('*a'))
|
|
o:close()
|
|
i:close()
|
|
end
|
|
|
|
local function getsrc(id)
|
|
local src
|
|
if string.find(id, ":") then src = id:match("^[a-z]+[^:]") end
|
|
local name = id:match([[[^:]*$]])
|
|
if name then
|
|
local pre = opts.nameexp.pre or "https://"
|
|
local map = opts.nameexp.map or {
|
|
gl = 'gitlab.com',
|
|
cb = 'codeberg.org',
|
|
sr = 'sr.ht',
|
|
gh = 'github.com'
|
|
}
|
|
return {
|
|
link = (pre..map[src]) or false,
|
|
repo = name
|
|
}
|
|
end
|
|
end
|
|
|
|
local function openlog()
|
|
if opts.logging.log then -- log if asked to
|
|
-- get our logfile's full path
|
|
fn = mp.command_native({'expand-path', opts.logging.logfile})
|
|
|
|
f = io.open(fn, 'a') -- open file buffer
|
|
if not f then return 1 end
|
|
io.output(f) -- set it as default
|
|
end
|
|
end
|
|
|
|
local function logwrite(string)
|
|
if opts.logging.log then
|
|
io.write(os.date(opts.logging.logdate)..' '..string..'\n')
|
|
end
|
|
end
|
|
|
|
local function closelog()
|
|
if opts.logging.log then
|
|
io.close(f)
|
|
end
|
|
end
|
|
|
|
-- get the requested git repos
|
|
local function clonegit(plugdir, url, branch)
|
|
logwrite('downloading '..url)
|
|
|
|
-- clone the repo
|
|
-- BUG: logwriting the git command doesn't actually log the output
|
|
run('git -C '..opts.dl.dir..' clone '..url..' '..plugdir)
|
|
run('git -C '..plugdir..' checkout -q '..branch)
|
|
end
|
|
|
|
-- check for updates
|
|
local function checkupdates(plugdir)
|
|
local localhash = run('git -C '..plugdir..' log -1 --format=format:"%H"')
|
|
local remotehash = run('git -C '..plugdir..' rev-parse $(git -C '..
|
|
plugdir..' branch -r) | tail -1')
|
|
if localhash ~= remotehash then return true else return false end
|
|
end
|
|
|
|
-- start install
|
|
local function startinstall(i)
|
|
local src = getsrc(plugins[i][1])
|
|
local plugin = { -- plugin table spec
|
|
id = plugins[i][1] or false,
|
|
url = plugins[i]['url'] or (src['link'].."/"..src['repo']),
|
|
file = plugins[i]['file'] or false,
|
|
dir = plugins[i]['dir'] or 'scripts',
|
|
pin = plugins[i]['pin'] or false,
|
|
branch = plugins[i]['branch'] or false,
|
|
}
|
|
|
|
-- check if the user has defined a file for the current plugin
|
|
if not plugin['file'] then
|
|
logwrite('WARNING! File not configured for '..plugin[1])
|
|
goto continue
|
|
end
|
|
-- skip install of pinned files
|
|
if plugin['pin'] == true then goto continue end
|
|
|
|
-- get the plugins tmp download dir
|
|
local plugdir = opts.dl.dir..'/'..testforslash(src['repo']):gsub('.git', '')
|
|
|
|
-- if no specified branch we use the default
|
|
plugin['branch'] = plugin['branch'] or testforslash(
|
|
run('git -C '..plugdir..' symbolic-ref refs/remotes/origin/HEAD')
|
|
)
|
|
|
|
-- check for multiple files
|
|
if type(plugin['file']) == 'string' then
|
|
plugin['file'] = {}
|
|
table.insert(plugin['file'], plugins[i]['file'])
|
|
end
|
|
|
|
-- get the requested file(s)
|
|
for j = 1, #plugin['file'] or 1 do
|
|
-- get the file's dir
|
|
local pluginfile = plugdir..'/'..plugin['file'][j]
|
|
|
|
-- get the dest dir
|
|
local destfile = mp.command_native({'expand-path', '~~/'})..
|
|
'/'..plugin['dir']..'/'..testforslash(plugin['file'][j])
|
|
|
|
if fileexists(plugdir..'/') then
|
|
-- if we need to update, update
|
|
if checkupdates(plugdir) then
|
|
logwrite(plugin['file'][j]..' is updating.')
|
|
-- make sure we are on the main branch
|
|
run('git -C '..plugdir..' checkout -q '..plugin['branch'])
|
|
run('git -C '..plugdir..' pull') -- get the latest commits
|
|
else
|
|
logwrite(plugin['file'][j]..' is up to date!')
|
|
end
|
|
else
|
|
clonegit(plugdir, plugin['url'], plugin['branch'])
|
|
end
|
|
|
|
-- copy the file contents over to the desired location
|
|
cp(pluginfile, destfile)
|
|
end
|
|
::continue::
|
|
end
|
|
|
|
local function initupdate()
|
|
openlog()
|
|
|
|
logwrite('# of plugins defined in table: '..tablelength(plugins))
|
|
os.execute('mkdir -p '..opts.dl.dir) -- make download dir
|
|
|
|
-- start the install process
|
|
logwrite('Starting Download...')
|
|
mp.osd_message('Downloading plugins!')
|
|
|
|
-- start iterating through plugins
|
|
for i = 1, tablelength(plugins) do
|
|
local f = coroutine.create(function() startinstall(i) end)
|
|
coroutine.resume(f)
|
|
end
|
|
|
|
-- closing/removing everything
|
|
if opts.dl.powerwash == true then
|
|
logwrite('powerwashing the tmp dir "'..opts.dl.dir..'"')
|
|
os.execute('rm -rf '..opts.dl.dir)
|
|
end
|
|
|
|
closelog()
|
|
end
|
|
|
|
-- remove logfile on startup
|
|
if opts.logging.log then
|
|
openlog()
|
|
os.remove(fn)
|
|
closelog()
|
|
end
|
|
|
|
mp.add_key_binding(opts.bind, 'UpdatePlugins', initupdate)
|