Exemplo n.º 1
0
def list_entries_query(db, req):
    """
    Reusable function
    """

    query = {}

    if "author" in req:
        # FIXME debug
        r = dbref("users", req["author"], database=app.config["DB_SYSTEM_DATABASE"])
        query["revdoc.author"] = r

    if "class" in req:
        if req["class"] == "page":
            query["class"] = "page"
        elif req["class"] == "notpage":
            query["class"] = {"$ne": "page"}
        elif req["class"] == "text":
            query["class"] = "text"
        elif req["class"] == "markdown":
            query["class"] = "markdown"
        elif req["class"] == "figure":
            query["class"] = "figure"

    if "archived" in req:
        # three values: yes, no, all
        if req["archived"] == "all":
            pass
        elif req["archived"] == "yes":
            query["revdoc.archived"] = True
        elif req["archived"] == "no":
            query["revdoc.archived"] = False
    else:
        query["revdoc.archived"] = False

    limit = 100
    if "limit" in req:
        limit = int(req["limit"])

    tgt_fields = {"class": 1, "head": 1, "revdoc.title": 1, "revdoc.author": 1, "revdoc.date": 1, "revdoc.tags": 1}
    if query == {}:
        results = db.entries.find(fields=tgt_fields).sort("revdoc.date", -1).limit(limit)
    else:
        results = db.entries.find(query, fields=tgt_fields).sort("revdoc.date", -1).limit(limit)

    results_data = []
    for r in results:
        # fixme add date
        rd = {
            "_id": str(r["_id"]),
            "class": r["class"],
            "head": str(r["head"].id),
            "title": str(r["revdoc"]["title"]),
            "author": str(r["revdoc"]["author"].id),
            "date": str(r["revdoc"]["date"].isoformat()),
            "tags": r["revdoc"]["tags"],
        }

        results_data.append(rd)
    return results_data
Exemplo n.º 2
0
def api_rev_get(notebook, revid):
    """
    get rev
    
    """
    db = g.dbconn[get_nb_dbname(notebook)]

    rev = db.dereference(dbref('revisions', revid))

    
    return jsonify(dm.rev_to_json[rev['class']](rev))
Exemplo n.º 3
0
def home():
    notebooks = g.sysdb.notebooks.find({'users':  dbref('users', session['user_id']),
                                        'archived' : { "$ne" :  True}})
    nblist = []
    for n in notebooks:
        nblist.append({'name' : n['name'],
                       'title' : n['title']})
    
    return render_template("home.html", nblist = nblist,
                           notebook = None, 
                           session = session,
                           version = app.config['VERSION_GIT_DESCRIBE'])
Exemplo n.º 4
0
def api_notebookadmin_list():
    """
    List all the notebooks available to this user
    
    """

    if request.mimetype != "application/json":
        return "Invalid request type, must be application/json", HTTP_ERROR_CLIENT_BADREQUEST

    notebooks = g.sysdb.notebooks.find({'users' :  dbref('users', session['user_id']),
                                        'archived' : { "$ne" :  True}})
    nblist = []
    for n in notebooks:
        nblist.append({'name' : n['name'],
                       'title' : n['title']})

    return jsonify({"notebooks" : nblist})
Exemplo n.º 5
0
def lookup_user(userid):
    """
    FIXME: cache this eventually

    Take in a userid and return doc
     
     """
    if isinstance(userid, bson.dbref.DBRef):
        ref = userid
    else:
        ref = dbref("users", userid)

    doc = g.sysdb.dereference(ref)

    return {
        "_id": str(ref.id),
        "username": doc["username"],
        "name": doc.get("name", ""),
        "email": doc.get("email", ""),
        "avatar": doc.get("avatar", ""),
        "twitter": doc.get("twitter", ""),
    }
