Example #1
0
def api_entry_text_new():
    """
    Create a new entry 

    You can POST a new page to this URL and get back the JSON-ified page,
    it's entry, the fully-spec'd ref, etc.

    input json:

    {'title' : title of the page,
     'body' : body text }

    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", 400

    request_data = request.json

    if 'title' not in request_data:
        return "'title' not present in request",  400
    if 'body' not in request_data:
        return "'body' not present in request", 400

    title = request_data['title']
    body = request_data['body']

    rev = dm.text_entry_revision_create(title, body)
    rev.update(dm.revision_create(bson.dbref.DBRef("users",
                                                   bson.objectid.ObjectId(session["user_id"]))))

    revid = g.db.revisions.insert(rev, safe=True)
    rev["_id"] = revid
    
    ent_dict = dm.entry_create(dbref("revisions", revid),
                               'text', rev)

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

    rev["_id"] = revid

    rev_json = dm.entry_text_rev_to_json(rev)
    return jsonify({'entry' : {'class' : 'text',
                               'head' : str(revid),
                               '_id' : str(entid)},
                    
                    'revision' : rev_json})
Example #2
0
def save_entry(entryid):
    
    if request.method == "POST":
        # extract the fields from post

        # add the fields 

        entry_class = request.form['entry_class']
        entry_id = request.form['entry_id']

        request_dict = {}
        # turn the multidict into a single dict
        
        for k in request.form:
            request_dict[k] = request.form[k]
                    
        vdoc = dm.revision_class_create[entry_class](**request_dict)
        author = bson.dbref.DBRef(session["user_id"], "users")
        entry_ver = dm.revision_create(author=author,
                                            parent = request.form["rev_id"])
        vdoc.update(entry_ver)
        
        # create the doc, now insert it into mongo
        col_entries = g.db['entries']
        col_revisions = g.db['revisions']

        oid = col_revisions.insert(vdoc, safe=True)

        
        tref = bson.dbref.DBRef("revisions", oid)

        # FIXME FIXME FIXME USE COMPARE AND SWAP HERE

        col_entries.save({'_id' : bson.objectid.ObjectId(entry_id),
                          'head' : tref}, safe=True)


        div = entry_divs.create[entry_class]({'_id' : entry_id,
                                              'head' : tref,
                                              'archived' : False}, vdoc) # FIXME archived
        print "Saved document!" 
        return div
    
    else:
        pass
Example #3
0
def page_new():
    """
    
    """
 
    title = "New Page"
    entries = []

    page_rev = dm.page_entry_revision_create(title, entries)
    author = dbref("users", session["user_id"])
    
    page_rev.update(dm.revision_create(author))

    revid = g.db.revisions.insert(page_rev, safe=True)
    page_rev["_id"] = revid
    
    ent_dict = dm.entry_create(dbref("revisions", revid), 'page', page_rev)
    
    entid = g.db.entries.insert(ent_dict, safe=True)
    
    return redirect("/page/%s" % entid)
Example #4
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))
Example #5
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})
Example #6
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)})
Example #7
0
def api_entry_get_post(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
    
    
    """
    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", 400
        
        rd = request.json

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


        if dclass == 'text':
            rev = dm.text_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")
        
        author = dbref("users", session["user_id"])
        pref = dbref("revisions", parent)
        
        rev.update(dm.revision_create(author, parent=pref,
                                      archived=rd.get('archived', False)))


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

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

        
        res = g.db.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!
            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

            g.db.revisions.remove({'_id' : new_rev_oid})

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

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

            resp =  jsonify({"reason" : "Incorrect latest", 
                             "latest_revision_doc" : latest_rev_json})
            resp.status = "400"
            return resp
        
        
    elif request.method == "GET":
        # fixme update this to use denormalized stuff
        
        entry_ref = dbref("entries", entryid)
        entry_doc = g.db.dereference(entry_ref)
        
        latest_page_ref = entry_doc['head']

        latest_page_rev = g.db.dereference(latest_page_ref)


        return jsonify({"entry" : dm.entry_to_json(entry_doc),
                        "revision" : dm.rev_to_json[entry_doc['class']](latest_page_rev)})
Example #8
0
def api_page_new():
    """
    You can POST a new page to this URL and get back the JSON-ified page,
    it's entry, the fully-spec'd ref, etc.

    input json:

    {'title' : title of the page,
     'entries' : [ {'entry' : text_string_of_entry_id,
                    'hidden' : boolean [default : False]
                    'rev' : text string of revision ID if pinned } ]}


    returns :
       {'entry' : standard entry doc,
        'revision' : standard revision doc
        }

    or 400 if an invalid request

    note does not check to see if IDs are valid
    
    """
 
    if request.mimetype != "application/json":
        return "Invalid request type, must be application/json", 400
    
    request_data = request.json
   
    if 'title' not in request_data:
        return "'title' not present in request",  400

    title = request_data['title']
    

    entries = []
    if 'entry' in request_data:
        for e in request_data['entries']:

            if 'entry' not in e:
                return 'invalid entry', 400

            edict = {'entry' : bson.dbref.DBRef("entries", e['entry']), 
                     'hidden' : get(e, 'hidden', False)}

            if 'rev' in e:
                edict['rev'] = bson.dbref.DBRef("revisions", e['rev'])

            entries.append(edict)

    page_rev = dm.page_entry_revision_create(title, entries)
    author = bson.dbref.DBRef("users", bson.objectid.ObjectId(session["user_id"]))
    page_rev.update(dm.revision_create(author))

    revid = g.db.revisions.insert(page_rev, safe=True)
    page_rev["_id"] = revid
    
    ent_dict = dm.entry_create(dbref("revisions", revid), 'page', page_rev)
    
    entid = g.db.entries.insert(ent_dict, safe=True)

    ent_dict["_id"] = entid

    page_rev_json = dm.page_rev_to_json(page_rev)

    
    return jsonify({'entry' : {'class' : 'page',
                       'head' : str(revid),
                       '_id' : str(entid)},
            
                    'revision' : page_rev_json})
