-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmodels.py
148 lines (121 loc) · 4.85 KB
/
models.py
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
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
import os
from StringIO import StringIO
from sqlalchemy import Table, Column, Integer, String, ForeignKey, create_engine
from sqlalchemy.orm import relationship, sessionmaker
from sqlalchemy.ext.declarative import declarative_base
from PIL import Image
from lxml import etree
import requests
from settings import *
Base = declarative_base()
engine = create_engine('mysql://{0}:{1}@{2}:{3}/{4}'.format(
DATABASE['user'],
DATABASE['password'],
DATABASE['host'],
DATABASE['port'],
DATABASE['name']))
Session = sessionmaker(bind=engine)
class ImageModel(Base):
__abstract__ = True
id = Column(Integer, primary_key=True)
_path = Column(String(1024))
height = Column(Integer)
width = Column(Integer)
@property
def path(self):
return APP_ROOT + '/' + self._path
def __repr__(self):
return '<{0}: {1}>'.format(self.__class__.__name__, self.__unicode__())
def __unicode__(self):
return ''
class FlickrImage(ImageModel):
__tablename__ = 'flickr_images'
flickr_user = Column(String(255))
flickr_src = Column(String(1024))
def get_cropped(self, width, height, session):
cropped = session.query(CroppedFlickrImage).filter(
CroppedFlickrImage.full_img==self,
CroppedFlickrImage.height==height,
CroppedFlickrImage.width==width).first()
if cropped:
return cropped
else:
# Crop image
i = Image.open(self.path)
d_ratio = float(width) / float(height)
i_ratio = float(self.width) / float(self.height)
corners = (0, 0, 0, 0) # (left, top, right, bottom)
# If image is shorter than desired image, make height full height
if i_ratio > d_ratio:
w = int(round(self.height * d_ratio))
padding = int(round((self.width - w) / 2))
corners = (padding, 0, padding + w, self.height)
# If image is thinner than desired image, make width full width
else:
h = int(round(self.width / d_ratio))
padding = int(round((self.height - h) / 2))
corners = (0, padding, self.width, padding + h)
i = i.crop(corners)
# Resize image
i = i.resize((width, height), Image.ANTIALIAS)
# Make CropppedFlickrImage
filename = self.path.split('/')[-1]
name = '.'.join(filename.split('.')[:-1])
ext = filename.split('.')[-1]
new_filename = '{0}_{1}X{2}.{3}'.format(name, width, height, ext)
new_img = CroppedFlickrImage(
_path='resources/thumbnails/' + new_filename,
width=width,
height=height,
image_id=self.id
)
i.save(new_img.path)
session.add(new_img)
session.commit()
return new_img
def __unicode__(self):
return self.path
class CroppedFlickrImage(ImageModel):
__tablename__ = 'cropped_flickr_images'
image_id = Column(Integer, ForeignKey('flickr_images.id'))
full_img = relationship('FlickrImage', backref='cropped')
def show(self):
Image.open(self.path).show()
def __unicode__(self):
return self.path
def seed_db(session):
with open('data/flickr_links.txt') as f:
for url in f.readlines():
url = url.strip()
r = session.query(FlickrImage).filter(FlickrImage.flickr_src==url)
if (list(r)):
print str(r[0]) + ' already in database'
continue
html = requests.get(url).text
tree = etree.parse(StringIO(html), etree.HTMLParser())
user_elt = tree.xpath('//span[@class="photo-name-line-1"]/a')[0]
user = user_elt.text.strip()
full_url = url + 'sizes/o/in/photostream/'
full_html = requests.get(full_url).text
full_tree = etree.parse(StringIO(full_html), etree.HTMLParser())
img_elt = full_tree.xpath('//div[@id="allsizes-photo"]/img')[0]
img_src = img_elt.get('src').strip()
filename = img_src.split('/')[-1]
img_content = requests.get(img_src).content
img = Image.open(StringIO(img_content))
with open('resources/full_res/' + filename, 'w') as img_file:
img_file.write(img_content)
db_img = FlickrImage(
_path='resources/full_res/' + filename,
height=img.size[1],
width=img.size[0],
flickr_user=user,
flickr_src=url
)
print db_img
session.add(db_img)
session.commit()
if __name__ == '__main__':
s = Session()
seed_db(s)
s.close()