Esempio n. 1
0
    def get(self, format):
        # allow cross-origin requests
        self.response.headers["Access-Control-Allow-Origin"] = "*"
        self.response.headers["Access-Control-Allow-Methods"] = "GET"

        if format == "json":

            # set the type to JSON
            self.response.headers["Content-Type"] = "application/json"

            if self.request.get("type"):
                # if self.request.get('type') not in ['gadget','robot']:
                # prevent illegal extension types (may want to make this list global)
                # 	self.response.out.write('{\"error\":\"Parameter \\\"type\\\" must be \\\"gadget\\\" or \\\"robot\\\"\"}')
                # 	self.response.set_status(404)
                # 	return
                extList = Extension.gql("WHERE type = :1", self.request.get("type")).fetch(limit=None)
            else:
                extList = Extension.gql("").fetch(limit=None)

                # Turn the list of Extensions into a list of dictionaries
            extDictList = createExtDictList(extList, self.request.host_url)
            # Convert the dictionaries to JSON and print it
            self.response.out.write(json.dumps(extDictList))
        else:
            error404(self.response)
Esempio n. 2
0
    def get(self, format):
        # allow cross-origin requests
        self.response.headers["Access-Control-Allow-Origin"] = "*"
        self.response.headers["Access-Control-Allow-Methods"] = "GET"

        if format == "json":
            # set the type to JSON
            self.response.headers["Content-Type"] = "application/json"

            extID = self.request.get("id")
            if not extID:
                self.response.out.write('{"error":"Required parameter \\"id\\" was missing"}')
                self.response.set_status(404)
                return

            ext = Extension.gql("WHERE extID = :1", extID).get()

            if not ext:
                self.response.out.write('{"error":"No extension found with ID \\"' + extID + '\\""}')
                self.response.set_status(404)
                return

                # change the extension to a dictionary, which can then be converted to JSON
            ext = extToDict(ext, self.request.host_url)

            # convert the dictionary to JSON
            self.response.out.write(json.dumps(ext))
        else:
            error404(self.response)
	def get(self,extID):
		ext = Extension.gql('WHERE extID = :1',extID).get()
		if ext.icon:
			self.response.headers['Content-Type'] = 'image/png'
			self.response.out.write(ext.icon)
		else:
			self.error(404)
	def get(self, category):
		path = os.path.join(os.path.dirname(__file__), 'templates/head.html')
		self.response.out.write(template.render(path, {'stylesheet':'gallery'}))
		
		# Search for extensions in the category
		results = galleryIndex.search('category:' + category)
		
		# Create a list for the returned extensions
		extlist = []
		# Loop over the scored documents
		for result in results.results:
			# Do a datastore lookup for each extension ID
			ext = Extension.gql('WHERE extID = :1', result._doc_id).get()
			# If the  extension is found, fetch its rating info. and add it to the list
			if ext:
				ext.ratingCount,ext.upvotePercent,ext.downvotePercent = getRatingInfo(ext.extID)
				extlist.append(ext)
		
		category = category[0].upper() + category[1:].lower()
		
		path = os.path.join(os.path.dirname(__file__), 'templates/gallerylist.html')
		self.response.out.write(template.render(path, {'query':category,'extlist':extlist}))
		
		path = os.path.join(os.path.dirname(__file__), 'templates/foot.html')
		self.response.out.write(template.render(path, {}))
