From dc964f39410d911a0fdde9cd9af87cfbb213add6 Mon Sep 17 00:00:00 2001 From: yparitcher Date: Thu, 7 Jan 2021 14:38:10 -0500 Subject: [PATCH] reader.lua: rework file/directory argument handling. (#7053) platform: do not pass a directory on the command line. The home directory will be properly set by Device.home_dir. It was sometimes crashing when opened with no args. Fixes: #7049 --- frontend/device/sdl/device.lua | 3 +- frontend/device/sony-prstux/device.lua | 1 + kodev | 6 +- platform/android/llapp_main.lua | 4 +- platform/appimage/AppRun | 13 +- platform/cervantes/koreader.sh | 11 +- platform/debian/koreader.sh | 10 +- platform/kindle/extensions/koreader/menu.json | 67 ++------- platform/kobo/koreader.sh | 9 +- platform/mac/do_mac_bundle.sh | 1 - platform/pocketbook/koreader.app | 9 +- platform/remarkable/koreader.sh | 8 +- platform/ubuntu-touch/koreader.sh | 2 +- reader.lua | 127 +++++++++--------- 14 files changed, 89 insertions(+), 182 deletions(-) diff --git a/frontend/device/sdl/device.lua b/frontend/device/sdl/device.lua index 41fc0cd1c..762e7263c 100644 --- a/frontend/device/sdl/device.lua +++ b/frontend/device/sdl/device.lua @@ -54,7 +54,7 @@ local external = require("device/thirdparty"):new{ local Device = Generic:new{ model = "SDL", isSDL = yes, - home_dir = os.getenv("HOME"), + home_dir = os.getenv("XDG_DOCUMENTS_DIR") or os.getenv("HOME"), hasBattery = SDL.getPowerInfo(), hasKeyboard = yes, hasKeys = yes, @@ -125,7 +125,6 @@ local Emulator = Device:new{ local UbuntuTouch = Device:new{ model = "UbuntuTouch", hasFrontlight = yes, - home_dir = nil, } function Device:init() diff --git a/frontend/device/sony-prstux/device.lua b/frontend/device/sony-prstux/device.lua index 3a8498ad7..bb78c62ce 100644 --- a/frontend/device/sony-prstux/device.lua +++ b/frontend/device/sony-prstux/device.lua @@ -15,6 +15,7 @@ local SonyPRSTUX = Generic:new{ canReboot = yes, canPowerOff = yes, usbPluggedIn = false, + home_dir = nil, } diff --git a/kodev b/kodev index c808133ef..9ab98a79d 100755 --- a/kodev +++ b/kodev @@ -853,11 +853,9 @@ TARGET: KOREADER_COMMAND="${valgrind} env LD_LIBRARY_PATH=${KO_LD_LIBRARY_PATH} ./luajit reader.lua ${KOREADER_ARGS}" fi - echo "[*] Running KOReader with arguments: $*..." + echo "[*] Running KOReader with arguments: $* ..." pushd "${EMU_DIR}" && { - if [ $# -lt 1 ]; then - args="${CURDIR}/test" - else + if [ $# -ge 1 ]; then args="$*" [[ "${args}" != /* ]] && args="${CURDIR}/${args}" fi diff --git a/platform/android/llapp_main.lua b/platform/android/llapp_main.lua index 984086af3..4d065dedf 100644 --- a/platform/android/llapp_main.lua +++ b/platform/android/llapp_main.lua @@ -75,9 +75,9 @@ C.setenv("TESSDATA_PREFIX", path.."/koreader/data", 1) -- create fake command-line arguments -- luacheck: ignore 121 if android.isDebuggable() then - arg = {"-d", file or path} + arg = {"-d", file} else - arg = {file or path} + arg = {file} end dofile(android.dir.."/reader.lua") diff --git a/platform/appimage/AppRun b/platform/appimage/AppRun index b5302cc19..9f28b39dc 100755 --- a/platform/appimage/AppRun +++ b/platform/appimage/AppRun @@ -12,19 +12,8 @@ export LD_LIBRARY_PATH=${KOREADER_DIR}/libs:${LD_LIBRARY_PATH} RETURN_VALUE=85 -if [ $# -eq 0 ]; then - # no arguments - if [ -n "${XDG_DOCUMENTS_DIR+x}" ]; then - start_path=${XDG_DOCUMENTS_DIR} - else - start_path=$(pwd) - fi -else - start_path="$*" -fi - while [ ${RETURN_VALUE} -eq 85 ]; do - ./reader.lua "${start_path}" + ./reader.lua "$@" RETURN_VALUE=$? done diff --git a/platform/cervantes/koreader.sh b/platform/cervantes/koreader.sh index 751df8f73..e4dc89e85 100755 --- a/platform/cervantes/koreader.sh +++ b/platform/cervantes/koreader.sh @@ -39,19 +39,12 @@ ko_update_check() { fi } -# if no args were passed to the script, start the FM on public partition. -if [ "$#" -eq 0 ]; then - args="/mnt/public" -else - args="$*" -fi - # NOTE: Keep doing an initial update check, in addition to one during the restart loop, so we can pickup potential updates of this very script... ko_update_check # If an update happened, and was successful, reexec if [ -n "${fail}" ] && [ "${fail}" -eq 0 ]; then # By now, we know we're in the right directory, and our script name is pretty much set in stone, so we can forgo using $0 - exec ./koreader.sh "${args}" + exec ./koreader.sh "$@" fi # load our own shared libraries if possible @@ -101,7 +94,7 @@ while [ "${RETURN_VALUE}" -ge "${RESTART_KOREADER}" ]; do ko_update_check # run KOReader - ./reader.lua "${args}" >>crash.log 2>&1 + ./reader.lua "$@" >>crash.log 2>&1 RETURN_VALUE=$? # check if KOReader requested to enter in mass storage mode. diff --git a/platform/debian/koreader.sh b/platform/debian/koreader.sh index 3227b9da6..3f68a5fb1 100755 --- a/platform/debian/koreader.sh +++ b/platform/debian/koreader.sh @@ -4,14 +4,10 @@ export LC_ALL="en_US.UTF-8" # writable storage: ${HOME}/.config/koreader. export KO_MULTIUSER=1 -if [ -z "${1}" ]; then - ARGS="${HOME}" +if [ $# -eq 1 ] && [ -e "$(pwd)/${1}" ]; then + ARGS="$(pwd)/${1}" else - if [ $# -eq 1 ] && [ -e "$(pwd)/${1}" ]; then - ARGS="$(pwd)/${1}" - else - ARGS="${*}" - fi + ARGS="${*}" fi # working directory of koreader diff --git a/platform/kindle/extensions/koreader/menu.json b/platform/kindle/extensions/koreader/menu.json index b1cd0a83b..488c2aefc 100644 --- a/platform/kindle/extensions/koreader/menu.json +++ b/platform/kindle/extensions/koreader/menu.json @@ -5,54 +5,26 @@ "priority": 0, "items": [ { - "name": "Start the filemanager", - "if": "\"KindleVoyage\" -m!", - "priority": 1, - "action": "/mnt/us/koreader/koreader.sh", - "params": "--kual /mnt/us/documents", - "status": false, - "internal": "status Start KOReader on the File Manager" - }, - { - "name": "Start the filemanager", - "if": "\"KindleVoyage\" -m", - "priority": 1, - "action": "/mnt/us/koreader/koreader.sh", - "params": "--kual /mnt/us/documents", - "exitmenu": false, - "status": false, - "internal": "status Start KOReader on the File Manager" - }, - { - "name": "Open the last document", + "name": "Start KOReader", "if": "\"KindleVoyage\" -m!", "priority": 2, "action": "/mnt/us/koreader/koreader.sh", "params": "--kual", "status": false, - "internal": "status Start KOReader on the last document" + "internal": "status Start KOReader" }, { - "name": "Open the last document", + "name": "Start KOReader", "if": "\"KindleVoyage\" -m", "priority": 2, "action": "/mnt/us/koreader/koreader.sh", "params": "--kual", "exitmenu": false, "status": false, - "internal": "status Start KOReader on the last document" + "internal": "status Start KOReader" }, { - "name": "Start the filemanager (no framework)", - "if": "\"Kindle2\" -m \"KindleDX\" -m \"KindleDXG\" -m \"Kindle3\" -m \"Kindle4\" -m || || || ||", - "priority": 3, - "action": "/mnt/us/koreader/koreader.sh", - "params": "--kual --framework_stop /mnt/us/documents", - "status": false, - "internal": "status Kill the framework and start KOReader's FM" - }, - { - "name": "Open the last document (no framework)", + "name": "Start KOReader (no framework)", "if": "\"Kindle2\" -m \"KindleDX\" -m \"KindleDXG\" -m \"Kindle3\" -m \"Kindle4\" -m || || || ||", "priority": 4, "action": "/mnt/us/koreader/koreader.sh", @@ -61,42 +33,23 @@ "internal": "status Kill the framework and start KOReader" }, { - "name": "Start the filemanager (ASAP)", - "if": "\"KindleVoyage\" -m!", - "priority": 5, - "action": "/mnt/us/koreader/koreader.sh", - "params": "--kual --asap /mnt/us/documents", - "status": false, - "internal": "status Start KOreader on the File Manager ASAP" - }, - { - "name": "Start the filemanager (ASAP)", - "if": "\"KindleVoyage\" -m", - "priority": 5, - "action": "/mnt/us/koreader/koreader.sh", - "params": "--kual --asap /mnt/us/documents", - "exitmenu": false, - "status": false, - "internal": "status Start KOreader on the File Manager ASAP" - }, - { - "name": "Open the last document (ASAP)", + "name": "Start KOReader (ASAP)", "if": "\"KindleVoyage\" -m!", "priority": 6, "action": "/mnt/us/koreader/koreader.sh", "params": "--kual --asap", "status": false, - "internal": "status Start KOreader on the last document ASAP" + "internal": "status Start KOReader ASAP" }, { - "name": "Open the last document (ASAP)", + "name": "Start KOReader (ASAP)", "if": "\"KindleVoyage\" -m", "priority": 6, "action": "/mnt/us/koreader/koreader.sh", "params": "--kual --asap", "exitmenu": false, "status": false, - "internal": "status Start KOreader on the last document ASAP" + "internal": "status Start KOReader ASAP" }, { "name": "Tools", @@ -122,7 +75,7 @@ "checked": true, "refresh": false, "status": false, - "internal": "status Try to install KOreader from scratch . . ." + "internal": "status Try to install KOReader from scratch . . ." } ] } diff --git a/platform/kobo/koreader.sh b/platform/kobo/koreader.sh index 8a71611e1..2d3dd4bfd 100755 --- a/platform/kobo/koreader.sh +++ b/platform/kobo/koreader.sh @@ -198,13 +198,6 @@ if [ "${VIA_NICKEL}" = "true" ]; then fi fi -# fallback for old fmon, KFMon and advboot users (-> if no args were passed to the script, start the FM) -if [ "$#" -eq 0 ]; then - args="/mnt/onboard" -else - args="$*" -fi - # check whether PLATFORM & PRODUCT have a value assigned by rcS if [ -z "${PRODUCT}" ]; then # shellcheck disable=SC2046 @@ -333,7 +326,7 @@ while [ ${RETURN_VALUE} -ne 0 ]; do ko_do_dns fi - ./reader.lua "${args}" >>crash.log 2>&1 + ./reader.lua "$@" >>crash.log 2>&1 RETURN_VALUE=$? # Did we crash? diff --git a/platform/mac/do_mac_bundle.sh b/platform/mac/do_mac_bundle.sh index a4a61f9ad..6c04d89fe 100755 --- a/platform/mac/do_mac_bundle.sh +++ b/platform/mac/do_mac_bundle.sh @@ -175,7 +175,6 @@ rm -rf cache clipboard history ota \ sed '1d' reader.lua >tempfile sed -i.backup 's/.\/reader.lua/koreader/' tempfile -sed -i.backup 's/the last viewed document will be opened"/" .. os.getenv("HOME") .. " will be opened"/' tempfile mv tempfile reader.lua rm -f tempfile* chmod -x reader.lua diff --git a/platform/pocketbook/koreader.app b/platform/pocketbook/koreader.app index c7dae839d..4e3e49e9b 100755 --- a/platform/pocketbook/koreader.app +++ b/platform/pocketbook/koreader.app @@ -65,13 +65,6 @@ export TESSDATA_PREFIX="data" # export dict directory export STARDICT_DATA_DIR="data/dict" -# shellcheck disable=2000 -if [ "$(echo "$@" | wc -c)" -eq 1 ]; then - args="/mnt/ext1/" -else - args="$*" -fi - # we keep at maximum 500K worth of crash log if [ -e crash.log ]; then tail -c 500000 crash.log >crash.log.new @@ -94,7 +87,7 @@ while [ "${RETURN_VALUE}" -ne 0 ]; do ko_update_check fi - ./reader.lua "${args}" >>crash.log 2>&1 + ./reader.lua "$@" >>crash.log 2>&1 # Account for the fact a hard crash may have prevented the KO_EXIT_CODE file from being written to... if [ -f "${KO_EXIT_CODE}" ]; then diff --git a/platform/remarkable/koreader.sh b/platform/remarkable/koreader.sh index db58cd3fd..58ce89494 100755 --- a/platform/remarkable/koreader.sh +++ b/platform/remarkable/koreader.sh @@ -132,12 +132,6 @@ if [ -e crash.log ]; then mv -f crash.log.new crash.log fi -if [ "$#" -eq 0 ]; then - args="/home/root" -else - args="$*" -fi - CRASH_COUNT=0 CRASH_TS=0 CRASH_PREV_TS=0 @@ -152,7 +146,7 @@ while [ ${RETURN_VALUE} -ne 0 ]; do ko_do_fbdepth fi - ./reader.lua "${args}" >>crash.log 2>&1 + ./reader.lua "$@" >>crash.log 2>&1 RETURN_VALUE=$? # Did we crash? diff --git a/platform/ubuntu-touch/koreader.sh b/platform/ubuntu-touch/koreader.sh index 95920cda9..7669cc263 100755 --- a/platform/ubuntu-touch/koreader.sh +++ b/platform/ubuntu-touch/koreader.sh @@ -22,7 +22,7 @@ export SDL_FULLSCREEN=1 RETURN_VALUE=85 while [ ${RETURN_VALUE} -eq 85 ]; do - ./reader.lua -d ~/Documents + ./reader.lua -d RETURN_VALUE=$? done diff --git a/reader.lua b/reader.lua index 3e02ddfff..e67dba139 100755 --- a/reader.lua +++ b/reader.lua @@ -80,12 +80,31 @@ local function showusage() print("If you give the name of a directory instead of a file path, a file") print("chooser will show up and let you select a file") print("") - print("If you don't pass any path, the last viewed document will be opened") + print("If you don't pass any path, the File Manager will be opened") print("") print("This software is licensed under the AGPLv3.") print("See http://github.com/koreader/koreader for more info.") end +local function getPathFromURI(str) + local hexToChar = function(x) + return string.char(tonumber(x, 16)) + end + + local unescape = function(url) + return url:gsub("%%(%x%x)", hexToChar) + end + + local prefix = "file://" + if str:sub(1, #prefix) ~= prefix then + return str + end + return unescape(str):sub(#prefix+1) +end + +local lfs = require("libs/libkoreader-lfs") +local file +local directory local Profiler = nil local ARGV = arg local argidx = 1 @@ -109,8 +128,14 @@ while argidx <= #ARGV do Profiler = require("jit.p") Profiler.start("la") else - -- not a recognized option, should be a filename - argidx = argidx - 1 + -- not a recognized option, should be a filename or directory + local sanitized_path = getPathFromURI(arg) + local mode = lfs.attributes(sanitized_path, "mode") + if mode == "file" then + file = sanitized_path + elseif mode == "directory" or mode == "link" then + directory = sanitized_path + end break end end @@ -206,87 +231,69 @@ if G_reader_settings:isTrue("color_rendering") and not Device:hasColorScreen() t }) end +-- Get which file to start with +local last_file = G_reader_settings:readSetting("lastfile") +local start_with = G_reader_settings:readSetting("start_with") or "filemanager" + -- Helpers -local lfs = require("libs/libkoreader-lfs") local function retryLastFile() local ConfirmBox = require("ui/widget/confirmbox") return ConfirmBox:new{ text = _("Cannot open last file.\nThis could be because it was deleted or because external storage is still being mounted.\nDo you want to retry?"), ok_callback = function() - local last_file = G_reader_settings:readSetting("lastfile") - if lfs.attributes(last_file, "mode") == "file" then - local ReaderUI = require("apps/reader/readerui") - UIManager:nextTick(function() - ReaderUI:showReader(last_file) - end) - else + if lfs.attributes(last_file, "mode") ~= "file" then UIManager:show(retryLastFile()) end end, + cancel_callback = function() + start_with = "filemanager" + end, } end -local function getPathFromURI(str) - local hexToChar = function(x) - return string.char(tonumber(x, 16)) - end - - local unescape = function(url) - return url:gsub("%%(%x%x)", hexToChar) - end - - local prefix = "file://" - if str:sub(1, #prefix) ~= prefix then - return str - end - return unescape(str):sub(#prefix+1) -end - --- Get which file to start with -local last_file = G_reader_settings:readSetting("lastfile") -local start_with = G_reader_settings:readSetting("start_with") -local open_last = start_with == "last" - -if open_last and last_file and lfs.attributes(last_file, "mode") ~= "file" then - UIManager:show(retryLastFile()) - last_file = nil +-- Start app +local exit_code +if file then + local ReaderUI = require("apps/reader/readerui") + UIManager:nextTick(function() + ReaderUI:showReader(file) + end) + exit_code = UIManager:run() +elseif directory then + local FileManager = require("apps/filemanager/filemanager") + UIManager:nextTick(function() + FileManager:setRotationMode(true) + FileManager:showFiles(directory) + end) + exit_code = UIManager:run() else local QuickStart = require("ui/quickstart") if not QuickStart:isShown() then - open_last = true + start_with = "last" last_file = QuickStart:getQuickStart() end -end --- Start app -local exit_code -if ARGV[argidx] and ARGV[argidx] ~= "" then - local file - local sanitized_path = getPathFromURI(ARGV[argidx]) - if lfs.attributes(sanitized_path, "mode") == "file" then - file = sanitized_path - elseif open_last and last_file then - file = last_file + if start_with == "last" and last_file and lfs.attributes(last_file, "mode") ~= "file" then + UIManager:show(retryLastFile()) + -- no exit code as something else will be run after this. + UIManager:run() end - -- if file is given in command line argument or open last document is set - -- true, the given file or the last file is opened in the reader - if file and file ~= "" then + if start_with == "last" and last_file then local ReaderUI = require("apps/reader/readerui") UIManager:nextTick(function() - ReaderUI:showReader(file) + ReaderUI:showReader(last_file) end) - -- we assume a directory is given in command line argument - -- the filemanger will show the files in that path + exit_code = UIManager:run() else local FileManager = require("apps/filemanager/filemanager") local home_dir = - G_reader_settings:readSetting("home_dir") or ARGV[argidx] + G_reader_settings:readSetting("home_dir") or Device.home_dir or lfs.currentdir() UIManager:nextTick(function() FileManager:setRotationMode(true) FileManager:showFiles(home_dir) end) - -- always open history on top of filemanager so closing history - -- doesn't result in exit + -- Always open history on top of filemanager so closing history + -- doesn't result in exit. if start_with == "history" then local FileManagerHistory = require("apps/filemanager/filemanagerhistory") UIManager:nextTick(function() @@ -307,16 +314,8 @@ if ARGV[argidx] and ARGV[argidx] ~= "" then }:onShowFolderShortcutsDialog() end) end + exit_code = UIManager:run() end - exit_code = UIManager:run() -elseif last_file then - local ReaderUI = require("apps/reader/readerui") - UIManager:nextTick(function() - ReaderUI:showReader(last_file) - end) - exit_code = UIManager:run() -else - return showusage() end -- Exit