View Single Post
Old 05-18-2025, 06:54 AM   #51
febalci
Member
febalci began at the beginning.
 
Posts: 11
Karma: 10
Join Date: Oct 2019
Device: none
Couldn't had the will to handle under KoboRoot.tgz, so somebody else might do it maybe...

This script creates an .md file of annotations and bookmarks and copy the file to your dropbox account when you select "Sync Annotations" from nickel menu.


1. From https://github.com/fsantini/KoboClou...ocal/kobocloud download "curl" and "ca-bundle.crt" and copy it under .adds/notes folder on Kobo

2. Go to https://www.dropbox.com/developers/apps
Click “Create app”
Choose:
Scoped access
Select App Folder
Give your app a name (Should be unique worldwide)
Under OAuth 2, click “Generate access token”
Copy and use that token as DROPBOX_ACCESS_TOKEN in the script.

3. notes.sh:
Code:
#!/bin/sh
'
🧭 Steps
    Go to https://www.dropbox.com/developers/apps
    Click “Create app”
    Choose:
        Scoped access
        Select App Folder
    Give your app a name (Should be unique worldwide)
    Under OAuth 2, click “Generate access token”
    Use that token in your curl upload

From https://github.com/fsantini/KoboCloud/tree/master/src/usr/local/kobocloud
download curl and ca-bundle.crt to notes folder
'
DROPBOX_ACCESS_TOKEN="YOUR_DROPBOX_ACCESS_TOKEN"

NOTES="/mnt/onboard/.adds/notes"
# Note: Depending on your language this folder may have a different name
EXPORT_FOLDER="/mnt/onboard/Exported Annotations"
EXPORT_FILE="notes-$(date "+%Y-%m-%d").md"
EXPORT="$EXPORT_FOLDER/$EXPORT_FILE"
KEEP=21

DB="/mnt/onboard/.kobo/KoboReader.sqlite"
SQLITE="${NOTES}/sqlite3"

LD_LIBRARY_PATH="${NOTES}/lib:${LD_LIBRARY_PATH}"
export LD_LIBRARY_PATH

mkdir -p "$(dirname "$EXPORT")"

echo -e "# Kobo Notes\n" > $EXPORT
echo -e "*$(date -R)*\n" >> $EXPORT
echo -e "## Highlights\n" >> $EXPORT

# UTF-8 char table (decimal):
#      9: Tab
#     10: Line feed
#     32: Space
#     58: :
#     62: >
#     42: *
#     92: \
#   8230: …
#   9999: ✏
# 128278: 🔖
# 128196: 📄

SQL="SELECT TRIM(
  '### ' ||
  CASE
    WHEN b.Type = 'dogear' THEN
      char(128278, 32)
    WHEN b.Type = 'note' THEN
      char(9999, 32)
    WHEN b.Type = 'highlight' THEN
      char(128196, 32)
  END
  || c.Title || ', ' || COALESCE(c.Attribution, 'N/A') || char(10, 10, 42)
  || datetime(b.dateCreated) || char(42, 92, 10) /* force Markdown newline */
  || COALESCE(c1.Title, '') || char(10, 10, 62, 32) ||
  CASE
    WHEN b.Type = 'dogear' THEN
      COALESCE(ContextString, 'No context available') || char(8230, 10) /* only kepubs have context */
    ELSE
      REPLACE(              /* start Markdown quote */
        REPLACE(
          TRIM(             /* trim newlines */
            TRIM(           /* trim tabs */
              TRIM(b.Text), /* trim spaces */
              char(9)
            ),
            char(10)
          ),
          char(9), ''
        ),
        char(10), char(10, 62, 32, 10, 62, 32)) /* continue Markdown quote for multiple paragraphs */
      || char(10, 10)
      || COALESCE(b.Annotation, '') || char(10)
  END, char(10)
  ) || char(10, 10)
  FROM Bookmark b
    INNER JOIN content c ON b.VolumeID = c.ContentID
    LEFT OUTER JOIN content c1 ON (c1.ContentId LIKE b.ContentId || '%' AND c1.ContentType != 9)
  ORDER BY c.Title ASC,
           c.VolumeIndex ASC,
           b.ChapterProgress ASC,
           b.DateCreated ASC;"

$SQLITE "$DB" "$SQL" >> $EXPORT

echo -e "## Bookmarks:\n" >> $EXPORT

