Finish up Bheesham's work on adding team images for card covers and banners, fixes #25

This commit is contained in:
Michael Hall 2018-06-10 13:06:46 -04:00
parent 7540b93d0a
commit a366fa951b
15 changed files with 160 additions and 48 deletions

View file

@ -155,7 +155,15 @@ class DateTimeWidget(forms.SplitDateTimeWidget):
class TeamForm(forms.ModelForm): class TeamForm(forms.ModelForm):
class Meta: class Meta:
model = Team model = Team
fields = ['name', 'description', 'category', 'city', 'web_url', 'tz'] fields = [
'name',
'description',
'category',
'city',
'web_url',
'tz',
'cover_img',
]
widgets = { widgets = {
'city': Lookup(source=City), 'city': Lookup(source=City),
} }
@ -167,7 +175,12 @@ class TeamForm(forms.ModelForm):
class NewTeamForm(forms.ModelForm): class NewTeamForm(forms.ModelForm):
class Meta: class Meta:
model = Team model = Team
fields = ['name', 'city', 'tz'] fields = [
'name',
'city',
'tz',
'cover_img',
]
widgets = { widgets = {
'city': Lookup(source=City), 'city': Lookup(source=City),
} }

View file

@ -0,0 +1,18 @@
# Generated by Django 2.0 on 2018-06-10 15:31
from django.db import migrations, models
import imagekit.models.fields
class Migration(migrations.Migration):
dependencies = [
('events', '0032_add_team_slug'),
]
operations = [
migrations.RemoveField(
model_name='team',
name='cover_img',
),
]

View file

@ -0,0 +1,19 @@
# Generated by Django 2.0 on 2018-06-10 15:34
from django.db import migrations, models
import imagekit.models.fields
class Migration(migrations.Migration):
dependencies = [
('events', '0033_remove_unused_team_cover_img'),
]
operations = [
migrations.AddField(
model_name='team',
name='cover_img',
field=models.ImageField(blank=True, null=True, upload_to='team_covers', verbose_name='Cover Image'),
),
]

View file

@ -4,6 +4,7 @@ from django.contrib.auth.models import User, Group
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext_lazy as _
from django.shortcuts import reverse from django.shortcuts import reverse
from django.utils import timezone from django.utils import timezone
from django.conf import settings
from rest_framework import serializers from rest_framework import serializers
from mptt.models import MPTTModel, TreeForeignKey from mptt.models import MPTTModel, TreeForeignKey
@ -132,8 +133,13 @@ class Event(models.Model):
def update_event_searchable(event): def update_event_searchable(event):
site = Site.objects.get(id=1) site = Site.objects.get(id=1)
event_url = "https://%s%s" % (site.domain, event.get_absolute_url()) if settings.DEBUG:
origin_url = "https://%s%s" % (site.domain, reverse('searchables')) schema = 'http'
else:
schema = 'https'
event_url = "%s://%s%s" % (schema, site.domain, event.get_absolute_url())
origin_url = "%s://%s%s" % (schema, site.domain, reverse('searchables'))
md5 = hashlib.md5() md5 = hashlib.md5()
federation_url = event_url.split('/') federation_url = event_url.split('/')
@ -152,10 +158,8 @@ def update_event_searchable(event):
searchable.event_url = event_url searchable.event_url = event_url
if event.team.category: searchable.img_url = "%s://%s%s" % (schema, site.domain, event.team.card_img_url)
searchable.img_url = event.team.category.img_url
else:
searchable.img_url = "https://%s%s" % (site.domain, '/static/img/team_placeholder.png')
searchable.event_title = event.name searchable.event_title = event.name
searchable.group_name = event.team.name searchable.group_name = event.team.name
searchable.start_time = event.start_time searchable.start_time = event.start_time
@ -179,8 +183,12 @@ def update_event_searchable(event):
def delete_event_searchable(event): def delete_event_searchable(event):
site = Site.objects.get(id=1) site = Site.objects.get(id=1)
event_url = "https://%s%s" % (site.domain, event.get_absolute_url()) if settings.DEBUG:
origin_url = "https://%s%s" % (site.domain, reverse('searchables')) schema = 'http'
else:
schema = 'https'
event_url = "%s://%s%s" % (schema, site.domain, event.get_absolute_url())
origin_url = "%s://%s%s" % (schema, site.domain, reverse('searchables'))
md5 = hashlib.md5() md5 = hashlib.md5()
federation_url = event_url.split('/') federation_url = event_url.split('/')
@ -295,7 +303,11 @@ class CommonEvent(models.Model):
def get_full_url(self): def get_full_url(self):
site = self.organization.site site = self.organization.site
return "https://%s%s" % (site.domain, self.get_absolute_url()) if settings.DEBUG:
schema = 'http'
else:
schema = 'https'
return "%s://%s%s" % (schema, site.domain, self.get_absolute_url())
@property @property
def slug(self): def slug(self):
@ -370,7 +382,11 @@ class EventSeries(models.Model):
def get_full_url(self): def get_full_url(self):
site = Site.objects.get(id=1) site = Site.objects.get(id=1)
return "https://%s%s" % (site.domain, self.get_absolute_url()) if settings.DEBUG:
schema = 'http'
else:
schema = 'https'
return "%s://%s%s" % (schema, site.domain, self.get_absolute_url())
@property @property
def slug(self): def slug(self):

