WIP: Attach invoice PDF to payment emails #104418
@ -21,7 +21,7 @@
|
|||||||
{% if item.static_asset.download_url %}
|
{% if item.static_asset.download_url %}
|
||||||
<a href="{{ item.static_asset.download_url }}"
|
<a href="{{ item.static_asset.download_url }}"
|
||||||
target="_blank"
|
target="_blank"
|
||||||
download
|
download="{{ item.static_asset.get_download_name }}"
|
||||||
class="dropdown-item">
|
class="dropdown-item">
|
||||||
<i class="i-download me-1"></i>
|
<i class="i-download me-1"></i>
|
||||||
<span>Download{% if additional_download %}{{ additional_download|capfirst }} {% endif %} <span class="text-muted">({{ item.static_asset.download_size }})</span></span>
|
<span>Download{% if additional_download %}{{ additional_download|capfirst }} {% endif %} <span class="text-muted">({{ item.static_asset.download_size }})</span></span>
|
||||||
@ -36,22 +36,22 @@
|
|||||||
{% firstof "" item.preview_video_static_asset.video.tracks.count as preview_video_has_subtitles %}
|
{% firstof "" item.preview_video_static_asset.video.tracks.count as preview_video_has_subtitles %}
|
||||||
{% firstof "" item.static_asset.video.tracks.count as has_subtitles %}
|
{% firstof "" item.static_asset.video.tracks.count as has_subtitles %}
|
||||||
{# in case there's more than one downloadable, show a dropdown #}
|
{# in case there's more than one downloadable, show a dropdown #}
|
||||||
{% if item.preview_video_static_asset and item.static_asset or preview_video_has_subtitles or has_subtitles %}
|
{% if item.preview_video_static_asset and item.static_asset or preview_video_has_subtitles or has_subtitles %}
|
||||||
{% include "common/components/navigation/download_button.html" with static_asset=item.static_asset %}
|
{% include "common/components/navigation/download_button.html" with static_asset=item.static_asset %}
|
||||||
<button data-bs-toggle="dropdown" data-bs-target="#downloadDropdown" class="btn btn-link dropdown-toggle">
|
<button data-bs-toggle="dropdown" data-bs-target="#downloadDropdown" class="btn btn-link dropdown-toggle">
|
||||||
<i class="i-chevron-down"></i>
|
<i class="i-chevron-down"></i>
|
||||||
</button>
|
</button>
|
||||||
<div class="dropdown-menu dropdown-menu-end" id="downloadDropdown">
|
<div class="dropdown-menu dropdown-menu-end" id="downloadDropdown">
|
||||||
{% if item.preview_video_static_asset %}
|
{% if item.preview_video_static_asset %}
|
||||||
{% include "common/components/navigation/download_button.html" with static_asset=item.preview_video_static_asset additional_download="video" %}
|
{% include "common/components/navigation/download_button.html" with static_asset=item.preview_video_static_asset additional_download="video" %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% if has_subtitles or preview_video_has_subtitles %}
|
{% if has_subtitles or preview_video_has_subtitles %}
|
||||||
{% with static_asset=item.preview_video_static_asset|default:item.static_asset %}
|
{% with static_asset=item.preview_video_static_asset|default:item.static_asset %}
|
||||||
{% firstof item.name item as vtt_filename %}
|
{% firstof item.name item as vtt_filename %}
|
||||||
{% include "common/components/navigation/download_subtitles.html" with name=vtt_filename %}
|
{% include "common/components/navigation/download_subtitles.html" with name=vtt_filename %}
|
||||||
{% endwith %}
|
{% endwith %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
{% else %}
|
{% else %}
|
||||||
{% include "common/components/navigation/download_button.html" with static_asset=item.static_asset %}
|
{% include "common/components/navigation/download_button.html" with static_asset=item.static_asset %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
@ -74,7 +74,7 @@
|
|||||||
{% if item.static_asset.download_url %}
|
{% if item.static_asset.download_url %}
|
||||||
<a href="{{ item.static_asset.download_url }}"
|
<a href="{{ item.static_asset.download_url }}"
|
||||||
target="_blank"
|
target="_blank"
|
||||||
download
|
download="{{ item.static_asset.get_download_name }}"
|
||||||
class="dropdown-item">
|
class="dropdown-item">
|
||||||
<i class="i-download me-1"></i>
|
<i class="i-download me-1"></i>
|
||||||
<span>Download{% if additional_download %}{{ additional_download|capfirst }} {% endif %} <span class="text-muted">({{ item.static_asset.download_size }})</span></span>
|
<span>Download{% if additional_download %}{{ additional_download|capfirst }} {% endif %} <span class="text-muted">({{ item.static_asset.download_size }})</span></span>
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
{% if asset.contains_blend_file or asset.static_asset.source_type == "file" %}
|
{% if asset.contains_blend_file or asset.static_asset.source_type == "file" %}
|
||||||
<a href="{{ static_asset.download_url }}"
|
<a href="{{ static_asset.download_url }}"
|
||||||
target="_blank"
|
target="_blank"
|
||||||
download
|
download="{{ static_asset.get_download_name }}"
|
||||||
class="{% if additional_download %}dropdown-item{% else %}btn btn-link{% endif %}">
|
class="{% if additional_download %}dropdown-item{% else %}btn btn-link{% endif %}">
|
||||||
<i class="i-download me-1"></i>
|
<i class="i-download me-1"></i>
|
||||||
<span>Download {% if additional_download %}{{ additional_download|capfirst }} {% endif %}<span class="text-muted">({{ static_asset.download_size }})</span></span>
|
<span>Download {% if additional_download %}{{ additional_download|capfirst }} {% endif %}<span class="text-muted">({{ static_asset.download_size }})</span></span>
|
||||||
|
@ -196,15 +196,31 @@ class StaticAsset(
|
|||||||
def __str__(self):
|
def __str__(self):
|
||||||
return f'({self.id}) {self.original_filename}'
|
return f'({self.id}) {self.original_filename}'
|
||||||
|
|
||||||
|
def get_download_name(self) -> Optional[str]:
|
||||||
|
"""Return file name of what gets downloaded depending on available variations."""
|
||||||
|
if self.source_type != 'video' or not self.video:
|
||||||
|
return self.download_name
|
||||||
|
|
||||||
|
video = self.video
|
||||||
|
default_variation = video.default_variation
|
||||||
|
if default_variation:
|
||||||
|
return default_variation.download_name
|
||||||
|
return video.download_name
|
||||||
|
|
||||||
|
@property
|
||||||
|
def download_name(self) -> Optional[str]:
|
||||||
|
"""Return a human-readable file name, if possible."""
|
||||||
|
path = PurePosixPath(self.source.name)
|
||||||
|
ext = path.suffix
|
||||||
|
|
||||||
|
if self.original_filename:
|
||||||
|
return f'{slugify(PurePosixPath(self.original_filename).stem)}{ext}'
|
||||||
|
return None
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def content_disposition(self) -> Optional[str]:
|
def content_disposition(self) -> Optional[str]:
|
||||||
"""Try to get a human-readable file name for Content-Disposition header."""
|
"""Try to get a human-readable file name for Content-Disposition header."""
|
||||||
path = PurePosixPath(self.source.name)
|
filename = self.download_name
|
||||||
ext = path.suffix
|
|
||||||
filename = None
|
|
||||||
|
|
||||||
if self.original_filename:
|
|
||||||
filename = f'{slugify(PurePosixPath(self.original_filename).stem)}{ext}'
|
|
||||||
|
|
||||||
if filename:
|
if filename:
|
||||||
return f'attachment; filename="{filename}"'
|
return f'attachment; filename="{filename}"'
|
||||||
@ -293,16 +309,20 @@ class Video(models.Model):
|
|||||||
return f'{self._meta.model_name} {self.static_asset.original_filename}'
|
return f'{self._meta.model_name} {self.static_asset.original_filename}'
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def content_disposition(self) -> Optional[str]:
|
def download_name(self) -> Optional[str]:
|
||||||
"""Try to get a human-readable file name for Content-Disposition header."""
|
|
||||||
path = PurePosixPath(self.source.name)
|
path = PurePosixPath(self.source.name)
|
||||||
ext = path.suffix
|
ext = path.suffix
|
||||||
filename = None
|
|
||||||
resolution_label = f'-{self.resolution_label}' if self.resolution_label else ''
|
resolution_label = f'-{self.resolution_label}' if self.resolution_label else ''
|
||||||
original_filename = self.static_asset.original_filename
|
original_filename = self.static_asset.original_filename
|
||||||
|
|
||||||
if original_filename:
|
if original_filename:
|
||||||
filename = f'{slugify(PurePosixPath(original_filename).stem)}{resolution_label}{ext}'
|
return f'{slugify(PurePosixPath(original_filename).stem)}{resolution_label}{ext}'
|
||||||
|
return None
|
||||||
|
|
||||||
|
@property
|
||||||
|
def content_disposition(self) -> Optional[str]:
|
||||||
|
"""Try to get a human-readable file name for Content-Disposition header."""
|
||||||
|
filename = self.download_name
|
||||||
|
|
||||||
if filename:
|
if filename:
|
||||||
return f'attachment; filename="{filename}"'
|
return f'attachment; filename="{filename}"'
|
||||||
@ -331,20 +351,22 @@ class VideoVariation(models.Model):
|
|||||||
return f"Video variation for {self.video.static_asset.original_filename}"
|
return f"Video variation for {self.video.static_asset.original_filename}"
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def content_disposition(self) -> Optional[str]:
|
def download_name(self) -> Optional[str]:
|
||||||
"""Try to get a human-readable file name for Content-Disposition header."""
|
"""Return a human-readable file name, if possible."""
|
||||||
path = PurePosixPath(self.source.name)
|
path = PurePosixPath(self.source.name)
|
||||||
ext = path.suffix
|
ext = path.suffix
|
||||||
filename = None
|
|
||||||
resolution_label = f'-{self.resolution_label}' if self.resolution_label else ''
|
resolution_label = f'-{self.resolution_label}' if self.resolution_label else ''
|
||||||
original_filename = self.video.static_asset.original_filename
|
|
||||||
|
|
||||||
section = getattr(self.video.static_asset, 'section', None)
|
section = getattr(self.video.static_asset, 'section', None)
|
||||||
# This is a training section video, use its name as a file name
|
# This is a training section video, use its name as a file name
|
||||||
if section:
|
if section:
|
||||||
filename = f'{slugify(section.name)}{resolution_label}{ext}'
|
return f'{slugify(section.name)}{resolution_label}{ext}'
|
||||||
elif original_filename:
|
return self.video.download_name
|
||||||
filename = f'{slugify(PurePosixPath(original_filename).stem)}{resolution_label}{ext}'
|
|
||||||
|
@property
|
||||||
|
def content_disposition(self) -> Optional[str]:
|
||||||
|
"""Try to get a human-readable file name for Content-Disposition header."""
|
||||||
|
filename = self.download_name
|
||||||
|
|
||||||
if filename:
|
if filename:
|
||||||
return f'attachment; filename="{filename}"'
|
return f'attachment; filename="{filename}"'
|
||||||
|
@ -34,7 +34,7 @@ class StaticAssetSerializer(common.serializers.IdModelSerializer):
|
|||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = StaticAsset
|
model = StaticAsset
|
||||||
fields = '__all__'
|
exclude = ['source_storage']
|
||||||
writable_fields = (
|
writable_fields = (
|
||||||
'author_id',
|
'author_id',
|
||||||
'contributors_ids',
|
'contributors_ids',
|
||||||
|
Loading…
Reference in New Issue
Block a user