Exemplo n.º 6
0
def page_new(notebook):
    """
    
    """


    nbdb = g.dbconn[get_nb_dbname(notebook)]
    
    title = "New Page"
    entries = []

    page_rev = dm.page_entry_revision_create(title, entries)
    author =  session["user_id"]
    
    page_rev.update(dm.revision_create(author, app.config['DB_SYSTEM_DATABASE']))

    revid = nbdb.revisions.insert(page_rev, safe=True)
    page_rev["_id"] = revid
    
    ent_dict = dm.entry_create(dbref("revisions", revid), 'page', page_rev)
    
    entid = nbdb.entries.insert(ent_dict, safe=True)
    
    return redirect("/notebook/%s/page/%s" % (notebook, entid))
Exemplo n.º 7
0
def settings():

    if request.method == "GET":
        userref = dbref("users", session["user_id"])
        user = g.sysdb.dereference(userref)
        return render_template("usersettings.html", user=user,
                               session = session,
                               version = app.config['VERSION_GIT_DESCRIBE'])

    
    elif request.method == "POST":
        # FIXME add password changing
        
        userref = dbref("users", session["user_id"])
        user = g.sysdb.dereference(userref)
        
        if request.form['form'] == 'password' :
            pw1 = request.form['password']
            pw2 = request.form['password2']
            if pw1 != pw2 :
                return render_template("usersettings.html", user=user,
                                       session = session,
                                       action='password',
                                       success = False,
                                       version = app.config['VERSION_GIT_DESCRIBE'])

            else:
                saltpw = saltpassword(pw1, app.config['PASSWORDSALT'])
                user['password'] = saltpw
                user['apikey'] = random_api_key()

                g.sysdb.users.update({'_id' : user['_id'], },
                                  user)
                
                return render_template("usersettings.html", user=user,
                                       session = session,
                                       action='password',
                                       success = True,
                                       version = app.config['VERSION_GIT_DESCRIBE'])
            
            
        elif request.form['form'] == 'settings' :

            user['name'] = request.form['name']
            user['email'] = request.form['email']
            user['twitter'] =  request.form['twitter']

            g.sysdb.users.update({'_id' : user['_id'], },
                              user)
            session['name'] = user['name']
            
            return render_template("usersettings.html", user=user,
                                   session = session,
                                   action='settings',
                                   success = True,
                                   version = app.config['VERSION_GIT_DESCRIBE'])


        else:
            print "UNKNOWN FORM" # FIXME throw real error

        
        #user['name'] = request.form('username')
    else:
        raise "Invalid method"
Exemplo n.º 8
0
def api_entry_new(notebook):
    """
    Create a new revision and entry.
    
    You can POST a new json object to this URL and get back the JSON-ified page,
    it's entry, the fully-spec'd rev. 

    Note the input json must contain class
    and then any of the requirements for this class, for example:

    all:
       archived:
       tags: 
       
    text:
        title
        body

    page:
        title
        entries : [ {entry:, hidden:, rev:},]

    figure:
        title
        caption
        images
        
    returns :
       {'entry' : standard entry doc,
        'revision' : standard revision doc
        }

    or 400 if an invalid request

    """
    
    if request.mimetype != "application/json":
        return "Invalid request type, must be application/json", HTTP_ERROR_CLIENT_BADREQUEST


    request_data = request.json

    if 'class' not in request_data:
        return "'class' not present in request", HTTP_ERROR_CLIENT_BADREQUEST
    
    dclass = request_data['class']

    if dclass not in dm.json_to_rev:
        return "Unknown class",  HTTP_ERROR_CLIENT_BADREQUEST

    rev =  dm.json_to_rev[dclass](request_data)

    archived = request_data.get("archived", False)
    tags  = request_data.get("tags", [])

    rev.update(dm.revision_create(session["user_id"],
                                  app.config['DB_SYSTEM_DATABASE'], 
                                  archived=archived,
                                  tags = tags))
    nbdb = g.dbconn[get_nb_dbname(notebook)]

    revid = nbdb.revisions.insert(rev, safe=True)
    rev["_id"] = revid

    
    ent_dict = dm.entry_create(dbref("revisions", revid),
                               dclass, rev)

    entid = nbdb.entries.insert(ent_dict, safe=True)
    ent_dict["_id"] = entid

    # tag cleanup
    [tagutils.inc_tag(nbdb, t) for t in tags]
    

    rev_json = dm.rev_to_json[dclass](rev)
    
    return jsonify({'entry' : {'class' : dclass,
                               'head' : str(revid),
                               '_id' : str(entid)},
                    
                    'revision' : rev_json})
