def post(self): session = is_logged_in(self) if not session: return self.redirect(REDIR_URL) req = self.request errors = {} ad_url = validate_string(req, errors, 'ad_url', 'Craigslist Ad URL') if ad_url: if ad_url[:7] != 'http://': ad_url = 'http://' + ad_url m = RE_URL_CHECK.match(ad_url) if not m: errors['ad_url'] = 'This URL does not appear to be a valid craigslist.org webpage.' else: m = RE_ID.match(ad_url) if not m: errors['ad_url'] = 'Could not extract the ID from Ad URL' else: cid = int(m.group(1)) if len(errors): return self.redirect_to_self(GET_PARAMS, errors) # efficiency: get Ad and UserCmt at the same time to_put = [] ad_key = db.Key.from_path('Ad', cid) cmt_key = db.Key.from_path('UserCmt', '%s%s' % (session['my_id'], cid)) ad, cmt = db.get([ad_key, cmt_key]) # download the ad if we don't already have it in our db if not ad: ret = self.fetch_and_parse_page(ad_url) if not ret: errors['ad_url'] = 'Unable to download the webpage' return self.redirect_to_self(GET_PARAMS, errors) title, desc, dt = ret ad = Ad(key=ad_key, feeds=['manual'], title=title, desc=desc, update_dt=dt, url=ad_url) to_put = [ad] elif 'manual' not in ad.feeds: ad.feeds.insert(0, 'manual') to_put = [ad] # create UserCmt if not cmt: cmt = UserCmt(key=cmt_key, feeds=ad.feeds) to_put.append(cmt) elif 'manual' in cmt.feeds: return self.redirect('/tracker?info=You%20are%20already%20manually%20tracking%20that%20ad.') elif cmt.feeds != ad.feeds: cmt.feeds = ad.feeds to_put.append(cmt) # save the new entities if to_put: db.put(to_put) # redirect the user to the feed page self.redirect('/tracker?info=Added%20Ad%20%23' + str(cid) + '%20to%20your%20manually%20specified%20list.')
def get_cmt_from_cid(self, str_cid, uid): key_name = uid + str_cid cmt = UserCmt.get_by_key_name(key_name) if not cmt: ad = Ad.get_by_id(int(str_cid)) if not ad: logging.warn('%s for unknown Ad cid=%s from_uid=%s' % (self.get_action_name(), str_cid, uid)) return False # create a new user comment entity for this Ad return UserCmt(key_name=key_name, feeds=ad.feeds) return cmt
def get_cmt_from_cid(self, str_cid, uid): key_name = uid + str_cid cmt = UserCmt.get_by_key_name(key_name) if not cmt: ad = Ad.get_by_id(int(str_cid)) if not ad: logging.warn("%s for unknown Ad cid=%s from_uid=%s" % (self.get_action_name(), str_cid, uid)) return False # create a new user comment entity for this Ad return UserCmt(key_name=key_name, feeds=ad.feeds) return cmt
def post(self): token = self.request.get('token') url = 'https://rpxnow.com/api/v2/auth_info' args = { 'format': 'json', 'apiKey': '78383d7d2030d84d6df056d5cd3fb962c88f18a4', 'token': token } r = urlfetch.fetch(url=url, payload=urllib.urlencode(args), method=urlfetch.POST, headers={'Content-Type':'application/x-www-form-urlencoded'}) json = simplejson.loads(r.content) # close any active session the user has since he is trying to login session = get_current_session() old_uid = old_feed_infos = None if session.is_active(): old_uid = session.get('my_id', 'x') if old_uid[0] == 'Z': old_feed_infos = get_feed_infos(None) session.terminate() redir_to = self.request.get('redir_to') if json['stat'] == 'ok': # extract some useful fields info = json['profile'] oid = info['identifier'] email = info.get('email', '') try: display_name = info['displayName'] except KeyError: display_name = email.partition('@')[0] if not display_name: display_name = 'Unknown' # get the user's account (creating one if they did not previously have one) hashed_id = User.make_key_name(oid) user = User.get_or_insert(key_name=hashed_id, display_name=display_name, email=email) # start a session for the user session['my_dname'] = user.display_name session['my_id'] = hashed_id session['my_last_seen'] = int(time.mktime(user.last_seen.timetuple())) session['my_email'] = user.email # if the user was logged in anonymously, merge their info into this account more = '' if old_uid and old_uid[0] == 'Z': # 1) Add User.feeds and feed_names into this User old_feed_infos = [(of_name, of_feed.key().name()) for of_name, of_feed in old_feed_infos] new_feed_infos = zip(user.feed_names, user.feeds) changed = False for ofi in old_feed_infos: if ofi not in new_feed_infos: new_feed_infos.append(ofi) changed = True if changed: tfn, tf = zip(*new_feed_infos) user.feed_names, user.feeds = list(tfn), list(tf) user.put() # clear memcache for this user since the value is stale if present memcache.delete("user-feeds:%s" % hashed_id) # 2) Get the UserCmt for old_uid and move them to the logged in user account if old_feed_infos: start_key, end_key = db.Key.from_path('UserCmt', old_uid), db.Key.from_path('UserCmt', old_uid+'\ufffd') old_cmts = UserCmt.all().filter('__key__ >', start_key).filter('__key__ <', end_key).fetch(250) new_cmts = [UserCmt(key_name='%s%s'%(hashed_id,cmt.cid), feeds=cmt.feeds, rating=cmt.rating, cmt=cmt.cmt, dt_hidden=cmt.dt_hidden) for cmt in old_cmts] db.put(new_cmts) db.delete(old_cmts) if len(new_cmts) == 250: more = '?info=We%20merged%20250%20comments%20so%20far%20and%20we%20will%20finish%20the%20rest%20soon.' logging.error('Need to finish converting anonymous comments by uid %s to %s' % (old_uid, hashed_id)) # TODO: do this on the task queue instead of just raising an error if not redir_to or more: self.redirect('/tracker' + more) else: self.redirect(redir_to.replace('@$@', '&')) else: msg = json['err']['msg'] if not redir_to: qp = dict(login_error=msg) else: qp = dict(login_error=msg, redir_to=redir_to) self.redirect('/?' + urllib.urlencode(qp))
def get(self): session = is_logged_in(self) if not session: return self.redirect('/') uid = session['my_id'] now = datetime.datetime.now() feed_key_name = self.request.get('f') t = self.request.get('t') overall_view = (not feed_key_name and t != 'newest') if feed_key_name == 'manual': fhid = 'manual' age = desc = None updating_shortly = False if t == 'hidden': name = "Manually-Added Ads that were Hidden" elif t == 'newest': return self.redirect('/tracker') else: name = "Manually-Added Ads" elif feed_key_name: fhid = Feed.hashed_id_from_pk(feed_key_name) # get the user's name for this feed name = get_search_name(self, feed_key_name) if name is None: return self.redirect('/tracker') # user is no longer tracking this feed elif name is False: return self.redirect('/') # login related error # compute how old the data is feed_dt_updated = dt_feed_last_updated(feed_key_name) if not feed_dt_updated: return self.redirect('/tracker?err=That%20feed%20no%20longer%20exists.') age = str_age(feed_dt_updated, now) td = now - feed_dt_updated updating_shortly = td.days>0 or td.seconds>MAX_AGE_MIN*60 if updating_shortly: age += ' - update in progress' # update the feed if we haven't retrieved the latest ads recently updating = update_feed_if_needed(feed_key_name) if updating is None: return self.redirect('/tracker?err=The%20requested%20feed%20does%20not%20exist.') elif overall_view: age = desc = fhid = None updating_shortly = False if t == 'hidden': name = "All Hidden Ads" else: name = "All Rated/Noted Ads" else: # t=newest and feed=all doesn't make sense together return self.redirect('/tracker') # determine which set of ads to show next = self.request.get('next') if t == 'newest': # show the newest ads (regardless of whether the user has commented on them or not) q = Ad.all().filter('feeds =', fhid).order('-update_dt') if next: q.with_cursor(next) ads = q.fetch(ADS_PER_PAGE) # get user comments on these ads, if any user_ad_keys = [db.Key.from_path('UserCmt', '%s%s' % (uid, a.cid)) for a in ads] user_ad_notes = db.get(user_ad_keys) title_extra = 'Newest Ads' else: # show ads this user has commented on/rated (whether to show hidden ads or not depends on t) hidden = (t == 'hidden') q = UserCmt.all() q.filter('uid =', session['my_id']) if fhid: q.filter('feeds =', fhid) if hidden: q.filter('dt_hidden >', DT_PRESITE).order('-dt_hidden') else: q.filter('dt_hidden =', None).order('-rating') if next: q.with_cursor(next) user_ad_notes = q.fetch(ADS_PER_PAGE) # get the ads associated with these comments ad_keys = [db.Key.from_path('Ad', uan.cid) for uan in user_ad_notes] ads = db.get(ad_keys) if t == 'hidden': title_extra = "Ignored Ads" else: title_extra = "Ads I've Rated" # put the ads and their comments together ad_infos = zip(ads, user_ad_notes) # check that each UserCmt.feeds field is up to date with Ad.feeds (can # only do this when we're searching by Ad, i.e., t=newest) if t == 'newest': # TODO: only mark as outdated if they are inequal EXCEPT 'manual' # TODO: when updating cmt.feeds, don't copy over 'manual' (user-specific) # TODO: reconsider this code ... outdated = [(ad,cmt) for ad, cmt in ad_infos if cmt and ad.feeds!=cmt.feeds] if outdated: # update any out of date comments for ad,cmt in outdated: cmt.feeds = ad.feeds db.put([cmt for ad,cmt in outdated]) # whether there may be more ads more = (len(ads) == ADS_PER_PAGE) if more: more = q.cursor() if not more or more==str(next): more = None # get a description of the search we're viewing if fhid and fhid!='manual': tmp_feed = Feed(key_name=feed_key_name) tmp_feed.extract_values() desc = tmp_feed.desc() if not next: page = 1 else: try: page = int(self.request.get('page', 1)) except ValueError: page = 1; self.response.headers['Content-Type'] = 'text/html' self.response.out.write(MakoLoader.render('search_view.html', request=self.request, ADS_PER_PAGE=ADS_PER_PAGE, ads=ad_infos, more=more, age=age, now=now, search_desc=desc, title_extra=title_extra, page=page, name=name, updating_shortly=updating_shortly, overall_view=overall_view))
def post(self): session = is_logged_in(self) if not session: return self.redirect(REDIR_URL) req = self.request errors = {} ad_url = validate_string(req, errors, 'ad_url', 'Craigslist Ad URL') if ad_url: if ad_url[:7] != 'http://': ad_url = 'http://' + ad_url m = RE_URL_CHECK.match(ad_url) if not m: errors[ 'ad_url'] = 'This URL does not appear to be a valid craigslist.org webpage.' else: m = RE_ID.match(ad_url) if not m: errors['ad_url'] = 'Could not extract the ID from Ad URL' else: cid = int(m.group(1)) if len(errors): return self.redirect_to_self(GET_PARAMS, errors) # efficiency: get Ad and UserCmt at the same time to_put = [] ad_key = db.Key.from_path('Ad', cid) cmt_key = db.Key.from_path('UserCmt', '%s%s' % (session['my_id'], cid)) ad, cmt = db.get([ad_key, cmt_key]) # download the ad if we don't already have it in our db if not ad: ret = self.fetch_and_parse_page(ad_url) if not ret: errors['ad_url'] = 'Unable to download the webpage' return self.redirect_to_self(GET_PARAMS, errors) title, desc, dt = ret ad = Ad(key=ad_key, feeds=['manual'], title=title, desc=desc, update_dt=dt, url=ad_url) to_put = [ad] elif 'manual' not in ad.feeds: ad.feeds.insert(0, 'manual') to_put = [ad] # create UserCmt if not cmt: cmt = UserCmt(key=cmt_key, feeds=ad.feeds) to_put.append(cmt) elif 'manual' in cmt.feeds: return self.redirect( '/tracker?info=You%20are%20already%20manually%20tracking%20that%20ad.' ) elif cmt.feeds != ad.feeds: cmt.feeds = ad.feeds to_put.append(cmt) # save the new entities if to_put: db.put(to_put) # redirect the user to the feed page self.redirect('/tracker?info=Added%20Ad%20%23' + str(cid) + '%20to%20your%20manually%20specified%20list.')