Example #9
0
def api_page_mutate(page_entryid):
    """
    Primary page mutation interface

    """

    COMMIT_ATTEMPTS = 30 # otherwise something is pretty wrong!
    
    
    action = request.form('action')
    page_ver_id = request.form('page_ver_id')

    for commit_attempt in range(COMMIT_ATTEMPTS):

        latest_page_entry_doc = db_get_entry_doc(page_entryid)

        if str(latest_page_entry_doc.head) != page_ver_id:
            print "Page has been updated since this edit"


        latest_page_rev_doc  = g.db.dereference(latest_page_entry_doc.head)

        if can_mutate_page(action, latest_page_rev_doc,
                      action_data) :
            new_doc = mutate_page(action, latest_page_rev_doc,
                                  action_data)
            author = bson.dbref.DBRef(session["user_id"], "users")

            new_doc.update(dm.revision_create(author,
                                              parent=latest_page_rev))
            
            new_doc_oid = revisions.insert(new_doc, safe=True)

            # create new, updated entry doc pointing to this doc

            new_entry_doc = d.entry_create(bson.dbref.DBRef(new_doc_oid,  'revisions'),
                                           latest_page_entry_doc['class'])

            # compare-and-swap
            res = entries.update(latest_page_entry_doc,
                                 new_entry_doc, safe=True)
            
            if res['updatedExisting'] == True:
                # success!
                return jsonify({"latest_page_revision_doc" : new_doc})
                              
            
            else:
                # failed to update, meaning someone else updated the entry ahead of us
                revisions.remove({'_id' : new_doc_oid})
                
                # then loop

        else:
            # couldn't actually perform mutation,
            # return latst doc along with status "Invalid mutation"
            
            return jsonify({"reason" : "invalid mutation" ,
                            "latest_page_revision_doc" : latest_page_rev_doc}), 400

        return jsonify({"reason" : "too much contention"}), 400
Example #10
0
def api_page_new():
    """
    You can POST a new page to this URL and get back the JSON-ified page,
    it's entry, the fully-spec'd ref, etc.

    input json:

    {'title' : title of the page,
     'entries' : [ {'entry' : text_string_of_entry_id,
                    'hidden' : boolean [default : False]
                    'rev' : text string of revision ID if pinned } ]}


    returns :
       {'entry' : standard entry doc,
        'revision' : standard revision doc
        }

    or 400 if an invalid request

    note does not check to see if IDs are valid
    
    """

    if 'title' not in request.form:
        return "'title' not present in request",  400
    if 'entries' not in request.form:
        return "'entries' not present in request", 400

    title = request.form['title']

    entries = []
    for e in request.form['entries']:
        if 'entry' not in e:
            return 'invalid entry', 400

        edict = {'entry' : bson.dbref.DBRef("entries", e['entry']), 
                 'hidden' : get(e, 'hidden', False)}
                 
        if 'rev' in e:
            edict['rev'] = bson.dbref.DBRef("revisions", e['rev'])

        entries.append(edict)

    page_rev = dm.page_entry_revision_create(title, entries)
    page_rev.update(dm.revision_create(bson.dbref.DBRef("users",
                                                        session["user_id"])))

    revid = revisions.insert(page_rev, safe=True)

    ent_dict = entry_create(bson.dbref.DBRef("revisions", revid))

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

    page_rev["_id"] = revid

    
    return {'entry' : {'class' : 'page',
                       'head' : revid,
                       '_id' : entid},
            
            'revision' : dm.page_to_json(page_rev)}
Example #11
0
                  'This is a test 6' : 5,
                  "And here is some more 7": 4,
                  }

entries = []


for title, revisions in docs_to_create.iteritems():

    parent = None
    for r in range(revisions):

        rt = randomtext.text[revisions]
        t = dm.text_entry_revision_create(title,
                                          rt)        
        t.update(dm.revision_create(u1oid, parent=parent))

        toid = col_revisions.insert(t)
        t['_id'] = toid
        parent = toid
        
    e = dm.entry_create(toid, t['class'], t)
    
    eoid = col_entries.insert(e)
    entries.append({'entry' : bson.dbref.DBRef("entries", eoid),
                    'hidden' : False})


p = dm.page_entry_revision_create("This is a title for a page", entries)
p.update(dm.revision_create(u1oid))