6 Commits
v1.0 ... v2.0

Author SHA1 Message Date
878f0faaf7 add some nil checks, and make lssi work with eatit changes 2023-10-17 22:24:49 -04:00
6f091a7648 Major changes!
- 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
2023-10-17 22:03:41 -04:00
96c3e6f3e6 add nil checks 2023-10-15 07:04:07 -04:00
25765c4ace fix indentation 2023-10-15 07:02:40 -04:00
b6dff07a12 fix typo and make commands appear nicer 2023-07-28 19:24:44 -04:00
af125691f7 add bootstrap script and better instructions for installation 2023-07-28 19:23:26 -04:00
5 changed files with 175 additions and 98 deletions

View File

@ -3,25 +3,21 @@ Eat It is a plugin manager for mpv which allows you to declare what files you
want from git repos. want from git repos.
## Installing Eat It ## Installing Eat It
To install Eat It simply put the `eatit.lua` file into your mpv scripts
directory (~/.config/mpv/scripts by default on linux). After you have done that
Eat It is installed, however it won't do anything without the `eatit-cfg.lua`,
which has to be placed in the root of your mpv config dir (~/.config/mpv by
default on linux).
Alternatively you can run these two commands: ### First time
```sh To install eatit run these two commands [Make sure you know what it does](https://explainshell.com/explain?cmd=curl+-L+https%3A%2F%2Fgit.squi.bid%2Feat-it%2Fplain%2Featit.lua+-o+~%2F.config%2Fmpv%2Fscripts%2Featit.lua+curl+-L+https%3A%2F%2Fgit.squi.bid%2Feat-it%2Fplain%2Featit-cfg.lua+-o+~%2F.config%2Fmpv%2Featit-cfg.lua):
curl -L https://git.squi.bid/eat-it/plain/eatit.lua -o ~/.config/mpv/scripts/eatit.lua curl -L https://git.squi.bid/eat-it/plain/eatit.lua -o ~/.config/mpv/scripts/eatit.lua
curl -L https://git.squi.bid/eat-it/plain/eatit-cfg.lua -o ~/.config/mpv/eatit-cfg.lua curl -L https://git.squi.bid/eat-it/plain/eatit-cfg.lua -o ~/.config/mpv/eatit-cfg.lua
```
### Bootstraping
The included bootstrap script will install and load eatit as soon as mpv starts.
## FAQ ## FAQ
Q: Where does the name 'Eat It' come from? Q: Where does the name 'Eat It' come from?
A: The plugin manager eats all the useless files and keeps the ones you want, A: The plugin manager eats all the useless files and keeps the ones you want,
*and Weird Al is a funny guy* *and Weird Al is a funny guy*
## TODO ## TODO
- make an auto install script that can be put into a mpv config
## ALTERNATIVES ## ALTERNATIVES
[email me](mailto:me@zacharyscheiman.com) if you know of any alternatives [email me](mailto:me@zacharyscheiman.com) if you know of any alternatives

8
bootstrap.lua Normal file
View File

@ -0,0 +1,8 @@
os.execute('git clone https://git.squi.bid/eat-it /tmp/eatit-tmp')
local a = io.open('/tmp/eatit-tmp/eatit.lua', 'r')
local b = io.open(mp.command_native({'expand-path', '~~/scripts/eatit.lua'}), 'w')
b:write(a:read('*a'))
b:close()
a:close()
dofile(mp.command_native({'expand-path', '~~/scripts/eatit.lua'}))
os.execute('rm -rf /tmp/eatit-tmp')

View File