View file

@ -1,12 +1,13 @@
from django.db import models from django.db import models
from django.contrib.sites.models import Site from django.contrib.sites.models import Site
from django.contrib.auth.models import User, Group, AnonymousUser from django.contrib.auth.models import User, Group, AnonymousUser
from django.contrib.staticfiles.templatetags.staticfiles import static
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext_lazy as _
from django.utils import timezone from django.utils import timezone
from django.conf import settings from django.conf import settings
from imagekit.models import ProcessedImageField from imagekit.models import ProcessedImageField, ImageSpecField
from imagekit.processors import ResizeToFill, ResizeToFit from imagekit.processors import ResizeToFill, ResizeToFit, Adjust, ColorOverlay
from rest_framework import serializers from rest_framework import serializers
@ -225,6 +226,21 @@ class Team(models.Model):
slug = models.CharField(max_length=256, null=False, blank=False, unique=True) slug = models.CharField(max_length=256, null=False, blank=False, unique=True)
organization = models.ForeignKey(Organization, related_name='teams', null=True, blank=True, on_delete=models.CASCADE) organization = models.ForeignKey(Organization, related_name='teams', null=True, blank=True, on_delete=models.CASCADE)
cover_img = models.ImageField(verbose_name=_('Cover Image'), upload_to='team_covers', null=True, blank=True)
tile_img = ImageSpecField(source='cover_img',
processors=[
Adjust(contrast=0.8, color=1),
ResizeToFill(338, 200),
],
format='PNG')
banner_img = ImageSpecField(source='cover_img',
processors=[
Adjust(contrast=0.8, color=1),
ResizeToFill(825, 200),
],
format='PNG')
description = models.TextField(blank=True, null=True) description = models.TextField(blank=True, null=True)
country = models.ForeignKey(Country, on_delete=models.CASCADE) country = models.ForeignKey(Country, on_delete=models.CASCADE)
@ -240,7 +256,6 @@ class Team(models.Model):
admin_profiles = models.ManyToManyField(UserProfile, related_name='admins', blank=True) admin_profiles = models.ManyToManyField(UserProfile, related_name='admins', blank=True)
contact_profiles = models.ManyToManyField(UserProfile, related_name='contacts', blank=True) contact_profiles = models.ManyToManyField(UserProfile, related_name='contacts', blank=True)
cover_img = models.URLField(_("Team Photo"), null=True, blank=True)
languages = models.ManyToManyField(Language, blank=True) languages = models.ManyToManyField(Language, blank=True)
active = models.BooleanField(_("Active Team"), default=True) active = models.BooleanField(_("Active Team"), default=True)
tz = models.CharField(max_length=32, verbose_name=_('Default Timezone'), default='UTC', choices=location.TimezoneChoices(), blank=False, null=False, help_text=_('The most commonly used timezone for this Team.')) tz = models.CharField(max_length=32, verbose_name=_('Default Timezone'), default='UTC', choices=location.TimezoneChoices(), blank=False, null=False, help_text=_('The most commonly used timezone for this Team.'))
@ -257,6 +272,15 @@ class Team(models.Model):
premium_started = models.DateTimeField(blank=True, null=True) premium_started = models.DateTimeField(blank=True, null=True)
premium_expires = models.DateTimeField(blank=True, null=True) premium_expires = models.DateTimeField(blank=True, null=True)
@property
def card_img_url(self):
if self.tile_img is not None and self.tile_img.name is not None:
return self.tile_img.url
elif self.category is not None:
return self.category.img_url
else:
return static('img/team_placeholder.png')
@property @property
def location_name(self): def location_name(self):
if self.city: if self.city:

View file

@ -12,4 +12,8 @@
<th><label for="id_tz">{{ team_form.tz.label }}:</label></th> <th><label for="id_tz">{{ team_form.tz.label }}:</label></th>
<td>{{ team_form.tz }}</td> <td>{{ team_form.tz }}</td>
</tr> </tr>
<tr>
<th><label for="id_cover_img">{{ team_form.cover_img.label }}:</label></th>
<td>{{ team_form.cover_img }}</td>
</tr>
</table> </table>

