inital commit
This commit is contained in:
182
marketing/services.py
Normal file
182
marketing/services.py
Normal file
@@ -0,0 +1,182 @@
|
||||
from datetime import timedelta
|
||||
|
||||
from django.utils import timezone
|
||||
|
||||
from .models import ListingClick
|
||||
|
||||
|
||||
def _clean_param(params, key: str, max_len: int = 255) -> str:
|
||||
raw = params.get(key)
|
||||
if raw is None:
|
||||
return ""
|
||||
s = str(raw).strip()
|
||||
return s[:max_len]
|
||||
|
||||
|
||||
def classify_traffic(
|
||||
*,
|
||||
utm_source: str,
|
||||
utm_medium: str,
|
||||
utm_campaign: str,
|
||||
utm_term: str,
|
||||
utm_content: str,
|
||||
gclid: str,
|
||||
fbclid: str,
|
||||
) -> str:
|
||||
if any(
|
||||
(
|
||||
utm_source,
|
||||
utm_medium,
|
||||
utm_campaign,
|
||||
utm_term,
|
||||
utm_content,
|
||||
gclid,
|
||||
fbclid,
|
||||
)
|
||||
):
|
||||
return ListingClick.TrafficType.MARKETING
|
||||
return ListingClick.TrafficType.ORGANIC
|
||||
|
||||
|
||||
def extract_attribution_from_request(request) -> dict:
|
||||
p = request.query_params if hasattr(request, "query_params") else request.GET
|
||||
utm_source = _clean_param(p, "utm_source")
|
||||
utm_medium = _clean_param(p, "utm_medium")
|
||||
utm_campaign = _clean_param(p, "utm_campaign")
|
||||
utm_term = _clean_param(p, "utm_term")
|
||||
utm_content = _clean_param(p, "utm_content")
|
||||
gclid = _clean_param(p, "gclid")
|
||||
fbclid = _clean_param(p, "fbclid")
|
||||
referrer = ""
|
||||
if hasattr(request, "META"):
|
||||
ref = request.META.get("HTTP_REFERER") or ""
|
||||
referrer = ref[:2048]
|
||||
traffic_type = classify_traffic(
|
||||
utm_source=utm_source,
|
||||
utm_medium=utm_medium,
|
||||
utm_campaign=utm_campaign,
|
||||
utm_term=utm_term,
|
||||
utm_content=utm_content,
|
||||
gclid=gclid,
|
||||
fbclid=fbclid,
|
||||
)
|
||||
return {
|
||||
"utm_source": utm_source,
|
||||
"utm_medium": utm_medium,
|
||||
"utm_campaign": utm_campaign,
|
||||
"utm_term": utm_term,
|
||||
"utm_content": utm_content,
|
||||
"gclid": gclid,
|
||||
"fbclid": fbclid,
|
||||
"referrer": referrer,
|
||||
"traffic_type": traffic_type,
|
||||
}
|
||||
|
||||
|
||||
def record_equipment_listing_click(request, equipment_item) -> ListingClick:
|
||||
attrs = extract_attribution_from_request(request)
|
||||
user = request.user if getattr(request, "user", None) and request.user.is_authenticated else None
|
||||
return ListingClick.objects.create(
|
||||
vendor=equipment_item.vendor,
|
||||
listing_type=ListingClick.ListingType.EQUIPMENT,
|
||||
equipment_item=equipment_item,
|
||||
adventure_offering=None,
|
||||
user=user,
|
||||
**attrs,
|
||||
)
|
||||
|
||||
|
||||
def record_adventure_listing_click(request, adventure_offering) -> ListingClick:
|
||||
attrs = extract_attribution_from_request(request)
|
||||
user = request.user if getattr(request, "user", None) and request.user.is_authenticated else None
|
||||
return ListingClick.objects.create(
|
||||
vendor=adventure_offering.vendor,
|
||||
listing_type=ListingClick.ListingType.ADVENTURE,
|
||||
equipment_item=None,
|
||||
adventure_offering=adventure_offering,
|
||||
user=user,
|
||||
**attrs,
|
||||
)
|
||||
|
||||
|
||||
def record_listing_click_from_payload(
|
||||
*,
|
||||
listing_type: str,
|
||||
equipment_item=None,
|
||||
adventure_offering=None,
|
||||
utm_source: str = "",
|
||||
utm_medium: str = "",
|
||||
utm_campaign: str = "",
|
||||
utm_term: str = "",
|
||||
utm_content: str = "",
|
||||
gclid: str = "",
|
||||
fbclid: str = "",
|
||||
referrer: str = "",
|
||||
user=None,
|
||||
) -> ListingClick:
|
||||
traffic_type = classify_traffic(
|
||||
utm_source=utm_source or "",
|
||||
utm_medium=utm_medium or "",
|
||||
utm_campaign=utm_campaign or "",
|
||||
utm_term=utm_term or "",
|
||||
utm_content=utm_content or "",
|
||||
gclid=gclid or "",
|
||||
fbclid=fbclid or "",
|
||||
)
|
||||
if listing_type == ListingClick.ListingType.EQUIPMENT:
|
||||
return ListingClick.objects.create(
|
||||
vendor=equipment_item.vendor,
|
||||
listing_type=ListingClick.ListingType.EQUIPMENT,
|
||||
equipment_item=equipment_item,
|
||||
adventure_offering=None,
|
||||
traffic_type=traffic_type,
|
||||
utm_source=utm_source[:255],
|
||||
utm_medium=utm_medium[:255],
|
||||
utm_campaign=utm_campaign[:255],
|
||||
utm_term=utm_term[:255],
|
||||
utm_content=utm_content[:255],
|
||||
gclid=gclid[:255],
|
||||
fbclid=fbclid[:255],
|
||||
referrer=referrer[:2048],
|
||||
user=user,
|
||||
)
|
||||
return ListingClick.objects.create(
|
||||
vendor=adventure_offering.vendor,
|
||||
listing_type=ListingClick.ListingType.ADVENTURE,
|
||||
equipment_item=None,
|
||||
adventure_offering=adventure_offering,
|
||||
traffic_type=traffic_type,
|
||||
utm_source=utm_source[:255],
|
||||
utm_medium=utm_medium[:255],
|
||||
utm_campaign=utm_campaign[:255],
|
||||
utm_term=utm_term[:255],
|
||||
utm_content=utm_content[:255],
|
||||
gclid=gclid[:255],
|
||||
fbclid=fbclid[:255],
|
||||
referrer=referrer[:2048],
|
||||
user=user,
|
||||
)
|
||||
|
||||
|
||||
ATTRIBUTION_MAX_AGE_DAYS = 90
|
||||
|
||||
|
||||
def listing_click_valid_for_booking(*, click, equipment_item=None, adventure_offering=None) -> bool:
|
||||
if click is None:
|
||||
return False
|
||||
cutoff = timezone.now() - timedelta(days=ATTRIBUTION_MAX_AGE_DAYS)
|
||||
if click.created_at < cutoff:
|
||||
return False
|
||||
if equipment_item is not None:
|
||||
return (
|
||||
click.listing_type == ListingClick.ListingType.EQUIPMENT
|
||||
and click.equipment_item_id == equipment_item.id
|
||||
and click.vendor_id == equipment_item.vendor_id
|
||||
)
|
||||
if adventure_offering is not None:
|
||||
return (
|
||||
click.listing_type == ListingClick.ListingType.ADVENTURE
|
||||
and click.adventure_offering_id == adventure_offering.id
|
||||
and click.vendor_id == adventure_offering.vendor_id
|
||||
)
|
||||
return False
|
||||
Reference in New Issue
Block a user