diff --git a/.codex/config.toml##os.Linux b/.codex/config.toml##os.Linux index 1d2e8a7..d9b8593 100644 --- a/.codex/config.toml##os.Linux +++ b/.codex/config.toml##os.Linux @@ -210,6 +210,9 @@ trust_level = "trusted" [projects."/home/sudacode/.local/share/Anki2"] trust_level = "trusted" +[projects."/home/sudacode/projects/japanese/subminer.moe"] +trust_level = "trusted" + [notice.model_migrations] "gpt-5.3-codex" = "gpt-5.4" @@ -234,6 +237,9 @@ enabled = true [plugins."browser@openai-bundled"] enabled = true +[plugins."coderabbit@openai-curated"] +enabled = true + [tui.model_availability_nux] "gpt-5.5" = 4 diff --git a/.config/hypr/hyprland.lua b/.config/hypr/hyprland.lua index 6999c4b..e09048f 100644 --- a/.config/hypr/hyprland.lua +++ b/.config/hypr/hyprland.lua @@ -27,9 +27,9 @@ hl.monitor({ position = "0x0", scale = 1, vrr = 2, - -- cm = srgb + cm = srgb, -- Optional HDR settings - cm = "hdr", + -- cm = "hdr", bitdepth = 10, sdr_min_luminance = 0.005, sdr_max_luminance = 200, diff --git a/.config/hypr/windowrules.lua b/.config/hypr/windowrules.lua index 26a614b..d15117b 100644 --- a/.config/hypr/windowrules.lua +++ b/.config/hypr/windowrules.lua @@ -337,17 +337,8 @@ hl.window_rule({ hl.window_rule({ match = { - class = "SubMiner", + class = "^SubMiner$", }, - opacity = "1.0 override", - pin = false, -}) - -hl.window_rule({ - match = { - class = "SubMiner", - }, - float = true, border_size = 0, xray = false, @@ -356,8 +347,7 @@ hl.window_rule({ no_dim = true, opaque = true, dim_around = false, - allows_input = false, - opacity = "1.0 override", + opacity = "1.0 override 1.0 override", pin = false, }) diff --git a/.config/mpv/scripts/ytdl-preload.lua b/.config/mpv/scripts/ytdl-preload.lua deleted file mode 100644 index 2e447d7..0000000 --- a/.config/mpv/scripts/ytdl-preload.lua +++ /dev/null @@ -1,454 +0,0 @@ ----------------------- --- #example ytdl_preload.conf --- # make sure lines do not have trailing whitespace --- # ytdl_opt has no sanity check and should be formatted exactly how it would appear in yt-dlp CLI, they are split into a key/value pair on whitespace --- # at least on Windows, do not escape '\' in temp, just us a single one for each divider - --- #temp=R:\ytdltest --- #ytdl_opt1=-r 50k --- #ytdl_opt2=-N 5 --- #ytdl_opt#=etc ----------------------- -local nextIndex -local caught = true --- local pop = false -local ytdl = "yt-dlp" -local utils = require("mp.utils") - -local options = require("mp.options") -local opts = { - temp = "/tmp/ytdl-preload", - ytdl_opt1 = "", - ytdl_opt2 = "", - ytdl_opt3 = "", - ytdl_opt4 = "", - ytdl_opt5 = "", - ytdl_opt6 = "", - ytdl_opt7 = "", - ytdl_opt8 = "", - ytdl_opt9 = "", -} -options.read_options(opts, "ytdl_preload") -local additionalOpts = {} -for k, v in pairs(opts) do - if k:find("ytdl_opt%d") and v ~= "" then - additionalOpts[k] = v - -- print("entry") - -- print(k .. v) - end -end -local cachePath = opts.temp - -local chapter_list = {} -local json = "" -local filesToDelete = {} - -local function exists(file) - local ok, err, code = os.rename(file, file) - if not ok then - if code == 13 then -- Permission denied, but it exists - return true - end - end - return ok, err -end -local function useNewLoadfile() - for _, c in pairs(mp.get_property_native("command-list")) do - if c["name"] == "loadfile" then - for _, a in pairs(c["args"]) do - if a["name"] == "index" then - return true - end - end - end - end -end ---from ytdl_hook -local function time_to_secs(time_string) - local ret - local a, b, c = time_string:match("(%d+):(%d%d?):(%d%d)") - if a ~= nil then - ret = (a * 3600 + b * 60 + c) - else - a, b = time_string:match("(%d%d?):(%d%d)") - if a ~= nil then - ret = (a * 60 + b) - end - end - return ret -end -local function extract_chapters(data, video_length) - local ret = {} - for line in data:gmatch("[^\r\n]+") do - local time = time_to_secs(line) - if time and (time < video_length) then - table.insert(ret, { time = time, title = line }) - end - end - table.sort(ret, function(a, b) - return a.time < b.time - end) - return ret -end -local function chapters() - if json.chapters then - for i = 1, #json.chapters do - local chapter = json.chapters[i] - local title = chapter.title or "" - if title == "" then - title = string.format("Chapter %02d", i) - end - table.insert(chapter_list, { time = chapter.start_time, title = title }) - end - elseif not (json.description == nil) and not (json.duration == nil) then - chapter_list = extract_chapters(json.description, json.duration) - end -end ---end ytdl_hook -local title = "" -local fVideo = "" -local fAudio = "" -local function load_files(dtitle, destination, audio, wait) - if wait then - if exists(destination .. ".mka") then - print("---wait success: found mka---") - audio = "audio-file=" .. destination .. ".mka," - else - print("---could not find mka after wait, audio may be missing---") - end - end - -- if audio ~= "" then - -- table.insert(filesToDelete, destination .. ".mka") - -- end - -- table.insert(filesToDelete, destination .. ".mkv") - dtitle = dtitle:gsub("-" .. ("[%w_-]"):rep(11) .. "$", "") - dtitle = dtitle:gsub("^" .. ("%d"):rep(10) .. "%-", "") - if useNewLoadfile() then - mp.commandv( - "loadfile", - destination .. ".mkv", - "append", - -1, - audio .. 'force-media-title="' .. dtitle .. '",demuxer-max-back-bytes=1MiB,demuxer-max-bytes=3MiB,ytdl=no' - ) - else - mp.commandv( - "loadfile", - destination .. ".mkv", - "append", - audio .. 'force-media-title="' .. dtitle .. '",demuxer-max-back-bytes=1MiB,demuxer-max-bytes=3MiB,ytdl=no' - ) --,sub-file="..destination..".en.vtt") --in case they are not set up to autoload - end - mp.commandv("playlist_move", mp.get_property("playlist-count") - 1, nextIndex) - mp.commandv("playlist_remove", nextIndex + 1) - caught = true - title = "" - -- pop = true -end - -local listenID = "" -local function listener(event) - if not caught and event.prefix == mp.get_script_name() and string.find(event.text, listenID) then - local destination = string.match(event.text, "%[download%] Destination: (.+).mkv") - or string.match(event.text, "%[download%] (.+).mkv has already been downloaded") - -- if destination then print("---"..cachePath) end; - if destination and string.find(destination, string.gsub(cachePath, "~/", "")) then - -- print(listenID) - mp.unregister_event(listener) - _, title = utils.split_path(destination) - local audio = "" - if fAudio == "" then - load_files(title, destination, audio, false) - else - if exists(destination .. ".mka") then - audio = "audio-file=" .. destination .. ".mka," - load_files(title, destination, audio, false) - else - print("---expected mka but could not find it, waiting for 2 seconds---") - mp.add_timeout(2, function() - load_files(title, destination, audio, true) - end) - end - end - end - end -end - ---from ytdl_hook -mp.add_hook("on_preloaded", 10, function() - if string.find(mp.get_property("path"), cachePath) then - chapters() - if next(chapter_list) ~= nil then - mp.set_property_native("chapter-list", chapter_list) - chapter_list = {} - json = "" - end - end -end) ---end ytdl_hook -function dump(o) - if type(o) == "table" then - local s = "{ " - for k, v in pairs(o) do - if type(k) ~= "number" then - k = '"' .. k .. '"' - end - s = s .. "[" .. k .. "] = " .. dump(v) .. "," - end - return s .. "} " - else - return tostring(o) - end -end - -local function addOPTS(old) - for k, v in pairs(additionalOpts) do - -- print(k) - if string.find(v, "%s") then - for l, w in string.gmatch(v, "([-%w]+) (.+)") do - table.insert(old, l) - table.insert(old, w) - end - else - table.insert(old, v) - end - end - -- print(dump(old)) - return old -end - -local AudioDownloadHandle = {} -local VideoDownloadHandle = {} -local JsonDownloadHandle = {} -local function download_files(id, success, result, error) - if result.killed_by_us then - return - end - local jfile = cachePath .. "/" .. id .. ".json" - - local jfileIO = io.open(jfile, "w") - jfileIO:write(result.stdout) - jfileIO:close() - json = utils.parse_json(result.stdout) - -- print(dump(json)) - if json.requested_downloads[1].requested_formats ~= nil then - local args = { - ytdl, - "--no-continue", - "-q", - "-f", - fAudio, - "--restrict-filenames", - "--no-playlist", - "--no-part", - "-o", - cachePath .. "/" .. id .. "-%(title)s-%(id)s.mka", - "--load-info-json", - jfile, - } - args = addOPTS(args) - AudioDownloadHandle = mp.command_native_async({ - name = "subprocess", - args = args, - playback_only = false, - }, function() end) - else - fAudio = "" - fVideo = fVideo:gsub("bestvideo", "best") - fVideo = fVideo:gsub("bv", "best") - end - - local args = { - ytdl, - "--no-continue", - "-f", - fVideo .. "/best", - "--restrict-filenames", - "--no-playlist", - "--no-part", - "-o", - cachePath .. "/" .. id .. "-%(title)s-%(id)s.mkv", - "--load-info-json", - jfile, - } - args = addOPTS(args) - VideoDownloadHandle = mp.command_native_async({ - name = "subprocess", - args = args, - playback_only = false, - }, function() end) -end - -local function DL() - local index = tonumber(mp.get_property("playlist-pos")) - if - mp.get_property("playlist/" .. index .. "/filename"):find("/videos$") - and mp.get_property("playlist/" .. index + 1 .. "/filename"):find("/shorts$") - then - return - end - if - tonumber(mp.get_property("playlist-pos-1")) > 0 - and mp.get_property("playlist-pos-1") ~= mp.get_property("playlist-count") - then - nextIndex = index + 1 - local nextFile = mp.get_property("playlist/" .. nextIndex .. "/filename") - if nextFile and caught and nextFile:find("://", 0, false) then - caught = false - mp.enable_messages("info") - mp.register_event("log-message", listener) - local ytFormat = mp.get_property("ytdl-format") - fVideo = string.match(ytFormat, "(.+)%+.+//?") or "bestvideo" - fAudio = string.match(ytFormat, ".+%+(.+)//?") or "bestaudio" - -- print("start"..nextFile) - listenID = tostring(os.time()) - local args = { - ytdl, - "--dump-single-json", - "--no-simulate", - "--skip-download", - "--restrict-filenames", - "--no-playlist", - "--sub-lang", - "en", - "--write-sub", - "--no-part", - "-o", - cachePath .. "/" .. listenID .. "-%(title)s-%(id)s.%(ext)s", - nextFile, - } - args = addOPTS(args) - -- print(dump(args)) - table.insert(filesToDelete, listenID) - JsonDownloadHandle = mp.command_native_async({ - name = "subprocess", - args = args, - capture_stdout = true, - capture_stderr = true, - playback_only = false, - }, function(...) - download_files(listenID, ...) - end) - end - end -end - -local function clearCache() - -- print(pop) - - --if pop == true then - mp.abort_async_command(AudioDownloadHandle) - mp.abort_async_command(VideoDownloadHandle) - mp.abort_async_command(JsonDownloadHandle) - -- for k, v in pairs(filesToDelete) do - -- print("remove: " .. v) - -- os.remove(v) - -- end - local ftd = io.open(cachePath .. "/temp.files", "a") - for k, v in pairs(filesToDelete) do - ftd:write(v .. "\n") - if package.config:sub(1, 1) ~= "/" then - os.execute('del /Q /F "' .. cachePath .. "\\" .. v .. '*"') - else - os.execute("rm -f " .. cachePath .. "/" .. v .. "*") - end - end - ftd:close() - print("clear") - mp.command("quit") - --end -end -mp.add_hook("on_unload", 50, function() - -- mp.abort_async_command(AudioDownloadHandle) - -- mp.abort_async_command(VideoDownloadHandle) - mp.abort_async_command(JsonDownloadHandle) - mp.unregister_event(listener) - caught = true - listenID = "resetYtdlPreloadListener" - -- print(listenID) -end) - -local skipInitial -mp.observe_property("playlist-count", "number", function() - if skipInitial then - DL() - else - skipInitial = true - end -end) - ---from ytdl_hook -local platform_is_windows = (package.config:sub(1, 1) == "\\") -local o = { - exclude = "", - try_ytdl_first = false, - use_manifests = false, - all_formats = false, - force_all_formats = true, - ytdl_path = "", -} -local paths_to_search = { "yt-dlp", "yt-dlp_x86", "youtube-dl" } ---local options = require 'mp.options' -options.read_options(o, "ytdl_hook") - -local separator = platform_is_windows and ";" or ":" -if o.ytdl_path:match("[^" .. separator .. "]") then - paths_to_search = {} - for path in o.ytdl_path:gmatch("[^" .. separator .. "]+") do - table.insert(paths_to_search, path) - end -end - -local function exec(args) - local ret = mp.command_native({ - name = "subprocess", - args = args, - capture_stdout = true, - capture_stderr = true, - }) - return ret.status, ret.stdout, ret, ret.killed_by_us -end - -local msg = require("mp.msg") -local command = {} -for _, path in pairs(paths_to_search) do - -- search for youtube-dl in mpv's config dir - local exesuf = platform_is_windows and ".exe" or "" - local ytdl_cmd = mp.find_config_file(path .. exesuf) - if ytdl_cmd then - msg.verbose("Found youtube-dl at: " .. ytdl_cmd) - ytdl = ytdl_cmd - break - else - msg.verbose("No youtube-dl found with path " .. path .. exesuf .. " in config directories") - --search in PATH - command[1] = path - es, json, result, aborted = exec(command) - if result.error_string == "init" then - msg.verbose("youtube-dl with path " .. path .. exesuf .. " not found in PATH or not enough permissions") - else - msg.verbose("Found youtube-dl with path " .. path .. exesuf .. " in PATH") - ytdl = path - break - end - end -end ---end ytdl_hook - -mp.register_event("start-file", DL) -mp.register_event("shutdown", clearCache) -local ftd = io.open(cachePath .. "/temp.files", "r") -while ftd ~= nil do - local line = ftd:read() - if line == nil or line == "" then - ftd:close() - io.open(cachePath .. "/temp.files", "w"):close() - break - end - -- print("DEL::"..line) - if package.config:sub(1, 1) ~= "/" then - os.execute('del /Q /F "' .. cachePath .. "\\" .. line .. '*" >nul 2>nul') - else - os.execute("rm -f " .. cachePath .. "/" .. line .. "* &> /dev/null") - end -end