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 |
93bdab9d | 19 | |
93bdab9d | 20 | from mediagoblin import mg_globals as mgg |
4535f759 | 21 | from mediagoblin.processing import BadMediaFail, \ |
ab35ad46 | 22 | create_pub_filepath, THUMB_SIZE, MEDIUM_SIZE, FilenameMunger |
a180ca26 JW |
23 | from mediagoblin.tools.exif import exif_fix_image_orientation, \ |
24 | extract_exif, clean_exif, get_gps_data, get_useful | |
93bdab9d | 25 | |
ab35ad46 BS |
26 | def resize_image(entry, filename, new_path, exif_tags, workdir, new_size, |
27 | size_limits=(0, 0)): | |
063670e9 BS |
28 | """Store a resized version of an image and return its pathname. |
29 | ||
30 | Arguments: | |
31 | entry -- the entry for the image to resize | |
32 | filename -- the filename of the original image being resized | |
ab35ad46 | 33 | new_path -- public file path for the new resized image |
063670e9 BS |
34 | exif_tags -- EXIF data for the original image |
35 | workdir -- directory path for storing converted image files | |
36 | new_size -- 2-tuple size for the resized image | |
37 | size_limits (optional) -- image is only resized if it exceeds this size | |
38 | ||
39 | """ | |
40 | try: | |
41 | resized = Image.open(filename) | |
42 | except IOError: | |
43 | raise BadMediaFail() | |
44 | resized = exif_fix_image_orientation(resized, exif_tags) # Fix orientation | |
45 | ||
176f207b | 46 | if ((resized.size[0] > size_limits[0]) or |
063670e9 BS |
47 | (resized.size[1] > size_limits[1])): |
48 | resized.thumbnail(new_size, Image.ANTIALIAS) | |
49 | ||
063670e9 | 50 | # Copy the new file to the conversion subdir, then remotely. |
ab35ad46 | 51 | tmp_resized_filename = os.path.join(workdir, new_path[-1]) |
063670e9 BS |
52 | with file(tmp_resized_filename, 'w') as resized_file: |
53 | resized.save(resized_file) | |
ab35ad46 | 54 | mgg.public_store.copy_local_to_storage(tmp_resized_filename, new_path) |
063670e9 | 55 | |
93bdab9d JW |
56 | def process_image(entry): |
57 | """ | |
58 | Code to process an image | |
59 | """ | |
60 | workbench = mgg.workbench_manager.create_workbench() | |
8e5f9746 JW |
61 | # Conversions subdirectory to avoid collisions |
62 | conversions_subdir = os.path.join( | |
63 | workbench.dir, 'conversions') | |
64 | os.mkdir(conversions_subdir) | |
93bdab9d | 65 | |
8545cfc9 | 66 | queued_filepath = entry.queued_media_file |
93bdab9d JW |
67 | queued_filename = workbench.localized_file( |
68 | mgg.queue_store, queued_filepath, | |
69 | 'source') | |
ab35ad46 | 70 | name_munger = FilenameMunger(queued_filename) |
8e5f9746 | 71 | |
e8e444a8 JW |
72 | # EXIF extraction |
73 | exif_tags = extract_exif(queued_filename) | |
74 | gps_data = get_gps_data(exif_tags) | |
75 | ||
063670e9 | 76 | # Always create a small thumbnail |
ab35ad46 BS |
77 | thumb_filepath = create_pub_filepath( |
78 | entry, name_munger.munge('{basename}.thumbnail{ext}')) | |
79 | resize_image(entry, queued_filename, thumb_filepath, | |
80 | exif_tags, conversions_subdir, THUMB_SIZE) | |
93bdab9d JW |
81 | |
82 | # If the size of the original file exceeds the specified size of a `medium` | |
063670e9 | 83 | # file, a `.medium.jpg` files is created and later associated with the media |
93bdab9d | 84 | # entry. |
ab35ad46 BS |
85 | medium_filepath = create_pub_filepath( |
86 | entry, name_munger.munge('{basename}.medium{ext}')) | |
87 | resize_image(entry, queued_filename, medium_filepath, | |
88 | exif_tags, conversions_subdir, MEDIUM_SIZE, MEDIUM_SIZE) | |
93bdab9d JW |
89 | |
90 | # we have to re-read because unlike PIL, not everything reads | |
91 | # things in string representation :) | |
92 | queued_file = file(queued_filename, 'rb') | |
93 | ||
94 | with queued_file: | |
ab35ad46 BS |
95 | original_filepath = create_pub_filepath( |
96 | entry, name_munger.munge('{basename}{ext}') ) | |
93bdab9d | 97 | |
8e5f9746 JW |
98 | with mgg.public_store.get_file(original_filepath, 'wb') \ |
99 | as original_file: | |
93bdab9d JW |
100 | original_file.write(queued_file.read()) |
101 | ||
e8e444a8 | 102 | # Remove queued media file from storage and database |
93bdab9d | 103 | mgg.queue_store.delete_file(queued_filepath) |
8545cfc9 | 104 | entry.queued_media_file = [] |
e8e444a8 JW |
105 | |
106 | # Insert media file information into database | |
93bdab9d JW |
107 | media_files_dict = entry.setdefault('media_files', {}) |
108 | media_files_dict['thumb'] = thumb_filepath | |
109 | media_files_dict['original'] = original_filepath | |
e8e444a8 JW |
110 | media_files_dict['medium'] = medium_filepath |
111 | ||
112 | # Insert exif data into database | |
113 | media_data = entry.setdefault('media_data', {}) | |
497d9279 E |
114 | |
115 | # TODO: Fix for sql media_data, when exif is in sql | |
116 | if media_data is not None: | |
117 | media_data['exif'] = { | |
118 | 'clean': clean_exif(exif_tags)} | |
119 | media_data['exif']['useful'] = get_useful( | |
120 | media_data['exif']['clean']) | |
ea200c32 E |
121 | |
122 | if len(gps_data): | |
123 | for key in list(gps_data.keys()): | |
124 | gps_data['gps_' + key] = gps_data.pop(key) | |
125 | entry.media_data_init(**gps_data) | |
93bdab9d JW |
126 | |
127 | # clean up workbench | |
128 | workbench.destroy_self() | |
e8e444a8 | 129 | |
e8e444a8 JW |
130 | if __name__ == '__main__': |
131 | import sys | |
132 | import pprint | |
133 | ||
134 | pp = pprint.PrettyPrinter() | |
135 | ||
136 | result = extract_exif(sys.argv[1]) | |
137 | gps = get_gps_data(result) | |
a180ca26 JW |
138 | clean = clean_exif(result) |
139 | useful = get_useful(clean) | |
e8e444a8 | 140 | |
e8e444a8 | 141 | print pp.pprint( |
a180ca26 | 142 | clean) |