Skip to content

Commit 89ea62f

Browse files
committed
feat: add Phase 2 resources - forms, companies, notes, stages, assets, tags, categories, pages, webhooks, fields, reports, points
12 new command modules with full test coverage (117 tests total). All endpoints validated against live Mautic 6.0.6 and official API docs.
1 parent 7829b18 commit 89ea62f

26 files changed

Lines changed: 1336 additions & 2 deletions

src/mautic_cli/commands/__init__.py

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,33 @@ def register_commands(cli):
88
from mautic_cli.commands.emails import emails
99
from mautic_cli.commands.campaigns import campaigns
1010
from mautic_cli.commands.auth_cmd import auth
11+
from mautic_cli.commands.forms import forms
12+
from mautic_cli.commands.companies import companies
13+
from mautic_cli.commands.notes import notes
14+
from mautic_cli.commands.stages import stages
15+
from mautic_cli.commands.assets import assets
16+
from mautic_cli.commands.tags import tags
17+
from mautic_cli.commands.categories import categories
18+
from mautic_cli.commands.pages import pages
19+
from mautic_cli.commands.webhooks import webhooks
20+
from mautic_cli.commands.fields import fields
21+
from mautic_cli.commands.reports import reports
22+
from mautic_cli.commands.points import points
1123

1224
cli.add_command(contacts)
1325
cli.add_command(segments)
1426
cli.add_command(emails)
1527
cli.add_command(campaigns)
1628
cli.add_command(auth)
29+
cli.add_command(forms)
30+
cli.add_command(companies)
31+
cli.add_command(notes)
32+
cli.add_command(stages)
33+
cli.add_command(assets)
34+
cli.add_command(tags)
35+
cli.add_command(categories)
36+
cli.add_command(pages)
37+
cli.add_command(webhooks)
38+
cli.add_command(fields)
39+
cli.add_command(reports)
40+
cli.add_command(points)

