def get(self): if self.user: if not self.user.interestingFriends: if ProgressCache.get(self.userID, 'isRunning'): logging.info('Algorithm is already running') else: ProgressCache.set(self.userID, 'isRunning', True) logging.info('Starting algorithm') taskqueue.add(url = '/calc-friends', method = 'GET', params = {'access_token': self.user.access_token, 'user_id': self.user.user_id}) self.render('runs', interestingFriends = None, userID = self.userID) else: logging.info('Retrieving interesting friends from DB') interestingFriendsList = eval(str(self.user.interestingFriends)) Couple = namedtuple('Couple', 'firstName firstID secondName secondID') interestingFriends = [eval(couple) for couple in interestingFriendsList] firstFriends = interestingFriends[: self.NUM_OF_PAIRS / 2] lastFriends = interestingFriends[self.NUM_OF_PAIRS / 2: self.NUM_OF_PAIRS] # if ProgressCache.get(self.userID, 'isRunning'): # self.render('runs', interestingFriends = None, userID = self.userID) # else: self.render('runs', interestingFriends = interestingFriends, firstFriends = firstFriends, lastFriends = lastFriends) else: self.render('welcome')
def __calcFloydWarshall(self): n = len(self.graph) lastFloor = 0 for k in range(n): # print algorithm progress floor = math.floor(float(k) / n * 10) if floor != lastFloor: logging.info('%s percent done' % (str(int(floor) * 10))) # print '%s percent done' % (str(int(floor) * 10)) lastFloor = floor # cache algorithm progress # memcache.set('graph_progress', float(k) / n) ProgressCache.set(self.userID, 'graph_progress', float(k) / n) for i in range(n): if i == k: continue for j in range(n): if j == i or j == k: continue if self.path[i][k] + self.path[k][j] < self.path[i][j]: self.path[i][j] = self.path[i][k] + self.path[k][j] self.nextEdge[i][j] = [k] elif 1 < self.path[i][k] + self.path[k][j] == self.path[i][j] < sys.maxint: self.nextEdge[i][j].append(k) logging.info('100 percent done') ProgressCache.set(self.userID, 'graph_progress', 1.0)
def __getFriends(self, myFriends, wifeID): # separate the friend calls to batches of 50 BATCH_SIZE = 50 MUTUAL_FRIENDS_THRESHOLD = 1#len(myFriends) / 50 idx = 0 friendsList = [] smallFriends = [] numOfBatches = len(myFriends) / BATCH_SIZE + 1 #numOfBatches = 1 for batchIdx in range(numOfBatches): # insert progress into cache ProgressCache.set(self.userID, 'fetch_progress', float(batchIdx) / numOfBatches) start = batchIdx * BATCH_SIZE end = start + BATCH_SIZE friends = myFriends.keys()[start: end] logging.info('Getting batch %s to %s' % (start, end)) # print 'Getting batch %s to %s' % (start, end) mutualBatch = self.__getBatchRequest(friends, wifeID) for mutual in mutualBatch: id, mutualFriends = mutual if len(mutualFriends) >= MUTUAL_FRIENDS_THRESHOLD: friendsList.append((id, myFriends[id], idx, mutualFriends)) idx += 1 else: smallFriends.append(id) # set cache to done ProgressCache.set(self.userID, 'fetch_progress', 1.0) # remove friends with low mutual count from friends lists friendsList = map(lambda x: (x[0], x[1], x[2], list(set(x[3]).difference(smallFriends))), friendsList) return friendsList
def __getFriendsByIntersection(self): edges = {} n = len(self.graph) for i in range(n): ProgressCache.set(self.userID, 'graph_progress', float(i) / n) for j in range(i + 1, n): key = i, j if self.path[i][j] < sys.maxint: edges[key] = self.__calcFriendsIntersection(key) else: # edges[key] = sys.maxint edges[key] = sys.maxint, sys.maxint, sys.maxint, sys.maxint ProgressCache.set(self.userID, 'graph_progress', 1.0) return edges
def __getMostVisitedEdges(self): edges = {} n = len(self.graph) for i in range(n): # memcache.set('edges_progress', float(i) / n) ProgressCache.set(self.userID, 'edges_progress', float(i) / n) for j in range(n): routes = self.__getAllPaths(i, j) for route in routes: for k in range(len(route) - 1): key = (route[k], route[k + 1]) if key[0] < key[1]: if key not in edges: edges[key] = 0.0 edges[key] += 1.0 / len(routes) ProgressCache.set(self.userID, 'edges_progress', 1.0) # f = open('edges.txt') # edges = eval(f.read()) # f.close() for idx, key in enumerate(edges.keys()): # memcache.set('ratio_progress', float(idx) / len(edges)) ProgressCache.set(self.userID, 'ratio_progress', float(idx) / len(edges)) ratio = self.__calcFriendsIntersection(key) if ratio < 0.05: edges[key] = (edges[key], ratio) else: edges[key] = (1, ratio) ProgressCache.set(self.userID, 'ratio_progress', 1.0) return edges
def get(self): logging.info('Calculating interesting friends') ProgressCache.setMulti(self.request.get('user_id'), {'fetch_progress': 0, 'graph_progress': 0, 'edges_progress': 0, 'ratio_progress': 0}) try: finder = friendsFinder.FriendsFinder(self.request.get('access_token'), self.request.get('user_id')) interestingFriends = finder.getInterestingFriends() user = User.get_by_key_name(self.request.get('user_id')) user.storeInterestingFriends(interestingFriends[: 20]) except DeadlineExceededError: self.response.clear() self.response.set_status(500) self.response.out.write("You have too many friends...") finally: # reset progress counters ProgressCache.set(self.request.get('user_id'), 'isRunning', False)