SQL="SELECT TRIM(
  '### ' ||
  CASE
    WHEN b.Type = 'dogear' THEN
      char(128278, 32)
  END
  || c.Title || ', ' || COALESCE(c.Attribution, 'N/A') || ', ' || c.Publisher || ', ' || strftime('%Y', date(datetime(c.dateCreated))) || char(10, 10)
  || strftime('%d/%m/%Y', date(datetime(b.dateCreated))) || ' ' || time(time(datetime(b.dateCreated)), '+1 hours') || char(10, 58, 10) /* force Markdown newline */
  || COALESCE(c1.Title, 'No chapter title') ||', ' || c.___PercentRead || '%  read' || char(10, 10, 62, 32) ||
  CASE
    WHEN b.Type = 'dogear' THEN
      COALESCE(ContextString, 'No context available') || char(8230, 10) /* only kepubs have context */
    ELSE
      REPLACE(              /* start Markdown quote */
        REPLACE(
          TRIM(             /* trim newlines */
            TRIM(           /* trim tabs */
              TRIM(b.Text), /* trim spaces */
              char(9)
            ),
            char(10)
          ),
          char(9), ''
        ),
        char(10), char(10, 62, 32, 10, 62, 32)) /* continue Markdown quote for multiple paragraphs */
      || char(10, 10)
      || COALESCE(b.Annotation, '') || char(10)
  END, char(10)
  ) || char(10)
  FROM Bookmark b
    INNER JOIN Event e ON e.ContentId = b.volumeId
        INNER JOIN content c ON b.VolumeID = c.ContentID
    LEFT OUTER JOIN content c1 ON (c1.ContentId LIKE b.ContentId || '%' AND c1.ContentType != 9)
  WHERE EventType=8 AND b.Hidden='false' AND b.ContextString!=''
  GROUP BY b.dateCreated, c.BookTitle
  ORDER BY c.BookTitle ASC, b.dateCreated DESC;"

$SQLITE "$DB" "$SQL" >> $EXPORT

echo -e "## Currently reading:\n" >> $EXPORT

SQL="SELECT
  '- ' || c.Title || COALESCE(', ' || c.Attribution, '')
  || ' (' || COALESCE(c1.Title || ', ', '') || c.___PercentRead || '% read' || ')'
  FROM Content c
  LEFT OUTER JOIN Content c1 ON (
    c.ContentID = c1.BookID
    AND c1.ContentType = 899
    AND REPLACE(c1.ContentID, '!', '/') LIKE /* get chapter id without anchor or query string */
      '%' || SUBSTR(c.ChapterIDBookmarked, 1, INSTR(c.ChapterIDBookmarked, '#') + INSTR(c.ChapterIDBookmarked, '?') - 1) || '%'
  )
  WHERE c.ContentType = 6
    AND c.ReadStatus = 1
    AND c.IsDownloaded = 'true'
  ORDER BY c.___PercentRead DESC,
           c.Title ASC,
           c.Attribution ASC;"

$SQLITE "$DB" "$SQL" >> $EXPORT

# Clean up old notes
cd "$EXPORT_FOLDER"
for i in $(ls -v notes* | head -n -$KEEP); do
  rm "$i"
done


'
# PHP Server:

- create "uploads" folder in www root folder with chown 777
- create "upload.php" file in www root folder

## PHP:
<?php
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_FILES['file'])) {
    $uploadDir = __DIR__ . '/uploads/';
    $filename = basename($_FILES['file']['name']);
    $targetPath = $uploadDir . $filename;

    // 🔒 Restrict allowed file extensions
    $allowedExtensions = ['txt', 'md'];
    $extension = strtolower(pathinfo($filename, PATHINFO_EXTENSION));

    if (!in_array($extension, $allowedExtensions)) {
        http_response_code(400);
        echo "Error: Only .txt and .md files are allowed.";
        exit;
    }

    // Proceed with upload
    if (move_uploaded_file($_FILES['file']['tmp_name'], $targetPath)) {
        echo "File uploaded successfully: " . htmlspecialchars($filename);
    } else {
        echo "Upload failed.";
    }
} else {
    echo "No file uploaded.";
}
?>

## command in this script file:
/mnt/onboard/.adds/notes/curl -X POST -F "file=@$EXPORT" http://server-ip/upload.php
'

/mnt/onboard/.adds/notes/curl --cacert /mnt/onboard/.adds/notes/ca-bundle.crt -X POST https://content.dropboxapi.com/2/files/upload \
    --header "Authorization: Bearer $DROPBOX_ACCESS_TOKEN" \
    --header "Dropbox-API-Arg: {\"path\": \"/$EXPORT_FILE\",\"mode\": \"add\",\"autorename\": true,\"mute\": false}" \
    --header "Content-Type: application/octet-stream" \
    --data-binary @"$EXPORT"
febalci is offline   Reply With Quote