src/mautic_cli/commands/assets.py

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
from __future__ import annotations
2+
3+
import click
4+
5+
from mautic_cli.context import pass_context, MauticContext
6+
from mautic_cli.client import MauticApiError
7+
8+
9+
@click.group()
10+
def assets():
11+
"""Manage Mautic assets."""
12+
13+
14+
@assets.command("list")
15+
@click.option("--search", default=None, help="Mautic search string.")
16+
@click.option("--limit", default=30, type=int)
17+
@click.option("--offset", default=0, type=int)
18+
@pass_context
19+
def list_assets(mctx: MauticContext, search, limit, offset):
20+
"""List assets."""
21+
params = {"limit": limit, "start": offset}
22+
if search:
23+
params["search"] = search
24+
if mctx.published_only:
25+
params["search"] = ((params.get("search") or "") + " is:published").strip()
26+
try:
27+
data = mctx.client.get("/assets", params=params)
28+
mctx.output_list(data, "assets")
29+
except MauticApiError as e:
30+
mctx.error(e)
31+
raise SystemExit(1)
32+
33+
34+
@assets.command()
35+
@click.argument("id", type=int)
36+
@pass_context
37+
def get(mctx: MauticContext, id):
38+
"""Get an asset by ID."""
39+
try:
40+
data = mctx.client.get(f"/assets/{id}")
41+
mctx.output_single(data, "asset")
42+
except MauticApiError as e:
43+
mctx.error(e)
44+
raise SystemExit(1)
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
from __future__ import annotations
2+
3+
import click
4+
5+
from mautic_cli.context import pass_context, MauticContext
6+
from mautic_cli.client import MauticApiError
7+
from mautic_cli.json_input import parse_json_input
8+
9+
10+
@click.group()
11+
def categories():
12+
"""Manage Mautic categories."""
13+
14+
15+
@categories.command("list")
16+
@click.option("--search", default=None, help="Mautic search string.")
17+
@click.option("--limit", default=30, type=int)
18+
@click.option("--offset", default=0, type=int)
19+
@click.option("--bundle", default=None, help="Filter by bundle type (e.g. email, asset).")
20+
@pass_context
21+
def list_categories(mctx: MauticContext, search, limit, offset, bundle):
22+
"""List categories."""
23+
params = {"limit": limit, "start": offset}
24+
if search:
25+
params["search"] = search
26+
if mctx.published_only:
27+
params["search"] = ((params.get("search") or "") + " is:published").strip()
28+
if bundle:
29+
params["bundle"] = bundle
30+
try:
31+
data = mctx.client.get("/categories", params=params)
32+
mctx.output_list(data, "categories")
33+
except MauticApiError as e:
34+
mctx.error(e)
35+
raise SystemExit(1)
36+
37+
38+
@categories.command()
39+
@click.option("--json", "json_str", required=True, help="JSON data or @file.")
40+
@pass_context
41+
def create(mctx: MauticContext, json_str):
42+
"""Create a new category."""
43+
try:
44+
payload = parse_json_input(json_str)
45+
data = mctx.client.post("/categories/new", json=payload)
46+
mctx.output(data)
47+
except MauticApiError as e:
48+
mctx.error(e)
49+
raise SystemExit(1)
Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
from __future__ import annotations
2+
3+
import click
4+
5+
from mautic_cli.context import pass_context, MauticContext
6+
from mautic_cli.client import MauticApiError
7+
from mautic_cli.json_input import parse_json_input
8+
9+
10+
@click.group()
11+
def companies():
12+
"""Manage Mautic companies."""
13+
14+
15+
@companies.command("list")
16+
@click.option("--search", default=None, help="Mautic search string.")
17+
@click.option("--limit", default=30, type=int)
18+
@click.option("--offset", default=0, type=int)
19+
@pass_context
20+
def list_companies(mctx: MauticContext, search, limit, offset):
21+
"""List companies."""
22+
params = {"limit": limit, "start": offset}
23+
if search:
24+
params["search"] = search
25+
if mctx.published_only:
26+
params["search"] = ((params.get("search") or "") + " is:published").strip()
27+
try:
28+
data = mctx.client.get("/companies", params=params)
29+
mctx.output_list(data, "companies")
30+
except MauticApiError as e:
31+
mctx.error(e)
32+
raise SystemExit(1)
33+
34+
35+
@companies.command()
36+
@click.argument("id", type=int)
37+
@pass_context
38+
def get(mctx: MauticContext, id):
39+
"""Get a company by ID."""
40+
try:
41+
data = mctx.client.get(f"/companies/{id}")
42+
mctx.output_single(data, "company")
43+
except MauticApiError as e:
44+
mctx.error(e)
45+
raise SystemExit(1)
46+
47+
48+
@companies.command()
49+
@click.option("--json", "json_str", required=True, help="JSON data or @file.")
50+
@pass_context
51+
def create(mctx: MauticContext, json_str):
52+
"""Create a new company."""
53+
try:
54+
payload = parse_json_input(json_str)
55+
data = mctx.client.post("/companies/new", json=payload)
56+
mctx.output(data)
57+
except MauticApiError as e:
58+
mctx.error(e)
59+
raise SystemExit(1)
60+
61+
62+
@companies.command()
63+
@click.argument("id", type=int)
64+
@click.option("--json", "json_str", required=True, help="JSON data or @file.")
65+
@pass_context
66+
def edit(mctx: MauticContext, id, json_str):
67+
"""Edit a company."""
68+
try:
69+
payload = parse_json_input(json_str)
70+
data = mctx.client.patch(f"/companies/{id}/edit", json=payload)
71+
mctx.output(data)
72+
except MauticApiError as e:
73+
mctx.error(e)
74+
raise SystemExit(1)
75+
76+
77+
@companies.command()
78+
@click.argument("id", type=int)
79+
@pass_context
80+
def delete(mctx: MauticContext, id):
81+
"""Delete a company."""
82+
try:
83+
data = mctx.client.delete(f"/companies/{id}/delete")
84+
mctx.output(data)
85+
except MauticApiError as e:
86+
mctx.error(e)
87+
raise SystemExit(1)
88+
89+
90+
@companies.command("add-contact")
91+
@click.argument("company_id", type=int)
92+
@click.argument("contact_id", type=int)
93+
@pass_context
94+
def add_contact(mctx: MauticContext, company_id, contact_id):
95+
"""Add a contact to a company."""
96+
try:
97+
data = mctx.client.post(f"/companies/{company_id}/contact/{contact_id}/add")
98+
mctx.output(data)
99+
except MauticApiError as e:
100+
mctx.error(e)
101+
raise SystemExit(1)
102+
103+
104+
@companies.command("remove-contact")
105+
@click.argument("company_id", type=int)
106+
@click.argument("contact_id", type=int)
107+
@pass_context
108+
def remove_contact(mctx: MauticContext, company_id, contact_id):
109+
"""Remove a contact from a company."""
110+
try:
111+
data = mctx.client.post(f"/companies/{company_id}/contact/{contact_id}/remove")
112+
mctx.output(data)
113+
except MauticApiError as e:
114+
mctx.error(e)
115+
raise SystemExit(1)

