Commit | Line | Data |
---|---|---|
93bdab9d | 1 | # GNU MediaGoblin -- federated, autonomous media hosting |
cf29e8a8 | 2 | # Copyright (C) 2011, 2012 MediaGoblin contributors. See AUTHORS. |
93bdab9d JW |
3 | # |
4 | # This program is free software: you can redistribute it and/or modify | |
5 | # it under the terms of the GNU Affero General Public License as published by | |
6 | # the Free Software Foundation, either version 3 of the License, or | |
7 | # (at your option) any later version. | |
8 | # | |
9 | # This program is distributed in the hope that it will be useful, | |
10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of | |
11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
12 | # GNU Affero General Public License for more details. | |
13 | # | |
14 | # You should have received a copy of the GNU Affero General Public License | |
15 | # along with this program. If not, see <http://www.gnu.org/licenses/>. | |
16 | ||
17 | import Image | |
8e5f9746 | 18 | import os |
92f129b5 | 19 | import logging |
93bdab9d | 20 | |
93bdab9d | 21 | from mediagoblin import mg_globals as mgg |
4535f759 JW |
22 | from mediagoblin.processing import BadMediaFail, \ |
23 | create_pub_filepath, THUMB_SIZE, MEDIUM_SIZE | |
a180ca26 JW |
24 | from mediagoblin.tools.exif import exif_fix_image_orientation, \ |
25 | extract_exif, clean_exif, get_gps_data, get_useful | |
93bdab9d | 26 | |
92f129b5 JW |
27 | _log = logging.getLogger(__name__) |
28 | ||
29 | SUPPORTED_FILETYPES = ['png', 'gif', 'jpg', 'jpeg'] | |
30 | ||
ec4261a4 | 31 | def sniff_handler(media_file, **kw): |
92f129b5 JW |
32 | if not kw.get('media') == None: # That's a double negative! |
33 | name, ext = os.path.splitext(kw['media'].filename) | |
34 | clean_ext = ext[1:].lower() # Strip the . from ext and make lowercase | |
35 | ||
36 | _log.debug('name: {0}\next: {1}\nlower_ext: {2}'.format( | |
37 | name, | |
38 | ext, | |
39 | clean_ext)) | |
40 | ||
41 | if clean_ext in SUPPORTED_FILETYPES: | |
42 | _log.info('Found file extension in supported filetypes') | |
43 | return True | |
44 | else: | |
45 | _log.debug('Media present, extension not found in {1}'.format( | |
46 | SUPPORTED_FILETYPES)) | |
47 | else: | |
48 | _log.warning('Need additional information (keyword argument \'media\')' | |
49 | ' to be able to handle sniffing') | |
50 | ||
ec4261a4 JW |
51 | return False |
52 | ||
93bdab9d JW |
53 | def process_image(entry): |
54 | """ | |
55 | Code to process an image | |
56 | """ | |
57 | workbench = mgg.workbench_manager.create_workbench() | |
8e5f9746 JW |
58 | # Conversions subdirectory to avoid collisions |
59 | conversions_subdir = os.path.join( | |
60 | workbench.dir, 'conversions') | |
61 | os.mkdir(conversions_subdir) | |
93bdab9d | 62 | |
8545cfc9 | 63 | queued_filepath = entry.queued_media_file |
93bdab9d JW |
64 | queued_filename = workbench.localized_file( |
65 | mgg.queue_store, queued_filepath, | |
66 | 'source') | |
67 | ||
58dd8d9e PUS |
68 | filename_bits = os.path.splitext(queued_filename) |
69 | basename = os.path.split(filename_bits[0])[1] | |
70 | extension = filename_bits[1].lower() | |
8e5f9746 | 71 | |
e8e444a8 JW |
72 | # EXIF extraction |
73 | exif_tags = extract_exif(queued_filename) | |
74 | gps_data = get_gps_data(exif_tags) | |
75 | ||
93bdab9d JW |
76 | try: |
77 | thumb = Image.open(queued_filename) | |
78 | except IOError: | |
79 | raise BadMediaFail() | |
80 | ||
e8e444a8 JW |
81 | thumb = exif_fix_image_orientation(thumb, exif_tags) |
82 | ||
93bdab9d | 83 | thumb.thumbnail(THUMB_SIZE, Image.ANTIALIAS) |
93bdab9d | 84 | |
8e5f9746 JW |
85 | # Copy the thumb to the conversion subdir, then remotely. |
86 | thumb_filename = 'thumbnail' + extension | |
87 | thumb_filepath = create_pub_filepath(entry, thumb_filename) | |
63bd7c04 | 88 | |
8e5f9746 JW |
89 | tmp_thumb_filename = os.path.join( |
90 | conversions_subdir, thumb_filename) | |
63bd7c04 | 91 | |
8e5f9746 JW |
92 | with file(tmp_thumb_filename, 'w') as thumb_file: |
93 | thumb.save(thumb_file) | |
63bd7c04 | 94 | |
8e5f9746 JW |
95 | mgg.public_store.copy_local_to_storage( |
96 | tmp_thumb_filename, thumb_filepath) | |
93bdab9d JW |
97 | |
98 | # If the size of the original file exceeds the specified size of a `medium` | |
99 | # file, a `medium.jpg` files is created and later associated with the media | |
100 | # entry. | |
101 | medium = Image.open(queued_filename) | |
63bd7c04 JW |
102 | |
103 | # Fix orientation | |
e8e444a8 | 104 | medium = exif_fix_image_orientation(medium, exif_tags) |
93bdab9d JW |
105 | |
106 | if medium.size[0] > MEDIUM_SIZE[0] or medium.size[1] > MEDIUM_SIZE[1]: | |
107 | medium.thumbnail(MEDIUM_SIZE, Image.ANTIALIAS) | |
108 | ||
e8e444a8 JW |
109 | medium_filename = 'medium' + extension |
110 | medium_filepath = create_pub_filepath(entry, medium_filename) | |
63bd7c04 | 111 | |
e8e444a8 JW |
112 | tmp_medium_filename = os.path.join( |
113 | conversions_subdir, medium_filename) | |
93bdab9d | 114 | |
e8e444a8 JW |
115 | with file(tmp_medium_filename, 'w') as medium_file: |
116 | medium.save(medium_file) | |
93bdab9d | 117 | |
e8e444a8 JW |
118 | mgg.public_store.copy_local_to_storage( |
119 | tmp_medium_filename, medium_filepath) | |
93bdab9d JW |
120 | |
121 | # we have to re-read because unlike PIL, not everything reads | |
122 | # things in string representation :) | |
123 | queued_file = file(queued_filename, 'rb') | |
124 | ||
125 | with queued_file: | |
58dd8d9e PUS |
126 | #create_pub_filepath(entry, queued_filepath[-1]) |
127 | original_filepath = create_pub_filepath(entry, basename + extension) | |
93bdab9d | 128 | |
8e5f9746 JW |
129 | with mgg.public_store.get_file(original_filepath, 'wb') \ |
130 | as original_file: | |
93bdab9d JW |
131 | original_file.write(queued_file.read()) |
132 | ||
e8e444a8 | 133 | # Remove queued media file from storage and database |
93bdab9d | 134 | mgg.queue_store.delete_file(queued_filepath) |
8545cfc9 | 135 | entry.queued_media_file = [] |
e8e444a8 JW |
136 | |
137 | # Insert media file information into database | |
93bdab9d JW |
138 | media_files_dict = entry.setdefault('media_files', {}) |
139 | media_files_dict['thumb'] = thumb_filepath | |
140 | media_files_dict['original'] = original_filepath | |
e8e444a8 JW |
141 | media_files_dict['medium'] = medium_filepath |
142 | ||
143 | # Insert exif data into database | |
144 | media_data = entry.setdefault('media_data', {}) | |
a180ca26 JW |
145 | media_data['exif'] = { |
146 | 'clean': clean_exif(exif_tags)} | |
147 | media_data['exif']['useful'] = get_useful( | |
148 | media_data['exif']['clean']) | |
e8e444a8 | 149 | media_data['gps'] = gps_data |
93bdab9d JW |
150 | |
151 | # clean up workbench | |
152 | workbench.destroy_self() | |
e8e444a8 | 153 | |
e8e444a8 JW |
154 | if __name__ == '__main__': |
155 | import sys | |
156 | import pprint | |
157 | ||
158 | pp = pprint.PrettyPrinter() | |
159 | ||
160 | result = extract_exif(sys.argv[1]) | |
161 | gps = get_gps_data(result) | |
a180ca26 JW |
162 | clean = clean_exif(result) |
163 | useful = get_useful(clean) | |
e8e444a8 | 164 | |
e8e444a8 | 165 | print pp.pprint( |
a180ca26 | 166 | clean) |