from howlongtobeatpy import HowLongToBeat def _h(val): """Return float hours if valid, else None.""" try: v = float(val) return v if v > 0 else None except (TypeError, ValueError): return None def fetch(game_name): """ Search HowLongToBeat for game_name. Returns dict with keys 'main', 'extra', 'complete' (each float or None), or None if nothing found / on any error. """ try: results = HowLongToBeat().search(game_name) except Exception: return None if not results: return None best = max(results, key=lambda r: r.similarity) if best.similarity < 0.4: return None return { 'main': _h(best.main_story), 'extra': _h(best.main_extra), 'complete': _h(best.completionist), } def apply_to_item(item): """Fetch HLTB data and save it onto item. Always marks hltb_fetched=True.""" if item.category != 'games' or not item.name: return data = fetch(item.name) fields = ['hltb_fetched'] item.hltb_fetched = True if data is not None: item.hltb_main = data['main'] item.hltb_extra = data['extra'] item.hltb_complete = data['complete'] fields += ['hltb_main', 'hltb_extra', 'hltb_complete'] item.save(update_fields=fields)