@ -18,10 +18,36 @@ GNU General Public License for more details.
-- after being called with dofile() -- after being called with dofile()
plugins = { -- the plugins you want to load plugins = { -- the plugins you want to load
{ 'https://git.squi.bid/eat-it', -- required, specifies the git repo { 'squibid/eat-it', -- required, specifies the git repo
file = 'eatit.lua', -- required, specifies the desired file -- optional, sets repo link (see advanced example for more info on how to
dir = 'scripts', -- optional, sets the dest dir -- use this)
branch = 'master', -- optional, sets the desired branch url = 'https://git.squi.bid/eat-it',
-- required, specifies the desired file from the git repo
file = 'eatit.lua',
-- optional, sets the destination of the requested file
dir = 'scripts',
-- optional, sets the desired branch of the git repo
branch = 'master',
-- optional, stop the plugin from being updated
pin = false,
},
-- advanced example
{ 'gh:po5/thumbfast', -- expands to https://github.com/po5/thumbfast
file = { -- multiple files all going to the same place
'thumbfast.lua',
'osc.lua'
},
branch = 'ancient',
--[[
no need to specify dir as it defaults to ~~/scripts
no need to specify url as it is extrapolated from name
name expansion can be configured in the opts section
]]
}, },
} }
@ -35,6 +61,16 @@ opts = {
}, },
dl = { -- options for dealing with the git repos dl = { -- options for dealing with the git repos
dir = '/tmp/mpv-eatit', dir = '/tmp/mpv-eatit',
powerwash = false, -- if true the dl dir gets deleted after mpv closes powerwash = false, -- if true the download dir gets deleted after mpv closes
},
nameexp = {
pre = 'https://',
map = {
-- shortcut = link
gl = 'gitlab.com',
cb = 'codeberg.org',
sr = 'sr.ht',
gh = 'github.com'
}
} }
} }

143
eatit.lua
View File

