Firefox does a nice job of keeping my history. But not a perfect one: certain history gets in my way, and I didn’t find a good extension to automatically clean it. So I wrote a python3
script that lets me do it manually.
GitHub: Gist: clean_places.py
: Python 3 script to manually remove some Firefox history items.
#!/usr/bin/python3
# The queries operate only if either:
# * There are more than 10 visits (for things like my mail, which only bug me
# once they are trying to clog up my new tab page)
# * They are > 10 days old (for things like searches; recent searches aren't
# a big problem; old searches are).
# This should be run only if Firefox is shut down (and I mean really; you
# don't want to corrupt your DB because it was hung!)
# Also, take care about your queries!
import datetime
import sqlite3
import time
PLACES_DB = "/EDITME/path/to/places.sqlite"
conn = sqlite3.connect(PLACES_DB)
cursor = conn.cursor()
select_statement = """select url from moz_places
where url like :query and
(last_visit_date < :ten_days_ago or
visit_count > 10)"""
delete_statement = """delete from moz_places
where url like :query and
(last_visit_date < :ten_days_ago or
visit_count > 10)"""
# The time stored in the DB is in UTC, so we need to be consistent.
old_time_dt = datetime.datetime.utcnow() - datetime.timedelta(days=10)
raw_time = time.mktime(old_time_dt.timetuple())
ten_days_ago = int(raw_time * 1000000)
queries = ["%localhost/roundcube/?%", # Round Cube
"%.google.com/search?%", # Google Search
]
# Set to True if you want to preview what would be deleted
TEST_MODE = False
if TEST_MODE:
statement = select_statement
else:
statement = delete_statement
for query in queries:
variable_bindings = {"query": query, "ten_days_ago": ten_days_ago}
cursor.execute(statement, variable_bindings)
if TEST_MODE:
for row in cursor:
print(row['url'])
if not TEST_MODE:
print("Deleted {} rows.".format(conn.total_changes))
conn.commit()
cursor.close()
To use it you first shut down Firefox. You should make sure it’s really shut down, as you don’t want to try to modify the database while something else is. If you want to be extra paranoid, make a fresh backup your places.sqlite
file.
You need to edit the PLACES_DB
variable to point to your places.sqlite
file. It’s usually somewhere like: /home/YOUR_USER/.mozilla/firefox/YOUR_PROFILE_FOLDER/places.sqlite
.
You need to edit your query strings (queries
variable). Use %
as a wildcard match.
You should set TEST_MODE
to True
and run the script once to make sure it’s hitting your targets. The two statements are the same except one is a SELECT
and the other a DELETE
.
TEST_MODE
will simply print what the script would delete.
If you’re satisfied, you can turn TEST_MODE
off and let it rip.
If you’re adventurous you can install the sqlite3
command line tool and open the database and explore. Note that you should also ensure Firefox is not running (at least not on the same profile) when opening your places.sqlite
in sqlite3
.
Thanks for this. I’m gonna try this over the weekend.
How can I perform the same thing but deleting all the entries that DOES NOT match with the queries?
You use the word “not” in the select_statement and delete_statement after “where” (“where not url like :query”) but be sure to backup and use the test output before you delete it as I’ve not tested that case.