Skip to content

Commit

Permalink
Merge branch 'issue/7' into develop
Browse files Browse the repository at this point in the history
  • Loading branch information
JackMorganNZ committed Feb 24, 2017
2 parents 4409a4d + e905d03 commit dfab2a2
Show file tree
Hide file tree
Showing 29 changed files with 431 additions and 1 deletion.
6 changes: 5 additions & 1 deletion csunplugged/config/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
INSTALLED_APPS = [
'general.apps.GeneralConfig',
'topics.apps.TopicsConfig',
'resources.apps.ResourcesConfig',
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
Expand All @@ -61,7 +62,10 @@
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [os.path.join(SETTINGS_PATH, 'templates')],
'DIRS': [
os.path.join(SETTINGS_PATH, 'templates'),
os.path.join(SETTINGS_PATH, 'resources/content/')
],
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
Expand Down
1 change: 1 addition & 0 deletions csunplugged/config/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
urlpatterns = i18n_patterns(
url(r'', include('general.urls', namespace='general')),
url(r'^topics/', include('topics.urls', namespace='topics')),
url(r'^resources/', include('resources.urls', namespace='resources')),
url(r'^admin/', include(admin.site.urls)),
)
# ] + static(settings.STATIC_URL, documnet_root=settings.STATIC_ROOT)
Empty file.
3 changes: 3 additions & 0 deletions csunplugged/resources/admin.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
from django.contrib import admin

# Register your models here.
5 changes: 5 additions & 0 deletions csunplugged/resources/apps.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
from django.apps import AppConfig


class ResourcesConfig(AppConfig):
name = 'resources'
11 changes: 11 additions & 0 deletions csunplugged/resources/content/fonts/PatrickHand-LICENSE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# Copyright

Copyright (c) 2012 Patrick Wagesreiter ([mail@patrickwagesreiter.at](mailto:mail@patrickwagesreiter.at))

# License

This Font Software is licensed under the SIL Open Font License, Version 1.1. This license is available with a FAQ at: http://scripts.sil.org/OFL

# More info

**Designer:** Patrick Wagesreiter http://www.patrickwagesreiter.at
Binary file not shown.
3 changes: 3 additions & 0 deletions csunplugged/resources/content/resources.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
sorting-network:
name: Sorting Network
folder: sorting_network
102 changes: 102 additions & 0 deletions csunplugged/resources/content/sorting_network/generate.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
from django.http import HttpResponse
from django.template.loader import render_to_string

from weasyprint import HTML, CSS
from PIL import Image, ImageDraw, ImageFont
from io import BytesIO
import base64
from random import sample
from multiprocessing import Pool
from django.utils.translation import ugettext as _

MM_TO_PIXEL_RATIO = 3.78

def generate_image(base_image_settings):
# Load image
base_image = Image.open(base_image_settings['base_image_path'])
draw = ImageDraw.Draw(base_image)

# Add numbers to text if needed
if base_image_settings['prefilled_values'] != 'blank':
font = ImageFont.truetype(base_image_settings['font_path'], base_image_settings['font_size'])
numbers = sample(range(base_image_settings['range_min'], base_image_settings['range_max']), 6)
base_coord_x = 70
base_coord_y = 2560
coord_x_increment = 204
for number in numbers:
text = str(number)
text_width, text_height = draw.textsize(text, font=font)
coord_x = base_coord_x - (text_width / 2)
coord_y = base_coord_y - (text_height / 2)
draw.text(
(coord_x, coord_y),
text,
font=font,
fill='#000'
)
base_coord_x += coord_x_increment

# Resize image to reduce file size
if base_image_settings['paper_size'] == "a4":
max_pixel_height = 267 * MM_TO_PIXEL_RATIO
elif base_image_settings['paper_size'] == "letter":
max_pixel_height = 249 * MM_TO_PIXEL_RATIO
(width, height) = base_image.size
if height > max_pixel_height:
ratio = max_pixel_height / height
width *= ratio
height *= ratio
base_image = base_image.resize((int(width), int(height)), Image.ANTIALIAS)

# Save image to buffer
image_buffer = BytesIO()
base_image.save(image_buffer, format='PNG')
return base64.b64encode(image_buffer.getvalue())

class PageCreator(object):
def __init__(self, base_image_settings):
self.base_image_settings = base_image_settings

def __call__(self, call_num):
return generate_image(self.base_image_settings)

def pdf(request, resource, **kwargs):
context = dict()

prefilled_values = request.GET['prefilled_values']
paper_size = request.GET['size']

base_image_settings = dict()
base_image_settings['prefilled_values'] = prefilled_values
base_image_settings['paper_size'] = paper_size
if prefilled_values == 'easy':
base_image_settings['range_min'] = 1
base_image_settings['range_max'] = 10
base_image_settings['font_size'] = 150
elif prefilled_values == 'medium':
base_image_settings['range_min'] = 10
base_image_settings['range_max'] = 100
base_image_settings['font_size'] = 120
elif prefilled_values == 'hard':
base_image_settings['range_min'] = 100
base_image_settings['range_max'] = 1000
base_image_settings['font_size'] = 90

# Create resource image
base_image_settings['base_image_path'] = 'resources/content/{}/sorting-network-colour.png'.format(resource.folder)
base_image_settings['font_path'] = 'resources/content/fonts/PatrickHand-Regular.ttf'
with Pool() as pool:
context['resource_images'] = pool.map(PageCreator(base_image_settings), range(0, int(request.GET['copies'])))

# Write to PDF
context['paper_size'] = paper_size
context['resource'] = resource
html_string = render_to_string('resources/base-resource-pdf.html', context)

html = HTML(string=html_string, base_url=request.build_absolute_uri())
base_css = CSS(string=open('static/css/print-resource-pdf.css', encoding='UTF-8').read())
pdf_file = html.write_pdf(stylesheets=[base_css]);

response = HttpResponse(pdf_file, content_type='application/pdf')
response['Content-Disposition'] = 'attachment; filename="example.pdf"'
return response
41 changes: 41 additions & 0 deletions csunplugged/resources/content/sorting_network/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
{% extends "resources/base-resource.html" %}

<!-- Name of resource -->
{% block name %}{{ resource.name }}{% endblock name %}

<!-- Description of resource -->
{% block description %}
<p>This resource will show you how computers sort random numbers into order using
a thing called a sorting network.</p>
{% endblock description %}

{% block generation_form %}
<fieldset>
<legend>Prefill with Numbers</legend>
<input type="radio" name="prefilled_values" id="none" value="blank" checked="checked">
<label for="blank">None (Blank)</label>
<br>
<input type="radio" name="prefilled_values" id="easy" value="easy">
<label for="size_easy">Easy Numbers (1 digit)</label>
<br>
<input type="radio" name="prefilled_values" id="medium" value="medium">
<label for="medium">Medium Numbers (2 digits)</label>
<br>
<input type="radio" name="prefilled_values" id="hard" value="hard">
<label for="hard">Hard Numbers (3 digits)</label>
</fieldset>

<fieldset>
<legend>Paper Size</legend>
<input type="radio" name="size" id="size_a4" value="a4" checked="checked">
<label for="size_a4">A4</label>
<br>
<input type="radio" name="size" id="size_letter" value="letter">
<label for="size_letter">US Letter</label>
</fieldset>

<fieldset>
<legend>Number of Copies</legend>
<input type="number" name="copies" value=1 min=1 max=50>
</fieldset>
{% endblock generation_form %}
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Empty file.
Empty file.
40 changes: 40 additions & 0 deletions csunplugged/resources/management/commands/loadresources.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
from django.core.management.base import BaseCommand, CommandError
from resources.models import Resource
from django.db import transaction
import yaml
import os
import os.path
import sys

class Command(BaseCommand):
help = 'Reads resource data and adds to database'

def handle(self, *args, **options):
"""The function called when the loadresources command is given"""
self.BASE_PATH = 'resources/content/' # TODO: Hardcoded for prototype
self.load_log = []
self.resource_list = self.read_yaml('resources.yaml')
self.load_resources(self.resource_list)
self.print_load_log()

def read_yaml(self, filepath):
path = os.path.join(self.BASE_PATH, filepath)
structure_file = open(path, encoding='UTF-8').read()
return yaml.load(structure_file)

def print_load_log(self):
for (log, indent) in self.load_log:
self.stdout.write('{indent}{text}'.format(indent=' '*indent,text=log))
self.stdout.write('\n')
self.load_log = []

@transaction.atomic
def load_resources(self, resource_list):
for (resource_slug, resource_data) in resource_list.items():
resource = Resource(
slug=resource_slug,
name=resource_data['name'],
folder=resource_data['folder'],
)
resource.save()
self.load_log.append(('\nAdded Resource: {}'.format(resource.name), 0))
24 changes: 24 additions & 0 deletions csunplugged/resources/migrations/0001_initial.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.10.5 on 2017-02-21 06:23
from __future__ import unicode_literals

from django.db import migrations, models


class Migration(migrations.Migration):

initial = True

dependencies = [
]

operations = [
migrations.CreateModel(
name='Resource',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('slug', models.SlugField(unique=True)),
('name', models.CharField(max_length=200)),
],
),
]
21 changes: 21 additions & 0 deletions csunplugged/resources/migrations/0002_resource_folder.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.10.5 on 2017-02-22 23:30
from __future__ import unicode_literals

