Script: bulk star Wallabag entries by URL
Useful if you imported from Pocket CSV, and it didn’t include your favourites
I migrated my Pocket data to Wallabag when Pocket shut down. As I have mentioned before, the official Pocket CSV export doesn’t include which articles were favorite. However, data from the unofficial 3rd party Pocket exporter that I also used, does.
But the Wallabag importer is designed for use with the Pocket CSV, not the pile of JSON files from the 3rd party export.
So, I imported my Pocket CSV.
Then, I wrote a Python script that accepts a URL as input, and uses the Wallabag API to find the entry with that URL and star it.
Then, I wrote a jq snippet, which goes through all the JSON files from the 3rd party export and spits out the URLs for the entries that were starred in Pocket.
cat **.json | jq '.. | objects | select(has("isFavorite") and .isFavorite == true) | .url'
(Run it in Fish shell or Bash with setopt globstar to make ** work.)
Try that on its own in the directory with your 3rd party Pocket export first, to make sure everything looks good.
And test the script with just one URL to make sure it is working.
Then, you can pipe each of those URLs to the Python script (below) with xargs:
cat **.json | jq '.. | objects | select(has("isFavorite") and .isFavorite == true) | .url' | xargs -I{} python3 star_wallabag_entry_by_url.py "{}"
Boom! 659 favorites appear. (Actually, it runs pretty slowly.)
You will need to create a Wallabag API client (if you don’t already have one) and provide WALLABAG_BASE_URL, WALLABAG_CLIENT_ID, WALLABAG_CLIENT_SECRET, WALLABAG_USERNAME, and WALLABAG_PASSWORD as environment variables. (Unfortunately the Wallabag API requires the username and password. I know, it’s not good!)
You will also need to create a virtual environment and install two Python packages. I like to use uv for this:
uv venv .readitlater
source .readitlater/bin/activate
uv pip install requests json
(Note: I actually got this script to run in the browser, 100% client-side, with PyScript. If you want to bulk-star Wallabag entries by URL without using Python and installing stuff, let me know and I will clean up and publish that version.)
Here’s the script. It isn’t fancy, or designed to handle every edge case — because for my purposes, it just had to work once, on my machine — but it gets the job done.
import requests
import json
import os
import sys
class WallabagAPI:
def __init__(self, BASE_URL, CLIENT_ID, CLIENT_SECRET, USERNAME, PASSWORD):
self.BASE_URL = BASE_URL
self.CLIENT_ID = CLIENT_ID
self.CLIENT_SECRET = CLIENT_SECRET
self.USERNAME = USERNAME
self.PASSWORD = PASSWORD
self.access_token = None
def _get_access_token(self):
if not self.access_token:
data = {'username': self.USERNAME, 'password': self.PASSWORD,'client_id': self.CLIENT_ID, 'client_secret': self.CLIENT_SECRET, 'grant_type': 'password'}
response = requests.post('{}/oauth/v2/token'.format(self.BASE_URL), data)
access_token = response.json().get('access_token')
self.access_token = access_token
return access_token
def star_article_by_url(self, url):
"""Star an article by its URL"""
# First get the article ID
headers = {'Authorization': f'Bearer {self._get_access_token()}'}
params = {'url': url, 'return_id':1}
response = requests.get(f"{self.BASE_URL}/api/entries/exists.json",
headers=headers,
params=params)
response.raise_for_status()
data = response.json()
print(data)
entry_id = data['exists']
if entry_id:
print(f"starring {entry_id} ({url})")
# Star the article
response = requests.patch(
f"{self.BASE_URL}/api/entries/{entry_id}.json",
headers=headers,
data={'starred': 1}
)
response.raise_for_status()
return True
else:
print(f"No ID found ({entry_id}) for url: {url}")
return False
# Initialize API client
wallabag = WallabagAPI(
BASE_URL=os.environ["WALLABAG_BASE_URL"],
CLIENT_ID=os.environ["WALLABAG_CLIENT_ID"],
CLIENT_SECRET=os.environ["WALLABAG_CLIENT_SECRET"],
USERNAME=os.environ["WALLABAG_USERNAME"],
PASSWORD=os.environ["WALLABAG_PASSWORD"],
)
if __name__ == "__main__":
if len(sys.argv) != 2:
print("Usage: python script.py <article_url>")
sys.exit(1)
url = sys.argv[1]
wallabag.star_article_by_url(url)