Esempio n. 5
0
	def get(self,extID):
		user = users.get_current_user()
		if user:
			templateArgs = {'title':'Edit Extension'}
			if self.request.get('msg'):
				if self.request.get('msg') == 'success':
					templateArgs['message'] = 'Your extension has been successfully updated. <a href=\"/gallery/info/' + extID + '\">Click here</a> to see your extension in the gallery.'
				elif self.request.get('msg') == 'icontype':
					templateArgs['message'] = 'The icon you uploaded was not a PNG.  Your extension\'s other properties have been successfully updated.'
				elif self.request.get('msg') == 'badurl':
					templateArgs['message'] = 'The gadget URL you entered was improperly formatted and therefore not saved.  Your extension\'s other properties have been successfully updated.'
				elif self.request.get('msg') == 'badaddress':
					templateArgs['message'] = 'The address you entered was improperly formatted and therefore not saved.  Your extension\'s other properties have been successfully updated.'
				templateArgs['message'] += '<br /><a href=\"/dev\">Click here</a> to return to your developer dashboard.</a>'
			path = os.path.join(os.path.dirname(__file__), 'templates/head.html')
			self.response.out.write(template.render(path, templateArgs))
			
			ext = Extension.gql('WHERE extID = :1', extID).get()
			if ext:
				if ext.developer == user or users.is_current_user_admin():
					path = os.path.join(os.path.dirname(__file__), 'templates/edit.html')
					self.response.out.write(template.render(path, {'ext':ext}))
				else:
					self.response.out.write('<h1>Error</h1>')
					self.response.out.write('<p>You do not have permission to edit this extension.</p>')
					self.response.out.write('<p><a href=\"/dev\">Click here</a> to return to your developer dashboard.</p>')
			else:
				self.response.out.write('<h1>Error</h1>')
				self.response.out.write('<p>Extension ' + extID + ' could not be found.</p>')
				self.response.out.write('<p><a href=\"/dev\">Click here</a> to return to your developer dashboard.</p>')
			
			path = os.path.join(os.path.dirname(__file__), 'templates/foot.html')
			self.response.out.write(template.render(path, {}))
		else:
			self.redirect(users.create_login_url(self.request.uri))
Esempio n. 6
0
	def get(self,format):
		if format == 'json':
			# set the type to JSON
			self.response.headers['Content-Type'] = 'application/json'
			
			extID = self.request.get('id')
			if not extID:
				self.response.out.write('{\"error\":\"Required parameter \\\"id\\\" was missing\"}')
				self.response.set_status(404)
				return
			
			ext = Extension.gql('WHERE extID = :1',extID).get()
			
			if not ext:
				self.response.out.write('{\"error\":\"No extension found with ID \\\"' + extID + '\\\"\"}')
				self.response.set_status(404)
				return
			
			# change the extension to a dictionary, which can then be converted to JSON
			ext = extToDict(ext,self.request.host_url)
			# add rating information to each Extension object
			ext['ratingCount'],ext['upvotePercent'],ext['downvotePercent'] = getRatingInfo(ext['id'])
			
			# convert the dictionary to JSON
			self.response.out.write(json.dumps(ext))
		else:
			error404(self.response)
Esempio n. 7
0
	def get(self,extID,number):
		ext = Extension.gql('WHERE extID = :1',extID).get()
		number = parseInt(number,-1)
		if number != -1 and ext and ext.screenshots and number < len(ext.screenshots):
			self.response.headers['Content-Type'] = 'image/png'
			self.response.out.write(ext.screenshots[number])
		else:
			self.error(404)
Esempio n. 8
0
	def get(self):
		user = users.get_current_user()
		if user:
			# Create a new Extension entry
			newExt = Extension()
			newExt.developer = user
			
			# Give the Extension a random unique ID (I decided on 16 hexadecimal
			# characters, but other suggestions are welcome).
			newExt.extID = hashlib.md5(os.urandom(128)).hexdigest()[:16]
			while Extension.gql('WHERE extID = :1', newExt.extID).count(limit=1) > 0:
				newExt.extID = hashlib.md5(os.urandom(128)).hexdigest()[:16]
			newExt.put()
			
			# Automatically upvote the extension as the developer
			
			# Check if a rating for that extension ID exists
			# (it should not, but just in case).
			rating = Rating.gql('WHERE user = :1 AND extID = :2',user,newExt.extID).get()
			# Create the rating if it does not exist
			# (which, again, it should not).
			if not rating:
				rating = Rating()
				rating.user = user
				rating.extID = newExt.extID
			rating.value = 1
			rating.put()
			
			# Redirect to the editing page
			self.redirect('/dev/edit/' + newExt.extID)
		else:
			self.redirect(users.create_login_url(self.request.uri))
