freemyid 0.2.0.dev1__py3-none-any.whl
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.
- freemyid/__init__.py +2 -0
- freemyid/_data/brokers/LICENSE-DATA.md +28 -0
- freemyid/_data/brokers/registry.sample.yaml +674 -0
- freemyid/_data/brokers/state_laws.yaml +448 -0
- freemyid/_data/schema/registry.schema.json +668 -0
- freemyid/_data/schema/setup-config.schema.json +538 -0
- freemyid/_data/schema/state_laws.schema.json +222 -0
- freemyid/cli.py +725 -0
- freemyid/cli_json.py +198 -0
- freemyid/config.py +43 -0
- freemyid/consent.py +82 -0
- freemyid/crypto.py +197 -0
- freemyid/doctor.py +374 -0
- freemyid/engine/__init__.py +0 -0
- freemyid/engine/_dev/__init__.py +101 -0
- freemyid/engine/_dev/devrun.py +101 -0
- freemyid/engine/_dev/inbox/devauto.eml +7 -0
- freemyid/engine/_dev/registry.yaml +106 -0
- freemyid/engine/_dev/site/devauto.example/confirm.html +1 -0
- freemyid/engine/_dev/site/devauto.example/name/jane-testperson/il.html +17 -0
- freemyid/engine/_dev/site/devauto.example/name/jane-testperson/nc.html +4 -0
- freemyid/engine/_dev/site/devauto.example/name/jane-testperson/oh.html +4 -0
- freemyid/engine/_dev/site/devauto.example/optout/done.html +1 -0
- freemyid/engine/_dev/site/devauto.example/optout.html +6 -0
- freemyid/engine/_dev/site/devblocked.example/name/jane-testperson/il.html +3 -0
- freemyid/engine/_dev/site/devblocked.example/optout.html +3 -0
- freemyid/engine/_dev/site/devfill.example/ajax.html +20 -0
- freemyid/engine/_dev/site/devfill.example/aria.html +16 -0
- freemyid/engine/_dev/site/devfill.example/consent.html +20 -0
- freemyid/engine/_dev/site/devfill.example/done.html +3 -0
- freemyid/engine/_dev/site/devfill.example/empty.html +1 -0
- freemyid/engine/_dev/site/devfill.example/fullname.html +12 -0
- freemyid/engine/_dev/site/devfill.example/labels.html +32 -0
- freemyid/engine/_dev/site/devfill.example/late.html +22 -0
- freemyid/engine/_dev/site/devfind.example/hostile.html +12 -0
- freemyid/engine/_dev/site/devfind.example/p/jane-testperson-shelbyville-il.html +6 -0
- freemyid/engine/_dev/site/devfind.example/p/jane-testperson-springfield-il.html +6 -0
- freemyid/engine/_dev/site/devfind.example/results.html +11 -0
- freemyid/engine/_dev/site/devfind.example/search.html +16 -0
- freemyid/engine/_dev/site/devweb.example/remove.html +1 -0
- freemyid/engine/browser.py +430 -0
- freemyid/engine/fill_for_me.py +630 -0
- freemyid/engine/filler.py +523 -0
- freemyid/engine/handoff.py +237 -0
- freemyid/engine/letters.py +125 -0
- freemyid/engine/listing_finder.py +538 -0
- freemyid/engine/mail.py +406 -0
- freemyid/engine/mail_tls.py +198 -0
- freemyid/engine/matcher.py +208 -0
- freemyid/engine/outbox.py +421 -0
- freemyid/engine/plugins.py +68 -0
- freemyid/engine/runner.py +791 -0
- freemyid/engine/tiers.py +107 -0
- freemyid/interfaces.py +164 -0
- freemyid/logging_setup.py +152 -0
- freemyid/models.py +700 -0
- freemyid/netpolicy.py +145 -0
- freemyid/notify.py +58 -0
- freemyid/paths.py +83 -0
- freemyid/registry.py +275 -0
- freemyid/scheduler/__init__.py +203 -0
- freemyid/scheduler/render.py +91 -0
- freemyid/secret_backends.py +562 -0
- freemyid/secrets.py +25 -0
- freemyid/setup_config.py +311 -0
- freemyid/state.py +151 -0
- freemyid/storage/__init__.py +3 -0
- freemyid/storage/db.py +394 -0
- freemyid/submitters/__init__.py +0 -0
- freemyid/submitters/assisted.py +171 -0
- freemyid/submitters/base.py +119 -0
- freemyid/submitters/email.py +40 -0
- freemyid/submitters/web_form.py +276 -0
- freemyid/templates/_identity.txt.j2 +19 -0
- freemyid/templates/_signature.txt.j2 +7 -0
- freemyid/templates/ccpa.txt.j2 +16 -0
- freemyid/templates/follow_up.txt.j2 +15 -0
- freemyid/templates/generic_removal.txt.j2 +12 -0
- freemyid/templates/legal_demand.txt.j2 +20 -0
- freemyid/templates/phone_script.txt.j2 +25 -0
- freemyid/templates/postal_letter.txt.j2 +20 -0
- freemyid/templates/state_privacy.txt.j2 +17 -0
- freemyid/wizard/__init__.py +0 -0
- freemyid/wizard/dashboard.py +401 -0
- freemyid/wizard/desktop.py +188 -0
- freemyid/wizard/draft.py +627 -0
- freemyid/wizard/firstrun.py +42 -0
- freemyid/wizard/flows.py +283 -0
- freemyid/wizard/report.py +86 -0
- freemyid/wizard/server.py +834 -0
- freemyid/wizard/static/__init__.py +0 -0
- freemyid/wizard/static/app.js +98 -0
- freemyid/wizard/static/freemyid.png +0 -0
- freemyid/wizard/static/style.css +85 -0
- freemyid/wizard/ui.py +343 -0
- freemyid-0.2.0.dev1.dist-info/METADATA +396 -0
- freemyid-0.2.0.dev1.dist-info/RECORD +100 -0
- freemyid-0.2.0.dev1.dist-info/WHEEL +4 -0
- freemyid-0.2.0.dev1.dist-info/entry_points.txt +2 -0
- freemyid-0.2.0.dev1.dist-info/licenses/LICENSE +661 -0
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
"""Submitter lookup (order from interfaces.Submitter):
|
|
2
|
+
|
|
3
|
+
1. broker.submitter 'freemyid.submitters.<module>:<Class>' (namespace enforced by the model)
|
|
4
|
+
2. entry point group 'freemyid.submitters' keyed by broker id
|
|
5
|
+
3. module freemyid.submitters.<broker_id> with a class named `Submitter`
|
|
6
|
+
4. generic by tier: AUTOMATIC -> WebFormSubmitter, EMAIL -> EmailSubmitter,
|
|
7
|
+
ASSISTED -> AssistedSubmitter
|
|
8
|
+
|
|
9
|
+
v1 ships no per-broker modules (PLAN_V1 D1). Steps 1-3 stay for later exceptions.
|
|
10
|
+
"""
|
|
11
|
+
from __future__ import annotations
|
|
12
|
+
|
|
13
|
+
import importlib
|
|
14
|
+
import logging
|
|
15
|
+
from importlib.metadata import entry_points
|
|
16
|
+
|
|
17
|
+
from ..interfaces import Submitter
|
|
18
|
+
from ..models import Broker, Tier
|
|
19
|
+
|
|
20
|
+
log = logging.getLogger(__name__)
|
|
21
|
+
|
|
22
|
+
_GENERIC_NAMES = {"base", "assisted", "email", "web_form"}
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
def _instantiate(obj: object) -> Submitter | None:
|
|
26
|
+
if isinstance(obj, type) and issubclass(obj, Submitter):
|
|
27
|
+
return obj()
|
|
28
|
+
return None
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
def custom_submitter(broker: Broker) -> Submitter | None:
|
|
32
|
+
if broker.submitter:
|
|
33
|
+
mod, _, cls = broker.submitter.partition(":")
|
|
34
|
+
try:
|
|
35
|
+
return _instantiate(getattr(importlib.import_module(mod), cls))
|
|
36
|
+
except (ImportError, AttributeError) as e:
|
|
37
|
+
log.warning("custom submitter for %s unavailable: %s", broker.id, type(e).__name__)
|
|
38
|
+
try:
|
|
39
|
+
for ep in entry_points(group="freemyid.submitters"):
|
|
40
|
+
if ep.name == broker.id:
|
|
41
|
+
return _instantiate(ep.load())
|
|
42
|
+
except Exception as e: # noqa: BLE001 - a broken plugin must not stop the run
|
|
43
|
+
log.warning("entry point for %s failed: %s", broker.id, type(e).__name__)
|
|
44
|
+
if broker.id not in _GENERIC_NAMES:
|
|
45
|
+
try:
|
|
46
|
+
module = importlib.import_module(f"freemyid.submitters.{broker.id}")
|
|
47
|
+
return _instantiate(getattr(module, "Submitter", None))
|
|
48
|
+
except ImportError:
|
|
49
|
+
pass
|
|
50
|
+
return None
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
def generic_submitter(tier: Tier) -> Submitter:
|
|
54
|
+
if tier == Tier.AUTOMATIC:
|
|
55
|
+
from ..submitters.web_form import WebFormSubmitter
|
|
56
|
+
return WebFormSubmitter()
|
|
57
|
+
if tier == Tier.EMAIL:
|
|
58
|
+
from ..submitters.email import EmailSubmitter
|
|
59
|
+
return EmailSubmitter()
|
|
60
|
+
from ..submitters.assisted import AssistedSubmitter
|
|
61
|
+
return AssistedSubmitter()
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
def get_submitter(broker: Broker, tier: Tier) -> Submitter:
|
|
65
|
+
"""Custom submitters only apply to the Automatic tier; others use the generic path."""
|
|
66
|
+
if tier == Tier.AUTOMATIC and (custom := custom_submitter(broker)):
|
|
67
|
+
return custom
|
|
68
|
+
return generic_submitter(tier)
|