from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
('resources', '0001_initial'),
]

operations = [
migrations.AddField(
model_name='resource',
name='folder',
field=models.CharField(default='', max_length=200),
preserve_default=False,
),
]
Empty file.
11 changes: 11 additions & 0 deletions csunplugged/resources/models.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
from django.db import models


class Resource(models.Model):
# Auto-incrementing 'id' field is automatically set by Django
slug = models.SlugField(unique=True)
name = models.CharField(max_length=200)
folder = models.CharField(max_length=200)

def __str__(self):
return self.name
3 changes: 3 additions & 0 deletions csunplugged/resources/tests.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
from django.test import TestCase

# Create your tests here.
25 changes: 25 additions & 0 deletions csunplugged/resources/urls.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
from django.conf.urls import url

from . import views

app_name = 'resources'
urlpatterns = [
# eg: /resource/
url(
r'^$',
views.IndexView.as_view(),
name='index'
),
# eg: /resource/example-resource/
url(
r'^(?P<resource_slug>[-\w]+)/$',
views.resource,
name='resource'
),
# eg: /resource/example-resource/generate/
url(
r'^(?P<resource_slug>[-\w]+)/generate$',
views.generate_resource,
name='generate'
),
]
31 changes: 31 additions & 0 deletions csunplugged/resources/views.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
from django.views import generic
from django.utils.translation import ugettext
from django.shortcuts import get_object_or_404, render
from django.http import Http404
from resources.models import Resource
import importlib

