#!/usr/bin/env python3 """ Pocket to Pinboard Import Script This script imports bookmarks from a Pocket export CSV file to Pinboard. To run this script with uv in a single command: uv run --with pinboard https://gist.github.com/dctanner/e0e00b32d4df6936a8a19ac7da89a056/raw/pocket_to_pinboard_standalone.py pocket_export.csv username:api_token Or download first and run: curl -O https://gist.github.com/dctanner/e0e00b32d4df6936a8a19ac7da89a056/raw/pocket_to_pinboard_standalone.py uv run --with pinboard pocket_to_pinboard_standalone.py pocket_export.csv username:api_token Requirements: - uv (install from https://github.com/astral-sh/uv) - A Pocket export CSV file (export from https://getpocket.com/export) - A Pinboard API token (get from https://pinboard.in/settings/password) Usage: python pocket_to_pinboard_standalone.py Arguments: pocket_csv_file Path to the Pocket export CSV file pinboard_api_token Pinboard API token in username:token format Example: python pocket_to_pinboard_standalone.py pocket_export.csv myusername:1234567890ABCDEF Note: The script respects Pinboard's rate limiting (3 seconds between requests). """ import csv import argparse import time from datetime import datetime import pinboard def parse_pocket_csv(csv_file): """Parse Pocket export CSV and return list of bookmarks.""" bookmarks = [] with open(csv_file, 'r', encoding='utf-8') as f: reader = csv.DictReader(f) for row in reader: # Skip items without URLs if not row.get('url'): continue bookmark = { 'url': row['url'], 'description': row.get('title', ''), 'tags': row.get('tags', '').split(',') if row.get('tags') else [], 'time': datetime.fromtimestamp(int(row.get('time_added', 0))) if row.get('time_added') else None, 'toread': row.get('status') == 'unread' } bookmarks.append(bookmark) return bookmarks def import_to_pinboard(bookmarks, api_token): """Import bookmarks to Pinboard.""" pb = pinboard.Pinboard(api_token) total = len(bookmarks) successful = 0 failed = 0 print(f"Starting import of {total} bookmarks...") for i, bookmark in enumerate(bookmarks, 1): try: # Pinboard API has rate limiting (1 request per 3 seconds) if i > 1: time.sleep(3) pb.posts.add( url=bookmark['url'], description=bookmark['description'], tags=' '.join(bookmark['tags']), dt=bookmark['time'], toread=bookmark['toread'] ) successful += 1 print(f"[{i}/{total}] Added: {bookmark['description'][:50]}...") except Exception as e: failed += 1 print(f"[{i}/{total}] Failed to add {bookmark['url']}: {str(e)}") print(f"\nImport complete!") print(f"Successful: {successful}") print(f"Failed: {failed}") def main(): parser = argparse.ArgumentParser(description='Import Pocket bookmarks to Pinboard') parser.add_argument('csv_file', help='Path to Pocket export CSV file') parser.add_argument('api_token', help='Pinboard API token (username:token format)') args = parser.parse_args() # Parse CSV try: bookmarks = parse_pocket_csv(args.csv_file) print(f"Parsed {len(bookmarks)} bookmarks from CSV") except Exception as e: print(f"Error reading CSV file: {e}") return 1 # Import to Pinboard try: import_to_pinboard(bookmarks, args.api_token) except Exception as e: print(f"Error during import: {e}") return 1 return 0 if __name__ == '__main__': exit(main())