Esempio n. 9
0
	def get(self,extID):
		ext = Extension.gql('WHERE extID = :1',extID).get()
		if ext:
			if ext.icon:
				self.response.headers['Content-Type'] = 'image/png'
				self.response.out.write(ext.icon)
			else:
				self.redirect('/static/images/gadget_icon_128x128.png')
		else:
			self.error(404)
Esempio n. 10
0
	def get(self,format):
		if format == 'json':
			# set the type to JSON
			self.response.headers['Content-Type'] = 'application/json'
			
			if self.request.get('type'):
				#if self.request.get('type') not in ['gadget','robot']:
					# prevent illegal extension types (may want to make this list global)
				#	self.response.out.write('{\"error\":\"Parameter \\\"type\\\" must be \\\"gadget\\\" or \\\"robot\\\"\"}')
				#	self.response.set_status(404)
				#	return
				extList = Extension.gql('WHERE type = :1',self.request.get('type')).fetch(limit=None)
			else:
				extList = Extension.gql('').fetch(limit=None)
			
			# Turn the list of Extensions into a list of dictionaries
			extDictList = createExtDictList(extList,self.request.host_url)
			# Convert the dictionaries to JSON and print it
			self.response.out.write(json.dumps(extDictList))
		else:
			error404(self.response)
Esempio n. 11
0
	def get(self):
		path = os.path.join(os.path.dirname(__file__), 'templates/head.html')
		self.response.out.write(template.render(path, {'stylesheet':'gallery'}))
		
		extlist = Extension.gql('WHERE type = :1','robot').fetch(limit=None)
		for ext in extlist:
			ext.ratingCount,ext.upvotePercent,ext.downvotePercent = getRatingInfo(ext.extID)
		path = os.path.join(os.path.dirname(__file__), 'templates/gallerylist.html')
		self.response.out.write(template.render(path, {'extlist':extlist}))
		
		path = os.path.join(os.path.dirname(__file__), 'templates/foot.html')
		self.response.out.write(template.render(path, {}))
Esempio n. 12
0
	def get(self,extID):
		ext = Extension.gql('WHERE extID = :1',extID).get()
		
		if not ext:
			path = os.path.join(os.path.dirname(__file__), 'templates/head.html')
			self.response.out.write(template.render(path, {'title':'Extension Not Found'}))
			path = os.path.join(os.path.dirname(__file__), 'templates/ext404.html')
			self.response.out.write(template.render(path, {}))
			self.response.set_status(404);
		else:
			# Convert the Markdown in the description to HTML,
			# but escape any HTML added by the user.
			ext.description = markdown.markdown(text=gfm.gfm(ext.description), safe_mode='escape')
			
			# Add the Extension to the template vars dictionary and
			# set other template vars to their default values.
			templateVars = {
				'ext':ext,
				'upvotePercent':0,
				'downvotePercent':0,
				'ratingCount':0,
				'userRating':None,
				'starred':False,
				'userIsDev':False
			}
			
			if ext.developer:
				templateVars['devname'] = ext.developer.nickname()
			
			templateVars['ratingCount'],templateVars['upvotePercent'],templateVars['downvotePercent'] = getRatingInfo(extID)
			
			user = users.get_current_user()
			if user:
				userEntry = User.gql('WHERE user = :1',user).get()
				if userEntry:
					if extID in userEntry.starred:
						templateVars['starred'] = True
				userRating = Rating.gql('WHERE user = :1 AND extID = :2',user,extID).get()
				if userRating:
					templateVars['userRating'] = userRating.value
				else:
					templateVars['userRating'] = 0 # Every user's default vote is zero
				
				if user == ext.developer:
					templateVars['userIsDev'] = True
			
			path = os.path.join(os.path.dirname(__file__), 'templates/head.html')
			self.response.out.write(template.render(path, {'title':ext.title,'stylesheet':'gallery'}))
			path = os.path.join(os.path.dirname(__file__), 'templates/info.html')
			self.response.out.write(template.render(path, templateVars))
		path = os.path.join(os.path.dirname(__file__), 'templates/foot.html')
		self.response.out.write(template.render(path, {}))