Exemplo n.º 9
0
def api_notebookadmin_config(notebook):
    """
    Configure notebook settings, updates the indicated fields

    # fields :
    title:
    admin
    users
    archived
    
    Always returns full doc

    """

    if request.mimetype != "application/json":
        return "Invalid request type, must be application/json", HTTP_ERROR_CLIENT_BADREQUEST

    def denorm_users(ul):
        users = {}
        for u in ul:
            ud = g.sysdb.dereference(u)
            users[str(ud["_id"])] = lookup_user(ud['_id'])
            
        return users; 
            
    if request.method == 'POST':
        # check if user is on admin list, otherwise this can't pass
        if not has_notebook_admin(session['user_id'], notebook):
            return "Don't have access", HTTP_ERROR_FORBIDDEN

        
        rd = request.json

        d = g.sysdb.notebooks.find({'name' : notebook})
        n = d[0]

        raw_nb_doc =  d[0]

        if 'title' in rd:
            raw_nb_doc['title'] = rd['title']

        if 'archived' in rd:
            if rd['archived']:
                raw_nb_doc['archived'] = True
            else:
                raw_nb_doc['archived'] = False
                

        # check unique
        
        if 'users' in rd:
            if len(set(rd['users']) ) != len(rd['users']):
                return "Duplicate in user list, error!", HTT_ERROR_CLIENT_BADREQUEST
            
            raw_nb_doc['users'] = []
            for u in rd['users'] :
                raw_nb_doc['users'].append(dbref('users', u))

        if 'admins' in rd:
            if len(set(rd['admins']) ) != len(rd['admins']):
                return "Duplicate in user list, error!", HTT_ERROR_CLIENT_BADREQUEST

            raw_nb_doc['admins'] = []
            for u in rd['admins'] :
                if dbref('users', u) not in raw_nb_doc['users']:
                    return "Admin must also be user", HTTP_ERROR_CLIENT_BADREQUEST
                
                raw_nb_doc['admins'].append(dbref('users', u))


        r = g.sysdb.notebooks.update({'_id' : raw_nb_doc['_id']},
                                     raw_nb_doc, safe=True)

        d = g.sysdb.notebooks.find({'name' : notebook})
        users = denorm_users(d[0]['users'])

        
        return jsonify({'notebook' : dm.notebook_to_json(d[0]),
                        'users' : users});
    
    

    elif request.method == "GET":

        d = g.sysdb.notebooks.find({'name' : notebook})
        # this is a hack, but whatever -- get the user info
        users = denorm_users(d[0]['users'])
        return jsonify({'notebook' : dm.notebook_to_json(d[0]),
                        'users' : users})
