from otree.api import Currency as c, currency_range from ._builtin import Page, WaitPage import settings from .models import Constants import time import requests from common.utils import is_player_suspicious from otree.settings import RECAPTCHA_PRIVATE_KEY, RECAPTCHA_PUBLIC_KEY class StartPage(Page): live_method = 'live_method' # timeout_seconds = 120 def js_vars(self): return dict( data_received=self.player.data_received, api_key='b409301bc2294441bfb0b39a69811e2a', ) def before_next_page(self): # time.time() returns the number of seconds passed since epoch (January 1, 1970, 00:00:00) self.participant.vars['experiment_starting_time'] = time.time() api_key = "179102cc61dcfc5c4a05cffac078260f0ace484021fc1713cff739a94f75f63f" # URL of the page you want to scrape url = f'https://api12.scamalytics.com/v3/huanrenzhang/?key={api_key}&ip={self.player.ip}' try: response = requests.get(url, timeout=5) if not response.ok: print("⚠️ Scamalytics request failed:", response.status_code) return # parse JSON directly data = response.json() # navigate to risk score & ISP scam = data.get("scamalytics", {}) self.player.risk_score = scam.get("scamalytics_score") self.player.isp = scam.get("scamalytics_isp") or scam.get("scamalytics_org") # ---- ASN info (from external data sources, e.g. ip2proxy_lite / maxmind / ipinfo) ---- asn_info = {} for source in ["ip2proxy_lite", "maxmind_geolite2", "ipinfo"]: if source in data.get("external_datasources", {}): asn_info = data["external_datasources"][source] if asn_info.get("asn"): break self.player.asn = asn_info.get("asn") self.player.as_name = asn_info.get("as_name") # ---- Classify network type ---- isp_lower = (self.player.isp or "").lower() as_name_lower = (self.player.as_name or "").lower() if any(x in isp_lower for x in ["mobile", "cellular", "wireless"]): self.player.network_type = "mobile" elif any(x in as_name_lower for x in ["amazon", "aws", "google", "microsoft", "azure", "ovh", "digitalocean", "hetzner", "contabo", "m247"]): self.player.network_type = "cloud/hosting" elif data.get("scamalytics", {}).get("scamalytics_proxy", {}).get("is_vpn"): self.player.network_type = "vpn" elif data.get("scamalytics", {}).get("scamalytics_proxy", {}).get("is_datacenter"): self.player.network_type = "datacenter" else: self.player.network_type = "residential/unknown" # optional: log for debugging # print(f"[IP {self.player.ip}] Risk Score:", self.player.risk_score, "| ISP:", self.player.isp) player = self.player player.suspicious = 0 if player.session.config.get('checking_suspicious_participants', 1): player.suspicious = is_player_suspicious(player) ## additional test for duplicate location and ip address if player.suspicious != 1: others = player.get_others_in_subsession() localities = list(set([p.locality for p in others]) - set([''])) if player.locality in localities: duplicate_players = [p for p in others if p.ip[:8] == player.ip[:8]] if len(duplicate_players) >= 1: player.suspicious = 1 except Exception as e: print(f"⚠️ Error fetching Scamalytics data for IP {self.player.ip}: {e}") def vars_for_template(self): real_world_currency_per_point = self.session.config.get( 'real_world_currency_per_point', settings.SESSION_CONFIG_DEFAULTS.get('real_world_currency_per_point', 1), ) points_per_dollar = int( 1 / real_world_currency_per_point ) consent = self.session.config.get('consent', True) real_currency = self.session.config.get('real_currency', getattr(settings, 'REAL_WORLD_CURRENCY_CODE', '$')) total_payment = self.session.config.get('total_payment', 100) return { 'consent': consent, 'payment': self.session.config.get('payment',0), 'interactive': self.session.config.get('interactive', 0), 'ready_to_start': self.session.config.get('ready_to_start',1), 'experimental_currency': getattr(settings, 'POINTS_CUSTOM_NAME', 'tokens'), 'real_currency': real_currency, 'total_payment': total_payment, 'points_per_dollar': points_per_dollar, } class Captcha(Page): form_model = 'player' form_fields = ['captcha'] live_method = 'live_method' def js_vars(self): return dict( data_received=self.player.data_received, ) def vars_for_template(self): return { "RECAPTCHA_PUBLIC_KEY": RECAPTCHA_PUBLIC_KEY, 'debug': self.session.config.get('debug', False), } page_sequence = [ StartPage, Captcha, ]