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. Silently does nothing on failure.""" if item.category != 'games' or not item.name: return data = fetch(item.name) if data is None: return item.hltb_main = data['main'] item.hltb_extra = data['extra'] item.hltb_complete = data['complete'] item.save(update_fields=['hltb_main', 'hltb_extra', 'hltb_complete'])