class IndexView(generic.ListView):
template_name = 'resources/index.html'
context_object_name = 'all_resources'

def get_queryset(self):
"""Return all topics"""
return Resource.objects.order_by('name')

def resource(request, resource_slug):
resource = get_object_or_404(Resource, slug=resource_slug)
template_string = '{}/index.html'.format(resource.folder)
context = dict()
context['resource'] = resource
return render(request, template_string, context)

def generate_resource(request, resource_slug, **kwargs):
module_name = resource_slug.replace('-', '_')
resource = get_object_or_404(Resource, slug=resource_slug)
module_path = 'resources.content.{}.generate'.format(resource.folder)
try:
pdf_view = importlib.import_module(module_path)
except ImportError:
raise Http404("PDF generation does not exist for resource: {}".format(resource_slug))
return pdf_view.pdf(request, resource, **kwargs)
30 changes: 30 additions & 0 deletions csunplugged/static/css/print-resource-pdf.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
div#base-image-container {
text-align: center;
page-break-after: always;
}
img#base-image {
max-width: 100%;
margin: 8mm;
}
.fixed-running-element{
text-align: center;
width: 100%;
position: fixed;
margin: 0;
font-family: 'Open Sans', sans-serif;
font-size: 0.8em;
color: #888;
}
.fixed-running-element img {
max-height: 1.5em;
vertical-align: text-bottom;
}
.fixed-running-element .logo-text {
color: #cc0423;
}
footer {
bottom: 0;
}
header {
top: 0;
}
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added csunplugged/static/img/logo-without-subtitle.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions csunplugged/templates/base.html
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
<div class="navbar-nav">
<a class="nav-item nav-link" href="{% url 'general:home' %}">Home</a>
<a class="nav-item nav-link" href="{% url 'topics:index' %}">Topics</a>
<a class="nav-item nav-link" href="{% url 'resources:index' %}">Resources</a>
<a class="nav-item nav-link" href="{% url 'general:about' %}">About</a>
</div>
</div>
Expand Down

0 comments on commit dfab2a2

Please sign in to comment.