mktgtech commited on
Commit
23032a8
·
verified ·
1 Parent(s): 937e7cc

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +29 -40
app.py CHANGED
@@ -101,79 +101,48 @@ def apply_business_logic(df):
101
  if "lead_quality_score" in df.columns:
102
  df["Quality_Group"] = df["lead_quality_score"].apply(categorize_quality)
103
 
104
- # 2. Campaign Logic (Hybrid Strict Match)
105
  rules = load_campaign_rules()
106
 
107
  def resolve_campaign(row):
108
- # Clean path to be safe
109
- path = str(row.get("landing_page_path", "")).strip().lower()
110
-
111
- # SCENARIO 1: We HAVE a specific landing page path (e.g., /blog/..., /services/...)
112
- # We strictly enforce keyword matching here to avoid generic pages getting grouped.
113
- if path and path not in ["", "/", "/home", "nan", "none"]:
114
  match = get_campaign_match(path, rules)
115
- return match if match else "Uncategorized"
116
-
117
- # SCENARIO 2: The path is missing (unenriched preview) OR it's a generic Homepage
118
- # Here we fallback to website and industry so your dashboard actually populates!
119
- website = str(row.get("website_url", "")).strip().lower()
120
- industry = str(row.get("primary_industry", "")).strip().lower()
121
-
122
- match = get_campaign_match(website, rules)
123
- if match: return match
124
-
125
- match = get_campaign_match(industry, rules)
126
- if match: return match
127
-
128
  return "Uncategorized"
129
-
130
  df["Campaign"] = df.apply(resolve_campaign, axis=1)
131
  return df
132
 
133
  # =====================================================
134
- # 2. PRESETS (UPDATED WITH COUNTRY/CITY/INDUSTRY)
135
  # =====================================================
136
  DASHBOARD_PRESETS = {
137
- # -- SPECIAL VIEWS --
138
  "Key Campaigns Bifurcation (MS Tech, Fintech, Adtech)": ("SPECIAL_KEY_BIFURCATION", None, None),
139
  "All Campaigns Performance": ("SPECIAL_ALL_PERFORMANCE", None, None),
140
-
141
- # -- CAMPAIGN & QUALITY --
142
  "Visits by Campaign": ("Campaign", "total_visits", "sum"),
143
  "Leads by Campaign": ("Campaign", "company_name", "count"),
144
  "Leads by Quality Group": ("Quality_Group", "company_name", "count"),
145
-
146
- # -- GEOGRAPHY (NEW) --
147
  "Visits by Country": ("country", "total_visits", "sum"),
148
  "Leads by Country": ("country", "company_name", "count"),
149
  "Visits by City": ("city", "total_visits", "sum"),
150
  "Leads by City": ("city", "company_name", "count"),
151
-
152
- # -- INDUSTRY (NEW) --
153
  "Visits by Industry": ("primary_industry", "total_visits", "sum"),
154
  "Leads by Industry": ("primary_industry", "company_name", "count"),
155
-
156
- # -- OTHERS --
157
  "Top Accounts by Visits": ("company_name", "total_visits", "sum"),
158
  }
159
 
160
  TREND_PRESETS = {
161
- # -- CAMPAIGN & QUALITY --
162
  "Visits Trend by Campaign": ("total_visits", "sum", "Campaign"),
163
  "Leads Trend by Campaign": ("company_name", "count", "Campaign"),
164
  "Visits Trend by Quality": ("total_visits", "sum", "Quality_Group"),
165
-
166
- # -- GEOGRAPHY (NEW) --
167
  "Visits Trend by Country": ("total_visits", "sum", "country"),
168
  "Leads Trend by Country": ("company_name", "count", "country"),
169
  "Visits Trend by City": ("total_visits", "sum", "city"),
170
  "Leads Trend by City": ("company_name", "count", "city"),
171
-
172
- # -- INDUSTRY (NEW) --
173
  "Visits Trend by Industry": ("total_visits", "sum", "primary_industry"),
174
  "Leads Trend by Industry": ("company_name", "count", "primary_industry"),
175
-
176
- # -- GENERAL --
177
  "Total Visits Trend": ("total_visits", "sum", None),
178
  "Active Accounts Trend": ("company_name", "count", None),
179
  }
@@ -389,6 +358,26 @@ def build_dashboard(df, preset, top_n):
389
  grouped = df.groupby(dim, dropna=False).size().reset_index(name="value")
390
  else:
391
  grouped = df.groupby(dim, dropna=False)[metric].agg(agg).reset_index(name="value")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
392
  return px.bar(grouped.sort_values("value", ascending=False).head(top_n), x=dim, y="value", title=preset, color=dim)
393
 
394
  def build_trend(df, preset, grain, filter_values):
@@ -474,7 +463,7 @@ with gr.Blocks(title="Leadfeeder Campaign Pro") as demo:
474
  gr.Markdown("### 📊 Charts")
475
  with gr.Row():
476
  preset = gr.Dropdown(choices=list(DASHBOARD_PRESETS.keys()), label="Chart View", value="Key Campaigns Bifurcation (MS Tech, Fintech, Adtech)")
477
- top_n = gr.Slider(5, 50, value=10, label="Top N Items")
478
  chart = gr.Plot()
479
  gr.Button("Build View").click(build_dashboard, [df_state, preset, top_n], chart)
480
 
@@ -491,7 +480,7 @@ with gr.Blocks(title="Leadfeeder Campaign Pro") as demo:
491
  # --- TAB 4: SETTINGS ---
