def get_general_close_places(self, client_longitude, client_latitude):
        #import pdb; pdb.set_trace()
        places = []
        try:
            client_longitude = float(client_longitude)
            client_latitude  = float(client_latitude)

            place_cursor = self.PLACE.find( { "loc" : {"$near": [client_longitude, client_latitude]} } ).limit(config.NUM_PLACES_FOR_LIST)

            for place in place_cursor:
                dist = util.calc_approximate_distance( (client_longitude, client_latitude), (place['longitude'], place['latitude']) )
                place['distance'] = dist
                place['distance_txt'] = "%.2f" % dist

                if place.get(u'description', None) is not None and len(place[u'description']) > 100:
                    place[u'description'] = "%s..." % place[u'description'][:100]
                if place.get('last_update', None) is not None:
                    del place['last_update']
                p_loc = place.get('location', {})
                place['address_url'] = "%s+%s+%s" % (p_loc.get('street', "").encode('utf-8').replace(' ', '+'), p_loc.get('city', "").encode('utf-8').replace(' ', '+'), p_loc.get('state',"").encode('utf-8').replace(' ', '+'))
                places.append(place)
        except:
            import traceback
            msg = "Getting close places from mongodb failed.."
            logger.error(msg)
            logger.error("Unexpected error:%s", sys.exc_info())
            logger.error("%s", traceback.format_exc())
            if DEBUG:
                raise PersistenceLayerException(msg)
            return []
        return places
    def get_recommendation(self, uid, client_longitude, client_latitude):
#        import pdb; pdb.set_trace()
        client_longitude = float(client_longitude)
        client_latitude = float(client_latitude)
        logger.debug("uid:%s, client_longitude:%s, client_latitude:%s", uid, client_longitude, client_latitude)
        places_recommendation = []

        user = self.get_user(uid)
        friend_ids = user['friends']
        me_friend_ids = [uid] + friend_ids

        logger.debug("num of associated users: %s", len(me_friend_ids))
        #logger.debug("associated users: %s", me_friend_ids)
        me_friend_checkins = self.CHECKIN.find({"loc":{"$near": [client_longitude, client_latitude]}, "author_uid": {"$in": me_friend_ids}}, {'target_id':1}).limit(30)
        count = me_friend_checkins.count()

        # still 0 then we can't recommend any
        if count == 0:
            return []

        list_ci_target_ids = []
        for ci in me_friend_checkins:
            #logger.debug("%s", ci)
            #logger.debug("%s %s", ci.get('uname', None), ci.get('loc', None))
            list_ci_target_ids.append(long(ci['target_id']))
            
        similar_places_cursor = self.PLACE_SIMILAR.find({"loc":{"$near": [client_longitude, client_latitude]}, "source_page_ids": {"$in": list_ci_target_ids}},
                                                            {'_id':1, 'location':1, 'longitude':1, 'latitude':1, 'description':1, 'page_id':1, 'display_subtext':1, 
                                                             'name':1, 'loc':1, 'categories':1, 'page_url':1}
                                                            ).limit(config.NUM_PLACES_FOR_LIST)
        place_id_recomm_hash = {}
        for similar_place in similar_places_cursor:
            id_similar_place = similar_place.get('_id', None)
            if id_similar_place is not None and place_id_recomm_hash.get(long(id_similar_place), None) is None:
                place_id_recomm_hash[long(id_similar_place)] = True
                dist = util.calc_approximate_distance( (client_longitude, client_latitude), (similar_place['loc'][0], similar_place['loc'][1]) )
                similar_place['distance'] = dist
                similar_place['distance_txt'] = "%.2f" % dist

                if similar_place.get(u'description', None) is not None and len(similar_place[u'description']) > 100:
                    similar_place[u'description'] = "%s..." % similar_place[u'description'][:100]

                if similar_place.get('last_update', None) is not None:
                    del similar_place['last_update']

                places_recommendation.append(similar_place)
                logger.debug("recommend place\n: %s" % similar_place)

        #import pdb; pdb.set_trace()
        return places_recommendation
Exemple #3
0
    def query_save_similar_places(self, rate_list, user_access_token, client_loc_longitude, client_loc_latitude):
        #import pdb; pdb.set_trace()
        logger.info("rate_list: %s, user_access_token:%s, client_loc_longitude:%s, client_loc_latitude:%s" % (rate_list, user_access_token, client_loc_longitude, client_loc_latitude))
        try:
            client_loc_longitude = float(client_loc_longitude)
            client_loc_latitude = float(client_loc_latitude)
        except:
            logger.error("client_loc_longitude:%s or client_loc_latitude:%s is not number" % (client_loc_longitude, client_loc_latitude))

        count = 0
        for pref in rate_list:
            places_nearby = []

            # skip if already saved or exceeds max query counts
            if self._persistence.is_similar_places_saved(pref['page_id']) or count > MAX_COUNT_QUERY_SIMILAR_PLACES_PER_USER:
                continue
            p = self._persistence.find_one_record('place', {'page_id': pref['page_id']})

            if p is not None and p.get('categories', None) is not None and p.get('latitude', None) is not None and \
                    p.get('longitude', None) is not None:
                logger.debug("fb place - Name:%s, categories:%s, display_subtext:%s, type:%s, latitude:%s, longitude:%s, checkin count:%s, fan count:%s", \
                                     repr(p['name']), repr(p.get('categories', None)), repr(p.get('display_subtext', None)), repr(p.get('type', None)), \
                                     p['latitude'], p['longitude'], p.get('checkin_count', None), p.get('fan_count', None))                    
                distance_appr = util.calc_approximate_distance((client_loc_longitude, client_loc_latitude), (p['longitude'], p['latitude'])) 

                query_str = p.get('categories', [])
                if len(query_str) > 0 and distance_appr < DISTANCE_QUERY_SIMILAR_PLACES_MILES:
                    query_str = query_str[0].get("name", None)
                    places_nearby = self.query_fb_nearby_places(user_access_token, p['latitude'], p['longitude'], query=query_str)
                    count += 1
                else:
                    logger.error("category not found or not close enougn (%smi)for %s", distance_appr, p)
        
                if len(places_nearby) > 0:
                    self._persistence.save_similar_places(places_nearby, p['page_id'])
            else:
                logger.error("place or its category is None. Skipping %s", p)
