Thread: Aura H2O AutoShelf beta
View Single Post
Old 05-19-2024, 04:05 PM   #229
had
Member
had began at the beginning.
 
Posts: 14
Karma: 10
Join Date: Aug 2015
Device: kobo aura hd, aura h20, elipsa 2e
Sorry for the late reply. I finally got motivated this weekend to fix it. The problem seems to have been the following line:

PRAGMA journal_mode = MEMORY;

which was causing the 'locked database' error. You'll see in my script, I have just commented out that line of SQL.

Here is my nickelmenu entry:

Code:
menu_item :main :Autoshelf :cmd_output :9999:quiet :/usr/local/AutoShelf/autoshelf-now.sh
And my script, autoshelf-now.sh
Code:
#!/bin/sh

export LD_LIBRARY_PATH="/usr/local/AutoShelf:$LD_LIBRARY_PATH"
PATH="/usr/local/AutoShelf:$PATH"
BASE="/mnt/onboard/.adds/autoshelf"
CONFIGFILE="$BASE/autoshelf.cfg"

#
# configuration
#
config() {
    local value
    value=$(grep -m 1 "^$1=" "$CONFIGFILE")
    value="${value:$((1+${#1}))}"
    [ "$value" != "" ] && echo "$value" || echo "$2"
}

# database escapes
escape() {
    echo -n "${1//"'"/"''"}"
}

like() {
    escape "$1" | sed -e 's@[%_]@\\\0@g'
}


udev_workarounds() {
    # udev kills slow scripts
    if [ "$SETSID" != "1" ]
    then
        SETSID=1 setsid "$0" "$@" &
        exit
    fi
}

suspend_nickel() {
    mkdir /tmp/suspend-nickel && (
        pkill -SIGSTOP sickel # 3.16.10 watchdog
        pkill -SIGSTOP nickel
    )
    mkdir /tmp/suspend-nickel/"$1" || exit
}

resume_nickel() {
    rmdir /tmp/suspend-nickel/"$1"
    rmdir /tmp/suspend-nickel && (
        pkill -SIGCONT nickel
        pkill -SIGKILL sickel # 3.16.10 watchdog
    )
}