Esempio n. 13
0
	def get(self):
		user = users.get_current_user()
		if user:
			self.response.headers['Content-Type'] = 'text/plain'
			if users.is_current_user_admin():
				# Clear the existing index
				while True:
					# Get a list of documents populating only the doc_id field and extract the ids.
					docIDs = [doc.doc_id for doc in galleryIndex.list_documents(ids_only=True)]
					if not docIDs:
						break
					# Remove the documents for the given ids from the Index.
					galleryIndex.remove(docIDs)
				
				extlist = Extension.gql('').fetch(limit=None)
				ratinglist = Rating.gql('').fetch(limit=None)
				for ext in extlist:
					if ext.title == None:
						ext.title = ''
					if ext.description == None:
						ext.description = ''
					if ext.type == None:
						ext.type = 'gadget'
					if ext.category == None:
						ext.category = 'other'
					
					rating = getRatingInfo(ext.extID)[1]
					
					doc = search.Document(
						doc_id=ext.extID,
						fields=[
							search.TextField(name='title', value=ext.title),
							search.TextField(name='description', value=ext.description),
							search.AtomField(name='type', value=ext.type),
							search.AtomField(name='category', value=ext.category),
							search.NumberField(name='rating', value=rating)
						]
					)
					self.response.out.write('Created document for ' + ext.title + ' (' + ext.extID + ')\n')
					try:
						galleryIndex.add(doc)
						self.response.out.write('Successfully added document to index\n')
					except search.Error:
						self.response.out.write('Failed to add document to index\n')
				self.response.out.write('Done!')
			else:
				self.response.out.write('Access denied')
				self.response.set_status(401)
		else:
			self.redirect(users.create_login_url(self.request.uri))
Esempio n. 14
0
	def get(self):
		user = users.get_current_user()
		if user:
			path = os.path.join(os.path.dirname(__file__), 'templates/head.html')
			self.response.out.write(template.render(path, {'title':'Developer Dashboard'}))
			
			extlist = Extension.gql('WHERE developer = :1 ORDER BY title ASC', user).fetch(None)
			path = os.path.join(os.path.dirname(__file__), 'templates/devdash.html')
			self.response.out.write(template.render(path, {'extlist':extlist}))
			
			path = os.path.join(os.path.dirname(__file__), 'templates/foot.html')
			self.response.out.write(template.render(path, {}))
		else:
			self.redirect(users.create_login_url(self.request.uri))
Esempio n. 15
0
def searchFor(query):
	# Search for the query
	results = galleryIndex.search(query)
	# Create a list for the returned extensions
	extlist = []
	# Loop over the scored documents
	for result in results.results:
		# Do a datastore lookup for each extension ID
		ext = Extension.gql('WHERE extID = :1', result._doc_id).get()
		# If the  extension is found, fetch its rating info. and add it to the list
		if ext:
			ext.ratingCount,ext.upvotePercent,ext.downvotePercent = getRatingInfo(ext.extID)
			extlist.append(ext)
	
	return extlist
