Skip to content

Instantly share code, notes, and snippets.

@lildude
Last active November 28, 2024 10:20
Show Gist options
  • Save lildude/80b7525b294341f32d4465c9c55d474b to your computer and use it in GitHub Desktop.
Save lildude/80b7525b294341f32d4465c9c55d474b to your computer and use it in GitHub Desktop.
#!/usr/bin/env bash
#
# Export all Omnivore saves to a bookmarks.html file to easy importing into things like Pocket.
#
# Sets the added and modified dates to order is retained in the receiving service if it honours those fields. Pocket does.
#
# Instructions:
#
# 1. Save file to your Linux, macOS or WSL on Windows
# 2. Get an API key from Omnivore. See https://docs.omnivore.app/integrations/api.html
# 3. In a terminal run, replacing <API_KEY> with the API key from above:
#
# bash ./omnivore-to-bookmarks.sh <API_KEY>
#
if [ "$#" -ne 1 ]; then
echo "Usage: $0 <API_KEY>"
exit 1
fi
API_KEY="$1"
ENDPOINT="https://api-prod.omnivore.app/api/graphql"
OUTPUT_FILE="omnivore_bookmarks.html"
# Initialize the bookmarks file
echo '<!DOCTYPE NETSCAPE-Bookmark-file-1>
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=UTF-8">
<TITLE>Bookmarks</TITLE>
<H1>Bookmarks</H1>
<DL><p>' > "$OUTPUT_FILE"
fetch_page() {
local after="$1"
local query
if [ -z "$after" ]; then
query='{"query": "query { search(first: 100, query: \"\", includeContent: false) { ... on SearchSuccess { edges { node { id url title savedAt updatedAt } } pageInfo { hasNextPage endCursor } } } }"}'
else
query="{\"query\": \"query { search(first: 100, after: \\\"$after\\\", query: \\\"\\\", includeContent: false) { ... on SearchSuccess { edges { node { id url title savedAt updatedAt } } pageInfo { hasNextPage endCursor } } } }\"}"
fi
curl --silent --location "$ENDPOINT" \
--header "Authorization: $API_KEY" \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--data "$query"
}
process_results() {
local json="$1"
echo "$json" | jq -r '.data.search.edges[] | "<DT><A HREF=\"\(.node.url)\" ADD_DATE=\"\(.node.savedAt | strptime("%Y-%m-%dT%H:%M:%S.000Z")|mktime)\" LAST_MODIFIED=\"\(.node.updatedAt | strptime("%Y-%m-%dT%H:%M:%S.000Z")|mktime)\">\(.node.title)</A>"' >> "$OUTPUT_FILE"
}
after=""
has_next_page=true
while $has_next_page; do
response=$(fetch_page "$after")
process_results "$response"
has_next_page=$(echo "$response" | jq -r '.data.search.pageInfo.hasNextPage')
after=$(echo "$response" | jq -r '.data.search.pageInfo.endCursor')
echo "Processed a page. More pages: $has_next_page"
# Optional: add a small delay to avoid hitting rate limits
sleep 1
done
# Close the bookmarks file
echo '</DL><p>' >> "$OUTPUT_FILE"
echo "Bookmarks have been saved to $OUTPUT_FILE"
@lildude
Copy link
Author

lildude commented Nov 28, 2024

Change:

echo "$json" | jq -r '.data.search.edges[] | "<DT><A HREF=\"\(.node.url)\" ADD_DATE=\"\(.node.savedAt | strptime("%Y-%m-%dT%H:%M:%S.000Z")|mktime)\" LAST_MODIFIED=\"\(.node.updatedAt | strptime("%Y-%m-%dT%H:%M:%S.000Z")|mktime)\">\(.node.title)</A>"' >> "$OUTPUT_FILE"
}

... to ...

echo "$json" | jq -r '.data.search.edges[] | "<DT><A HREF=\"\(.node.url)\">\(.node.title)</A>"' >> "$OUTPUT_FILE"
}

@beanstalkgleams
Copy link

OMG thank you so much, it worked. Thank you for my life

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment