tidy-gmail 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- tidy_gmail-0.1.0/.gitignore +382 -0
- tidy_gmail-0.1.0/CHANGELOG.md +194 -0
- tidy_gmail-0.1.0/CITATION.cff +53 -0
- tidy_gmail-0.1.0/LICENSE +21 -0
- tidy_gmail-0.1.0/PKG-INFO +518 -0
- tidy_gmail-0.1.0/README.md +490 -0
- tidy_gmail-0.1.0/pyproject.toml +140 -0
- tidy_gmail-0.1.0/src/tidy_gmail/__init__.py +1 -0
- tidy_gmail-0.1.0/src/tidy_gmail/_version.py +24 -0
- tidy_gmail-0.1.0/src/tidy_gmail/auth.py +71 -0
- tidy_gmail-0.1.0/src/tidy_gmail/classify.py +34 -0
- tidy_gmail-0.1.0/src/tidy_gmail/cleanup.py +172 -0
- tidy_gmail-0.1.0/src/tidy_gmail/cli.py +224 -0
- tidy_gmail-0.1.0/src/tidy_gmail/gmail_client.py +201 -0
- tidy_gmail-0.1.0/src/tidy_gmail/inventory.py +131 -0
- tidy_gmail-0.1.0/src/tidy_gmail/py.typed +0 -0
- tidy_gmail-0.1.0/src/tidy_gmail/reports.py +183 -0
- tidy_gmail-0.1.0/src/tidy_gmail/restore.py +146 -0
- tidy_gmail-0.1.0/src/tidy_gmail/rules.py +406 -0
- tidy_gmail-0.1.0/src/tidy_gmail/scan_state.py +335 -0
- tidy_gmail-0.1.0/src/tidy_gmail/storage.py +255 -0
- tidy_gmail-0.1.0/src/tidy_gmail/templates/config.toml +24 -0
- tidy_gmail-0.1.0/src/tidy_gmail/templates/sender_decisions.csv +1 -0
- tidy_gmail-0.1.0/src/tidy_gmail/templates/senders_always_delete.csv +1 -0
- tidy_gmail-0.1.0/src/tidy_gmail/templates/senders_protected.csv +1 -0
|
@@ -0,0 +1,382 @@
|
|
|
1
|
+
# ============================================================
|
|
2
|
+
# .gitignore (CUSTOM)
|
|
3
|
+
# ============================================================
|
|
4
|
+
# Updated: 2026-11-13
|
|
5
|
+
#
|
|
6
|
+
# WHAT: A Git configuration file that identifies files and directories
|
|
7
|
+
# that should not be included in the repository's version history.
|
|
8
|
+
# Git uses this file to determine which untracked files to ignore.
|
|
9
|
+
#
|
|
10
|
+
# WHEN: Use in professional repositories managed with Git.
|
|
11
|
+
# Git automatically applies these rules when working with files.
|
|
12
|
+
#
|
|
13
|
+
# WHY: Version the files we create and maintain for this project.
|
|
14
|
+
# Avoid tracking downloaded dependencies, generated output,
|
|
15
|
+
# temporary files, local settings, and sensitive information.
|
|
16
|
+
# Other projects maintain the source code and version history
|
|
17
|
+
# of their own dependencies.
|
|
18
|
+
#
|
|
19
|
+
# HOW: List file and directory patterns below.
|
|
20
|
+
# Patterns work across different languages, tools, and project types.
|
|
21
|
+
# Sections are organized by purpose for easier maintenance.
|
|
22
|
+
#
|
|
23
|
+
# In VS Code, open the 'Outline view' in the Explorer sidebar to
|
|
24
|
+
# see and navigate the different sections of this file.
|
|
25
|
+
# Requires the recommended 'Comment Section Outline' extension
|
|
26
|
+
# (see .vscode/extensions.json).
|
|
27
|
+
#
|
|
28
|
+
# TOOLS: Git tracks changes to project files and maintains version history.
|
|
29
|
+
# .gitignore controls which untracked files Git ignores.
|
|
30
|
+
#
|
|
31
|
+
# SKILLS: Git, version control, repository management,
|
|
32
|
+
# file patterns, dependency management, and project maintenance.
|
|
33
|
+
#
|
|
34
|
+
# REQ: All professional GitHub project repositories MUST include .gitignore.
|
|
35
|
+
# REQ: Never commit secrets or private credentials.
|
|
36
|
+
#
|
|
37
|
+
# OBS: .gitignore does not remove files already tracked by Git.
|
|
38
|
+
# OBS: Dependency manifests and lockfiles should generally be committed
|
|
39
|
+
# even when downloaded dependencies are ignored.
|
|
40
|
+
# OBS: Patterns for unused tools or languages are generally harmless.
|
|
41
|
+
#
|
|
42
|
+
# ALT: Repositories may customize ignores while preserving safety rules.
|
|
43
|
+
# CUSTOM: Delete sections that are not needed for the project.
|
|
44
|
+
# CUSTOM: Add project-specific patterns when necessary.
|
|
45
|
+
#
|
|
46
|
+
# ============================================================
|
|
47
|
+
# === INTRO: How .gitignore patterns work ===
|
|
48
|
+
# ============================================================
|
|
49
|
+
# NOTE: .gitignore uses glob-style patterns, not regular expressions.
|
|
50
|
+
#
|
|
51
|
+
# /name
|
|
52
|
+
# WHY: A leading slash anchors the pattern to the directory containing this
|
|
53
|
+
# .gitignore file. In a repository-root .gitignore, /name matches only name
|
|
54
|
+
# at the repository root.
|
|
55
|
+
# EXAMPLE: /pyproject.toml.ruff ignores only the root-level temporary fragment.
|
|
56
|
+
#
|
|
57
|
+
# name/
|
|
58
|
+
# WHY: A trailing slash means the pattern matches directories, not files.
|
|
59
|
+
# EXAMPLE: bin/ ignores directories named bin and their contents.
|
|
60
|
+
#
|
|
61
|
+
# *.ext
|
|
62
|
+
# WHY: An asterisk (*) matches any number of characters within one path component.
|
|
63
|
+
# EXAMPLE: *.log ignores files ending in .log.
|
|
64
|
+
#
|
|
65
|
+
# **
|
|
66
|
+
# WHY: A double asterisk (**) can match across directory levels.
|
|
67
|
+
# EXAMPLE: **/src/**/_version.py matches generated _version.py files inside
|
|
68
|
+
# src trees regardless of repository depth or package name.
|
|
69
|
+
#
|
|
70
|
+
# ?
|
|
71
|
+
# WHY: A question mark (?) matches exactly one character within a path component.
|
|
72
|
+
# EXAMPLE: temp?.txt matches temp1.txt and tempa.txt, but not temp10.txt.
|
|
73
|
+
#
|
|
74
|
+
# [abc]
|
|
75
|
+
# WHY: Square brackets match one character from the listed set or range.
|
|
76
|
+
# EXAMPLE: file[0-9].txt matches file0.txt through file9.txt.
|
|
77
|
+
#
|
|
78
|
+
# !pattern
|
|
79
|
+
# WHY: An exclamation point (!) negates an earlier ignore rule and re-includes
|
|
80
|
+
# a matching file when its parent directory has not itself been excluded.
|
|
81
|
+
# EXAMPLE: !.env.example keeps the safe example file even though .env.* is ignored.
|
|
82
|
+
#
|
|
83
|
+
# # text
|
|
84
|
+
# WHY: A leading # makes the line a comment unless the # is escaped.
|
|
85
|
+
#
|
|
86
|
+
# NOTE: Prefer the narrowest pattern that expresses the intent.
|
|
87
|
+
# Anchored patterns such as /name are safer when
|
|
88
|
+
# only a repository-root file should be ignored.
|
|
89
|
+
# ============================================================
|
|
90
|
+
|
|
91
|
+
# ============================================================
|
|
92
|
+
# === SECTION: CUSTOM ===
|
|
93
|
+
# ============================================================
|
|
94
|
+
|
|
95
|
+
# Private Gmail configuration and sender decisions
|
|
96
|
+
/data/
|
|
97
|
+
|
|
98
|
+
# Generated reports and cleanup logs
|
|
99
|
+
/output/
|
|
100
|
+
|
|
101
|
+
# OAuth credentials, tokens, and local state
|
|
102
|
+
/.local/
|
|
103
|
+
|
|
104
|
+
# ============================================================
|
|
105
|
+
# === SECTION: UNIVERSAL ===
|
|
106
|
+
# ============================================================
|
|
107
|
+
|
|
108
|
+
# === Environment variables and secrets ===
|
|
109
|
+
|
|
110
|
+
# WHY: Never commit credentials or environment-specific configuration.
|
|
111
|
+
*.env
|
|
112
|
+
.env
|
|
113
|
+
.env.*
|
|
114
|
+
|
|
115
|
+
# WHY: Commit .env.example as a safe template showing which variables to set.
|
|
116
|
+
# NOTE: Copy .env.example to .env locally and customize the local copy.
|
|
117
|
+
!.env.example
|
|
118
|
+
|
|
119
|
+
|
|
120
|
+
# === Private notes and local-only files ===
|
|
121
|
+
|
|
122
|
+
# WHY: Private working notes should remain local unless intentionally published.
|
|
123
|
+
PRIVATE-NOTES.md
|
|
124
|
+
PRIVATE_NOTES.md
|
|
125
|
+
|
|
126
|
+
# WHY: The root-level refs directory holds local reference papers and source
|
|
127
|
+
# materials that should be cited or linked to rather than committed.
|
|
128
|
+
# NOTE: The leading slash limits this rule to the repository-root refs directory.
|
|
129
|
+
# ALT: Commit only reference material that is intentionally redistributable and
|
|
130
|
+
# appropriate to include in the repository.
|
|
131
|
+
/refs/
|
|
132
|
+
|
|
133
|
+
|
|
134
|
+
# === Operating-system files ===
|
|
135
|
+
|
|
136
|
+
# WHY: OS-generated metadata files are machine-specific and should not be tracked.
|
|
137
|
+
.AppleDouble
|
|
138
|
+
.DS_Store
|
|
139
|
+
.LSOverride
|
|
140
|
+
.Spotlight-V100/
|
|
141
|
+
.Trashes
|
|
142
|
+
._*
|
|
143
|
+
Icon\r
|
|
144
|
+
Thumbs.db
|
|
145
|
+
desktop.ini
|
|
146
|
+
ehthumbs.db
|
|
147
|
+
|
|
148
|
+
|
|
149
|
+
# === Editors and IDEs ===
|
|
150
|
+
|
|
151
|
+
# WHY: IDE metadata is generally machine-local and should not be tracked.
|
|
152
|
+
*.code-workspace
|
|
153
|
+
.idea/
|
|
154
|
+
|
|
155
|
+
|
|
156
|
+
# === VS Code ===
|
|
157
|
+
|
|
158
|
+
# WHY: Ignore editor state by default while allowing shared project configuration.
|
|
159
|
+
# NOTE: Use .vscode/* (contents), not .vscode/ (directory). Git will not
|
|
160
|
+
# re-include a file whose parent directory is excluded.
|
|
161
|
+
.vscode/*
|
|
162
|
+
!.vscode/ABOUT_THIS_FOLDER.md
|
|
163
|
+
!.vscode/extensions.json
|
|
164
|
+
!.vscode/settings.json
|
|
165
|
+
!.vscode/launch.json
|
|
166
|
+
!.vscode/tasks.json
|
|
167
|
+
!.vscode/*.code-snippets
|
|
168
|
+
|
|
169
|
+
|
|
170
|
+
# === Temporary, lock, and swap files ===
|
|
171
|
+
|
|
172
|
+
# WHY: Temporary and swap files are machine-local noise and create meaningless diffs.
|
|
173
|
+
*.swo
|
|
174
|
+
*.swp
|
|
175
|
+
*.tmp
|
|
176
|
+
*~
|
|
177
|
+
|
|
178
|
+
# WHY: Microsoft Office creates temporary owner/lock files beside open documents.
|
|
179
|
+
# NOTE: These patterns cover Word, Excel, and PowerPoint temporary files without
|
|
180
|
+
# ignoring the actual Office documents.
|
|
181
|
+
~$*.doc*
|
|
182
|
+
~$*.xls*
|
|
183
|
+
~$*.ppt*
|
|
184
|
+
|
|
185
|
+
# WHY: LibreOffice and OpenOffice create temporary lock files beside open documents.
|
|
186
|
+
.~lock.*#
|
|
187
|
+
|
|
188
|
+
|
|
189
|
+
# === Logs and generated runtime output ===
|
|
190
|
+
|
|
191
|
+
# WHY: Ignore logs and runtime output by default.
|
|
192
|
+
# ALT: Explicitly re-include a specific log only when it is intentionally used
|
|
193
|
+
# as project evidence.
|
|
194
|
+
*.log
|
|
195
|
+
logs/
|
|
196
|
+
# !/project.log
|
|
197
|
+
|
|
198
|
+
|
|
199
|
+
# === Generic caches ===
|
|
200
|
+
|
|
201
|
+
# WHY: Generic caches are machine-local and should not be tracked.
|
|
202
|
+
.cache/
|
|
203
|
+
|
|
204
|
+
|
|
205
|
+
# === Generic bin (binary) folder ===
|
|
206
|
+
|
|
207
|
+
# WHY: The root-level bin directory contains generated executable or build output.
|
|
208
|
+
# NOTE: The leading slash limits this rule to the repository-root bin directory
|
|
209
|
+
# and avoids ignoring a nested source directory that happens to be named bin.
|
|
210
|
+
/bin/
|
|
211
|
+
|
|
212
|
+
|
|
213
|
+
# ============================================================
|
|
214
|
+
# === SECTION: PROJECT DOCS ===
|
|
215
|
+
# ============================================================
|
|
216
|
+
|
|
217
|
+
# WHY: Static site build output is generated from the documentation source.
|
|
218
|
+
# NOTE: Zensical uses site/ as the generated site output directory.
|
|
219
|
+
site/
|
|
220
|
+
|
|
221
|
+
# ============================================================
|
|
222
|
+
# === SECTION: PYTHON ===
|
|
223
|
+
# ============================================================
|
|
224
|
+
|
|
225
|
+
# === Python environments ===
|
|
226
|
+
|
|
227
|
+
# WHY: Virtual environments are machine-local and reproducible from project files.
|
|
228
|
+
.venv/
|
|
229
|
+
venv/
|
|
230
|
+
|
|
231
|
+
|
|
232
|
+
# === Python project state ===
|
|
233
|
+
|
|
234
|
+
# REQ: Do NOT git ignore .python-version.
|
|
235
|
+
# WHY: Commit .python-version to declare the Python version used by the project.
|
|
236
|
+
|
|
237
|
+
# REQ: Do NOT git ignore uv.lock.
|
|
238
|
+
# WHY: Commit uv.lock to preserve the resolved dependency environment and use it
|
|
239
|
+
# in CI/CD pipelines.
|
|
240
|
+
|
|
241
|
+
# WHY: Generated SCM version modules should not be tracked.
|
|
242
|
+
# NOTE: This recursive pattern works regardless of repository depth or package name.
|
|
243
|
+
**/src/**/_version.py
|
|
244
|
+
|
|
245
|
+
|
|
246
|
+
# === Python bytecode ===
|
|
247
|
+
|
|
248
|
+
# WHY: Python bytecode is generated automatically and is machine-specific.
|
|
249
|
+
*.pyc
|
|
250
|
+
*.pyd
|
|
251
|
+
*.pyo
|
|
252
|
+
__pycache__/
|
|
253
|
+
|
|
254
|
+
|
|
255
|
+
# === Python build and packaging artifacts ===
|
|
256
|
+
|
|
257
|
+
# WHY: Build and packaging artifacts are generated from project source.
|
|
258
|
+
*.egg
|
|
259
|
+
*.egg-info/
|
|
260
|
+
*.whl
|
|
261
|
+
.eggs/
|
|
262
|
+
build/
|
|
263
|
+
dist/
|
|
264
|
+
|
|
265
|
+
|
|
266
|
+
# === Python testing and coverage output ===
|
|
267
|
+
|
|
268
|
+
# WHY: Test and coverage reports are generated and can be reproduced.
|
|
269
|
+
.coverage
|
|
270
|
+
.coverage.*
|
|
271
|
+
.pytest_cache/
|
|
272
|
+
htmlcov/
|
|
273
|
+
coverage.xml
|
|
274
|
+
coverage.json
|
|
275
|
+
coverage.lcov
|
|
276
|
+
|
|
277
|
+
|
|
278
|
+
# === Python tooling caches ===
|
|
279
|
+
|
|
280
|
+
# WHY: Tooling caches improve local performance but should not be tracked.
|
|
281
|
+
.mypy_cache/
|
|
282
|
+
.pytype/
|
|
283
|
+
.ruff_cache/
|
|
284
|
+
.tox/
|
|
285
|
+
|
|
286
|
+
|
|
287
|
+
# === Python notebooks and marimo ===
|
|
288
|
+
|
|
289
|
+
# WHY: Jupyter notebook checkpoint state is generated.
|
|
290
|
+
.ipynb_checkpoints/
|
|
291
|
+
|
|
292
|
+
# REQ: Do NOT git ignore layouts/ when using marimo custom layouts.
|
|
293
|
+
# WHY: Marimo layout files are project source and should be version controlled.
|
|
294
|
+
|
|
295
|
+
# REQ: Do NOT git ignore public/ when it contains source assets or data
|
|
296
|
+
# used by marimo or WASM applications.
|
|
297
|
+
# WHY: These files may be required to reproduce or publish the application.
|
|
298
|
+
|
|
299
|
+
|
|
300
|
+
# ============================================================
|
|
301
|
+
# === SECTION: NODE ===
|
|
302
|
+
# ============================================================
|
|
303
|
+
# Some tooling and projects require Node.js and its dependencies.
|
|
304
|
+
|
|
305
|
+
# WHY: Node dependencies are restored from package-lock.json with npm ci.
|
|
306
|
+
node_modules/
|
|
307
|
+
|
|
308
|
+
# REQ: Do NOT git ignore package-lock.json.
|
|
309
|
+
# WHY: Commit package-lock.json to preserve reproducible Node dependency
|
|
310
|
+
# resolution and use it in CI/CD pipelines.
|
|
311
|
+
|
|
312
|
+
|
|
313
|
+
# === Node package-manager caches ===
|
|
314
|
+
|
|
315
|
+
# WHY: Package-manager caches are machine-local and should not be tracked.
|
|
316
|
+
.npm/
|
|
317
|
+
.pnpm-store/
|
|
318
|
+
.yarn/cache/
|
|
319
|
+
.yarn/unplugged/
|
|
320
|
+
.yarn/build-state.yml
|
|
321
|
+
.yarn/install-state.gz
|
|
322
|
+
|
|
323
|
+
# ============================================================
|
|
324
|
+
# === SECTION: TYPESCRIPT AND JAVASCRIPT ===
|
|
325
|
+
# ============================================================
|
|
326
|
+
|
|
327
|
+
# === TypeScript and JavaScript build output ===
|
|
328
|
+
|
|
329
|
+
# WHY: Compiled JavaScript output is generated from TypeScript source.
|
|
330
|
+
out/
|
|
331
|
+
|
|
332
|
+
# WHY: TypeScript incremental build metadata is generated.
|
|
333
|
+
*.tsbuildinfo
|
|
334
|
+
|
|
335
|
+
|
|
336
|
+
# === TypeScript and JavaScript tooling caches ===
|
|
337
|
+
|
|
338
|
+
# WHY: Tooling caches and generated coverage output should not be tracked.
|
|
339
|
+
.eslintcache
|
|
340
|
+
.nyc_output/
|
|
341
|
+
coverage/
|
|
342
|
+
|
|
343
|
+
|
|
344
|
+
# === VS Code extension test and package output ===
|
|
345
|
+
|
|
346
|
+
# WHY: VS Code extension test-host files are generated by @vscode/test-electron.
|
|
347
|
+
.vscode-test/
|
|
348
|
+
|
|
349
|
+
# WHY: VSIX packages are generated release artifacts.
|
|
350
|
+
*.vsix
|
|
351
|
+
|
|
352
|
+
# ============================================================
|
|
353
|
+
# === SECTION: COMPUTER-CHECKED MATHEMATICAL PROOFS (LEAN) ===
|
|
354
|
+
# ============================================================
|
|
355
|
+
|
|
356
|
+
# === Lean ===
|
|
357
|
+
|
|
358
|
+
# WHAT: Lean is a programming language and proof assistant used to
|
|
359
|
+
# express mathematical definitions, theorems, and proofs.
|
|
360
|
+
# It can also verify properties of software and logical systems.
|
|
361
|
+
# Lean checks whether formal proofs satisfy their stated rules.
|
|
362
|
+
#
|
|
363
|
+
# WHY: Lake, Lean's project and build tool, generates build files
|
|
364
|
+
# and downloads dependencies that do not need to be committed.
|
|
365
|
+
.lake/
|
|
366
|
+
lake-packages/
|
|
367
|
+
/docbuild/
|
|
368
|
+
|
|
369
|
+
|
|
370
|
+
# ============================================================
|
|
371
|
+
# === SECTION: CUSTOM GENERATED ARTIFACTS ===
|
|
372
|
+
# ============================================================
|
|
373
|
+
|
|
374
|
+
# === Generated files for supported repositories ===
|
|
375
|
+
|
|
376
|
+
# WHY: Generated analytics and guide-context artifacts should be rebuilt rather
|
|
377
|
+
# than committed.
|
|
378
|
+
# NOTE: These entries are harmless in repositories that do not generate them.
|
|
379
|
+
docs/assets/data/view-analytics.json
|
|
380
|
+
docs/assets/data/guide-context.json
|
|
381
|
+
# marimo WASM export; built at deploy time, not committed
|
|
382
|
+
docs/app/
|
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
<!-- markdownlint-disable MD024 -->
|
|
4
|
+
|
|
5
|
+
All notable changes to this project will be documented in this file.
|
|
6
|
+
|
|
7
|
+
The format is based on **[Keep a Changelog](https://keepachangelog.com/en/1.1.0/)**
|
|
8
|
+
and this project adheres to **[Semantic Versioning](https://semver.org/spec/v2.0.0.html)**.
|
|
9
|
+
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
## [Unreleased]
|
|
13
|
+
|
|
14
|
+
### Added
|
|
15
|
+
|
|
16
|
+
- Automatic resumption of bounded Gmail scans across invocations.
|
|
17
|
+
- Private SQLite checkpoints that commit metadata and cursor progress together.
|
|
18
|
+
- Explicit scan restart with private archives of earlier results.
|
|
19
|
+
- Partial/complete scan status and unavailable-message reports.
|
|
20
|
+
- Query and account identity checks, bounded read retries, and invalid-token diagnostics.
|
|
21
|
+
- Synthetic pagination, Ctrl+C, process-crash, deduplication, and large-inventory tests.
|
|
22
|
+
|
|
23
|
+
### Changed
|
|
24
|
+
|
|
25
|
+
- Scan inventory now accumulates unique records instead of replacing prior batches.
|
|
26
|
+
- Reports can read committed scan metadata even after interrupted CSV export.
|
|
27
|
+
- Sender discovery writes additions atomically while preserving existing decisions.
|
|
28
|
+
|
|
29
|
+
### Added
|
|
30
|
+
|
|
31
|
+
- Optional permanent sender approvals in `data/senders_always_delete.csv`.
|
|
32
|
+
- Approval source reporting and explicit keep/review conflict reports.
|
|
33
|
+
- Synthetic coverage for large lists, age boundaries, and final safety checks.
|
|
34
|
+
|
|
35
|
+
### Changed
|
|
36
|
+
|
|
37
|
+
- Refresh Gmail search exclusions before every Trash request.
|
|
38
|
+
- Apply configured dry-run to CLI restoration as well as cleanup.
|
|
39
|
+
|
|
40
|
+
### Fixed
|
|
41
|
+
|
|
42
|
+
- Protected sender report labels now show protection reasons instead of
|
|
43
|
+
undecided or trash decisions, while preserving saved sender decisions.
|
|
44
|
+
- Added synthetic regression coverage for workspace selection and protected
|
|
45
|
+
senders at candidate selection and the final pre-Trash check.
|
|
46
|
+
|
|
47
|
+
### Changed
|
|
48
|
+
|
|
49
|
+
- Separated published-user instructions in the README from source-checkout
|
|
50
|
+
and maintainer instructions in the development documentation.
|
|
51
|
+
|
|
52
|
+
### Added
|
|
53
|
+
|
|
54
|
+
- Permanent receipt protection with a default-enabled configuration setting.
|
|
55
|
+
- Decoded Subject matching for transactional records across Gmail categories.
|
|
56
|
+
- Receipt and invalid-metadata reports with separate sender summary counts.
|
|
57
|
+
- Final per-message metadata protection checks after cleanup confirmation.
|
|
58
|
+
- Offline tests for receipt formats, missing metadata, and changed candidates.
|
|
59
|
+
|
|
60
|
+
- CSV header examples and troubleshooting for preserved empty configuration.
|
|
61
|
+
- Explanation of successful local validation and the next OAuth setup step.
|
|
62
|
+
|
|
63
|
+
---
|
|
64
|
+
|
|
65
|
+
## [0.1.0] - 2026-11-14
|
|
66
|
+
|
|
67
|
+
### Added
|
|
68
|
+
|
|
69
|
+
- Local-first Gmail cleanup command-line application.
|
|
70
|
+
- `uvx tidy-gmail` entry point and configurable `--workspace` path.
|
|
71
|
+
- Windows and macOS workspace conventions.
|
|
72
|
+
- Workspace initialization that preserves existing configuration.
|
|
73
|
+
- Local configuration validation with `doctor`.
|
|
74
|
+
- Gmail OAuth authorization and metadata-only inspection.
|
|
75
|
+
- Persistent sender decisions and protected sender lists.
|
|
76
|
+
- Configurable protection for Gmail label IDs, own addresses,
|
|
77
|
+
and subject keywords.
|
|
78
|
+
- Sender discovery, inventory, and cleanup candidate reports.
|
|
79
|
+
- Dry-run defaults, live eligibility checks, and explicit
|
|
80
|
+
confirmation before moving messages to Gmail Trash.
|
|
81
|
+
- Durable audit logging and restoration of Inbox membership.
|
|
82
|
+
- Recovery support for interrupted restoration operations.
|
|
83
|
+
- Offline tests for classification, Gmail requests, cleanup,
|
|
84
|
+
and recovery.
|
|
85
|
+
- Workflow and local privacy documentation.
|
|
86
|
+
|
|
87
|
+
### Changed
|
|
88
|
+
|
|
89
|
+
- Standardized the protected sender filename as
|
|
90
|
+
`senders_protected.csv`.
|
|
91
|
+
- Separated authorization, inventory, classification, reporting,
|
|
92
|
+
cleanup, and restoration into dedicated modules.
|
|
93
|
+
- Made packaged templates the source of starter configuration.
|
|
94
|
+
|
|
95
|
+
### Fixed
|
|
96
|
+
|
|
97
|
+
- Restoration retries after untrashing succeeds but restoring
|
|
98
|
+
Inbox membership fails.
|
|
99
|
+
- Validation of an explicitly supplied zero cleanup limit.
|
|
100
|
+
- Stale documentation and lint errors.
|
|
101
|
+
|
|
102
|
+
---
|
|
103
|
+
|
|
104
|
+
## Notes on Versioning and Releases
|
|
105
|
+
|
|
106
|
+
- We use **SemVer**:
|
|
107
|
+
- **MAJOR** - breaking changes
|
|
108
|
+
- **MINOR** - backward-compatible
|
|
109
|
+
- **PATCH** - fixes, documentation, tooling
|
|
110
|
+
- Versions are driven by git tags. Tag `vX.Y.Z` to release.
|
|
111
|
+
- Docs are deployed per version tag and aliased to **latest**.
|
|
112
|
+
|
|
113
|
+
## Release Procedure (Required)
|
|
114
|
+
|
|
115
|
+
Follow these steps exactly when creating a new release.
|
|
116
|
+
|
|
117
|
+
### Task 1. Update release metadata (manual edits)
|
|
118
|
+
|
|
119
|
+
1. Update `CITATION.cff`: change `version` and `date-released`
|
|
120
|
+
2. Update `CHANGELOG.md`: move from unreleased, add entry, update links
|
|
121
|
+
3. Update `pyproject.toml`: update `[tool.hatch.version] fallback-version`
|
|
122
|
+
|
|
123
|
+
### Task 2. Validate
|
|
124
|
+
|
|
125
|
+
```shell
|
|
126
|
+
.\sit.ps1
|
|
127
|
+
|
|
128
|
+
# OR
|
|
129
|
+
|
|
130
|
+
uv self update
|
|
131
|
+
uv python install
|
|
132
|
+
uv lock --upgrade
|
|
133
|
+
uv sync
|
|
134
|
+
uv audit
|
|
135
|
+
|
|
136
|
+
# set up and run git hooks
|
|
137
|
+
uvx prek install --force
|
|
138
|
+
uvx prek update
|
|
139
|
+
|
|
140
|
+
git add -A
|
|
141
|
+
uvx prek run --all-files
|
|
142
|
+
# repeat if changes were made
|
|
143
|
+
uvx prek run --all-files
|
|
144
|
+
|
|
145
|
+
# run common chores
|
|
146
|
+
uv run ruff format .
|
|
147
|
+
uv run ruff check . --fix
|
|
148
|
+
uv run ty check
|
|
149
|
+
uv run python -m pytest
|
|
150
|
+
uv run python -m zensical build
|
|
151
|
+
|
|
152
|
+
uv run python -c "import shutil; from pathlib import Path; shutil.rmtree(Path('dist'), ignore_errors=True)"
|
|
153
|
+
|
|
154
|
+
uv build
|
|
155
|
+
uvx twine check dist/*
|
|
156
|
+
|
|
157
|
+
# update .github/workflows
|
|
158
|
+
uvx gha-tools autoupdate --pin=all --write .github/workflows
|
|
159
|
+
# check
|
|
160
|
+
uvx zizmor@latest .github/ --fix
|
|
161
|
+
# 1 informational or suppressed are still okay
|
|
162
|
+
|
|
163
|
+
uvx
|
|
164
|
+
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
### Task 3. Commit, push, tag
|
|
168
|
+
|
|
169
|
+
```shell
|
|
170
|
+
git add -A
|
|
171
|
+
git commit -m "Prepare X.Y.Z"
|
|
172
|
+
git push -u origin main
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
Verify actions run on GitHub. After success:
|
|
176
|
+
|
|
177
|
+
```shell
|
|
178
|
+
git tag vX.Y.Z -m "X.Y.Z"
|
|
179
|
+
git push origin vX.Y.Z
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
## Only As Needed (delete a tag)
|
|
183
|
+
|
|
184
|
+
```shell
|
|
185
|
+
git tag -d vX.Z.Y
|
|
186
|
+
git push origin :refs/tags/vX.Z.Y
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
## Links
|
|
190
|
+
|
|
191
|
+
[Unreleased]: https://github.com/analytics-toolworks/tidy-gmail/compare/v0.1.0...HEAD
|
|
192
|
+
[0.1.0]: https://github.com/analytics-toolworks/tidy-gmail/releases/tag/v0.1.0
|
|
193
|
+
|
|
194
|
+
<!-- markdownlint-enable MD024 -->
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
# ============================================================
|
|
2
|
+
# CITATION.cff (How to cite this project)
|
|
3
|
+
# ============================================================
|
|
4
|
+
# REQ: Professional open projects SHOULD include this file.
|
|
5
|
+
# USAGE: See https://citation-file-format.github.io/ for details.
|
|
6
|
+
# check with:
|
|
7
|
+
# uvx cffconvert --validate
|
|
8
|
+
|
|
9
|
+
cff-version: "1.2.0"
|
|
10
|
+
message: "If you use this project, please cite it using the information in CITATION.cff."
|
|
11
|
+
type: software
|
|
12
|
+
|
|
13
|
+
title: "tidy-gmail"
|
|
14
|
+
version: "0.1.0"
|
|
15
|
+
date-released: "2026-11-14"
|
|
16
|
+
|
|
17
|
+
authors:
|
|
18
|
+
- family-names: Case
|
|
19
|
+
given-names: Denise M.
|
|
20
|
+
orcid: "https://orcid.org/0000-0001-6165-7389"
|
|
21
|
+
affiliation: "Northwest Missouri State University, USA"
|
|
22
|
+
|
|
23
|
+
repository-code: "https://github.com/analytics-toolworks/tidy-gmail"
|
|
24
|
+
url: "https://github.com/analytics-toolworks/tidy-gmail"
|
|
25
|
+
license: MIT
|
|
26
|
+
|
|
27
|
+
abstract: |
|
|
28
|
+
tidy-gmail is an open-source, local-first Python command-line
|
|
29
|
+
utility for inspecting and cleaning Gmail accounts using
|
|
30
|
+
user-maintained configuration and explicit cleanup rules.
|
|
31
|
+
|
|
32
|
+
The project separates mailbox inspection, classification,
|
|
33
|
+
cleanup decisions, and execution. It is designed to preserve
|
|
34
|
+
personal correspondence, financial records, charitable
|
|
35
|
+
contribution receipts, and other potentially valuable messages
|
|
36
|
+
while identifying disposable email.
|
|
37
|
+
|
|
38
|
+
Configuration, credentials, audit records, and reports remain
|
|
39
|
+
under the user's control. The intended interface supports
|
|
40
|
+
inspection, dry-run evaluation, controlled movement to Gmail
|
|
41
|
+
Trash, and restoration.
|
|
42
|
+
|
|
43
|
+
keywords:
|
|
44
|
+
- gmail
|
|
45
|
+
- email
|
|
46
|
+
- email-cleanup
|
|
47
|
+
- email-organization
|
|
48
|
+
- automation
|
|
49
|
+
- privacy
|
|
50
|
+
- python
|
|
51
|
+
- command-line-tool
|
|
52
|
+
- uvx
|
|
53
|
+
- open-source
|
tidy_gmail-0.1.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Denise Case
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|