no fax
[edumed.git] / catalogue / publish.py
1 # -*- coding: utf-8
2 from django.core.files import File
3 from django.core.urlresolvers import reverse
4 from librarian import DocProvider, IOFile
5 from librarian.pyhtml import EduModuleFormat
6 from librarian.pypdf import EduModulePDFFormat
7 from .models import Lesson, Attachment
8 from fnpdjango.utils.text.slughifi import slughifi
9
10
11 # TODO: Using sorl.thumbnail for now,
12 # but this should be done in Librarian,
13 # directly using convert or PIL as a fallback.
14 def get_image(src_img_path, width=None, default_width=1600, formats=('PNG', 'JPEG', 'GIF')):
15     """ Returns an object with `url` and `storage` attributes,
16         or None if using the original image is OK.
17     """
18
19     from PIL import Image
20     from sorl.thumbnail import get_thumbnail
21
22     # Does it need converting?
23     # Yes, if width is given explicitly.
24     convert = width is not None
25     if not convert:
26         # Looks like it doesn't need converting.
27         # But let's try opening it and checking its type.
28         try:
29             simg = Image.open(src_img_path)
30         except IOError:
31             # It doesn't look like image,
32             # but maybe it's convertable to one.
33             convert = True
34         else:
35             if simg.format not in formats:
36                 # It's an image, but it's in some weird format.
37                 convert = True
38                 width = simg.size[0]
39
40     if convert:
41         if width is None:
42             width = default_width
43         try:
44             return get_thumbnail(src_img_path, '%sx%s' % (width, 10*width))
45         except:
46             # hard to predict what solr raises on invalid image
47             return None
48     else:
49         return None
50
51
52 class HtmlFormat(EduModuleFormat):
53     IMAGE_FORMATS = ('PNG', 'JPEG', 'GIF')
54     DEFAULT_IMAGE_WIDTH = 1600
55
56     def find_attachment(self, slug, fmt):
57         lesson_slug = self.wldoc.book_info.url.slug
58         try:
59             # If already saved, use it.
60             att = Attachment.objects.get(lesson__slug=lesson_slug,
61                                          slug=slug, ext=fmt)
62         except Attachment.DoesNotExist, e:
63             # If attached to source IOFile, save now.
64             att_name = "%s.%s" % (slug, fmt)
65             try:
66                 att_file = self.wldoc.source.attachments[att_name]
67             except KeyError:
68                 print u"ATTACHMENT MISSING:", att_name
69                 raise self.MaterialNotFound()
70             else:
71                 lesson = Lesson.objects.get(slug=lesson_slug)
72                 att = lesson.attachment_set.create(slug=slug, ext=fmt)
73                 att.file.save(att_name, File(att_file.get_file()))
74                 return att
75         else:
76             return att
77
78     def url_for_material(self, slug, fmt):
79         return self.find_attachment(slug, fmt).file.url
80
81     def url_for_image(self, slug, fmt, width=None):
82         try:
83             src_img = self.find_attachment(slug, fmt).file
84         except self.MaterialNotFound:
85             return ''
86         img = get_image(src_img.path, width, self.DEFAULT_IMAGE_WIDTH, self.IMAGE_FORMATS)
87         return (img or src_img).url
88
89     def text_to_anchor(self, text):
90         return slughifi(text)
91
92     def get_forma_url(self, forma):
93         return '%s#%s' % (
94             reverse('catalogue_lesson', args=['metody']),
95             self.text_to_anchor(forma)
96         )
97
98     def get_help_url(self, naglowek):
99         return '%s%s#%s' % (
100             '//edukacjamedialna.edu.pl',
101             reverse('info', args=['jak-korzystac/']),
102             self.naglowek_to_anchor(naglowek)
103         )
104
105
106 class PdfFormat(EduModulePDFFormat):
107     IMAGE_FORMATS = ('PNG', 'JPEG', 'GIF')
108     DEFAULT_IMAGE_WIDTH = 1600
109
110     def get_image(self, name):
111         src_img = super(PdfFormat, self).get_image(name)
112         img = get_image(
113             src_img.get_filename(),
114             default_width=self.DEFAULT_IMAGE_WIDTH,
115             formats=self.IMAGE_FORMATS)
116         if img:
117             return IOFile.from_filename(img.storage.path(img))
118         else:
119             return src_img
120
121
122 class OrmDocProvider(DocProvider):
123     def by_slug(self, slug):
124         """Should return a file-like object with a WL document XML."""
125         return IOFile.from_filename(Lesson.objects.get(slug=slug).xml_file.path)