forked from grangier/python-goose
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathimages.py
More file actions
123 lines (107 loc) · 4.07 KB
/
Copy pathimages.py
File metadata and controls
123 lines (107 loc) · 4.07 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
# -*- coding: utf-8 -*-
"""\
This is a python port of "Goose" orignialy licensed to Gravity.com
under one or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership.
Python port was written by Xavier Grangier for Recrutae
Gravity.com licenses this file
to you under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance
with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
"""
import hashlib
import os
import urllib2
from PIL import Image
from goose.utils.encoding import smart_str
from goose.image import ImageDetails
from goose.image import LocallyStoredImage
class ImageUtils(object):
@classmethod
def get_image_dimensions(self, identify_program, path):
image_details = ImageDetails()
try:
image = Image.open(path)
image_details.set_mime_type(image.format)
width, height = image.size
image_details.set_width(width)
image_details.set_height(height)
except IOError:
image_details.set_mime_type('NA')
return image_details
@classmethod
def store_image(self, http_client, link_hash, src, config):
"""\
Writes an image src http string to disk as a temporary file
and returns the LocallyStoredImage object
that has the info you should need on the image
"""
# check for a cache hit already on disk
image = self.read_localfile(link_hash, src, config)
if image:
return image
# no cache found download the image
data = self.fetch(http_client, src)
if data:
image = self.write_localfile(data, link_hash, src, config)
if image:
return image
return None
@classmethod
def get_mime_type(self, image_details):
mime_type = image_details.get_mime_type().lower()
mimes = {
'png': '.png',
'jpg': '.jpg',
'jpeg': '.jpg',
'gif': '.gif',
}
return mimes.get(mime_type, 'NA')
@classmethod
def read_localfile(self, link_hash, src, config):
local_image_name = self.get_localfile_name(link_hash, src, config)
if os.path.isfile(local_image_name):
identify = config.imagemagick_identify_path
image_details = self.get_image_dimensions(identify, local_image_name)
file_extension = self.get_mime_type(image_details)
bytes = os.path.getsize(local_image_name)
return LocallyStoredImage(
src=src,
local_filename=local_image_name,
link_hash=link_hash,
bytes=bytes,
file_extension=file_extension,
height=image_details.get_height(),
width=image_details.get_width()
)
return None
@classmethod
def write_localfile(self, entity, link_hash, src, config):
local_path = self.get_localfile_name(link_hash, src, config)
f = open(local_path, 'wb')
f.write(entity)
f.close()
return self.read_localfile(link_hash, src, config)
@classmethod
def get_localfile_name(self, link_hash, src, config):
image_hash = hashlib.md5(smart_str(src)).hexdigest()
return os.path.join(config.local_storage_path, '%s_%s' % (link_hash, image_hash))
@classmethod
def clean_src_string(self, src):
return src.replace(" ", "%20")
@classmethod
def fetch(self, http_client, src):
try:
req = urllib2.Request(src)
f = urllib2.urlopen(req)
data = f.read()
return data
except Exception:
return None