diff --git a/home/admin.py b/home/admin.py index d1f582d..b3a5383 100644 --- a/home/admin.py +++ b/home/admin.py @@ -2,3 +2,4 @@ from .models import * admin.site.register(Resource) +admin.site.register(Event) diff --git a/home/migrations/0001_initial.py b/home/migrations/0001_initial.py index fe56e9e..db99f9c 100644 --- a/home/migrations/0001_initial.py +++ b/home/migrations/0001_initial.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# Generated by Django 1.11.5 on 2018-01-26 02:12 +# Generated by Django 1.11.5 on 2018-05-06 18:39 from __future__ import unicode_literals from django.db import migrations, models @@ -13,6 +13,22 @@ class Migration(migrations.Migration): ] operations = [ + migrations.CreateModel( + name='Events', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('title', models.CharField(max_length=128, null=True)), + ('image', models.FileField(upload_to='events_images/')), + ('brief', models.CharField(max_length=500, null=True)), + ('url', models.URLField(db_index=True, max_length=128, null=True)), + ('date', models.DateField()), + ('typeofentry', models.CharField(choices=[('past', 'Past Event'), ('upcoming', 'Upcoming Event'), ('suggested', 'Suggested Event')], default='suggestion', max_length=20)), + ('suggested_by', models.IntegerField(blank=True, null=True)), + ], + options={ + 'permissions': (('approve_suggestion', 'Approve a suggested event'),), + }, + ), migrations.CreateModel( name='Resource', fields=[ diff --git a/home/migrations/0002_auto_20180506_2100.py b/home/migrations/0002_auto_20180506_2100.py new file mode 100644 index 0000000..c1798d3 --- /dev/null +++ b/home/migrations/0002_auto_20180506_2100.py @@ -0,0 +1,20 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.11.5 on 2018-05-06 21:00 +from __future__ import unicode_literals + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('home', '0001_initial'), + ] + + operations = [ + migrations.AlterField( + model_name='events', + name='typeofentry', + field=models.CharField(choices=[('past', 'Past Event'), ('upcoming', 'Upcoming Event'), ('suggested', 'Suggested Event')], default='suggested', max_length=20), + ), + ] diff --git a/home/migrations/0003_auto_20180507_1406.py b/home/migrations/0003_auto_20180507_1406.py new file mode 100644 index 0000000..ea92636 --- /dev/null +++ b/home/migrations/0003_auto_20180507_1406.py @@ -0,0 +1,19 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.11.5 on 2018-05-07 14:06 +from __future__ import unicode_literals + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('home', '0002_auto_20180506_2100'), + ] + + operations = [ + migrations.RenameModel( + old_name='Events', + new_name='Event', + ), + ] diff --git a/home/migrations/0004_auto_20180507_1520.py b/home/migrations/0004_auto_20180507_1520.py new file mode 100644 index 0000000..b946971 --- /dev/null +++ b/home/migrations/0004_auto_20180507_1520.py @@ -0,0 +1,20 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.11.5 on 2018-05-07 15:20 +from __future__ import unicode_literals + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('home', '0003_auto_20180507_1406'), + ] + + operations = [ + migrations.AlterField( + model_name='event', + name='image', + field=models.FileField(blank=True, null=True, upload_to='events_images/'), + ), + ] diff --git a/home/migrations/0005_auto_20180507_1524.py b/home/migrations/0005_auto_20180507_1524.py new file mode 100644 index 0000000..4bd7552 --- /dev/null +++ b/home/migrations/0005_auto_20180507_1524.py @@ -0,0 +1,20 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.11.5 on 2018-05-07 15:24 +from __future__ import unicode_literals + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('home', '0004_auto_20180507_1520'), + ] + + operations = [ + migrations.AlterField( + model_name='event', + name='image', + field=models.FileField(upload_to='events_images/'), + ), + ] diff --git a/home/models.py b/home/models.py index a574d8c..76a3d31 100644 --- a/home/models.py +++ b/home/models.py @@ -6,4 +6,22 @@ class Resource(models.Model): url = models.URLField(max_length=128, db_index=True, blank=False, null=True) def __str__(self): - return self.title \ No newline at end of file + return self.title + +class Event(models.Model): + class Meta: + permissions = ( + ('approve_suggestion', 'Approve a suggested event'), + ) + title = models.CharField(max_length=128, blank=False, null=True) + image=models.FileField(upload_to='events_images/') + brief = models.CharField(max_length=500, blank=False, null=True) + url = models.URLField(max_length=128, db_index=True, blank=False, null=True) + date=models.DateField() + typeofentry=models.CharField(max_length=20, choices = (("past", "Past Event"), + ("upcoming", "Upcoming Event"), + ("suggested", "Suggested Event")) , default='suggested') + suggested_by = models.IntegerField(blank=True, null=True) + + def __str__(self): + return self.title \ No newline at end of file diff --git a/home/urls.py b/home/urls.py index 957d1c7..b326df2 100644 --- a/home/urls.py +++ b/home/urls.py @@ -3,9 +3,12 @@ app_name='home' urlpatterns = [ -url(r'^$', views.Home.as_view(), name = 'home'), -url(r'^resources/', views.Resources.as_view(), name = 'resources') + url(r'^$', views.Home.as_view(), name = 'home'), + url(r'^resources/', views.Resources.as_view(), name = 'resources'), + url(r'^events/suggest', views.SuggestEvent.as_view(), name = 'suggest_event'), + url(r'^events/approve/(?P[^/]+)', views.ApproveEvent.as_view(), name = 'approve_event'), + url(r'^events/reject/(?P[^/]+)', views.RejectEvent.as_view(), name = 'reject_event'), + url(r'^events/', views.Events.as_view(), name='events'), ] handler404 = 'Template404.as_view()' - diff --git a/home/views.py b/home/views.py index 2a5382a..fdae64a 100644 --- a/home/views.py +++ b/home/views.py @@ -1,7 +1,11 @@ from django import views -from django.shortcuts import render +from django.shortcuts import render, Http404, HttpResponseRedirect from django.views.generic import TemplateView +from django.views.generic.edit import CreateView from .models import * +from datetime import date +from django.contrib.auth.mixins import LoginRequiredMixin +from django.core.urlresolvers import reverse class Template404(TemplateView): @@ -13,3 +17,54 @@ class Home(TemplateView): class Resources(views.View): def get(self, request, *args, **kwargs): return render(request, "home/resources/resources.html", {'resources': Resource.objects.all()}) + +class Events(views.View): + def get(self, request, *args, **kwargs): + events = Event.objects.all() + + for event in events: + if event.date < date.today(): + event.typeofentry='Past Events' + + past_events = events.filter(typeofentry="past") + upcoming_events = events.filter(typeofentry="upcoming") + suggested_events = [] + approved_events = [] + if request.user.has_perm('home.approve_suggestion'): + suggested_events = events.filter(typeofentry="suggested") + else: + if request.user.is_authenticated: + suggested_events = events.filter(typeofentry="suggested", suggested_by=request.user.pk) + approved_events = events.filter(typeofentry__in=['upcoming','past'], suggested_by=request.user.pk) + return render(request, 'home/events/events.html', {'past': past_events, 'upcoming': upcoming_events, + 'suggested': suggested_events, 'approved': approved_events}) + +class SuggestEvent(LoginRequiredMixin, CreateView): + login_url = '/login/' + model = Event + fields = ['title', 'url', 'image', 'brief', 'date'] + template_name = 'home/events/suggest_events.html' + success_url = '/' + + def form_valid(self, form): + form.instance.suggested_by = self.request.user.pk + return super(SuggestEvent, self).form_valid(form) + +class ApproveEvent(LoginRequiredMixin, views.View): + def get(self, request, pk, *args, **kwargs): + if request.user.has_perm('home.approve_suggestion'): + event = Event.objects.get(pk=pk) + event.typeofentry = "upcoming" + event.save() + return HttpResponseRedirect(reverse('home:events')) + else: + return Http404 + +class RejectEvent(LoginRequiredMixin, views.View): + def get(self, request, pk, *args, **kwargs): + if request.user.has_perm('home.approve_suggestion'): + event = Event.objects.get(pk=pk) + event.delete() + return HttpResponseRedirect(reverse('home:events')) + else: + return Http404 diff --git a/pclubWebsite/settings.py b/pclubWebsite/settings.py index aefc04b..ddbfbd6 100644 --- a/pclubWebsite/settings.py +++ b/pclubWebsite/settings.py @@ -24,7 +24,7 @@ SECRET_KEY = '$4p#tsin((&rnm!%696^2xutz_-n5k)o&mnwg3z*^f7&--99h&' # SECURITY WARNING: don't run with debug turned on in production! -DEBUG = False +DEBUG = True ALLOWED_HOSTS = ['*'] @@ -41,6 +41,7 @@ 'django.contrib.staticfiles', 'home', 'social_django', + 'storages', ] MIDDLEWARE = [ @@ -85,6 +86,13 @@ 'django.contrib.auth.backends.ModelBackend', ) +AWS_STORAGE_BUCKET_NAME = 'pclubuiet' +AWS_S3_REGION_NAME = 'us-east-2' +AWS_ACCESS_KEY_ID = 'AKIAJKJHQNOHPD3UNEUQ' +AWS_SECRET_ACCESS_KEY = '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' + +AWS_S3_CUSTOM_DOMAIN = '%s.s3.amazonaws.com' % AWS_STORAGE_BUCKET_NAME + SOCIAL_AUTH_GITHUB_KEY = '1bb44747fe47d4452460' SOCIAL_AUTH_GITHUB_SECRET = '888dbf7469fa2496f4508d99c17ff178d6bade67' @@ -153,4 +161,8 @@ MEDIA_ROOT = os.path.join(BASE_DIR, 'media') MEDIA_URL = '/media/' +MEDIAFILES_LOCATION = 'media' +DEFAULT_FILE_STORAGE = 's3_storages.MediaStorage' + STATICFILES_STORAGE = 'whitenoise.storage.CompressedManifestStaticFilesStorage' +DEFAULT_FILE_STORAGE = 's3_storages.MediaStorage' diff --git a/pclubWebsite/urls.py b/pclubWebsite/urls.py index df784d4..8d10202 100644 --- a/pclubWebsite/urls.py +++ b/pclubWebsite/urls.py @@ -18,6 +18,8 @@ from django.contrib.auth import views as auth_views from django.views.generic import TemplateView from django.views.generic.base import RedirectView +from django.conf.urls.static import static +from django.conf import settings urlpatterns = [ url(r'^sw.js', (TemplateView.as_view(template_name="sw.js", content_type='application/javascript', )), name='sw.js'), @@ -27,4 +29,4 @@ url(r'^logout/$', auth_views.logout, name='logout'), url(r'^oauth/', include('social_django.urls', namespace='social')), url(r'^$', RedirectView.as_view(url='/home/')), -] +] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT) diff --git a/requirements.txt b/requirements.txt index bea9041..64ffe82 100644 --- a/requirements.txt +++ b/requirements.txt @@ -4,4 +4,8 @@ gunicorn==19.7.1 psycopg2==2.7.3.1 pytz==2017.2 whitenoise==3.3.1 -social-auth-app-django==2.1.0 \ No newline at end of file +social-auth-app-django==2.1.0 +Pillow==5.1.0 +django-storages==1.6.6 +boto3==1.7.10 +datetime==4.2.0 diff --git a/s3_storages.py b/s3_storages.py new file mode 100644 index 0000000..64a9dda --- /dev/null +++ b/s3_storages.py @@ -0,0 +1,5 @@ +from django.conf import settings +from storages.backends.s3boto3 import S3Boto3Storage + +class MediaStorage(S3Boto3Storage): + location = settings.MEDIAFILES_LOCATION diff --git a/templates/base.html b/templates/base.html index ff79ed6..a92c294 100644 --- a/templates/base.html +++ b/templates/base.html @@ -11,10 +11,7 @@ - - - - + @@ -57,6 +54,7 @@ {% endif %}
  • Home
  • Resources
  • +
  • Events
  • {% if user.username %}
  • Logout
  • {% else %} @@ -71,6 +69,7 @@ {% endif %}
  • Home
  • Resources
  • +
  • Events
  • {% if user.username %}
  • Logout
  • {% else %} diff --git a/templates/home/events/events.html b/templates/home/events/events.html new file mode 100644 index 0000000..378f1b2 --- /dev/null +++ b/templates/home/events/events.html @@ -0,0 +1,116 @@ +{% extends 'base.html' %} +{% block styles %} + +{%endblock%} +{% block content %} +

    Events

    + + +
    +
    +
    + {% for event in upcoming %} +
    + Card image cap +
    +
    +

    {{event.title}}

    +

    {{event.brief}}

    + Know More +
    + +
    + {% endfor %} + {% if not upcoming.count %} + No Upcoming Events. + {% endif %} +
    +
    + +
    +
    + {% for event in past %} +
    + Card image cap +
    +
    +

    {{event.title}}

    +

    {{event.brief}}

    + Know More +
    + +
    + {% endfor %} + {% if not past.count %} + No Past Events. + {% endif %} +
    +
    + +
    + {% if not perms.home.approve_suggested %} +

    Your Suggestions

    +

    Approved

    +
    + {% for event in approved %} +
    + Card image cap +
    +
    +

    {{event.title}}

    +

    {{event.brief}}

    + Know More +
    + +
    + {% endfor %} +
    + {% if not approved.count %} + No events. + {% endif %} +
    +

    Awaiting Approval

    + {% else %} +

    All Suggestions Awaiting Approval

    + {% endif %} +
    + {% for event in suggested %} +
    + Card image cap +
    +
    +

    {{event.title}}

    + {% if perms.home.approve_suggested %} + Approve + {% endif %} + {% if perms.home.approve_suggested %} + Reject + {% endif %} +

    {{event.brief}}

    + Know More +
    + +
    + {% endfor %} + {% if not suggested.count %} + No events. + {% endif %} +
    +
    + Suggest an Event +
    +
    + +{% endblock %} diff --git a/templates/home/events/suggest_events.html b/templates/home/events/suggest_events.html new file mode 100644 index 0000000..5c3f838 --- /dev/null +++ b/templates/home/events/suggest_events.html @@ -0,0 +1,15 @@ +{% extends 'base.html' %} +{% block styles %} + +{% endblock %} +{% block content %} +
    + {% csrf_token %} + {{ form.as_p }} + +
    +{% endblock %}