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
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
|
# -*- coding: utf-8 -*-
#
# (C) Copyright 2009, APT-Portal Developers
# https://launchpad.net/~apt-portal-devs
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
# /appinfo/ contoller
"""
Application information controller
"""
from sqlalchemy.exceptions import IntegrityError
from sqlalchemy import __version__ as sa_version
from cherrypy_mako import *
from models.package import *
from models.application import *
import imghdr
import Image
import userinfo
def app_by_id(id):
""" Return app with id """
app = Application.query.filter_by(id = id).first()
return app
class AppInfo(object):
@cherrypy.expose
@cherrypy.tools.expires(secs=0)
def edit(self, for_package_id = None, from_app_id = None):
"""
Add/Edit an application record, after submission the browser
will be redirected to the referer page
"""
if not userinfo.is_admin():
raise cherrypy.HTTPError(403)
# We need these to fill the combo box
# do it here to avoid autoflush later
categories = ApplicationsCategory.query.all()
source_package = None
application = None
# the app info can be loaded from an app_id or for a package id
if from_app_id:
application = app_by_id(from_app_id)
if not application:
return "Application ID not found"
elif for_package_id:
package_id = for_package_id
package = Package.query.filter_by(id = package_id).one()
if not package:
return "Package id %d not found" % package_id
source_package = package.source or package.package
if source_package: # we got a package hint
application = Application.query.filter_by(\
source_package = source_package).first()
if not application: # app was not found, create new
application = Application()
application.source_package = source_package
# Automatically set app name to source package
# usefull hint on "for_package_id"
if not application.name:
application.name = source_package
# No changes here, save will be performed on edit_submit
session.rollback()
if sa_version.split(".") < ["0", "5", "0"]:
session.clear()
# Set the screenshot filename
username = cherrypy.session['login_username']
screenshot_filename = 'media/screens/%s_upload.png' % username
screenshot_filename = ""
id = application.id
if id:
screenshot_filename = "/media/screens/%d/%d_t.png" % (id, id)
return serve_template("app_edit.html" \
, application = application \
, categories = categories \
, screenshot_filename = screenshot_filename \
)
@cherrypy.expose
def edit_submit(self, id, source_package, name, homepage, license, \
descr, video_link, category):
"""
Add/Edit an application record - submit
"""
if not userinfo.is_admin():
raise cherrypy.HTTPError(403)
# Keep category query on top to avoid autoflush
cat = ApplicationsCategory.query.filter_by(name=category).first()
application = app_by_id(id) or Application()
application.source_package = source_package or None
application.name = name
application.homepage = homepage
application.descr = descr.decode('utf-8')
application.license = license
application.video_link = video_link
if cat:
application.category = cat
else:
return "ERROR: Could not find category", category
try:
session.commit()
except IntegrityError as e:
session.rollback()
return "ERROR: Unable to update"
id = application.id
# db operation was succesful, update the screenshot if submited
username = cherrypy.session['login_username']
filename = 'media/screens/%s_upload.png' % username
thumb_filename = 'media/screens/%s_upload_t.png' % username
# There is a screenshot image to be uploaded
if os.path.exists(filename):
screen_img_dir = "media/screens/%d" % id
if not os.path.isdir(screen_img_dir):
os.makedirs(screen_img_dir, 0700)
dest = "%s/%s.png" % (screen_img_dir, id)
thumb_dest = "%s/%d_t.png" % (screen_img_dir, id)
os.rename(filename, dest)
os.rename(thumb_filename, thumb_dest)
return "OK "+str(application.id)
@cherrypy.expose
def upload_screenshot(self, userfile):
if not userinfo.is_admin():
raise cherrypy.HTTPError(403)
username = cherrypy.session['login_username']
data = userfile.file.read()
filename = 'media/screens/%s_upload.png' % username
thumb_filename = 'media/screens/%s_upload_t.png' % username
f = open(filename, 'wb')
f.write(data)
f.close()
img_type = imghdr.what(filename)
if img_type != 'png':
os.unlink(filename)
return "ERROR: File format is not PNG!"
# Create the thumbnail to present on the form
# Calculate size to maintain aspect ratio
size = 260, 205
im = Image.open(filename)
width = im.size[0]
height = im.size[1]
newwidth = int(size[0])
newheight = int(height*(newwidth/float(width)))
if newheight > int(size[1]):
newheight = int(size[1])
newwidth = int(width*(newheight/float(height)))
size = newwidth, newheight
# Resize and save the image
im.thumbnail(size, Image.ANTIALIAS)
im.save(thumb_filename)
return "/"+thumb_filename
@cherrypy.expose
def change_category(self, action, name):
""" Add/Del a category """
if not userinfo.is_admin():
raise cherrypy.HTTPError(403)
if action == "Add":
appcat = ApplicationsCategory(name = name)
else:
appcat = ApplicationsCategory.query.filter_by(name = name).first()
if appcat:
appcat.delete();
try:
session.commit()
except IntegrityError as e:
pass
@cherrypy.expose
def default(self, **args):
print args
cherrypy.root.appinfo = AppInfo()
|