Exporting Tasks from Things 3 Database to Plain Text
This guide is written for Things on MacOS. There is a way to get your database on iOS or iPad. However, I can't guarantee the script will work with it.
Step 1: Locating Your Things 3 Database
Before you can use the script, you need to locate your Things 3 database:
- Quit Things 3 app on your Mac.
- Click on 'Finder' in your Dock.
- In the menu bar, select Go → Go to Folder.
- Paste this path: ~/Library/Group Containers/JLMPQHK86H.com.culturedcode.ThingsMac/
- Press the Return key.
- Open the folder named ThingsData-xxxxx.
- Copy (do not move) the Things Database.thingsdatabase to your desired location. Like your desktop. Or a custom folder in documents.
- To access the database, CTRL + click on the bundle and select 'Show Package Contents'. The file main.sqlite is your database.
Step 2: Setting Up the Python Environment
Make sure you have Python installed on your Mac. You can find instruction on installing Python here.
Step 3: Running the Script
- Save the Python script below this note, call it
things2plaintext.py
. I recommend saving it in the same directory as your main.sqlite. - Open your terminal.
- Navigate (how?) to the directory where you saved the script.
- Run the script by typing
python things2plaintext.py
.
Step 4: Using the Script
- When prompted, enter the path of your Things 3 database. If it's in the same directory, type
main.sqlite
. - Choose the export format: type 1 for Markdown or 2 for Todo.txt.
- The script will connect to your database and export the tasks to a file named exported_tasks.txt in the same directory.
Troubleshooting
If you encounter any errors, ensure that the database path is correct and that the right Python is installed. Raise an issue on our Github, when you are stuck.
I hope this helped making your tasks more resistent to time.
import sqlite3
import os
def get_database_path():
return input("Enter the path of your Things 3 database (main.sqlite): ")
def choose_export_format():
choice = input("Choose export syntax (1 for Markdown, 2 for todo.txt): ")
return 'markdown' if choice == '1' else 'todo.txt'
def connect_to_database(path):
try:
return sqlite3.connect(path)
except sqlite3.Error as e:
print(f"Error connecting to database: {e}")
return None
def fetch_tasks(cursor):
query = """
SELECT title, status
FROM TMTask
WHERE trashed = 0 AND status IN (0, 3, 2)
"""
cursor.execute(query)
return cursor.fetchall()
def task_status(status):
return {
0: 'Not Yet Done',
3: 'Done',
2: 'Canceled'
}.get(status, 'Unknown')
def format_task(task, format_type):
title, status = task
# Define the status markers and prefixes
status_markers = {
0: ('', ''), # Not Yet Done
3: ('x ', ''), # Done
2: ('x ', 'canceled ') # Canceled
}
# Get the appropriate marker and prefix for the task status
marker, prefix = status_markers.get(status, ('', ''))
if format_type == 'markdown':
return f"- [{marker.strip()}] {prefix}{title}\n"
else: # todo.txt format
# Only add a space after the marker if it's not empty
space = ' ' if marker else ''
return f"{marker}{space}{prefix}{title}\n"
def main():
db_path = get_database_path()
export_format = choose_export_format()
connection = connect_to_database(db_path)
if connection:
cursor = connection.cursor()
tasks = fetch_tasks(cursor)
tasks = [(title, status) for title, status in tasks if title.strip()]
with open("exported_tasks.txt", "w") as file:
for task in tasks:
file.write(format_task(task, export_format))
print("Tasks exported successfully.")
connection.close()
if __name__ == "__main__":
main()
← anonymous kudos for permalink
- Prevent Browser from Hijacking the Media Keys technology
- LinearMouse–the remedy to Logitech their dumb choices technology
- Today's Lack of Music with an Inherent Value musicology
- External files in Obsidian without duplicating obsidian
- How we value music as an art form musicology
- Controlling Boox Network Traffic technology
- Lay out all Obsidian notes in a grid obsidian
- Highlight callouts in Obsidian obsidian
- AI-assisted music is not the problem musicology
- Mela to Markdown (Python script) scripts
- Display Airplay Now-Playing on old Android Tablet with MQTT smarthome
- Understanding Streaming Music Royalty Payments technology
- My Rating System and Review Criteria musicology
- Display recent files in Obsidian Vault obsidian
- Convert Spotify Library to Markdown scripts
- Things3 Overview in Obsidian obsidian
- List unlinked notes in Obsidian obsidian
- My Zotero research paper template obsidian