Skip to content

Commit c00fbfa

Browse files
committed
refactor: normalized interfacing with ziggy
1 parent 3ee3d47 commit c00fbfa

File tree

2 files changed

+99
-70
lines changed

2 files changed

+99
-70
lines changed

src/uosc/lib/menus.lua

+32-58
Original file line numberDiff line numberDiff line change
@@ -895,49 +895,40 @@ function open_subtitle_downloader()
895895
end
896896
end
897897

898-
local handle_select, handle_search
899-
900-
-- Ensures response is valid, and returns its payload, or handles error reporting,
901-
-- and returns `nil`, indicating the consumer should abort response handling.
902-
local function ensure_response_data(success, result, error, check)
903-
local data
904-
if success and result and result.status == 0 then
905-
data = utils.parse_json(result.stdout)
906-
if not data or not check(data) then
907-
data = (data and data.error == true) and data or {
908-
error = true,
909-
message = t('invalid response json (see console for details)'),
910-
message_verbose = 'invalid response json: ' .. utils.to_string(result.stdout),
911-
}
912-
end
913-
else
914-
data = {
915-
error = true,
916-
message = error or t('process exited with code %s (see console for details)', result.status),
917-
message_verbose = result.stdout .. result.stderr,
918-
}
919-
end
920-
921-
if data.error then
922-
local message, message_verbose = data.message or t('unknown error'), data.message_verbose or data.message
923-
if message_verbose then msg.error(message_verbose) end
898+
local handle_download, handle_search
899+
900+
-- Checks if there an error, or data is invalid. If true, reports the error,
901+
-- updates menu to inform about it, and returns true.
902+
---@param error string|nil
903+
---@param data any
904+
---@param check_is_valid? fun(data: any):boolean
905+
---@return boolean abort Whether the further response handling should be aborted.
906+
local function should_abort(error, data, check_is_valid)
907+
if error or not data or (not check_is_valid or not check_is_valid(data)) then
924908
menu:update_items({
925909
{
926-
title = message,
927-
hint = t('error'),
910+
title = t('Something went wrong.'),
911+
align = 'center',
912+
muted = true,
913+
italic = true,
914+
selectable = false,
915+
},
916+
{
917+
title = t('See console for details.'),
918+
align = 'center',
928919
muted = true,
929920
italic = true,
930921
selectable = false,
931922
},
932923
})
933-
return
924+
msg.error(error or ('Invalid response: ' .. (utils.format_json(data) or tostring(data))))
925+
return true
934926
end
935-
936-
return data
927+
return false
937928
end
938929

939930
---@param data {kind: 'file', id: number}|{kind: 'page', query: string, page: number}
940-
handle_select = function(data)
931+
handle_download = function(data)
941932
if data.kind == 'page' then
942933
handle_search(data.query, data.page)
943934
return
@@ -953,25 +944,14 @@ function open_subtitle_downloader()
953944
end
954945
end)
955946