View file

@ -95,3 +95,18 @@ ul.errorlist li {
border-color: #ebcccc; border-color: #ebcccc;
color: #a94442; color: #a94442;
} }
.team-banner {
position: relative;
margin-bottom: 3px;
}
.team-banner .team-title {
position: absolute;
bottom: 0px;
left: 6px;
color: #FFF;
font-size: 2em;
font-weight: bold;
text-shadow: 2px 2px #444;
}

View file

@ -19,12 +19,10 @@
<div class="col-md-4"> <div class="col-md-4">
<div class="card mb-4 box-shadow"> <div class="card mb-4 box-shadow">
<div class="card-banner"> <div class="card-banner">
{% if event.team.category %} <a href="{{ event.get_absolute_url }}">
<img class="card-img-top" src="{{event.team.category.img_url}}" alt="{{event.name}}"> <img class="card-img-top" src="{{event.team.card_img_url}}" alt="{{event.name}}">
{% else %}
<img class="card-img-top" src="{% static 'img/team_placeholder.png' %}" alt="{{event.name}}">
{% endif %}
<p class="card-title">{{event.team.name}}</p> <p class="card-title">{{event.team.name}}</p>
</a>
</div> </div>
<div class="card-body"> <div class="card-body">
<p class="card-text"><strong><a class="card-link" href="{{event.get_absolute_url}}">{{event.name}}</a></strong></p> <p class="card-text"><strong><a class="card-link" href="{{event.get_absolute_url}}">{{event.name}}</a></strong></p>

View file

@ -99,8 +99,14 @@
<div class="fluid-container"> <div class="fluid-container">
<div class="row"> <div class="row">
<div class="col-md-9"> <div class="col-md-9">
<h2>{{ event.name }} {% if team.banner_img %}
</h2> <div class="team-banner">
<img class="card-img-top" src="{{ team.banner_img.url }}" alt="{{team.name}}'s cover image" height="200px" width="825px">
<h2 class="team-title">{{ event.name }}</h2>
</div>
{% else %}
<h2>{{ event.name }}</h2>
{% endif %}
<p class="text-muted">Hosted by <a href="{% url "show-team-by-slug" team.slug %}">{{ team.name }}</a></p> <p class="text-muted">Hosted by <a href="{% url "show-team-by-slug" team.slug %}">{{ team.name }}</a></p>
{% if settings.SOCIAL_AUTH_TWITTER_KEY %} {% if settings.SOCIAL_AUTH_TWITTER_KEY %}
<a href="https://twitter.com/intent/tweet?text=I'm+having+a+get+together!%0D{{event.name|urlencode}}&original_referer={{event.get_full_url|urlencode}}&url={{event.get_full_url|urlencode}}&hashtags=gettogether" data-size="large" class="btn btn-twitter btn-sm"><i class="fa fa-twitter"></i> Tweet</a> <a href="https://twitter.com/intent/tweet?text=I'm+having+a+get+together!%0D{{event.name|urlencode}}&original_referer={{event.get_full_url|urlencode}}&url={{event.get_full_url|urlencode}}&hashtags=gettogether" data-size="large" class="btn btn-twitter btn-sm"><i class="fa fa-twitter"></i> Tweet</a>

View file

@ -69,11 +69,7 @@
<div class="card mb-4 box-shadow"> <div class="card mb-4 box-shadow">
<div class="card-banner"> <div class="card-banner">
<a href="{% url 'show-team-by-slug' team.slug %}"> <a href="{% url 'show-team-by-slug' team.slug %}">
{% if team.category %} <img class="card-img-top" src="{{team.card_img_url}}" alt="{{team.name}}">
<img class="card-img-top" src="{{team.category.img_url}}" alt="{{team.name}}">
{% else %}
<img class="card-img-top" src="{% static 'img/team_placeholder.png' %}" alt="{{team.name}}">
{% endif %}
</a> </a>
<p class="card-title">{{team.name}}</p> <p class="card-title">{{team.name}}</p>
</div> </div>

View file

@ -3,7 +3,7 @@
{% block content %} {% block content %}
<h2>Get Together with friends</h2> <h2>Get Together with friends</h2>
<form action="{% url "create-team" %}" method="post" class="form"> <form action="{% url "create-team" %}" enctype="multipart/form-data" method="post" class="form">
{% csrf_token %} {% csrf_token %}
{% include "events/team_form.html" %} {% include "events/team_form.html" %}