autoshelf() {
    # variables from configuration file, if present
    cfg_path=$(config path '/mnt/onboard:/mnt/sd')
    cfg_skip=$(config skip '/mnt/onboard/.kobo')
    cfg_consume=$(config consume '1')
    cfg_series=$(config series '1')
    cfg_series_regexp=$(config series_regexp '#([^/]+)/([0-9.]+)#:\1:\2:#')
    cfg_exclusive=$(config exclusive '0')
    cfg_unique_book=$(config unique_book '1')
    cfg_uninstall=$(config uninstall '0')

    today="strftime('%Y-%m-%dT%H:%M:%f')"

    echo "
   --
   -- path = '$cfg_path'
   -- skip = '$cfg_skip'
   -- consume = '$cfg_consume'
   -- series = '$cfg_series'
   -- series_regexp = '$cfg_series_regexp'
   -- exclusive = '$cfg_exclusive'
   -- unique_book = '$cfg_unique_book'
   -- uninstall = '$cfg_uninstall'
   -- logfile = '$cfg_logfile'
   --
"

    echo "
PRAGMA synchronous = OFF;
-- PRAGMA journal_mode = MEMORY;
BEGIN TRANSACTION;

CREATE TABLE AutoShelf AS SELECT * FROM Shelf WHERE 0;
CREATE TABLE AutoShelfContent AS SELECT * FROM ShelfContent WHERE 0;
CREATE UNIQUE INDEX autoshelf_id ON AutoShelf(Id);
CREATE UNIQUE INDEX autoshelfcontent_key ON AutoShelfContent(ShelfName, ContentId);
CREATE UNIQUE INDEX autoshelf_name ON AutoShelf(InternalName);
"

    if [ "$cfg_unique_book" == "1" ]
    then
        echo "
CREATE UNIQUE INDEX autoshelfcontent_id ON AutoShelfContent(ContentId);
"
    fi

    echo "
REPLACE INTO AutoShelf SELECT * FROM Shelf WHERE _IsDeleted!='true';
REPLACE INTO AutoShelfContent SELECT * FROM ShelfContent WHERE _IsDeleted!='true';

DELETE FROM ShelfContent WHERE _IsSynced!='true';
UPDATE Shelf SET LastModified=$today, _IsDeleted='true';
UPDATE ShelfContent SET DateModified=$today, _IsDeleted='true';
"

    if [ "$cfg_exclusive" == "1" ]
    then
        echo "
UPDATE AutoShelf SET LastModified=$today, _IsDeleted='true';
UPDATE AutoShelfContent SET DateModified=$today, _IsDeleted='true';
"
    else
        echo "
UPDATE AutoShelf SET LastModified=$today, _IsDeleted='true' WHERE InternalName LIKE '%/';
UPDATE AutoShelfContent SET DateModified=$today, _IsDeleted='true' WHERE ShelfName LIKE '%/';
"
    fi

    if [ "$cfg_uninstall" == "1" ]
    then
        echo "DELETE FROM Activity WHERE Type='Shelf' AND Id LIKE '%/';"
        cfg_path=""
    fi

    consume=""

    while [ ${#cfg_skip} -gt 0 ]
    do
        # cut off first path element
        skip=${cfg_skip%%:*}
        echo "-- skip '$skip'"
        cfg_skip=${cfg_skip:$((${#skip}+1))}
        consume="$consume AND ContentId NOT LIKE 'file://$(like "$skip")/%' ESCAPE '\\'"
    done

    while [ ${#cfg_path} -gt 0 ]
    do
        # cut off first path element
        this=${cfg_path%%:*}
        cfg_path=${cfg_path:$((${#this}+1))}
        path=${this%%=*}
        pathlike=$(like "$path")
        prefix=${this:$((${#path}+1))}

        echo "-- path '$path' prefix '$prefix'"

        sqlite3 /mnt/onboard/.kobo/KoboReader.sqlite "
SELECT ContentId FROM content
WHERE ContentType=6 AND ContentId LIKE 'file://$pathlike/%' ESCAPE '\\' $consume
ORDER BY ContentId;
        " | tee -a "$cfg_logfile" | while read file
        do
            escapefile=$(escape "$file")
            base=${file:$((8+${#path}))}
            shelf=$(dirname /"$base")
            shelf=${shelf:1}
            shelf="$prefix$shelf"

            if [ "$shelf" != "$prevshelf" ]
            then
                prevshelf="$shelf"
                escapeshelf=$(escape "$shelf")
                echo "
UPDATE OR IGNORE AutoShelf
SET LastModified=$today, _IsDeleted='false', _IsVisible='true'
WHERE InternalName='$escapeshelf/';
INSERT OR IGNORE INTO AutoShelf ('CreationDate','Id','InternalName','LastModified','Name','Type','_IsDeleted','_IsVisible','_IsSynced')
VALUES ($today, '$escapeshelf/','$escapeshelf/',$today,'$escapeshelf/',NULL,'false','true','false');
"
            fi

            echo "
REPLACE INTO AutoShelfContent ('ShelfName','ContentId','DateModified','_IsDeleted','_IsSynced')
VALUES ('$escapeshelf/', '$escapefile', $today, 'false', 'false');
"

            if [ "$cfg_series" == "1" ]
            then
                result=$(echo -n "$base" | sed -r -e s"$cfg_series_regexp")
                echo "-- series_regexp '$base' -> '$result'"

                set --

                if [ "$result" != "$base" ]
                then
                    IFS=:
                    set -- $result
                    unset IFS
                fi

                if [ $# -ge 3 ]
                then
                    series=$2
                    number=$3

                    echo "
UPDATE content
SET Series='$(escape "$series")', SeriesNumber='$(escape "$number")'
WHERE ContentId='$escapefile';
"
                fi
            fi
        done

        if [ "$cfg_consume" == "1" ]
        then
            consume="$consume AND ContentId NOT LIKE 'file://$pathlike/%' ESCAPE '\\'"
        fi
    done

    echo "
REPLACE INTO Shelf SELECT * FROM AutoShelf;
REPLACE INTO ShelfContent SELECT * FROM AutoShelfContent;
DROP TABLE AutoShelf;
DROP TABLE AutoShelfContent;

COMMIT TRANSACTION;
"
}

udev_workarounds

touch /mnt/onboard.adds/cloud/write_test || mount -o remount,rw /mnt/onboard

qndb -m mwcToast 100 "Updating collections..."

suspend_nickel autoshelf



for i in $(seq 1 60)
do
    if [ -e /mnt/onboard/.kobo/KoboReader.sqlite ]
    then
        break
    fi

    sleep 1
done

if [ -e /mnt/onboard/.kobo/KoboReader.sqlite ]
then
    cfg_logfile="$BASE"/$(config logfile '')
    echo "-------- AutoShelf $(date) --------" | tee -a "$cfg_logfile"
    autoshelf > /tmp/autoshelf.sql
    echo "---- SQL Execution: ----" | tee -a "$cfg_logfile"
    (
        sqlite3 -bail -batch -echo /mnt/onboard/.kobo/KoboReader.sqlite < /tmp/autoshelf.sql \
        || (echo "---- Dump after error: ----"; cat /tmp/autoshelf.sql)
    ) 2>&1 | tee -a "$cfg_logfile"
    mv /tmp/autoshelf.sql /tmp/autoshelf.bak

    if [ "$(config uninstall 0)" == "1" ]
    then
        echo "==== Uninstalling ====" | tee -a "$cfg_logfile"
        touch /mnt/onboard/.addons/autoshelf/uninstalled-$(date +%Y%M%d-%H%M)
        rm /etc/udev/rules.d/autoshelf.rules
        rm -rf /usr/local/AutoShelf
    fi
fi

resume_nickel autoshelf

qndb -m mwcToast 2000 "Refreshing collections..."

qndb -m pfmRescanBooksFull
 
#probably should wait for the finish signal, then touch /mnt/onboard.adds/cloud/write_test || mount -o remount,rw /mnt/onboard

Quote:
Originally Posted by mangonerd View Post
Still struggling to make it work in my Kobo Sage. Could you please share your full script and nickelmenu entry? Thanks!
had is offline   Reply With Quote