492
  with gr.Tab("⚙️ Campaign Settings"):
493
  gr.Markdown("### Manage Campaign Groups")
494
- gr.Markdown("Select a campaign below and paste your keywords separated by commas.")
495
 
496
  init_rules = load_campaign_rules()
497
  camp_choices = list(init_rules.keys()) + ["+ Create New Campaign"]
 
101
  if "lead_quality_score" in df.columns:
102
  df["Quality_Group"] = df["lead_quality_score"].apply(categorize_quality)
103
 
104
+ # 2. Campaign Logic (Strict Landing Page Only)
105
  rules = load_campaign_rules()
106
 
107
  def resolve_campaign(row):
108
+ path = row.get("landing_page_path")
109
+ if path and path not in ["", "/", "/home"]:
 
 
 
 
110
  match = get_campaign_match(path, rules)
111
+ if match:
112
+ return match
 
 
 
 
 
 
 
 
 
 
 
113
  return "Uncategorized"
114
+
115
  df["Campaign"] = df.apply(resolve_campaign, axis=1)
116
  return df
117
 
118
  # =====================================================
119
+ # 2. PRESETS
120
  # =====================================================
121
  DASHBOARD_PRESETS = {
 
122
  "Key Campaigns Bifurcation (MS Tech, Fintech, Adtech)": ("SPECIAL_KEY_BIFURCATION", None, None),
123
  "All Campaigns Performance": ("SPECIAL_ALL_PERFORMANCE", None, None),
 
 
124
  "Visits by Campaign": ("Campaign", "total_visits", "sum"),
125
  "Leads by Campaign": ("Campaign", "company_name", "count"),
126
  "Leads by Quality Group": ("Quality_Group", "company_name", "count"),
 
 
127
  "Visits by Country": ("country", "total_visits", "sum"),
128
  "Leads by Country": ("country", "company_name", "count"),
129
  "Visits by City": ("city", "total_visits", "sum"),
130
  "Leads by City": ("city", "company_name", "count"),
 
 
131
  "Visits by Industry": ("primary_industry", "total_visits", "sum"),
132
  "Leads by Industry": ("primary_industry", "company_name", "count"),
 
 
133
  "Top Accounts by Visits": ("company_name", "total_visits", "sum"),
134
  }
135
 
136
  TREND_PRESETS = {
 
137
  "Visits Trend by Campaign": ("total_visits", "sum", "Campaign"),
138
  "Leads Trend by Campaign": ("company_name", "count", "Campaign"),
139
  "Visits Trend by Quality": ("total_visits", "sum", "Quality_Group"),
 
 
140
  "Visits Trend by Country": ("total_visits", "sum", "country"),
141
  "Leads Trend by Country": ("company_name", "count", "country"),
142
  "Visits Trend by City": ("total_visits", "sum", "city"),
143
  "Leads Trend by City": ("company_name", "count", "city"),
 
 
144
  "Visits Trend by Industry": ("total_visits", "sum", "primary_industry"),
145
  "Leads Trend by Industry": ("company_name", "count", "primary_industry"),
 
 
146
  "Total Visits Trend": ("total_visits", "sum", None),
147
  "Active Accounts Trend": ("company_name", "count", None),
148
  }
 
358
  grouped = df.groupby(dim, dropna=False).size().reset_index(name="value")
359
  else:
360
  grouped = df.groupby(dim, dropna=False)[metric].agg(agg).reset_index(name="value")
361
+
362
+ # --- NEW: Automatically render a Choropleth Map for country data ---
363
+ if dim == "country":
364
+ # Sort to put the highest values on top
365
+ grouped = grouped.sort_values("value", ascending=False)
366
+
367
+ fig = px.choropleth(
368
+ grouped,
369
+ locations=dim, # Maps directly to the "country" column
370
+ locationmode="country names", # Plotly automatically identifies country names
371
+ color="value", # The heat map scale
372
+ hover_name=dim,
373
+ title=preset,
374
+ color_continuous_scale="Blues" # A clean blue heat map gradient
375
+ )
376
+ # Update layout to remove margins and make the map look crisp
377
+ fig.update_layout(margin={"r":0,"t":40,"l":0,"b":0})
378
+ return fig
379
+ # -------------------------------------------------------------------
380
+
381
  return px.bar(grouped.sort_values("value", ascending=False).head(top_n), x=dim, y="value", title=preset, color=dim)
382
 
383
  def build_trend(df, preset, grain, filter_values):
 
463
  gr.Markdown("### 📊 Charts")
464
  with gr.Row():
465
  preset = gr.Dropdown(choices=list(DASHBOARD_PRESETS.keys()), label="Chart View", value="Key Campaigns Bifurcation (MS Tech, Fintech, Adtech)")
466
+ top_n = gr.Slider(5, 50, value=10, label="Top N Items (Not applicable to Maps)")
467
  chart = gr.Plot()
468
  gr.Button("Build View").click(build_dashboard, [df_state, preset, top_n], chart)
469
 
 
480
  # --- TAB 4: SETTINGS ---
481
  with gr.Tab("⚙️ Campaign Settings"):
482
  gr.Markdown("### Manage Campaign Groups")
483
+ gr.Markdown("Select a campaign below and paste your keywords separated by commas. Changes take effect on the next data load.")
484
 
485
  init_rules = load_campaign_rules()
486
  camp_choices = list(init_rules.keys()) + ["+ Create New Campaign"]