@ -47,24 +47,55 @@ end
local function run(cmd) local function run(cmd)
local x = io.popen(cmd) local x = io.popen(cmd)
if not x then return 1 end
local y = x:read("*a") local y = x:read("*a")
x:close() x:close()
return y return y
end 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() local function openlog()
if opts.logging.log then -- log if asked to if opts.logging.log then -- log if asked to
-- get our logfile's full path -- get our logfile's full path
fn = mp.command_native({'expand-path', opts.logging.logfile}) fn = mp.command_native({'expand-path', opts.logging.logfile})
f = io.open(fn, 'a') -- open file buffer f = io.open(fn, 'a') -- open file buffer
if not f then return 1 end
io.output(f) -- set it as default io.output(f) -- set it as default
end end
end end
local function logwrite(string) local function logwrite(string)
if opts.logging.log then if opts.logging.log then
io.write(os.date(opts.logging.logdate) .. ' ' .. string .. '\n') io.write(os.date(opts.logging.logdate)..' '..string..'\n')
end end
end end
@ -75,100 +106,106 @@ local function closelog()
end end
-- get the requested git repos -- get the requested git repos
local function clonegit(plugdir, i) local function clonegit(plugdir, url, branch)
logwrite('downloading ' .. plugins[i][1]) logwrite('downloading '..url)
-- clone the repo -- clone the repo
-- BUG: logwriting the git command doens't actually log the output -- BUG: logwriting the git command doesn't actually log the output
run('git -C ' .. opts.dl.dir .. ' clone ' .. plugins[i][1]) run('git -C '..opts.dl.dir..' clone '..url..' '..plugdir)
run('git -C ' .. plugdir .. ' checkout -q ' .. plugins[i]['branch']) run('git -C '..plugdir..' checkout -q '..branch)
end end
-- check for updates -- check for updates
local function checkupdates(plugdir) local function checkupdates(plugdir)
local localhash = run('git -C ' .. plugdir .. ' log -1 --format=format:"%H"') local localhash = run('git -C '..plugdir..' log -1 --format=format:"%H"')
local remotehash = run('git -C ' .. plugdir .. ' rev-parse $(git -C ' .. local remotehash = run('git -C '..plugdir..' rev-parse $(git -C '..
plugdir .. ' branch -r) | tail -1') plugdir..' branch -r) | tail -1')
if localhash ~= remotehash then return true else return false end if localhash ~= remotehash then return true else return false end
end end
-- start install -- start install
local function startinstall() local function startinstall(i)
-- let the user know that we are starting install local src = getsrc(plugins[i][1])
logwrite('Starting Download...') local plugin = { -- plugin table spec
mp.osd_message('Downloading plugins!') 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,
}
-- start iterating through plugins
for i = 1, tablelength(plugins) do
-- check if the user has defined a file for the current plugin -- check if the user has defined a file for the current plugin
if not plugins[i]['file'] then if not plugin['file'] then
logwrite('WARNING! Git repo "' .. plugins[i][1] .. logwrite('WARNING! File not configured for '..plugin[1])
'" doesn\'t have a specified file. Skipping download') goto continue
-- 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 end
-- skip install of pinned files
if plugin['pin'] == true then goto continue end
-- get the plugins tmp download dir -- get the plugins tmp download dir
local plugdir = opts.dl.dir .. '/' .. local plugdir = opts.dl.dir..'/'..testforslash(src['repo']):gsub('.git', '')
string.match(plugins[i][1], '/([^/]+)$'):gsub('.git', '')
-- if no specified branch we use the default -- if no specified branch we use the default
if not plugins[i]['branch'] then plugin['branch'] = plugin['branch'] or testforslash(
plugins[i]['branch'] = testforslash( run('git -C '..plugdir..' symbolic-ref refs/remotes/origin/HEAD')
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 end
-- get the requested file(s)
for j = 1, #plugin['file'] or 1 do
-- get the file's dir -- get the file's dir
local pluginfile = opts.dl.dir .. '/' .. local pluginfile = plugdir..'/'..plugin['file'][j]
string.match(plugins[i][1], '/([^/]+)$'):gsub('.git', '') ..
'/' .. plugins[i]['file']
-- get the dest dir -- get the dest dir
local destfile = mp.command_native({'expand-path', '~~/'}) .. local destfile = mp.command_native({'expand-path', '~~/'})..
'/' .. plugins[i]['dir'] .. '/'..plugin['dir']..'/'..testforslash(plugin['file'][j])
'/' .. testforslash(plugins[i]['file'])
if fileexists(plugdir .. '/') then if fileexists(plugdir..'/') then
-- if we need to update, update -- if we need to update, update
if checkupdates(plugdir) then if checkupdates(plugdir) then
logwrite(plugins[i]['file'] .. ' is updating.') logwrite(plugin['file'][j]..' is updating.')
-- make sure we are on the main branch -- make sure we are on the main branch
run('git -C ' .. plugdir .. ' checkout -q ' .. plugins[i]['branch']) run('git -C '..plugdir..' checkout -q '..plugin['branch'])
run('git -C ' .. plugdir .. ' pull') -- get the latest commits run('git -C '..plugdir..' pull') -- get the latest commits
else else
logwrite(plugins[i]['file'] .. ' is up to date!') logwrite(plugin['file'][j]..' is up to date!')
end end
else else
clonegit(plugdir, i) clonegit(plugdir, plugin['url'], plugin['branch'])
end end
-- copy the file contents over to the desired location -- copy the file contents over to the desired location
local infile = io.open(pluginfile, 'r') cp(pluginfile, destfile)
local outfile = io.open(destfile, 'w')
outfile:write(infile:read('*a'))
outfile:close()
infile:close()
end end
::continue::
end end
local function initupdate() local function initupdate()
openlog() openlog()
logwrite('# of plugins defined in table: ' .. tablelength(plugins)) logwrite('# of plugins defined in table: '..tablelength(plugins))
os.execute('mkdir -p ' .. opts.dl.dir) -- make download dir os.execute('mkdir -p '..opts.dl.dir) -- make download dir
startinstall()
-- 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 -- closing/removing everything
if opts.dl.powerwash == true then if opts.dl.powerwash == true then
logwrite('powerwashing the tmp dir "' .. opts.dl.dir .. '"') logwrite('powerwashing the tmp dir "'..opts.dl.dir..'"')
os.execute('rm -rf ' .. opts.dl.dir) os.execute('rm -rf '..opts.dl.dir)
end end
closelog() closelog()

View File

@ -27,7 +27,7 @@ Takes an input file and code then, it outputs a file with your code in there.
local mp = require('mp') local mp = require('mp')
mod = { mod = {
version = 'ALPHA 1', -- the current version of lssi version = 'ALPHA 1.1', -- the current version of lssi
author = 'squibid', author = 'squibid',
} }
@ -48,7 +48,7 @@ end
local function logwrite(string) local function logwrite(string)
if opts.logging.log then if opts.logging.log then
io.write(os.date(opts.logging.logdate) .. ' ' .. string .. '\n') io.write(os.date(opts.logging.logdate)..' '..string..'\n')
end end
end end
@ -58,6 +58,7 @@ local function openlog()
fn = mp.command_native({'expand-path', opts.logging.logfile}) fn = mp.command_native({'expand-path', opts.logging.logfile})
f = io.open(fn, 'a') -- open file buffer f = io.open(fn, 'a') -- open file buffer
if not f then return end
io.output(f) -- set it as default io.output(f) -- set it as default
end end
end end
@ -78,28 +79,28 @@ local function inject(infile, l, outfile)
-- don't do anything if there is already code injected into the file -- don't do anything if there is already code injected into the file
if string.find(infcont[1], "-- code injected by lssi") then if string.find(infcont[1], "-- code injected by lssi") then
logwrite('code is already injected into ' .. infile) logwrite('code is already injected into '..infile)
return return
end end
logwrite('Injecting code into ' .. infile) logwrite('Injecting code into '..infile)
for i in pairs(l) do for i in pairs(l) do
-- add requested line below existing line -- add requested line below existing line
if l[i][2] == 'G' then if l[i][2] == 'G' then
infcont[tablelength(infcont)] = infcont[tablelength(infcont)] .. '\n' .. l[i][1] infcont[tablelength(infcont)] = infcont[tablelength(infcont)]..'\n'..l[i][1]
elseif l[i][2] == 'g' then elseif l[i][2] == 'g' then
infcont[1] = l[i][1] .. '\n' .. infcont[1] infcont[1] = l[i][1]..'\n'..infcont[1]
else else
infcont[l[i][2]] = (infcont[l[i][2]]) .. '\n' .. l[i][1] infcont[l[i][2]] = (infcont[l[i][2]])..'\n'..l[i][1]
end end
end end
local outf = io.open(outfile, 'w') local outf = io.open(outfile, 'w')
-- we inject metadata to prevent writing to the file more than once -- we inject metadata to prevent writing to the file more than once
infcont[1] = "-- code injected by lssi " .. mod.version .. '\n' .. infcont[1] infcont[1] = "-- code injected by lssi "..mod.version..'\n'..infcont[1]
for i, v in ipairs(infcont) do for i, v in ipairs(infcont) do
outf:write(v .. '\n') outf:write(v..'\n')
end end
io.close(outf) io.close(outf)
@ -109,20 +110,19 @@ local function checkandinject()
openlog() openlog()
for i = 1, tablelength(plugins) do for i = 1, tablelength(plugins) do
-- check if the plugin has been configured with lssi
if plugins[i]['lssi'] ~= nil then
-- get the file we want to inject our code into -- get the file we want to inject our code into
local f = mp.command_native({'expand-path', '~~/'}) .. local f = mp.command_native({'expand-path', '~~/'}) ..
'/' .. plugins[i]['dir'] .. '/'..(plugins[i]['dir'] or 'scripts') ..
'/' .. plugins[i]['file'] '/'..plugins[i]['file']
-- check if the plugin has been configured with lssi
if plugins[i]['lssi'] then
-- and the file we are trying to modify actually exists -- and the file we are trying to modify actually exists
if fileexists(f) then if fileexists(f) then
-- inject it! no going back now -- inject it! no going back now
inject(f, plugins[i]['lssi'], f) inject(f, plugins[i]['lssi'], f)
else else
logwrite('Failed to inject code into "' .. logwrite('Failed to inject code into "' ..
plugins[i]['file'] .. '" file does not exist') plugins[i]['file']..'" file does not exist')
end end
end end
end end