~joaopinto/apt-portal/pre-modules

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()