src/mautic_cli/commands/fields.py

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
from __future__ import annotations
2+
3+
import click
4+
5+
from mautic_cli.context import pass_context, MauticContext
6+
from mautic_cli.client import MauticApiError
7+
from mautic_cli.json_input import parse_json_input
8+
9+
10+
@click.group()
11+
def fields():
12+
"""Manage Mautic custom fields."""
13+
14+
15+
@fields.command("list")
16+
@click.option("--search", default=None, help="Mautic search string.")
17+
@click.option("--limit", default=30, type=int)
18+
@click.option("--offset", default=0, type=int)
19+
@pass_context
20+
def list_fields(mctx: MauticContext, search, limit, offset):
21+
"""List custom fields."""
22+
params = {"limit": limit, "start": offset}
23+
if search:
24+
params["search"] = search
25+
if mctx.published_only:
26+
params["search"] = ((params.get("search") or "") + " is:published").strip()
27+
try:
28+
data = mctx.client.get("/fields/contact", params=params)
29+
mctx.output_list(data, "fields")
30+
except MauticApiError as e:
31+
mctx.error(e)
32+
raise SystemExit(1)
33+
34+
35+
@fields.command()
36+
@click.option("--json", "json_str", required=True, help="JSON data or @file.")
37+
@pass_context
38+
def create(mctx: MauticContext, json_str):
39+
"""Create a new custom field."""
40+
try:
41+
payload = parse_json_input(json_str)
42+
data = mctx.client.post("/fields/contact/new", json=payload)
43+
mctx.output(data)
44+
except MauticApiError as e:
45+
mctx.error(e)
46+
raise SystemExit(1)

src/mautic_cli/commands/forms.py

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
from __future__ import annotations
2+
3+
import click
4+
5+
from mautic_cli.context import pass_context, MauticContext
6+
from mautic_cli.client import MauticApiError
7+
8+
9+
@click.group()
10+
def forms():
11+
"""Manage Mautic forms."""
12+
13+
14+
@forms.command("list")
15+
@click.option("--search", default=None, help="Mautic search string.")
16+
@click.option("--limit", default=30, type=int)
17+
@click.option("--offset", default=0, type=int)
18+
@pass_context
19+
def list_forms(mctx: MauticContext, search, limit, offset):
20+
"""List forms."""
21+
params = {"limit": limit, "start": offset}
22+
if search:
23+
params["search"] = search
24+
if mctx.published_only:
25+
params["search"] = ((params.get("search") or "") + " is:published").strip()
26+
try:
27+
data = mctx.client.get("/forms", params=params)
28+
mctx.output_list(data, "forms")
29+
except MauticApiError as e:
30+
mctx.error(e)
31+
raise SystemExit(1)
32+
33+
34+
@forms.command()
35+
@click.argument("id", type=int)
36+
@pass_context
37+
def get(mctx: MauticContext, id):
38+
"""Get a form by ID."""
39+
try:
40+
data = mctx.client.get(f"/forms/{id}")
41+
mctx.output_single(data, "form")
42+
except MauticApiError as e:
43+
mctx.error(e)
44+
raise SystemExit(1)
45+
46+
47+
@forms.command()
48+
@click.argument("id", type=int)
49+
@click.option("--limit", default=30, type=int)
50+
@pass_context
51+
def submissions(mctx: MauticContext, id, limit):
52+
"""List form submissions."""
53+
try:
54+
data = mctx.client.get(f"/forms/{id}/submissions", params={"limit": limit})
55+
mctx.output(data)
56+
except MauticApiError as e:
57+
mctx.error(e)
58+
raise SystemExit(1)
59+
60+
61+
@forms.command()
62+
@click.argument("id", type=int)
63+
@pass_context
64+
def delete(mctx: MauticContext, id):
65+
"""Delete a form."""
66+
try:
67+
data = mctx.client.delete(f"/forms/{id}/delete")
68+
mctx.output(data)
69+
except MauticApiError as e:
70+
mctx.error(e)
71+
raise SystemExit(1)

0 commit comments

Comments
 (0)