|
| 1 | +from urllib.parse import quote |
| 2 | + |
| 3 | +from user_scanner.core.orchestrator import generic_validate |
| 4 | +from user_scanner.core.result import Result |
| 5 | + |
| 6 | +API_URL = "https://be-lb-app.scaleabout.com/api/v1" |
| 7 | + |
| 8 | + |
| 9 | +def validate_wisio(user: str) -> Result: |
| 10 | + show_url = f"https://www.wisio.com/{user}" |
| 11 | + |
| 12 | + def process_availability(response): |
| 13 | + available = response.text.strip() |
| 14 | + if response.status_code != 200 or available not in {"true", "false"}: |
| 15 | + return Result.error( |
| 16 | + f"Unexpected Wisio availability response: {response.status_code}" |
| 17 | + ) |
| 18 | + if available == "true": |
| 19 | + return Result.available() |
| 20 | + |
| 21 | + def process_profile(profile_response): |
| 22 | + if profile_response.status_code == 404: |
| 23 | + return Result.error( |
| 24 | + "No public creator profile " |
| 25 | + "(private, reserved, and invalid usernames look the same)" |
| 26 | + ) |
| 27 | + |
| 28 | + if profile_response.status_code != 200: |
| 29 | + return Result.error( |
| 30 | + f"Unexpected Wisio profile response: {profile_response.status_code}" |
| 31 | + ) |
| 32 | + profile = profile_response.json() |
| 33 | + |
| 34 | + username = profile.get("username") if isinstance(profile, dict) else None |
| 35 | + if not isinstance(username, str) or username.casefold() != user.casefold(): |
| 36 | + return Result.error( |
| 37 | + "Wisio profile did not match the requested username" |
| 38 | + ) |
| 39 | + |
| 40 | + skills = [ |
| 41 | + skill["name"] |
| 42 | + for skill in profile.get("skills") or [] |
| 43 | + if isinstance(skill, dict) and isinstance(skill.get("name"), str) |
| 44 | + ] |
| 45 | + social_links = [ |
| 46 | + channel.get("formatted_url") or channel.get("url") |
| 47 | + for channel in profile.get("social_channels") or [] |
| 48 | + if isinstance(channel, dict) |
| 49 | + and isinstance(channel.get("formatted_url") or channel.get("url"), str) |
| 50 | + ] |
| 51 | + external_links = [ |
| 52 | + link["url"] |
| 53 | + for link in profile.get("links") or [] |
| 54 | + if isinstance(link, dict) and isinstance(link.get("url"), str) |
| 55 | + ] |
| 56 | + avatar = profile.get("avatar") or {} |
| 57 | + cover = profile.get("cover_image") or {} |
| 58 | + |
| 59 | + return Result.taken( |
| 60 | + extra={ |
| 61 | + "id": profile.get("id"), |
| 62 | + "first_name": profile.get("first_name"), |
| 63 | + "last_name": profile.get("last_name"), |
| 64 | + "display_name": profile.get("display_name"), |
| 65 | + "title": profile.get("title"), |
| 66 | + "location": profile.get("location"), |
| 67 | + "skills": skills or None, |
| 68 | + "social_links": social_links or None, |
| 69 | + "external_links": external_links or None, |
| 70 | + "reviews": profile.get("reviews_count"), |
| 71 | + "rating": profile.get("reviews_score"), |
| 72 | + "created_at": profile.get("created_at"), |
| 73 | + "updated_at": profile.get("updated_at"), |
| 74 | + "preferred_currency": profile.get("preferred_currency"), |
| 75 | + "seller_availability": profile.get("seller_availability"), |
| 76 | + "locale": profile.get("locale"), |
| 77 | + "vacation": profile.get("vacation"), |
| 78 | + }, |
| 79 | + media={ |
| 80 | + "avatar": (avatar.get("medium") or {}).get("url") |
| 81 | + if isinstance(avatar, dict) |
| 82 | + else None, |
| 83 | + "cover": (cover.get("big") or {}).get("url") |
| 84 | + if isinstance(cover, dict) |
| 85 | + else None, |
| 86 | + }, |
| 87 | + ) |
| 88 | + |
| 89 | + return generic_validate( |
| 90 | + f"{API_URL}/users/{quote(user, safe='')}", |
| 91 | + process_profile, |
| 92 | + ) |
| 93 | + |
| 94 | + return generic_validate( |
| 95 | + f"{API_URL}/users/is_username_allowed", |
| 96 | + process_availability, |
| 97 | + params={"username": user}, |
| 98 | + show_url=show_url, |
| 99 | + ) |
0 commit comments