Mercurial > code > home > repos > href
view lookup.py @ 28:7c82ffbca5d0
py3 and k8s upgrade
author | drewp@bigasterisk.com |
---|---|
date | Sun, 12 Jul 2020 13:16:33 -0700 |
parents | e02fc021ab89 |
children | e86642cf7393 |
line wrap: on
line source
#!bin/python """ serve some queries over bookmarks: /user /user/tag+tag+tag and the add-bookmark stuff """ import pymongo, bottle, time, urllib.request, urllib.parse, urllib.error, datetime, json, logging import requests from collections import defaultdict from urllib.parse import urlparse from dateutil.tz import tzlocal from bottle import static_file from jadestache import Renderer from pagetitle import PageTitle from link import Links, NotFound db = pymongo.Connection('mongodb.default.svc.cluster.local', tz_aware=True)['href'] pageTitle = PageTitle(db) links = Links(db) renderer = Renderer(search_dirs=['template'], debug=bottle.DEBUG) log = logging.getLogger() def getLoginBar(): return requests.get("http://openid-proxy.default.svc.cluster.local:9023/_loginBar", headers={ "Cookie" : bottle.request.headers.get('cookie'), 'x-site': 'http://bigasterisk.com/openidProxySite/href', }).text def getUser(): agent = bottle.request.headers.get('x-foaf-agent', None) username = db['user'].find_one({'_id':agent})['username'] if agent else None return username, agent def siteRoot(): try: return bottle.request.headers['x-site-root'].rstrip('/') except KeyError: log.warn(repr(bottle.request.__dict__)) raise @bottle.route('/static/<path:path>') def server_static(path): return static_file(path, root='static') def recentLinks(user, tags, allowEdit): out = {'links':[]} t1 = time.time() spec = {'user':user} if tags: spec['extracted.tags'] = {'$all' : tags} for doc in db['links'].find(spec, sort=[('t', -1)], limit=50): link = links.forDisplay(doc) link['allowEdit'] = allowEdit out['links'].append(link) out['stats'] = {'queryTimeMs' : round((time.time() - t1) * 1000, 2)} return out def allTags(user, withTags=[]): """withTags limits results to other tags that have been used with those tags""" withTags = set(withTags) count = defaultdict(lambda: 0) # tag : count for doc in db['links'].find({'user':user}, fields=['extracted.tags']): docTags = set(doc.get('extracted', {}).get('tags', [])) if withTags and not withTags.issubset(docTags): continue for t in docTags.difference(withTags): count[t] = count[t] + 1 byFreq = [(n, t) for t,n in count.items()] byFreq.sort(key=lambda n_t: (-n_t[0], n_t[1])) return [{'label': t, 'count': n} for n, t in byFreq] def renderWithTime(name, data): t1 = time.time() rendered = renderer.render_name(name, data) dt = (time.time() - t1) * 1000 rendered = rendered.replace('TEMPLATETIME', "%.02f ms" % dt) return rendered @bottle.route('/addLink') def addLink(): out = { 'toRoot': siteRoot(), 'absRoot': siteRoot(), 'user': getUser()[0], 'withKnockout': True, 'fillHrefJson': json.dumps(bottle.request.params.get('url', '')), 'loginBar': getLoginBar(), } return renderWithTime('add.jade', out) @bottle.route('/addOverlay') def addOverlay(): p = bottle.request.params return "" @bottle.route('/addLink/proposedUri') def proposedUri(): uri = bottle.request.params.uri user, _ = getUser() try: prevDoc = links.find(uri, user) except NotFound: prevDoc = None return { 'description': prevDoc['description'] if prevDoc else pageTitle.pageTitle(uri), 'tag' : prevDoc['tag'] if prevDoc else '', 'extended' : prevDoc['extended'] if prevDoc else '', 'shareWith' : prevDoc.get('shareWith', []) if prevDoc else [], 'suggestedTags': ['tag1', 'tag2'], 'existed': prevDoc is not None, } if 0: pass#proposal check existing links, get page title (stuff that in db), get tags from us and other serviecs. maybe the deferred ones ater @bottle.route('/tags') def tagFilterComplete(): params = bottle.request.params haveTags = [_f for _f in params['have'].split(',') if _f] if haveTags and len(haveTags[-1]) > 0: haveTags, partialTerm = haveTags[:-1], haveTags[-1] else: partialTerm = "" out = [] for t in allTags(params.user, withTags=haveTags): if partialTerm and partialTerm not in t['label']: continue out.append({'id': t['label'], 'text': "%s (%s%s)" % (t['label'], t['count'], " left" if haveTags else "")}) return {'tags' : out} @bottle.route('/<user>/') def userSlash(user): bottle.redirect(siteRoot() + "/%s" % urllib.parse.quote(user)) @bottle.route('/<user>.json', method='GET') def userAllJson(user): data = recentLinks(user, [], allowEdit=getUser()[0] == user) data['toRoot'] = siteRoot() return json.dumps(data) @bottle.route('/<user>', method='GET') def userAll(user): return userLinks(user, "") @bottle.route('/<user>', method='POST') def userAddLink(user): if getUser()[0] != user: raise ValueError("not logged in as %s" % user) print(repr(bottle.request.params.__dict__)) doc = links.fromPostdata(bottle.request.params, user, datetime.datetime.now(tzlocal())) links.insertOrUpdate(doc) print("notify about sharing to", repr(doc['shareWith'])) bottle.redirect(siteRoot() + '/' + user) def parseTags(tagComponent): # the %20 is coming from davis.js, not me :( return [_f for _f in tagComponent.replace("%20", "+").split('+') if _f] @bottle.route('/<user>/<tags:re:.*>.json') def userLinksJson(user, tags): tags = parseTags(tags) data = recentLinks(user, tags, allowEdit=getUser()[0] == user) data['toRoot'] = siteRoot() return json.dumps(data) @bottle.route('/<user>/<tags>') def userLinks(user, tags): tags = parseTags(tags) log.info('userLinks user=%r tags=%r', user, tags) data = recentLinks(user, tags, allowEdit=getUser()[0] == user) data['loginBar'] = getLoginBar() data['desc'] = ("%s's recent links" % user) + (" tagged %s" % (tags,) if tags else "") data['toRoot'] = siteRoot() data['allTags'] = allTags(user) data['user'] = user data['showPrivateData'] = (user == getUser()[0]) data['pageTags'] = [{"word":t} for t in tags] data['stats']['template'] = 'TEMPLATETIME' return renderWithTime('links.jade', data) @bottle.route('/templates') def templates(): return json.dumps({'linklist': renderer.load_template("linklist.jade")}) @bottle.route('/') def root(): data = { 'loginBar': getLoginBar(), 'toRoot': siteRoot(), 'stats': {'template': 'TEMPLATETIME'}, 'users': [{'user':doc['username']} for doc in db['user'].find()], } return renderWithTime('index.jade', data) if __name__ == '__main__': logging.basicConfig(level=logging.INFO) bottle.run(server='gunicorn', host='0.0.0.0', port=10002, workers=4)