{"id":18889352,"url":"https://github.com/suurjaak/pyscripts","last_synced_at":"2025-09-04T09:33:31.068Z","repository":{"id":142025001,"uuid":"44612839","full_name":"suurjaak/pyscripts","owner":"suurjaak","description":"Various small Python utility scripts","archived":false,"fork":false,"pushed_at":"2015-10-20T14:43:44.000Z","size":136,"stargazers_count":6,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-09-01T00:14:14.081Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/suurjaak.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2015-10-20T14:42:07.000Z","updated_at":"2024-09-28T09:58:35.000Z","dependencies_parsed_at":"2023-03-13T13:36:35.502Z","dependency_job_id":null,"html_url":"https://github.com/suurjaak/pyscripts","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/suurjaak/pyscripts","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/suurjaak%2Fpyscripts","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/suurjaak%2Fpyscripts/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/suurjaak%2Fpyscripts/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/suurjaak%2Fpyscripts/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/suurjaak","download_url":"https://codeload.github.com/suurjaak/pyscripts/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/suurjaak%2Fpyscripts/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":273583440,"owners_count":25131831,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-09-04T02:00:08.968Z","response_time":61,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-08T07:48:45.404Z","updated_at":"2025-09-04T09:33:30.807Z","avatar_url":"https://github.com/suurjaak.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"Various small Python utility scripts\r\n====================================\r\n\r\n\r\n\r\n### [countbits.py](countbits.py)\r\n\r\nA command-line tool written just for lark: \r\nin communications theory the assumption is that a 0-bit is as likely as 1, \r\nbut how is the situation in filesystems?\r\n\r\n```\r\nusage: countbits.py [-h] [-d DIR [DIR ...]] [-nr] [-s] [--db DBPATH]\r\n                    [WILDCARD [WILDCARD ...]]\r\n\r\nCount the bits (0/1 ratio) in file system files.\r\n\r\npositional arguments:\r\n  WILDCARD              one or more filename patterns to match\r\n\r\noptional arguments:\r\n  -h, --help            show this help message and exit\r\n  -d DIR [DIR ...], --directory DIR [DIR ...]\r\n                        directories to process, filesystem root by default\r\n  -nr, --nonrecursive   skip subdirectories\r\n  -s, --statsonly       show accumulated statistics and exit\r\n  --db DBPATH           cache-database path, by default in program directory.\r\n                        Use :memory: or empty string for no caching.\r\n```\r\n\r\n\r\nMy result:\r\n```\r\nTOTAL ZERO/ONE    58% vs  42%   99,950,872,411 bytes   699,763 files\r\n-------------------------------------------------------------------------------\r\n          .dll    63% vs  37%   15,686,096,949 bytes    25,414 (16% size)\r\n          .avi    51% vs  49%   12,809,622,256 bytes       180 (13% size)\r\n          .bin    61% vs  39%    8,762,136,890 bytes       314 (9% size)\r\n          .exe    55% vs  45%    7,777,679,103 bytes     6,413 (8% size)\r\n           .db    62% vs  38%    6,963,647,404 bytes       384 (7% size)\r\n\u003cNO EXTENSION\u003e    54% vs  46%    3,935,827,090 bytes    36,492 (4% size)\r\n          .jpg    51% vs  49%    2,709,945,949 bytes    15,781 (3% size)\r\n          .txt    62% vs  38%    2,652,266,242 bytes    16,982 (3% size)\r\n          .pdf    50% vs  50%    2,598,121,519 bytes     1,475 (3% size)\r\n          .msi    51% vs  49%    2,353,022,146 bytes       241 (2% size)\r\n          .dat    51% vs  49%    1,724,590,136 bytes     3,105 (2% size)\r\n         .html    56% vs  44%    1,523,280,768 bytes    41,992 (2% size)\r\n          .jar    58% vs  42%    1,384,024,774 bytes     2,817 (1% size)\r\n          .xml    61% vs  39%    1,117,032,485 bytes     7,034 (1% size)\r\n            .o    69% vs  31%    1,016,419,994 bytes    13,390 (1% size)\r\n..\r\n```\r\nIt depends heavily on file types, but in general 0 is slightly more represented.\r\n\r\n\r\n### [db.py](db.py)\r\n\r\nSimple convenience wrapper class for SQLite.\r\n\r\nExample usage:\r\n\r\n```python\r\ndb.init(\":memory:\", \"CREATE TABLE test (id INTEGER PRIMARY KEY, val TEXT)\")\r\ndb.insert(\"test\", val=None)\r\nfor i in range(5): db.insert(\"test\", {\"val\": i})\r\ndb.fetch(\"test\", id=1)\r\ndb.fetchall(\"test\", order=\"val\", limit=3)\r\ndb.update(\"test\", {\"val\": \"new\"}, val=None)\r\ndb.fetchall(\"test\", val=(\"IN\", range(3)))\r\ndb.delete(\"test\", id=5)\r\ndb.execute(\"DROP TABLE test\")\r\n```\r\n\r\n\r\n### [duplicates.py](duplicates.py)\r\n\r\nCommand-line tool for detecting duplicate files.\r\n\r\n```\r\nusage: duplicates.py [-h] [-d DIR [DIR ...]] [-t  [...]] [-r] [-s]\r\n                     [WILDCARD [WILDCARD ...]]\r\n\r\nList files having the same content.\r\n\r\npositional arguments:\r\n  WILDCARD              one or more filename patterns to match\r\n\r\noptional arguments:\r\n  -h, --help            show this help message and exit\r\n  -d DIR [DIR ...], --directory DIR [DIR ...]\r\n                        directories to process, defaults to working directory\r\n  -t  [ ...], --type  [ ...]\r\n                        file types to match (image, audio, video)\r\n  -r, --recursive       process subdirectories\r\n  -s, --sizeonly        match by file size only\r\n```\r\n\r\n\r\n### [relayserver.py](relayserver.py)\r\n\r\nSimple network relay program - allows any number of clients to make a network\r\nconnection, relays sent data between all clients. Can log data to local db.\r\n\r\n```\r\nusage: relayserver.py [-h] [-p PORT] [--db [DB]] [--verbose] [-t]\r\n\r\nA simple network relay server to exchange data between clients.\r\n\r\noptional arguments:\r\n  -h, --help            show this help message and exit\r\n  -p PORT, --port PORT  TCP port to use, 9000 by default\r\n  --db [DB]             SQLite database to log traffic to, if any. If DB not\r\n                        given, defaults to 'relaylog.db' in program directory.\r\n  --verbose             print activity messages\r\n  -t, --test            do a test run with dummy clients\r\n```\r\n\r\n\r\n### [serialclient.py](serialclient.py)\r\n\r\nSimple serial port reader-writer class using background threads.\r\nNeeds pyserial.\r\n\r\nExample usage:\r\n```python\r\nimport serialclient\r\n\r\ndef callback(data):\r\n    print(\"Incoming serial data: %r.\" % data)\r\n\r\nclient = serialclient.SerialClient(\"/dev/ttyAMA0\", 115200, callback)\r\nclient.start()\r\nclient.send(\"outgoing data is queued and written in the background\")\r\n```\r\n\r\n\r\n### [shift_subtitles.py](shift_subtitles.py)\r\n\r\nCommand-line tool for advancing/delaying movie subtitle timestamps.\r\n\r\n```\r\nusage: shift_subtitles.py SUBTITLEFILE SECONDS\r\n\r\nShifts subtitle timestamps in an SRT file by a given amount.\r\n```\r\n\r\n\r\n### [thumbnails_mpc.py](thumbnails_mpc.py)\r\n\r\nCommand-line tool for making video thumbnails by invoking Media Player Classic.\r\nWindows-only.\r\n\r\n```\r\nusage: thumbnails_mpc.py [WILDCARD [WILDCARD ...]]\r\n\r\nCreates thumbnails for videos in current directory, using Media Player Classic.\r\n```\r\n\r\n\r\n### [util.py](util.py)\r\n\r\nAll sorts of handy little utility functions accumulated over the years.\r\n\r\n\r\nLicense\r\n-------\r\n\r\nPublished in 2015 by Erki Suurjaak.\r\nReleased as free open source software under the \r\n[Creative Commons CC0 1.0 Universal Public Domain Dedication](https://creativecommons.org/publicdomain/zero/1.0/). ![CC0](http://i.creativecommons.org/p/zero/1.0/88x31.png)\r\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsuurjaak%2Fpyscripts","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsuurjaak%2Fpyscripts","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsuurjaak%2Fpyscripts/lists"}