Beispiel #1
0
    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.')
Beispiel #2
0
 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
Beispiel #3
0
 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
Beispiel #4
0
    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))
Beispiel #5
0
    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))
Beispiel #6
0
    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.')