Esempio n. 16
0
	def get(self,extID):
		ext = Extension.gql('WHERE extID = :1',extID).get()
		
		if not ext:
			path = os.path.join(os.path.dirname(__file__), 'templates/head.html')
			self.response.out.write(template.render(path, {'title':'Extension Not Found'}))
			path = os.path.join(os.path.dirname(__file__), 'templates/ext404.html')
			self.response.out.write(template.render(path, {}))
			self.response.set_status(404);
		else:
			
			# Add the Extension to the template vars dictionary and
			# set other template vars to their default values.
			templateVars = {
				'ext':ext,
				'userRating':None,
				'starred':False,
				'userIsDev':False
			}
			
			if ext.developer:
				templateVars['devname'] = ext.developer.nickname()
			
			user = users.get_current_user()
			if user:
				userEntry = User.gql('WHERE user = :1',user).get()
				if userEntry:
					if extID in userEntry.starred:
						templateVars['starred'] = True
				userRating = Rating.gql('WHERE user = :1 AND extID = :2',user,extID).get()
				if userRating:
					templateVars['userRating'] = userRating.value
				else:
					templateVars['userRating'] = 0 # Every user's default vote is zero
				
				if user == ext.developer:
					templateVars['userIsDev'] = True
			
			path = os.path.join(os.path.dirname(__file__), 'templates/head.html')
			self.response.out.write(template.render(path, {'title':ext.title,'stylesheet':'gallery'}))
			path = os.path.join(os.path.dirname(__file__), 'templates/info.html')
			self.response.out.write(template.render(path, templateVars))
		path = os.path.join(os.path.dirname(__file__), 'templates/foot.html')
		self.response.out.write(template.render(path, {}))
Esempio n. 17
0
	def get(self):
		if not users.get_current_user():
			self.redirect(users.create_login_url(self.request.uri))
			return
		elif not users.is_current_user_admin():
			self.response.headers['Content-Type'] = 'text/plain; charset=utf-8'
			self.response.out.write('Error 401')
			self.response.set_status(401)
			return
		
		self.response.headers['Content-Type'] = 'text/plain; charset=utf-8'
		
		self.response.out.write('Loading extensions from the datastore...\n\n')
		
		extlist = Extension.gql('').fetch(limit=None)
		
		galleryIndex = search.Index(name=SEARCH_INDEX_NAME)
		for ext in extlist:
			if ext.title == None:
				ext.title = ''
			if ext.description == None:
				ext.description = ''
			if ext.type == None:
				ext.type = 'gadget'
			if ext.category == None:
				ext.category = 'other'
			
			doc = search.Document(
				doc_id=ext.extID,
				fields=[
					search.TextField(name='title', value=ext.title),
					search.HtmlField(name='description', value=ext.htmlDescription),
					search.AtomField(name='developer', value=ext.developer.nickname() if ext.developer else ''),
					search.AtomField(name='type', value=ext.type),
					search.AtomField(name='category', value=ext.category),
					search.NumberField(name='rating', value=ext.rating)
				]
			)
			galleryIndex.put(doc)
			self.response.out.write('Updated search Document for \"' + ext.title + '\" (' + ext.extID + ')\n')
		
		self.response.out.write('\nThe search index has been updated.')
Esempio n. 18
0
	def get(self):
		user = users.get_current_user()
		if user:
			# Create a new Extension entry
			newExt = Extension()
			newExt.developer = user
			
			# Give the Extension a random unique ID (I decided on 16 hexadecimal
			# characters, but other suggestions are welcome)
			newExt.extID = hashlib.md5(os.urandom(128)).hexdigest()[:16]
			while Extension.gql('WHERE extID = :1', newExt.extID).count(limit=1) > 0:
				newExt.extID = hashlib.md5(os.urandom(128)).hexdigest()[:16]
			newExt.put()
		
			# Redirect to the editing page
			self.redirect('/dev/edit/' + newExt.extID)
		else:
			self.redirect(users.create_login_url(self.request.uri))