Exemplo n.º 10
0
def api_entry_get_post(notebook, entryid):
    """
    GET the latest entry and rev for an entry

    POST an updated rev. Note that we extract out the relevant fields
    from the submitted doc, and overwrite other relevant ones. Things
    that must be present include:

    class
    parent: Parent points to the old entry; this is also what we think the entry currently points to 
    doc-specific entries

    we rewrite :
    author (current logged in author)
    date
    _id : with the new updated revid

    and update the entry

    If the entry is out of date, we reject, and instead
    return the latest entry/rev, with error 409
    
    
    """

    nbdb = g.dbconn[get_nb_dbname(notebook)]

    if request.method == 'POST':
        """
        Perform an update, assuming that the doc is pretty well-formed

        """

    
        if request.mimetype != "application/json":
            return "Invalid request type, must be application/json", HTTP_ERROR_CLIENT_BADREQUEST
        
        rd = request.json

        dclass = rd['class']
        parent = rd['parent']


        if dclass == 'text':
            rev = dm.text_entry_revision_create(rd['title'],
                                                rd['body'])
        elif dclass == 'figure':
            rev = dm.figure_entry_revision_create(rd['title'],
                                                  rd['caption'],
                                                  rd.get('maxsize', None),
                                                  gallery = rd.get("gallery", False),
                                                  images = rd['images'])

        elif dclass == 'markdown' :
            rev = dm.markdown_entry_revision_create(rd['title'],
                                                    rd['body'])
        
        elif dclass == 'page':
            rev = dm.page_entry_revision_create(rd['title'],
                                                rd['entries'])
        else:
            raise Exception("Unknown entry class '%s'" % dclass)
        
        author = dbref("users", session["user_id"])
        tags = rd.get("tags", [])
        
        pref = dbref("revisions", parent)
        
        rev.update(dm.revision_create(session["user_id"], 
                                      app.config['DB_SYSTEM_DATABASE'], 
                                      parent=pref,
                                      archived=rd.get('archived', False),
                                      tags = tags))

        # save the revision
        new_rev_oid = nbdb.revisions.insert(rev, safe=True)
        rev["_id"] = new_rev_oid

        new_entry_doc = dm.entry_create(dbref('revisions', new_rev_oid),
                                        dclass, rev)

        
        res = nbdb.entries.update({'_id' : bson.objectid.ObjectId(entryid),
                                   'head' : dbref('revisions', parent), 
                                   'class' : dclass},
                                  new_entry_doc, safe=True)

        
        new_entry_doc["_id"] = bson.objectid.ObjectId(entryid)
        
    
        if res['updatedExisting'] == True:
            # success!

            # get the old revisions tags, compute the diff
            olddoc = nbdb.dereference(dbref('revisions', parent))
            tagdeltas = tagutils.tagdelta(olddoc.get('tags', []),
                                          tags)

            [tagutils.inc_tag(nbdb, t) for t in tagdeltas[0]]
            [tagutils.dec_tag(nbdb, t) for t in tagdeltas[1]]

            new_rev_doc_json = dm.rev_to_json[dclass](rev)

            entry_doc_json = dm.entry_to_json(new_entry_doc)
            
            return jsonify({"latest_entry_doc" : entry_doc_json, 
                            "latest_revision_doc" : new_rev_doc_json})


        else:
            # failed to update, meaning someone else updated the entry ahead of us

            nbdb.revisions.remove({'_id' : new_rev_oid})

            entry_ref = dbref("entries", entryid)
            latest_entry_doc = nbdb.dereference(entry_ref)

            true_latest_rev_ref = latest_entry_doc['head']
            latest_rev_doc = nbdb.dereference(true_latest_rev_ref)
            latest_rev_json = dm.page_rev_to_json(latest_rev_doc)

            entry_doc_json = dm.entry_to_json(latest_entry_doc)

            return jsonify_error({"reason" : "Incorrect latest",
                                  "latest_entry_doc": entry_doc_json, 
                                  "latest_revision_doc" : latest_rev_json},
                                 HTTP_ERROR_CLIENT_CONFLICT)
        
        
    elif request.method == "GET":
        # fixme update this to use denormalized stuff
        
        entry_ref = dbref("entries", entryid)
        entry_doc = nbdb.dereference(entry_ref)
        
        latest_page_ref = entry_doc['head']

        latest_page_rev = nbdb.dereference(latest_page_ref)


        return jsonify({"entry" : dm.entry_to_json(entry_doc),
                        "revision" : dm.rev_to_json[entry_doc['class']](latest_page_rev)})