diff --git a/theme/templatetags/trade_offer_png.html b/theme/templatetags/trade_offer_png.html
index 995d3d3..bcf9914 100644
--- a/theme/templatetags/trade_offer_png.html
+++ b/theme/templatetags/trade_offer_png.html
@@ -9,7 +9,7 @@
diff --git a/trades/signals.py b/trades/signals.py
index 8bb7dad..76168cb 100644
--- a/trades/signals.py
+++ b/trades/signals.py
@@ -271,8 +271,12 @@ def trade_acceptance_reputation_delete(sender, instance, **kwargs):
@receiver(post_delete, sender=TradeAcceptance)
def bubble_up_trade_offer_updates(sender, instance, **kwargs):
"""
- Bubble up updates to the TradeOffer model when TradeOfferHaveCard, TradeOfferWantCard,
- or TradeAcceptance instances are created, updated, or deleted.
+ Bubble up updated_at to the TradeOffer model when related instances change.
+ Also invalidates any cached image by deleting the file.
"""
- if instance.trade_offer:
- instance.trade_offer.save(update_fields=['updated_at'])
\ No newline at end of file
+ trade_offer = getattr(instance, 'trade_offer', None)
+
+ if trade_offer and trade_offer.image:
+ trade_offer.image.delete(save=True) # deleting the image will trigger a save, which updates the updated_at field
+ elif trade_offer:
+ trade_offer.save(update_fields=['updated_at'])
\ No newline at end of file
diff --git a/trades/templatetags/trade_offer_tags.py b/trades/templatetags/trade_offer_tags.py
index 85a70a5..e7ea7d6 100644
--- a/trades/templatetags/trade_offer_tags.py
+++ b/trades/templatetags/trade_offer_tags.py
@@ -87,28 +87,38 @@ def action_button_class(state_value):
@register.inclusion_tag('templatetags/trade_offer_png.html', takes_context=True)
def render_trade_offer_png(context, offer, show_friend_code=False):
+ CARD_HEIGHT = 32
+ CARD_WIDTH = 160
+ HEADER_HEIGHT = 69
+ FOOTER_HEIGHT = 37
+ CARD_WIDTH_PADDING = 64
+ EXPANDED_CARD_WIDTH_PADDING = 80
+ CARD_COL_GAP = 4
+ OUTPUT_PADDING = 24 # height padding is handled by the HTML
have_cards_available = offer.have_cards_available
want_cards_available = offer.want_cards_available
num_cards = max(len(have_cards_available), len(want_cards_available))
expanded = (len(have_cards_available) + len(want_cards_available)) > 4
if expanded:
- num_cards = ceil(num_cards / 2)
- image_height = (num_cards * 40) + 106
- # cards incl pad + header/footer
+ num_cards = ceil(num_cards / 2) # 2 cards per row if expanded
+ image_height = (num_cards * CARD_HEIGHT) + ((num_cards - 1) * CARD_COL_GAP) + HEADER_HEIGHT + FOOTER_HEIGHT
if expanded:
- image_width = (4 * 160) + 110
+ image_width = (4 * CARD_WIDTH) + EXPANDED_CARD_WIDTH_PADDING
else:
- image_width = (2 * 160) + 92
+ image_width = (2 * CARD_WIDTH) + CARD_WIDTH_PADDING
+ image_width += OUTPUT_PADDING
+ image_height += OUTPUT_PADDING # height padding is handled by the HTML, but we need to also calculate it here for og meta tag use
+
request = context.get("request")
if request.get_host().startswith("localhost"):
base_url = "http://{0}".format(request.get_host())
else:
base_url = "https://{0}".format(request.get_host())
- return {
+ tag_context = {
'offer_pk': offer.pk,
'offer_hash': offer.hash,
'rarity_icon': offer.rarity_icon,
@@ -124,4 +134,8 @@ def render_trade_offer_png(context, offer, show_friend_code=False):
'image_width': image_width,
'image_height': image_height,
'base_url': base_url,
- }
\ No newline at end of file
+ 'cache_key': f'trade_offer_png_{offer.pk}_{offer.updated_at.timestamp()}_{expanded}',
+ }
+
+ context.update(tag_context)
+ return context
\ No newline at end of file
diff --git a/trades/views.py b/trades/views.py
index 3db67d7..8d0fa5d 100644
--- a/trades/views.py
+++ b/trades/views.py
@@ -1,3 +1,4 @@
+from django.template import RequestContext
from django.views.generic import DeleteView, CreateView, ListView, DetailView, UpdateView
from django.views import View
from django.urls import reverse_lazy
@@ -521,9 +522,13 @@ class TradeOfferPNGView(View):
image_height = tag_context.get('image_height')
if not image_width or not image_height:
raise ValueError("Could not determine image dimensions from tag_context")
- html = render_to_string("templatetags/trade_offer_png.html", tag_context)
+ html = render_to_string(
+ "templatetags/trade_offer_png.html",
+ context=tag_context,
+ request=request
+ )
- # if query string has "debug=true", render the HTML instead of the PNG
+ # if query string has "debug", render the HTML instead of the PNG
if request.GET.get("debug") == "html":
return render(request, "templatetags/trade_offer_png.html", tag_context)