Esempio n. 19
0
def searchFor(query='',limit=DEFAULT_QUERY_LIMIT,offset=DEFAULT_QUERY_OFFSET,sortBy=SORT_BEST_MATCH):
	# Create a sort expression for the given sort method, if any.
	expressions = None
	if sortBy == SORT_TOP_RATING:
		expressions = [
			search.SortExpression(
				expression='rating',
				direction=search.SortExpression.DESCENDING,
				default_value=0
			)
		]
		
	
	# Create the search query.
	searchQuery = search.Query(
		query_string=query,
		options=search.QueryOptions(
			limit=limit,
			offset=offset,
			sort_options=search.SortOptions(
				# Find best matches unless a different sort method is chosen.
				match_scorer=(search.MatchScorer() if sortBy == SORT_BEST_MATCH else None),
				expressions=expressions,
				limit=limit
			)
		)
	)
	
	# Search for the query
	results = search.Index(name=SEARCH_INDEX_NAME).search(searchQuery)
	# Create a list for the returned extensions
	extlist = []
	# Loop over the scored documents
	for result in results.results:
		# Do a datastore lookup for each extension ID
		ext = Extension.gql('WHERE extID = :1', result._doc_id).get()
		# If the  extension is found, fetch its rating info. and add it to the list
		if ext:
			extlist.append(ext)
	
	return extlist
Esempio n. 20
0
	def get(self,value,extID):
		user = users.get_current_user()
		if not user:
			self.redirect(users.create_login_url(self.request.uri))
		else:
			if Extension.gql('WHERE extID = :1',extID).count(limit=1) == 0:
				self.error(404)
			else:
				rating = Rating.gql('WHERE user = :1 AND extID = :2',user,extID).get()
				if not rating:
					rating = Rating()
					rating.user = user
					rating.extID = extID
				if value == 'up':
					rating.value = 1
				elif value == 'down':
					rating.value = -1
				else:
					rating.value = 0
				rating.put()
				self.redirect('/gallery/info/' + extID)
Esempio n. 21
0
    def get(self):
        user = users.get_current_user()
        if user:
            templateVars = {
                "useremail": user.email(),
                "usernickname": user.nickname(),
                "signouturl": users.create_logout_url("/"),
                "extlist": [],
            }
            userEntry = User.gql("WHERE user = :1", user).get()
            if userEntry and userEntry.starred:
                for extID in userEntry.starred:
                    extEntry = Extension.gql("WHERE extID = :1", extID).get()
                    if extEntry:
                        templateVars["extlist"].append(extEntry)

            path = os.path.join(os.path.dirname(__file__), "templates/head.html")
            self.response.out.write(template.render(path, {"title": "Your Account"}))
            path = os.path.join(os.path.dirname(__file__), "templates/account.html")
            self.response.out.write(template.render(path, templateVars))
            path = os.path.join(os.path.dirname(__file__), "templates/foot.html")
            self.response.out.write(template.render(path, {}))
        else:
            self.redirect(users.create_login_url(self.request.uri))
