Package: bitrot
Detects bit rotten files on the hard drive to save your precious photo
and music collection from slow decay.UsageGo to the desired directory and simply invoke:$ bitrotThis will start digging through your directory structure recursively
indexing all files found. The index is stored in a.bitrot.dbfile
which is a SQLite 3 database.Next time you runbitrotit will add new files and update the index
for files with a changed modification date. Most importantly however, it
will report all errors, e.g. files that changed on the hard drive but
still have the same modification date.All paths stored in.bitrot.dbare relative so it’s safe to rescan
a folder after moving it to another drive. Just remember to move it in
a way that doesn’t touch modification dates. Otherwise the checksum
database is useless.PerformanceObviously depends on how fast the underlying drive is.  Historically
the script was single-threaded because back in 2013 checksum
calculations on a single core still outran typical drives, including
the mobile SSDs of the day.  In 2020 this is no longer the case so the
script now uses a process pool to calculate SHA1 hashes and performstat()calls.No rigorous performance tests have been done.  Scanning a ~1000 file
directory totalling ~5 GB takes 2.2s on a 2018 MacBook Pro 15” with
a AP0512M SSD.  Back in 2013, that same feat on a 2015 MacBook Air with
a SM0256G SSD took over 20 seconds.On that same 2018 MacBook Pro 15”, scanning a 60+ GB music library takes
24 seconds.  Back in 2013, with a typical 5400 RPM laptop hard drive
it took around 15 minutes.  How times have changed!TestsThere’s a simple but comprehensive test scenario usingpytestandpytest-order <https://pypi.org/p/pytest-order>.Install:$ python3 -m venv .venv
$ . .venv/bin/activate
(.venv)$ pip install -e .[test]Run:(.venv)$ pytest -x
==================== test session starts ====================
platform darwin -- Python 3.10.12, pytest-7.4.0, pluggy-1.2.0
rootdir: /Users/ambv/Documents/Python/bitrot
plugins: order-1.1.0
collected 12 items

tests/test_bitrot.py ............                      [100%]

==================== 12 passed in 15.05s ====================Change Log1.0.1officially remove Python 2 support that was broken since 1.0.0
anyway; now the package works with Python 3.8+ because of a few
features1.0.0significantly sped up execution on solid state drives by using
a process pool executor to calculate SHA1 hashes and performstat()calls; use-w1if your runs on slow magnetic drives were
negatively affected by this changesped up execution by pre-loading all SQLite-stored hashes to memory
and doing comparisons using Python setsall UTF-8 filenames are now normalized to NFKD in the database to
enable cross-operating system checksthe SQLite database is now vacuumed to minimize its sizebugfix: additional Python 3 fixes when Unicode names were encountered0.9.2bugfix: one place in the code incorrectly hardcoded UTF-8 as the
filesystem encoding0.9.1bugfix: print the path that failed to decode with FSENCODINGbugfix: when using -q, don’t hide warnings about files that can’t be
statted or readbugfix: -s is no longer broken on Python 30.9.0bugfix: bitrot.db checksum checking messages now obey –quietPython 3 compatibility0.8.0bitrot now keeps track of its own database’s bitrot by storing
a checksum of .bitrot.db in .bitrot.sha512bugfix: now properly uses the filesystem encoding to decode file names
for use with the .bitrotdb database. Report and original patch by
pallinger.0.7.1bugfix: SHA1 computation now works correctly on Windows; previously
opened files in text-mode. This fix will change hashes of files
containing some specific bytes like 0x1A.0.7.0when a file changes or is renamed, the timestamp of the last check is
updated, toobugfix: files that disappeared during the run are now properly ignoredbugfix: files that are locked or with otherwise denied access are
skipped. If they were read before, they will be considered “missing”
in the report.bugfix: if there are multiple files with the same content in the
scanned directory tree, renames are now handled properly for themrefactored some horrible code to be a little less horrible0.6.0more control over performance with--commit-intervaland--chunk-sizecommand-line argumentsbugfix: symbolic links are now properly skipped (or can be followed if--follow-linksis passed)bugfix: files that cannot be opened are now gracefully skippedbugfix: fixed a rare division by zero when run in an empty directory0.5.1bugfix: warn about test mode only in test mode0.5.0--testcommand-line argument for testing the state without
updating the database on disk (works for testing databases you don’t
have write access to)size of the data read is reported upon finishminor performance updates0.4.0renames are now reported as suchall non-regular files (e.g. symbolic links, pipes, sockets) are now
skippedprogress presented in percentage0.3.0--sumcommand-line argument for easy comparison of multiple
databases0.2.1fixed regression from 0.2.0 where new files caused aKeyErrorexception0.2.0--verboseand--quietcommand-line argumentsif a file is no longer there, its entry is removed from the database0.1.0First published version.AuthorsGlued together byŁukasz Langa. Multiple
improvements byBen Shepherd,Jean-Louis Fuchs,Marcus Linderoth,p1r473,Peter Hofmann,Phil Lundrigan,Reid Williams,Stan Senotrusov,Yang Zhang, andZhuoyun Wei.