mcm-cli 1.4.1__py3-none-any.whl → 1.5.0__py3-none-any.whl
Sign up to get free protection for your applications and to get access to all the features.
- {mcm_cli-1.4.1.dist-info → mcm_cli-1.5.0.dist-info}/METADATA +1 -1
- {mcm_cli-1.4.1.dist-info → mcm_cli-1.5.0.dist-info}/RECORD +11 -11
- mcmcli/__main__.py +1 -1
- mcmcli/command/admin.py +3 -4
- mcmcli/command/campaign.py +45 -4
- mcmcli/data/campaign.py +19 -2
- {mcm_cli-1.4.1.dist-info → mcm_cli-1.5.0.dist-info}/LICENSE +0 -0
- {mcm_cli-1.4.1.dist-info → mcm_cli-1.5.0.dist-info}/NOTICE +0 -0
- {mcm_cli-1.4.1.dist-info → mcm_cli-1.5.0.dist-info}/WHEEL +0 -0
- {mcm_cli-1.4.1.dist-info → mcm_cli-1.5.0.dist-info}/entry_points.txt +0 -0
- {mcm_cli-1.4.1.dist-info → mcm_cli-1.5.0.dist-info}/top_level.txt +0 -0
@@ -1,18 +1,18 @@
|
|
1
1
|
mcmcli/__init__.py,sha256=-U6lMZ9_99IXAKwnqnYXYr6NcO6TSmG-kxewgvJjU4k,575
|
2
|
-
mcmcli/__main__.py,sha256=
|
2
|
+
mcmcli/__main__.py,sha256=yiI9lBAaJYM57lXTHPKr3teWqU_xF39ZHt52_E1hCN8,1844
|
3
3
|
mcmcli/logging.py,sha256=xjRS5ey1ONx_d34qB1Fetb_SwPysoh2hzNDuNAaYYWQ,1739
|
4
4
|
mcmcli/requests.py,sha256=IuySBQ8P_GoGF3f_TRysfgQNOhi2n9M84WK_eRXnoEU,2945
|
5
5
|
mcmcli/command/account.py,sha256=FWXmzOLj4rVLVLEv-w0eDVlQVrkONvR1UewZbcTDgE4,24994
|
6
|
-
mcmcli/command/admin.py,sha256=
|
6
|
+
mcmcli/command/admin.py,sha256=2GC0B3oqQsT5N5mHUyezgZvzPkB4-oGtddguOWfdLJs,15980
|
7
7
|
mcmcli/command/auth.py,sha256=Ak7ZNEskWPpMoeTJcbYlEpDBgzxn8N33Q2dNf67SsCs,2926
|
8
|
-
mcmcli/command/campaign.py,sha256=
|
8
|
+
mcmcli/command/campaign.py,sha256=wh6WU19dCw0NBTp521g5wK6_0GraviWZxxahIcSlD44,12364
|
9
9
|
mcmcli/command/config.py,sha256=08C5ftAvdvpQ26Z329LqhP8AxTI629LS7Ou6glzrRgw,4396
|
10
10
|
mcmcli/command/decision.py,sha256=iLvEDEa2k0LAgoXrOvcdn-HcFRo90E8Dxht_Ls9EGCY,8690
|
11
11
|
mcmcli/command/report.py,sha256=N8IMyDZ5QpY11-KkZG-n5_ZzEeh-ME5s2s3wrAKEGjY,5387
|
12
12
|
mcmcli/command/wallet.py,sha256=vG2rg7tPwGsV9YB7cpvkiocbqtB1reqXn7dmolFmzD4,11536
|
13
13
|
mcmcli/data/account.py,sha256=pe7tPapP6vlUD5D5L5Nh5k2bkWdYOK01Mpt5fBYFnJs,1782
|
14
14
|
mcmcli/data/account_user.py,sha256=27nQp52nMma5a3QszSJGqgq5Z0ivIb-nMZcZuhEgbEg,1328
|
15
|
-
mcmcli/data/campaign.py,sha256=
|
15
|
+
mcmcli/data/campaign.py,sha256=rbBbLt_5qrNXr8TM4nq5NtPqB0lJmtmINEAyepS7KJ4,2284
|
16
16
|
mcmcli/data/decision.py,sha256=bQ5j_PbPRSFa0sY5g9UVqdNzl_2epchcz1lHoDVuV90,2880
|
17
17
|
mcmcli/data/error.py,sha256=d6xa_jTXumlA0EzXy2PJQ86ajBb0Pm90fss9R3LuHUc,1094
|
18
18
|
mcmcli/data/item.py,sha256=Z2xTRhU8T4vyJADO0l6-XPyQXvb9DX_OAjExhSXpW2A,1091
|
@@ -23,10 +23,10 @@ mcmcli/data/seller.py,sha256=40SA7QekM3a3svDrDYLo_QYJ68VUxDO0KeGejJMp4k4,1004
|
|
23
23
|
mcmcli/data/token.py,sha256=11wtyLHCAZHu0LVbNDPa-yipcL6lenxoYIKEI58VzFs,1744
|
24
24
|
mcmcli/data/user_join_request.py,sha256=lXMO2hE_VpRg0JofVrYAVM82S-RLFkPrZk8-drvhoDI,1251
|
25
25
|
mcmcli/data/wallet.py,sha256=eMUi8N0vJdg_E10TPhSPoZkZtmIG7gHyqgabQ8C5Lg8,3217
|
26
|
-
mcm_cli-1.
|
27
|
-
mcm_cli-1.
|
28
|
-
mcm_cli-1.
|
29
|
-
mcm_cli-1.
|
30
|
-
mcm_cli-1.
|
31
|
-
mcm_cli-1.
|
32
|
-
mcm_cli-1.
|
26
|
+
mcm_cli-1.5.0.dist-info/LICENSE,sha256=RFhQPdSOiMTguUX7JSoIuTxA7HVzCbj_p8WU36HjUQQ,10947
|
27
|
+
mcm_cli-1.5.0.dist-info/METADATA,sha256=M_x0K3WbDKcyEmyXUI7dqa5VFHTH2rKSeT0VTrtFTxc,3056
|
28
|
+
mcm_cli-1.5.0.dist-info/NOTICE,sha256=Ldnl2MjRaXPxcldUdbI2NTybq60XAa2LowRhFrRTuiI,76
|
29
|
+
mcm_cli-1.5.0.dist-info/WHEEL,sha256=PZUExdf71Ui_so67QXpySuHtCi3-J3wvF4ORK6k_S8U,91
|
30
|
+
mcm_cli-1.5.0.dist-info/entry_points.txt,sha256=qTHAWZ-ejSiU4t11RYwtAU8ScqhQPDeMVTG9y4wMVLg,60
|
31
|
+
mcm_cli-1.5.0.dist-info/top_level.txt,sha256=sh7oqIaqLQlMtKHlxHHgpV2xGMrBMPFWpSp0C6nvJ_Y,7
|
32
|
+
mcm_cli-1.5.0.dist-info/RECORD,,
|
mcmcli/__main__.py
CHANGED
@@ -37,7 +37,7 @@ def version():
|
|
37
37
|
"""
|
38
38
|
Show the tool version
|
39
39
|
"""
|
40
|
-
typer.echo(f"Version: mcm-cli v1.
|
40
|
+
typer.echo(f"Version: mcm-cli v1.5.0")
|
41
41
|
|
42
42
|
app.add_typer(mcmcli.command.account.app, name="account", help="Ad account management")
|
43
43
|
app.add_typer(mcmcli.command.admin.app, name="admin", help="Platform administration")
|
mcmcli/command/admin.py
CHANGED
@@ -68,7 +68,7 @@ def list_all_campaigns(
|
|
68
68
|
print(error, file=sys.stderr, flush=True)
|
69
69
|
return
|
70
70
|
|
71
|
-
print("Account
|
71
|
+
print("Account ID,Account Title,Campaign ID,Campaign Title,Ad Type,Start,End,Budget Period,Budget Amount,Enabling State,State,Created At,Updated At")
|
72
72
|
for account_campaign in account_campaigns:
|
73
73
|
a, c = account_campaign
|
74
74
|
|
@@ -78,7 +78,8 @@ def list_all_campaigns(
|
|
78
78
|
print(f'"{c.budget.period}","{int(c.budget.amount.amount_micro) / 1000000}",', end="", flush=True)
|
79
79
|
print(f'"{c.enabling_state}","{c.state}",', end="", flush=True)
|
80
80
|
print(f'"{c.created_at}","{c.updated_at}",', end="", flush=True)
|
81
|
-
print(f'"{";".join(c.catalog_item_ids)}"')
|
81
|
+
# print(f'"{";".join(c.catalog_item_ids)}"')
|
82
|
+
print("", flush=True)
|
82
83
|
|
83
84
|
@app.command()
|
84
85
|
def list_platform_users(
|
@@ -404,8 +405,6 @@ class AdminCommand:
|
|
404
405
|
for id in accounts:
|
405
406
|
account = accounts[id]
|
406
407
|
echo('.')
|
407
|
-
if account.state_info.state == "INACTIVE":
|
408
|
-
continue
|
409
408
|
# print(f'{account.id}, \"{account.title}\"')
|
410
409
|
_, error, campaigns = cc.list_campaigns(account.id)
|
411
410
|
if error:
|
mcmcli/command/campaign.py
CHANGED
@@ -51,7 +51,7 @@ def list_campaigns(
|
|
51
51
|
print(curl)
|
52
52
|
return
|
53
53
|
if error:
|
54
|
-
print(f"ERROR: {error.message}")
|
54
|
+
print(f"ERROR: {error.message}", file=sys.stderr, flush=True)
|
55
55
|
return
|
56
56
|
if to_json:
|
57
57
|
json_dumps = [x.model_dump_json() for x in campaigns]
|
@@ -103,6 +103,47 @@ def read_campaign(
|
|
103
103
|
|
104
104
|
return
|
105
105
|
|
106
|
+
@app.command()
|
107
|
+
def archive_campaign(
|
108
|
+
account_id: str = typer.Option(help="Ad account ID"),
|
109
|
+
campaign_id: str = typer.Option(help="Campaign ID"),
|
110
|
+
profile: str = typer.Option("default", help="Profile name of the MCM CLI."),
|
111
|
+
):
|
112
|
+
"""
|
113
|
+
Turn off (pause and disable) the campaign and archive it.
|
114
|
+
"""
|
115
|
+
c = _create_campaign_command(profile)
|
116
|
+
if c is None:
|
117
|
+
return
|
118
|
+
|
119
|
+
_, error, campaign = c.read_campaign(account_id, campaign_id)
|
120
|
+
if error:
|
121
|
+
print(f"ERROR: Failed to read the campaign {campaign_id} of the ad account {account_id}: {error.message}", file=sys.stderr, flush=True)
|
122
|
+
return
|
123
|
+
|
124
|
+
if campaign.state == 'ARCHIVED':
|
125
|
+
print(f"The campaign {campaign_id} of the ad account {account_id} is already archived.")
|
126
|
+
return
|
127
|
+
|
128
|
+
# Turn off the campaign
|
129
|
+
campaign.enabling_state = 'DISABLED'
|
130
|
+
campaign.state = 'PAUSED'
|
131
|
+
#campaign.daily_budget.amount_micro = (campaign.daily_budget.amount_micro // 10000) * 10000
|
132
|
+
_, error, campaign = c.update_campaign(campaign)
|
133
|
+
if error:
|
134
|
+
print(f"ERROR: Failed to turn off the campaign {campaign_id} of the ad account {account_id}: {error.message}", file=sys.stderr, flush=True)
|
135
|
+
return
|
136
|
+
|
137
|
+
# Archive the campaign
|
138
|
+
campaign.hidden = True
|
139
|
+
campaign.state = 'ARCHIVED'
|
140
|
+
_, error, campaign = c.update_campaign(campaign)
|
141
|
+
if error:
|
142
|
+
print(f"ERROR: Failed to archive the campaign {campaign_id} of the ad account {account_id}: {error.message}", file=sys.stderr, flush=True)
|
143
|
+
return
|
144
|
+
|
145
|
+
print(f"Archived the campaign {campaign_id} of the ad account {account_id}.")
|
146
|
+
|
106
147
|
@app.command()
|
107
148
|
def list_campaign_items(
|
108
149
|
account_id: str = typer.Option(help="Ad account ID"),
|
@@ -124,7 +165,7 @@ def list_campaign_items(
|
|
124
165
|
print(curl)
|
125
166
|
return
|
126
167
|
if error:
|
127
|
-
print(f"ERROR: {error.message}")
|
168
|
+
print(f"ERROR: {error.message}", file=sys.stderr, flush=True)
|
128
169
|
return
|
129
170
|
if to_json:
|
130
171
|
json_dumps = [x.model_dump_json() for x in items]
|
@@ -156,7 +197,7 @@ def add_items_to_campaign(
|
|
156
197
|
|
157
198
|
_, error, campaign = c.read_campaign(account_id, campaign_id)
|
158
199
|
if error:
|
159
|
-
print(f"ERROR: {error.message}")
|
200
|
+
print(f"ERROR: {error.message}", file=sys.stderr, flush=True)
|
160
201
|
return
|
161
202
|
|
162
203
|
#
|
@@ -173,7 +214,7 @@ def add_items_to_campaign(
|
|
173
214
|
print(curl)
|
174
215
|
return
|
175
216
|
if error:
|
176
|
-
print(f"ERROR: {error.message}")
|
217
|
+
print(f"ERROR: {error.message}", file=sys.stderr, flush=True)
|
177
218
|
return
|
178
219
|
if to_json:
|
179
220
|
print(campaign.model_dump_json())
|
mcmcli/data/campaign.py
CHANGED
@@ -20,7 +20,7 @@ from typing import Optional
|
|
20
20
|
#
|
21
21
|
class MicroPrice(BaseModel):
|
22
22
|
currency: str
|
23
|
-
amount_micro:
|
23
|
+
amount_micro: int
|
24
24
|
|
25
25
|
class Schedule(BaseModel):
|
26
26
|
start: str
|
@@ -41,6 +41,23 @@ class Goal(BaseModel):
|
|
41
41
|
optimize_fixed_cpc: Optional[TargetCpc] = None
|
42
42
|
optimize_roas: Optional[TargetRoas] = None
|
43
43
|
|
44
|
+
class TargetingEvent(BaseModel):
|
45
|
+
event_type: str
|
46
|
+
matching_param: Optional[str] = None
|
47
|
+
negative: bool
|
48
|
+
matching_date: Optional[str] = None
|
49
|
+
|
50
|
+
class AudienceSetting(BaseModel):
|
51
|
+
event_based: Optional[list[TargetingEvent]] = None
|
52
|
+
label: Optional[str] = None
|
53
|
+
event_based_include_list: Optional[list[str]] = None
|
54
|
+
event_based_exclude_list: Optional[list[str]] = None
|
55
|
+
|
56
|
+
class Targeting(BaseModel):
|
57
|
+
campaign_targeting_placement_type: str
|
58
|
+
placement_setting: Optional[str]
|
59
|
+
audience_setting: Optional[AudienceSetting]
|
60
|
+
|
44
61
|
class Campaign(BaseModel):
|
45
62
|
id: str
|
46
63
|
title: str
|
@@ -52,7 +69,7 @@ class Campaign(BaseModel):
|
|
52
69
|
schedule: Schedule
|
53
70
|
daily_budget: MicroPrice
|
54
71
|
budget: Budget
|
55
|
-
targeting: Optional[
|
72
|
+
targeting: Optional[Targeting]
|
56
73
|
managed_setting: Optional[str]
|
57
74
|
text_entry: str
|
58
75
|
goal: Goal
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|