diff --git a/backlogger/hltb.py b/backlogger/hltb.py new file mode 100644 index 0000000..181eb03 --- /dev/null +++ b/backlogger/hltb.py @@ -0,0 +1,48 @@ +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']) diff --git a/backlogger/migrations/0004_item_hltb_fields.py b/backlogger/migrations/0004_item_hltb_fields.py new file mode 100644 index 0000000..52576da --- /dev/null +++ b/backlogger/migrations/0004_item_hltb_fields.py @@ -0,0 +1,26 @@ +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('backlogger', '0003_assign_existing_items_to_first_user'), + ] + + operations = [ + migrations.AddField( + model_name='item', + name='hltb_main', + field=models.FloatField(blank=True, null=True), + ), + migrations.AddField( + model_name='item', + name='hltb_extra', + field=models.FloatField(blank=True, null=True), + ), + migrations.AddField( + model_name='item', + name='hltb_complete', + field=models.FloatField(blank=True, null=True), + ), + ] diff --git a/backlogger/models.py b/backlogger/models.py index eef1e25..9bac648 100644 --- a/backlogger/models.py +++ b/backlogger/models.py @@ -35,6 +35,11 @@ class Item(models.Model): watched = models.BooleanField(null=True, blank=True) duration_minutes = models.IntegerField(null=True, blank=True) + # HowLongToBeat estimates (games only) + hltb_main = models.FloatField(null=True, blank=True) + hltb_extra = models.FloatField(null=True, blank=True) + hltb_complete = models.FloatField(null=True, blank=True) + class Meta: ordering = ['-favorite', 'name'] diff --git a/backlogger/templates/backlogger/item_form.html b/backlogger/templates/backlogger/item_form.html index 5627b0f..ea5e449 100644 --- a/backlogger/templates/backlogger/item_form.html +++ b/backlogger/templates/backlogger/item_form.html @@ -188,6 +188,14 @@ {{ form.total_hours }} {{ form.total_hours.errors }} + {% if item.hltb_main or item.hltb_extra or item.hltb_complete %} +