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 | 22 | from mediagoblin.processing import BadMediaFail, \ |
c56d4b55 | 23 | create_pub_filepath |
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 | ||
c56d4b55 | 31 | |
ec4261a4 | 32 | def sniff_handler(media_file, **kw): |
e2caf574 | 33 | if kw.get('media') is not None: # That's a double negative! |
92f129b5 JW |
34 | name, ext = os.path.splitext(kw['media'].filename) |
35 | clean_ext = ext[1:].lower() # Strip the . from ext and make lowercase | |
36 | ||
37 | _log.debug('name: {0}\next: {1}\nlower_ext: {2}'.format( | |
38 | name, | |
39 | ext, | |
40 | clean_ext)) | |
41 | ||
42 | if clean_ext in SUPPORTED_FILETYPES: | |
43 | _log.info('Found file extension in supported filetypes') | |
44 | return True | |
45 | else: | |
10085b77 | 46 | _log.debug('Media present, extension not found in {0}'.format( |
92f129b5 JW |
47 | SUPPORTED_FILETYPES)) |
48 | else: | |
49 | _log.warning('Need additional information (keyword argument \'media\')' | |
50 | ' to be able to handle sniffing') | |
51 | ||
ec4261a4 JW |
52 | return False |
53 | ||
c56d4b55 | 54 | |
93bdab9d JW |
55 | def process_image(entry): |
56 | """ | |
57 | Code to process an image | |
58 | """ | |
59 | workbench = mgg.workbench_manager.create_workbench() | |
8e5f9746 JW |
60 | # Conversions subdirectory to avoid collisions |
61 | conversions_subdir = os.path.join( | |
62 | workbench.dir, 'conversions') | |
63 | os.mkdir(conversions_subdir) | |
93bdab9d | 64 | |
8545cfc9 | 65 | queued_filepath = entry.queued_media_file |
93bdab9d JW |
66 | queued_filename = workbench.localized_file( |
67 | mgg.queue_store, queued_filepath, | |
68 | 'source') | |
69 | ||
58dd8d9e PUS |
70 | filename_bits = os.path.splitext(queued_filename) |
71 | basename = os.path.split(filename_bits[0])[1] | |
72 | extension = filename_bits[1].lower() | |
8e5f9746 | 73 | |
e8e444a8 JW |
74 | # EXIF extraction |
75 | exif_tags = extract_exif(queued_filename) | |
76 | gps_data = get_gps_data(exif_tags) | |
77 | ||
93bdab9d JW |
78 | try: |
79 | thumb = Image.open(queued_filename) | |
80 | except IOError: | |
81 | raise BadMediaFail() | |
82 | ||
e8e444a8 JW |
83 | thumb = exif_fix_image_orientation(thumb, exif_tags) |
84 | ||
c56d4b55 JW |
85 | thumb.thumbnail( |
86 | (mgg.global_config['media:thumb']['max_width'], | |
87 | mgg.global_config['media:thumb']['max_height']), | |
88 | Image.ANTIALIAS) | |
93bdab9d | 89 | |
8e5f9746 JW |
90 | # Copy the thumb to the conversion subdir, then remotely. |
91 | thumb_filename = 'thumbnail' + extension | |
92 | thumb_filepath = create_pub_filepath(entry, thumb_filename) | |
63bd7c04 | 93 | |
8e5f9746 JW |
94 | tmp_thumb_filename = os.path.join( |
95 | conversions_subdir, thumb_filename) | |
63bd7c04 | 96 | |
8e5f9746 JW |
97 | with file(tmp_thumb_filename, 'w') as thumb_file: |
98 | thumb.save(thumb_file) | |
63bd7c04 | 99 | |
8e5f9746 JW |
100 | mgg.public_store.copy_local_to_storage( |
101 | tmp_thumb_filename, thumb_filepath) | |
93bdab9d JW |
102 | |
103 | # If the size of the original file exceeds the specified size of a `medium` | |
104 | # file, a `medium.jpg` files is created and later associated with the media | |
105 | # entry. | |
106 | medium = Image.open(queued_filename) | |
63bd7c04 JW |
107 | |
108 | # Fix orientation | |
e8e444a8 | 109 | medium = exif_fix_image_orientation(medium, exif_tags) |
93bdab9d | 110 | |
c56d4b55 JW |
111 | if medium.size[0] > mgg.global_config['media:medium']['max_width'] \ |
112 | or medium.size[1] > mgg.global_config['media:medium']['max_height']: | |
113 | medium.thumbnail( | |
114 | (mgg.global_config['media:medium']['max_width'], | |
115 | mgg.global_config['media:medium']['max_height']), | |
116 | Image.ANTIALIAS) | |
93bdab9d | 117 | |
e8e444a8 JW |
118 | medium_filename = 'medium' + extension |
119 | medium_filepath = create_pub_filepath(entry, medium_filename) | |
63bd7c04 | 120 | |
e8e444a8 JW |
121 | tmp_medium_filename = os.path.join( |
122 | conversions_subdir, medium_filename) | |
93bdab9d | 123 | |
e8e444a8 JW |
124 | with file(tmp_medium_filename, 'w') as medium_file: |
125 | medium.save(medium_file) | |
93bdab9d | 126 | |
e8e444a8 JW |
127 | mgg.public_store.copy_local_to_storage( |
128 | tmp_medium_filename, medium_filepath) | |
93bdab9d JW |
129 | |
130 | # we have to re-read because unlike PIL, not everything reads | |
131 | # things in string representation :) | |
132 | queued_file = file(queued_filename, 'rb') | |
133 | ||
134 | with queued_file: | |
58dd8d9e | 135 | #create_pub_filepath(entry, queued_filepath[-1]) |
c56d4b55 | 136 | original_filepath = create_pub_filepath(entry, basename + extension) |
93bdab9d | 137 | |
8e5f9746 JW |
138 | with mgg.public_store.get_file(original_filepath, 'wb') \ |
139 | as original_file: | |
93bdab9d JW |
140 | original_file.write(queued_file.read()) |
141 | ||
e8e444a8 | 142 | # Remove queued media file from storage and database |
93bdab9d | 143 | mgg.queue_store.delete_file(queued_filepath) |
8545cfc9 | 144 | entry.queued_media_file = [] |
e8e444a8 JW |
145 | |
146 | # Insert media file information into database | |
93bdab9d JW |
147 | media_files_dict = entry.setdefault('media_files', {}) |
148 | media_files_dict['thumb'] = thumb_filepath | |
149 | media_files_dict['original'] = original_filepath | |
e8e444a8 JW |
150 | media_files_dict['medium'] = medium_filepath |
151 | ||
152 | # Insert exif data into database | |
153 | media_data = entry.setdefault('media_data', {}) | |
a180ca26 JW |
154 | media_data['exif'] = { |
155 | 'clean': clean_exif(exif_tags)} | |
156 | media_data['exif']['useful'] = get_useful( | |
157 | media_data['exif']['clean']) | |
e8e444a8 | 158 | media_data['gps'] = gps_data |
93bdab9d JW |
159 | |
160 | # clean up workbench | |
161 | workbench.destroy_self() | |
e8e444a8 | 162 | |
e8e444a8 JW |
163 | if __name__ == '__main__': |
164 | import sys | |
165 | import pprint | |
166 | ||
167 | pp = pprint.PrettyPrinter() | |
168 | ||
169 | result = extract_exif(sys.argv[1]) | |
170 | gps = get_gps_data(result) | |
a180ca26 JW |
171 | clean = clean_exif(result) |
172 | useful = get_useful(clean) | |
e8e444a8 | 173 | |
e8e444a8 | 174 | print pp.pprint( |
a180ca26 | 175 | clean) |