def post(self, json): logging.debug('post: %s' % json) assert 'short_code' not in json, ( "Posts should be modified with HTTP PUT, not POST" ) # short_code is just one row with the current largest serial number short_code = str(int(resale_db.eval(""" db.runCommand({ findAndModify: 'short_code', upsert: true, update: { $inc: { short_code: 1 } }, query: { short_code : { $gt : -1 } }, new: true }) """)['value']['short_code'])) logging.debug('short_code: %s' % short_code) json['short_code'] = short_code resale_db.post.ensure_index('short_code', unique=True) json['url'] = urlparse.urljoin( 'http://%s' % resale_settings.hostname, self.reverse_url('view_post', short_code) ) # TODO: client can insert whatever it wants in JSON and we'll insert it # into DB. Wouldn't it be cool if json_validate also had function to # make a JSON obj that *only* has required or optional elements? resale_db.post.save(json) if '_id' in json: del json['_id'] return { 'result': 'OK', 'post': json }
def get(self, json): """ Search posts using CGI arguments, e.g.: http://resaleapp.com/api/post/search?lat=37&long=-122&query=couch """ # Ensure Mongo uses a geospatial index on location, then search for # nearby posts with titles containing the query string. PyMongo doesn't # support '2d' indexes, so use Javascript to ensure the index. resale_db.eval('db.post.ensureIndex( { location : "2d", title: 1 } )') find_terms = { 'location': { '$near': [ float(self.get_argument('lat')), float(self.get_argument('long')) ] } } # Matching on title is optional if self.get_argument('query', None): find_terms['title'] = re.compile( r'.*%s.*' % re.escape( self.get_argument('query'), ), re.I ) # TODO: Has Mongo already sorted results by proximity to lat and long? search_results = resale_db.post.find(find_terms).limit(20) return { 'result': 'OK', 'posts': list(search_results) }