#        import pdb; pdb.set_trace()
        logger.info("Total of %s similar places queried.", count)
    def get_close_places(self, uid, client_longitude, client_latitude, sort_by=constant.SORT_BY_DISTANCE):
        logger.debug("method get_close_places(\nuid:%s, \nclient_longitude:%s, \nclient_latitude:%s)" % (uid, client_longitude, client_latitude))
        try:
            client_longitude = float(client_longitude)
            client_latitude  = float(client_latitude)

            me_friend_id_list = self.USER.find_one({"_id": long(uid)}, {"friends": 1}).get("friends", [])
            me_friend_id_list.append(long(uid))
            logger.debug("friend_id_list: %s" % me_friend_id_list)

            friend_uname_cursor = self.USER.find({ "_id": {"$in": me_friend_id_list} }, {"name": 1})
            friend_uname_list = []
            for f in friend_uname_cursor:
                friend_uname_list.append(f['name'])
            #logger.debug("friend_uname_list: %s" % friend_uname_list)

            # Searching embedded documents hasn't been supported yet
            # checkin_list = USER.find( { "checkin.loc" : {"$near": [client_longitude, client_latitude]} }, {"checkin.loc": 1} ).limit(300)
            # alternative is making separate collection Checkin
            if sort_by==constant.SORT_BY_DISTANCE:
                checkin_cursor = self.CHECKIN.find( { "loc" : {"$near": [client_longitude, client_latitude]}, "author_uid": {"$in": me_friend_id_list} } ).limit(config.NUM_PLACES_FOR_LIST)
            else:
                checkin_cursor = self.CHECKIN.find( { "loc" : {"$near": [client_longitude, client_latitude]}, "author_uid": {"$in": me_friend_id_list} } ).limit(config.NUM_PLACES_FOR_LIST).sort("timestamp", pymongo.DESCENDING)

            checkin_target_id_list = []
            checkin_hash_target_id = {}
            checkin_display_hash_target_id = {}
            for cin in checkin_cursor:
                #logger.debug("cin: %s" % cin)
                cin["date"] = unicode(datetime.datetime.fromtimestamp(int(cin["timestamp"])).strftime('%m/%d/%Y'))  # to avoid not JSON serializable
                del cin["timestamp"]

                if checkin_hash_target_id.get(cin["target_id"], None) is None:
                    checkin_hash_target_id[cin["target_id"]] = [cin]
                    checkin_target_id_list.append(cin["target_id"])
                else:
                    checkin_hash_target_id[cin["target_id"]].append(cin)
                
                if checkin_display_hash_target_id.get(cin["target_id"], None) is None:
                    checkin_display_hash_target_id[cin["target_id"]] = ["%s (%s)" % (cin.get("uname", None), cin["date"])]
                else:
                    checkin_display_hash_target_id[cin["target_id"]].append("%s (%s)" % (cin.get("uname", None), cin["date"]))

            #logger.debug("checkin_list: %s" % checkin_list)
            #logger.debug("checkin_target_id_list: %s" % checkin_target_id_list)
            logger.debug("checkin_display_hash_target_id: %s" % checkin_display_hash_target_id)

            #import pdb; pdb.set_trace()
            places = {}
            #place_cursor = self.PLACE.find( { "loc" : {"$near": [client_longitude, client_latitude]}, "page_id" : {"$in": checkin_target_id_list} } )
            place_cursor = self.PLACE.find( { "page_id" : {"$in": checkin_target_id_list} } )
            for place in place_cursor:
                place["checkins"] = checkin_hash_target_id[place["page_id"]]
                place["checkin_display_txts"] = checkin_display_hash_target_id[place["page_id"]]

                dist = util.calc_approximate_distance( (client_longitude, client_latitude), (place['longitude'], place['latitude']) )
                place['distance'] = dist
                place['distance_txt'] = "%.2f" % dist

                if place.get(u'description', None) is not None and len(place[u'description']) > 100:
                    place[u'description'] = "%s..." % place[u'description'][:100]
                if place.get('last_update', None) is not None:
                    del place['last_update']
                p_loc = place.get('location', {})
                place['address_url'] = "%s+%s+%s" % (p_loc.get('street', "").encode('utf-8').replace(' ', '+'), p_loc.get('city', "").encode('utf-8').replace(' ', '+'), p_loc.get('state',"").encode('utf-8').replace(' ', '+'))
                places[place['page_id']] = place

            places_ordered = []
            for target_id in checkin_target_id_list:
                if places.get(target_id, None) is not None:
                    places_ordered.append(places[target_id])
                    logger.debug("ordered close place\n: %s" % places[target_id])
            num_places = len(places_ordered)
            logger.debug("num of close places retrieved: %s" % num_places)
            return places_ordered
        except:
            import traceback
            msg = "Getting close places from mongodb failed.."
            logger.error(msg)
            logger.error("Unexpected error:%s", sys.exc_info())
            logger.error("%s", traceback.format_exc())
            if DEBUG:
                raise PersistenceLayerException(msg)
            return []