956-
local args = itable_join({config.ziggy_path, 'download-subtitles'}, credentials, {
947+
local args = itable_join({'download-subtitles'}, credentials, {
957948
'--file-id', tostring(data.id),
958949
'--destination', destination_directory,
959950
})
960951

961-
mp.command_native_async({
962-
name = 'subprocess',
963-
capture_stderr = true,
964-
capture_stdout = true,
965-
playback_only = false,
966-
args = args,
967-
}, function(success, result, error)
952+
call_ziggy_async(args, function(error, data)
968953
if not menu:is_alive() then return end
969-
970-
local data = ensure_response_data(success, result, error, function(data)
971-
return type(data.file) == 'string'
972-
end)
973-
974-
if not data then return end
954+
if should_abort(error, data, function(data) return type(data.file) == 'string' end) then return end
975955

976956
load_track('sub', data.file)
977957

@@ -1008,7 +988,7 @@ function open_subtitle_downloader()
1008988

1009989
menu:update_items({{icon = 'spinner', align = 'center', selectable = false, muted = true}})
1010990

1011-
local args = itable_join({config.ziggy_path, 'search-subtitles'}, credentials)
991+
local args = itable_join({'search-subtitles'}, credentials)
1012992

1013993
local languages = itable_filter(get_languages(), function(lang) return lang:match('.json$') == nil end)
1014994
args[#args + 1] = '--languages'
@@ -1027,20 +1007,14 @@ function open_subtitle_downloader()
10271007
args[#args + 1] = query
10281008
end
10291009

1030-
mp.command_native_async({
1031-
name = 'subprocess',
1032-
capture_stderr = true,
1033-
capture_stdout = true,
1034-
playback_only = false,
1035-
args = args,
1036-
}, function(success, result, error)
1010+
call_ziggy_async(args, function(error, data)
10371011
if not menu:is_alive() then return end
10381012

1039-
local data = ensure_response_data(success, result, error, function(data)
1013+
local function check_is_valid(data)
10401014
return type(data.data) == 'table' and data.page and data.total_pages
1041-
end)
1015+
end
10421016

1043-
if not data then return end
1017+
if should_abort(error, data, check_is_valid) then return end
10441018

10451019
local subs = itable_filter(data.data, function(sub)
10461020
return sub and sub.attributes and sub.attributes.release and type(sub.attributes.files) == 'table' and
@@ -1131,7 +1105,7 @@ function open_subtitle_downloader()
11311105
end
11321106
end)
11331107
elseif not event.action then
1134-
handle_select(event.value)
1108+
handle_download(event.value)
11351109
end
11361110
elseif event.type == 'search' then
11371111
handle_search(event.query)

src/uosc/lib/utils.lua

+67-12
Original file line numberDiff line numberDiff line change
@@ -814,30 +814,85 @@ function load_track(type, path)
814814
end
815815
end
816816

817-
---@return string|nil
818-
function get_clipboard()
817+
---@param args (string|number)[]
818+
---@return string|nil error
819+
---@return table data
820+
function call_ziggy(args)
819821
local result = mp.command_native({
820822
name = 'subprocess',
821823
capture_stderr = true,
822824
capture_stdout = true,
823825
playback_only = false,
824-
args = {config.ziggy_path, 'get-clipboard'},
826+
args = itable_join({config.ziggy_path}, args),
825827
})
826828

827-
local function print_error(message)
828-
msg.error('Getting clipboard data failed. Error: ' .. message)
829+
if result.status ~= 0 then
830+
return 'Calling ziggy failed. Exit code ' .. result.status .. ': ' .. result.stdout .. result.stderr, {}
831+
end
832+
833+
local data = utils.parse_json(result.stdout)
834+
if not data then
835+
return 'Ziggy response error. Couldn\'t parse json: ' .. result.stdout, {}
836+
elseif data.error then
837+
return 'Ziggy error: ' .. data.message, {}
838+
else
839+
return nil, data
829840
end
841+
end
830842

831-
if result.status == 0 then
832-
local data = utils.parse_json(result.stdout)
833-
if data and data.payload then
834-
return data.payload
843+
---@param args (string|number)[]
844+
---@param callback fun(error: string|nil, data: table)
845+
---@return fun() abort Function to abort the request.
846+
function call_ziggy_async(args, callback)
847+
local abort_signal = mp.command_native_async({
848+
name = 'subprocess',
849+
capture_stderr = true,
850+
capture_stdout = true,
851+
playback_only = false,
852+
args = itable_join({config.ziggy_path}, args),
853+
}, function(success, result, error)
854+
if not success or not result or result.status ~= 0 then
855+
local exit_code = (result and result.status or 'unknown')
856+
local message = error or (result and result.stdout .. result.stderr) or ''
857+
callback('Calling ziggy failed. Exit code: ' .. exit_code .. ' Error: ' .. message, {})
858+
return
859+
end
860+
861+
local json = result and type(result.stdout) == 'string' and result.stdout or ''
862+
local data = utils.parse_json(json)
863+
if not data then
864+
callback('Ziggy response error. Couldn\'t parse json: ' .. json, {})
865+
elseif data.error then
866+
callback('Ziggy error: ' .. data.message, {})
835867
else
836-
print_error(data and (data.error and data.message or 'unknown error') or 'couldn\'t parse json')
868+
return callback(nil, data)
837869
end
838-
else
839-
print_error('exit code ' .. result.status .. ': ' .. result.stdout .. result.stderr)
870+
end)
871+
872+
return function()
873+
mp.abort_async_command(abort_signal)
874+
end
875+
end
876+
877+
---@return string|nil
878+
function get_clipboard()
879+
local err, data = call_ziggy({'get-clipboard'})
880+
if err then
881+
mp.commandv('show-text', 'Get clipboard error. See console for details.')
882+
msg.error(err)
883+
end
884+
return data and data.payload
885+
end
886+
887+
---@param payload any
888+
---@return string|nil payload String that was copied to clipboard.
889+
function set_clipboard(payload)
890+
local err, data = call_ziggy({'set-clipboard', tostring(payload)})
891+
if err then
892+
mp.commandv('show-text', 'Set clipboard error. See console for details.')
893+
msg.error(err)
840894
end
895+
return data and data.payload
841896
end
842897

843898
--[[ RENDERING ]]

0 commit comments

Comments
 (0)