Esempio n. 22
0
	def post(self,extID):
		user = users.get_current_user()
		if user:
			error = None
			ext = Extension.gql('WHERE extID = :1', extID).get()
			if ext and ext.developer == user or users.is_current_user_admin():
				if self.request.get('title'):
					ext.title = self.request.get('title')
				else:
					ext.title = DEFAULT_EXTENSION_TITLE
				
				if self.request.get('type'):
					ext.type = self.request.get('type')
				else: # default to gadget if no type is sent
					ext.type = DEFAULT_EXTENSION_TYPE
				
				if ext.type == 'gadget':
					if self.request.get('gadgetURL'):
						url = self.request.get('gadgetURL')
						if not re.match('^https?:\/\/', url):
							url = 'http://' + url
						if not re.match('^https?:\/\/.+\..+', url):
							error = 'badurl'
						ext.gadgetURL = url
				else:
					ext.gadgetURL = None
				
				if ext.type == 'robot':
					if self.request.get('robotAddress'):
						address = self.request.get('robotAddress')
						if not re.match('.+@.+\..+', address):
							error = 'badaddress'
						else:
							ext.robotAddress = self.request.get('robotAddress')
				else:
					ext.robotAddress = None
				
				if self.request.get('description'):
					ext.description = self.request.get('description')
				else:
					ext.description = DEFAULT_EXTENSION_DESCRIPTION
				
				if self.request.get('category'):
					ext.category = self.request.get('category')
				else:
					ext.category = DEFAULT_EXTENSION_CATEGORY
				
				# If a new icon was uploaded,
				if self.request.get('icon'):
					# Get the icon <input>.
					iconFile = self.request.get('icon')
					# Make sure it is a PNG and return an error if it is not.
					icon = images.Image(image_data=iconFile)
					if icon.format != images.PNG:
						error = 'icontype'
					else:
						# Make sure it is the porper size.
						iconFile = images.resize(iconFile, 128, 128)
						# Overwrite the existing icon.
						ext.icon = db.Blob(iconFile)
				
				# Loop over the screenshot <input>s.
				screenshotFiles = self.request.get_all('screenshot')
				for i in range(len(screenshotFiles)):
					# Make sure something was actually uploaded in that <input>.
					if screenshotFiles[i]:
						# Make sure it is a PNG and return an error if it is not.
						screenshot = images.Image(image_data=screenshotFiles[i])
						if screenshot.format != images.PNG:
							error = 'screenshottype'
						else:
							# Make sure it is the proper size.
							screenshotFiles[i] = images.resize(screenshotFiles[i], 640, 400)
							# Put it in the extension's screenshots array.
							if i < len(ext.screenshots):
								ext.screenshots[i] = db.Blob(screenshotFiles[i])
							else:
								ext.screenshots.append(db.Blob(screenshotFiles[i]))
				
				ext.put()
				
				if error == None:
					self.redirect('/dev/edit/' + extID + '?msg=success')
				else:
					self.redirect('/dev/edit/' + extID + '?msg=' + error)
				return
		self.redirect('/dev/edit/' + extID)
Esempio n. 23
0
	def post(self,extID):
		user = users.get_current_user()
		if user:
			error = None
			ext = Extension.gql('WHERE extID = :1', extID).get()
			if ext and ext.developer == user or users.is_current_user_admin():
				if self.request.get('title'):
					ext.title = self.request.get('title')
				else:
					ext.title = ''
				
				if self.request.get('type'):
					ext.type = self.request.get('type')
				else: # default to gadget if no type is sent
					ext.type = 'gadget'
				
				if ext.type == 'gadget':
					if self.request.get('gadgetURL'):
						url = self.request.get('gadgetURL')
						if not re.match('^https?:\/\/', url):
							url = 'http://' + url
						if not re.match('^https?:\/\/.+\..+', url):
							error = 'badurl'
						ext.gadgetURL = url
				else:
					ext.gadgetURL = None
				
				if ext.type == 'robot':
					if self.request.get('robotAddress'):
						address = self.request.get('robotAddress')
						if not re.match('.+@.+\..+', address):
							error = 'badaddress'
						else:
							ext.robotAddress = self.request.get('robotAddress')
				else:
					ext.robotAddress = None
				
				if self.request.get('description'):
					ext.description = self.request.get('description')
				else:
					ext.description = ''
				
				if self.request.get('category'):
					ext.category = self.request.get('category')
				else:
					ext.category = 'other'
				
				if self.request.get('icon'):
					iconFile = self.request.get('icon')
					icon = images.Image(image_data = iconFile)
					if icon.format != images.PNG:
						error = 'icontype'
					else:
						iconFile = images.resize(iconFile, 128, 128)
						ext.icon = db.Blob(iconFile)
				
				ext.put()
				
				if error == None:
					self.redirect('/dev/edit/' + extID + '?msg=success')
				else:
					self.redirect('/dev/edit/' + extID + '?msg=' + error)
				return
		self.redirect('/dev/edit/' + extID)