--[[ 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) local y = x:read("*a") x:close() return y 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 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, i) logwrite('downloading ' .. plugins[i][1]) -- clone the repo -- BUG: logwriting the git command doens't actually log the output run('git -C ' .. opts.dl.dir .. ' clone ' .. plugins[i][1]) run('git -C ' .. plugdir .. ' checkout -q ' .. plugins[i]['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() -- let the user know that we are starting install logwrite('Starting Download...') mp.osd_message('Downloading plugins!') -- start iterating through plugins for i = 1, tablelength(plugins) do -- check if the user has defined a file for the current plugin if not plugins[i]['file'] then logwrite('WARNING! Git repo "' .. plugins[i][1] .. '" doesn\'t have a specified file. Skipping download') -- FIXME: this results in the last plugin being downloaded & copied twice i = i + 1 -- if not we go to the next plugin end -- if no destdir defined we set it to the root of the mpv config dir if not plugins[i]['dir'] then plugins[i]['dir'] = '~~/' end -- get the file's dir local pluginfile = opts.dl.dir .. '/' .. string.match(plugins[i][1], '/([^/]+)$'):gsub('.git', '') .. '/' .. plugins[i]['file'] -- get the dest dir local destfile = mp.command_native({'expand-path', '~~/'}) .. '/' .. plugins[i]['dir'] .. '/' .. plugins[i]['file'] if fileexists(pluginfile) then -- if we need to update, update if checkupdates(i) then logwrite(plugins[i]['file'] .. ' is updating.') clonegit(i) else logwrite(plugins[i]['file'] .. ' is up to date!') end else clonegit(i) end -- copy the file contents over to the desired location local infile = io.open(pluginfile, 'r') local outfile = io.open(destfile, 'w') outfile:write(infile:read('*a')) outfile:close() infile:close() end end local function initupdate() openlog() logwrite('# of plugins defined in table: ' .. tablelength(plugins)) os.execute('mkdir -p ' .. opts.dl.dir) -- make download dir startinstall() -- 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 -- run any user defined configs at startup -- NOTE: This is kinda useless and might be removed if there is no way to make -- it run in the desired plugin's thread local function runopts() openlog() for i = 1, tablelength(plugins) do if plugins[i]['cfg'] then logwrite('Running ' .. plugins[i]['file'] .. '\'s config') plugins[i]['cfg']() end end closelog() end -- remove logfile on startup if opts.logging.log then openlog() os.remove(fn) closelog() end runopts() mp.add_key_binding(opts.bind, 'UpdatePlugins', initupdate)