├── README.md ├── manager.json └── manager.lua /README.md: -------------------------------------------------------------------------------- 1 | # mpv_manager 2 | User script and shader manager for mpv. 3 | 4 | ## Requirements 5 | - git 6 | 7 | ## Installation 8 | Place manager.json next to your `mpv.conf`, and manager.lua in your `scripts` folder. 9 | 10 | ## Usage 11 | Define your rules in `manager.json` 12 | Assign a key to the update function with `M script-binding manager-update-all` in `input.conf` 13 | -------------------------------------------------------------------------------- /manager.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "git":"https://github.com/jgreco/mpv-scripts", 4 | "whitelist":"fastforward%.lua$", 5 | "dest":"~~/scripts" 6 | }, 7 | { 8 | "git":"https://github.com/wiiaboo/mpv-scripts", 9 | "whitelist":"auto%-profiles%.lua$", 10 | "dest":"~~/scripts" 11 | }, 12 | { 13 | "git":"https://github.com/d87/mpv-persist-properties", 14 | "whitelist":"%.lua$", 15 | "dest":"~~/scripts" 16 | }, 17 | { 18 | "git":"https://github.com/mpv-player/mpv", 19 | "whitelist":"autocrop%.lua$|autoload%.lua$", 20 | "dest":"~~/scripts" 21 | }, 22 | { 23 | "git":"https://github.com/po5/mpv_sponsorblock", 24 | "whitelist":"%.py$|%.lua$", 25 | "dest":"~~/scripts" 26 | }, 27 | { 28 | "git":"https://github.com/po5/uosc", 29 | "whitelist":"%.lua$", 30 | "dest":"~~/scripts" 31 | }, 32 | { 33 | "git":"https://github.com/po5/mpv-webm", 34 | "whitelist":"webm%.lua$", 35 | "dest":"~~/scripts" 36 | }, 37 | { 38 | "git":"https://github.com/po5/trackselect", 39 | "whitelist":"%.lua$", 40 | "dest":"~~/scripts" 41 | }, 42 | { 43 | "git":"https://github.com/po5/chapterskip", 44 | "whitelist":"%.lua$", 45 | "dest":"~~/scripts" 46 | }, 47 | { 48 | "git":"https://github.com/po5/groupwatch_sync", 49 | "whitelist":"%.lua$", 50 | "dest":"~~/scripts" 51 | }, 52 | { 53 | "git":"https://github.com/po5/mpv_irc", 54 | "whitelist":"%.lua$", 55 | "dest":"~~/scripts" 56 | }, 57 | { 58 | "git":"https://github.com/po5/mpv-scripts", 59 | "whitelist":"coverart%.lua$", 60 | "dest":"~~/scripts" 61 | }, 62 | { 63 | "git":"https://gist.github.com/igv/8a77e4eb8276753b54bb94c1c50c317e", 64 | "whitelist":"%.glsl$", 65 | "dest":"~~/shaders" 66 | }, 67 | { 68 | "git":"https://gist.github.com/igv/a015fc885d5c22e6891820ad89555637", 69 | "whitelist":"%.glsl$", 70 | "dest":"~~/shaders" 71 | }, 72 | { 73 | "git":"https://github.com/bjin/mpv-prescalers", 74 | "whitelist":"ravu%-lite%-r4%.hook$|ravu%-zoom%-r4%-chroma%.hook$", 75 | "dest":"~~/shaders" 76 | } 77 | ] -------------------------------------------------------------------------------- /manager.lua: -------------------------------------------------------------------------------- 1 | local utils = require "mp.utils" 2 | local legacy = mp.command_native_async == nil 3 | local config = {} 4 | local dir_cache = {} 5 | 6 | function run(args) 7 | if legacy then 8 | return utils.subprocess({args = args}) 9 | end 10 | return mp.command_native({name = "subprocess", capture_stdout = true, playback_only = false, args = args}) 11 | end 12 | 13 | function parent(path) 14 | return string.match(path, "(.*)[/\\]") 15 | end 16 | 17 | function cache(path) 18 | local p_path = parent(path) 19 | if p_path == nil or p_path == "" or dir_cache[p_path] then return end 20 | cache(p_path) 21 | dir_cache[path] = 1 22 | end 23 | 24 | function mkdir(path) 25 | if dir_cache[path] then return end 26 | cache(path) 27 | run({"git", "init", path}) 28 | end 29 | 30 | function match(str, patterns) 31 | for pattern in string.gmatch(patterns, "[^|]+") do 32 | if string.match(str, pattern) then 33 | return true 34 | end 35 | end 36 | end 37 | 38 | function apply_defaults(info) 39 | if info.git == nil then return false end 40 | if info.whitelist == nil then info.whitelist = "" end 41 | if info.blacklist == nil then info.blacklist = "" end 42 | if info.dest == nil then info.dest = "~~/scripts" end 43 | if info.branch == nil then info.branch = "master" end 44 | return info 45 | end 46 | 47 | function update(info) 48 | info = apply_defaults(info) 49 | if not info then return false end 50 | 51 | local base = nil 52 | 53 | local e_dest = string.match(mp.command_native({"expand-path", info.dest}), "(.-)[/\\]?$") 54 | mkdir(e_dest) 55 | 56 | local files = {} 57 | 58 | run({"git", "-C", e_dest, "remote", "add", "manager", info.git}) 59 | run({"git", "-C", e_dest, "remote", "set-url", "manager", info.git}) 60 | run({"git", "-C", e_dest, "fetch", "manager", info.branch}) 61 | 62 | for file in string.gmatch(run({"git", "-C", e_dest, "ls-tree", "-r", "--name-only", "remotes/manager/"..info.branch}).stdout, "[^\r\n]+") do 63 | local l_file = string.lower(file) 64 | if info.whitelist == "" or match(l_file, info.whitelist) then 65 | if info.blacklist == "" or not match(l_file, info.blacklist) then 66 | table.insert(files, file) 67 | if base == nil then base = parent(l_file) or "" end 68 | while string.match(base, l_file) == nil do 69 | if l_file == "" then break end 70 | l_file = parent(l_file) or "" 71 | end 72 | base = l_file 73 | end 74 | end 75 | end 76 | 77 | if base == nil then return false end 78 | 79 | if base ~= "" then base = base.."/" end 80 | 81 | if next(files) == nil then 82 | print("no files matching patterns") 83 | else 84 | for _, file in ipairs(files) do 85 | local based = string.sub(file, string.len(base)+1) 86 | local p_based = parent(based) 87 | if p_based and not info.flatten_folders then mkdir(e_dest.."/"..p_based) end 88 | local c = string.match(run({"git", "-C", e_dest, "--no-pager", "show", "remotes/manager/"..info.branch..":"..file}).stdout, "(.-)[\r\n]?$") 89 | local f = io.open(e_dest.."/"..(info.flatten_folders and file:match("[^/]+$") or based), "w") 90 | f:write(c) 91 | f:close() 92 | end 93 | end 94 | return true 95 | end 96 | 97 | function update_all() 98 | local f = io.open(mp.command_native({"expand-path", "~~/manager.json"}), "r") 99 | if f then 100 | local json = f:read("*all") 101 | f:close() 102 | 103 | local props = utils.parse_json(json or "") 104 | if props then 105 | config = props 106 | end 107 | end 108 | 109 | for i, info in ipairs(config) do 110 | print("update"..i, update(info)) 111 | end 112 | end 113 | 114 | mp.add_key_binding(nil, "manager-update-all", update_all) 115 | --------------------------------------------------------------------------------