|
| 1 | +import json |
| 2 | +from urllib.parse import quote |
| 3 | + |
| 4 | +from user_scanner.core.orchestrator import Result, generic_validate |
| 5 | + |
| 6 | +_SOCIAL_FIELDS = { |
| 7 | + 0: "facebook", |
| 8 | + 1: "twitter", |
| 9 | + 2: "youtube", |
| 10 | + 3: "instagram", |
| 11 | + 4: "social_website", |
| 12 | +} |
| 13 | + |
| 14 | + |
| 15 | +def validate_indiegogo_creator(user: str) -> Result: |
| 16 | + url = f"https://www.indiegogo.com/en/creators/{quote(user, safe='')}" |
| 17 | + |
| 18 | + def process(response): |
| 19 | + body = response.text |
| 20 | + if response.status_code == 404 and "<title>404: Page Not Found - Indiegogo</title>" in body: |
| 21 | + return Result.available() |
| 22 | + |
| 23 | + if response.status_code != 200: |
| 24 | + return Result.error(f"Unexpected status: {response.status_code}") |
| 25 | + |
| 26 | + props = _props(body) |
| 27 | + if not props or str(props.get("urlName", "")).casefold() != user.casefold(): |
| 28 | + return Result.error("200 without the matching Indiegogo account data") |
| 29 | + |
| 30 | + extra = { |
| 31 | + "id": props.get("creatorID"), |
| 32 | + "name": props.get("name"), |
| 33 | + "bio": props.get("description"), |
| 34 | + "location": props.get("displayedLocation"), |
| 35 | + "website": props.get("websiteUrl"), |
| 36 | + } |
| 37 | + for social in props.get("socialMediaUrls") or []: |
| 38 | + if isinstance(social, dict) and (field := _SOCIAL_FIELDS.get(social.get("type"))): |
| 39 | + extra[field] = social.get("url") |
| 40 | + |
| 41 | + media = {"avatar": props.get("creatorImageUrl")} |
| 42 | + if props.get("bannerImages"): |
| 43 | + media["banner"] = props["bannerImages"][0] |
| 44 | + return Result.taken(extra=extra, media=media) |
| 45 | + |
| 46 | + return generic_validate(url, process, show_url=url) |
| 47 | + |
| 48 | + |
| 49 | +def _props(body: str) -> dict | None: |
| 50 | + marker = "'App.Views.CreatorView', App.Views.CreatorView, " |
| 51 | + start = body.find(marker) |
| 52 | + if start == -1: |
| 53 | + return None |
| 54 | + |
| 55 | + start = body.find('{"props":', start) |
| 56 | + end = body.find(");</script>", start) |
| 57 | + if start == -1 or end == -1: |
| 58 | + return None |
| 59 | + |
| 60 | + props = json.loads(body[start:end]).get("props") |
| 61 | + return props if isinstance(props, dict) else None |
0 commit comments