View file

@ -2,7 +2,7 @@
{% load static %} {% load static %}
{% block content %} {% block content %}
<h2>Update {{team.name}}</h2> <h2>Update {{team.name}}</h2>
<form action="{% url "edit-team" team.id %}" method="post"> <form action="{% url "edit-team" team.id %}" enctype="multipart/form-data" method="post">
{% csrf_token %} {% csrf_token %}
{% include "events/team_form.html" %} {% include "events/team_form.html" %}
<br /> <br />

View file

@ -21,11 +21,7 @@
<div class="card mb-4 box-shadow"> <div class="card mb-4 box-shadow">
<div class="card-banner"> <div class="card-banner">
<a href="{% url 'show-team-by-slug' team.slug %}"> <a href="{% url 'show-team-by-slug' team.slug %}">
{% if team.category %} <img class="card-img-top" src="{{team.card_img_url}}" alt="{{team.name}}">
<img class="card-img-top" src="{{team.category.img_url}}" alt="{{team.name}}">
{% else %}
<img class="card-img-top" src="{% static 'img/team_placeholder.png' %}" alt="{{team.name}}">
{% endif %}
</a> </a>
<p class="card-title">{{team.name}}</p> <p class="card-title">{{team.name}}</p>
</div> </div>

View file

@ -1,5 +1,5 @@
{% extends "get_together/base.html" %} {% extends "get_together/base.html" %}
{% load markup tz %} {% load static markup tz %}
{% block add_to_title %} | {{team.name}}{% endblock %} {% block add_to_title %} | {{team.name}}{% endblock %}
@ -21,17 +21,24 @@
<div class="fluid-container"> <div class="fluid-container">
<div class="row"> <div class="row">
<div class="col-sm-9"> <div class="col-sm-9">
<h2>Welcome to {{ team.name }} {% if team.banner_img %}
</h2> <div class="team-banner">
{% if can_edit_team %} <img class="card-img-top" src="{{ team.banner_img.url }}" alt="{{team.name}}'s cover image" height="200px" width="825px">
<a href="{% url 'edit-team' team.id %}" class="btn btn-secondary btn-sm"><i class="fa fa-pencil"></i> Edit Team</a> <h2 class="team-title">Welcome to {{ team.name }}</h2>
<a href="{% url 'manage-members' team.id %}" class="btn btn-secondary btn-sm"><i class="fa fa-users"></i> Manage Members</a> </div>
{% endif %} {% else %}
{% if is_member %} <h2>Welcome to {{ team.name }}</h2>
{% if not team.owner_profile == request.user.profile %}<a href="{% url 'leave-team' team.id %}" class="btn btn-danger btn-sm">Leave Team</a>{% endif %} {% endif %}
{% else %}
<a href="{% url 'join-team' team.id %}" class="btn btn-success btn-sm">Join Team</a> {% if can_edit_team %}
{% endif %} <a href="{% url 'edit-team' team.id %}" class="btn btn-secondary btn-sm"><i class="fa fa-pencil"></i> Edit Team</a>
<a href="{% url 'manage-members' team.id %}" class="btn btn-secondary btn-sm"><i class="fa fa-users"></i> Manage Members</a>
{% endif %}
{% if is_member %}
{% if not team.owner_profile == request.user.profile %}<a href="{% url 'leave-team' team.id %}" class="btn btn-danger btn-sm">Leave Team</a>{% endif %}
{% else %}
<a href="{% url 'join-team' team.id %}" class="btn btn-success btn-sm">Join Team</a>
{% endif %}
<hr/> <hr/>
<table > <table >

View file

@ -80,7 +80,7 @@ def create_team(request, *args, **kwargs):
} }
return render(request, 'get_together/teams/create_team.html', context) return render(request, 'get_together/teams/create_team.html', context)
elif request.method == 'POST': elif request.method == 'POST':
form = NewTeamForm(request.POST) form = NewTeamForm(request.POST, request.FILES)
if form.is_valid(): if form.is_valid():
new_team = form.save() new_team = form.save()
new_team.owner_profile = request.user.profile new_team.owner_profile = request.user.profile
@ -111,7 +111,7 @@ def edit_team(request, team_id):
} }
return render(request, 'get_together/teams/edit_team.html', context) return render(request, 'get_together/teams/edit_team.html', context)
elif request.method == 'POST': elif request.method == 'POST':
form = TeamForm(request.POST, instance=team) form = TeamForm(request.POST, request.FILES, instance=team)
if form.is_valid(): if form.is_valid():
new_team = form.save() new_team = form.save()
new_team.owner_profile = request.user.profile new_team.owner_profile = request.user.profile