def getsections(): #pdb.set_trace() dbName = request.args.get('db', '') collectionName = request.args.get('col', '') sectionId = request.args.get('id', None) objType = request.args.get('type', 'Section') # passed to server to be returned to client (hack) sectionIndex = request.args.get('idx', None) db = conn[dbName] if sectionId: sectionObj = db[collectionName].find_one({'_id': ObjectId(sectionId)}) sectionObj["_id"] = str(sectionObj["_id"]) if sectionIndex: sectionObj["index"] = int(sectionIndex) return jsonify(sectionObj) else: sectionCursor = db[collectionName].find({ "type": objType }, { "waferName": 1, "section": 1 }).sort([("waferName", 1), ("section", 1)]) # make a new structure to return. Convert the ids to strings. sectionArray = [] for section in sectionCursor: section["_id"] = str(section["_id"]) sectionArray.append(section) data = {} data["sections"] = sectionArray return jsonify(data)
def get(self, restype, resid=None): """ Get restype with resid ['users'], if resid is not supplied, returns a list """ admin_db = models.ImageStore._get_db() # Restype has to be between allowed ones or the request will not come here if resid == None: objs = admin_db[restype].find() # TODO: need to paginate in near future objarray = list() for anobj in objs: # Filter the list with passwd if type is user if restype == "users": if "passwd" in anobj: del anobj["passwd"] objarray.append(anobj) return jsonify({ restype : objarray}) else: obj = admin_db[restype].find_one({"_id" : ObjectId(resid)}) if obj : if restype == "users": if "passwd" in obj: del obj["passwd"] return jsonify(obj) else: return Response("{\"error\" : \"resource not found\"}" , status=405)
def getsections(): #pdb.set_trace() dbName = request.args.get('db', '') collectionName = request.args.get('col', '') sectionId = request.args.get('id', None) objType = request.args.get('type', 'Section') # passed to server to be returned to client (hack) sectionIndex = request.args.get('idx', None) db = conn[dbName] if sectionId : sectionObj = db[collectionName].find_one({'_id':ObjectId(sectionId)}) sectionObj["_id"] = str(sectionObj["_id"]) if sectionIndex : sectionObj["index"] = int(sectionIndex) return jsonify(sectionObj) else : sectionCursor = db[collectionName].find({"type":objType},{"waferName":1, "section":1}).sort([("waferName", 1), ("section", 1)]) # make a new structure to return. Convert the ids to strings. sectionArray = []; for section in sectionCursor: section["_id"] = str(section["_id"]) sectionArray.append(section) data = {} data["sections"] = sectionArray return jsonify(data)
def post(self, dbid, sessid=None): # Parse the data in json format data = request.json # Unknown request if no parameters if data == None: abort(400) conn.register([Session]) db = self.get_data_db(dbid) if data.has_key("insert"): # Create the database object from the supplied parameters try: newsession = db["sessions"].Session() newsession["label"] = data["insert"]["label"] newsession["images"] = [] newsession.validate() newsession.save() except Exception as inst: # # If valid database object cannot be constructed it is invalid request return Response("{\"error\" : %s}" % str(inst), status=405) return jsonify(newsession) elif data.has_key("modify"): # Resid must be supplied if sessid == None : return Response("{\"error\" : \"No session _id supplied for modification\"}" , status=405) try: # Locate the resource newdb = db["sessions"].Session.find_one({"_id" : ObjectId(sessid)}) if newdb == None: raise Exception(" Resource %s not found" % (sessid)) except Exception as inst: # If valid database object cannot be constructed it is invalid request return Response("{\"error\" : \"%s\"}" % str(inst), status=405) # Now update try: for akey in data["modify"]: # Presently updating only label is supported if akey <> "label": return Response("{\"error\" : \"Cannot modify %s \"}" % (akey) , status=405) newdb[akey] = data["modify"][akey] newdb.validate() newdb.save() except Exception as inst: # If valid database object cannot be constructed it is invalid request return Response("{\"error\" : \"%s\"}" % str(inst), status=405) return jsonify(newdb) else: # Only insert and modify commands are supported abort(400)
def get(self, dbid, sessid=None): conn.register([Session, Database]) datadb = self.get_data_db(dbid) if datadb == None: return Response("{ \"error \" : \"Invalid database id %s\"}" % (dbid), status=405) if sessid == None: sessions = datadb["sessions"].Session.find({}, { 'images': 0, 'views': 0, 'attachments': 0 }) sessionlist = list() for asession in sessions: sessionlist.append(asession) if len(sessionlist) > 0: return jsonify({'sessions': sessionlist}) else: return Response( "{ \"error \" : \"You want You want a list of sessions in %s, but there are no sessions in it \"}" % (dbid), status=405) else: # Get and return a list of sessions from given database # TODO: Filter for the user that is requesting sessobj = datadb["sessions"].find_one({"_id": ObjectId(sessid)}) if sessobj == None: return Response( "{ \"error \" : \"Session %s does not exist in db %s\"}" % (sessid, dbid), status=405) # Dereference the views for aview in sessobj["views"]: viewdetails = datadb["views"].find_one({"_id": aview["ref"]}) viewdetails["image"] = datadb["images"].find_one( {"_id": viewdetails["img"]}, {"thumb": 0}) aview["details"] = viewdetails # Dereference the attachments attachments = [] if "attachments" in sessobj: gfs = GridFS(datadb, "attachments") for anattach in sessobj['attachments']: fileobj = gfs.get(anattach["ref"]) anattach["details"] = ({ 'name': fileobj.name, 'length': fileobj.length }) else: sessobj["attachments"] = [] return jsonify(sessobj)
def post(self, dbid, sessid=None): # Parse the data in json format data = request.json # Unknown request if no parameters if data == None: abort(400) db = self.get_data_db(dbid) if data.has_key("insert"): # Create the database object from the supplied parameters try: newsession = models.Session(image_store=db, label=data["insert"]["label"]) newsession.save() except Exception as inst: # If valid database object cannot be constructed it is invalid request return Response("{\"error\" : %s}" % str(inst), status=405) return jsonify(newsession) elif data.has_key("modify"): # Resid must be supplied if sessid == None : return Response("{\"error\" : \"No session _id supplied for modification\"}" , status=405) try: # Locate the resource newdb = models.Session.objects.with_id(sessid) if newdb == None: raise Exception(" Resource %s not found" % (sessid)) except Exception as inst: # If valid database object cannot be constructed it is invalid request return Response("{\"error\" : \"%s\"}" % str(inst), status=405) # Now update try: for akey in data["modify"]: # Presently updating only label is supported if akey != "label": return Response("{\"error\" : \"Cannot modify %s \"}" % (akey) , status=405) setattr(newdb, akey, data["modify"][akey]) newdb.save() except Exception as inst: # If valid database object cannot be constructed it is invalid request return Response("{\"error\" : \"%s\"}" % str(inst), status=405) return jsonify(newdb.to_mongo()) else: # Only insert and modify commands are supported abort(400)
def post(self, dbid, sessid, restype, resid=None): if resid == None: # Supported for new creations if restype == "attachments" or restype == "rawfiles": data = request.form # Only insert command is supported if data == None: return Response( "{\"error\" : \"Only create method is supported by post \"} ", status=405) if data.has_key("insert"): id = ObjectId() # No need to return conventional file list jsonresponse = {} jsonresponse["_id"] = id jsonresponse["type"] = restype return jsonify(jsonresponse) else: return Response( "{\"error\" : \"Only create method is supported by post \"} ", status=405) else: return Response( "{\"error\" : \"Only posting to all collections of %s are not implemented yet\"} " % (restype), status=405)
def getcorrelations(): #pdb.set_trace() dbName = request.args.get('db', '') collectionName = request.args.get('col', '') wafer = request.args.get('wafer', None) section = int(request.args.get('sect', 1)) db = conn[dbName] data = {} data["CorrelationArray0"] = [] data["CorrelationArray1"] = [] sectionObj0 = db[collectionName].find_one({ 'montage0.waferName': wafer, 'montage0.sectionNumber': section }) if sectionObj0: if "correlations" in sectionObj0: data["CorrelationArray0"] = sectionObj0["correlations"] sectionObj1 = db[collectionName].find_one({ 'montage1.waferName': wafer, 'montage1.sectionNumber': section }) if sectionObj1: if "correlations" in sectionObj1: data["CorrelationArray1"] = sectionObj1["correlations"] return jsonify(data)
def bookmark(): """ - /bookmark?key=0295cf24-6d51-4ce8-a923-772ebc71abb5 """ key = request.args.get('key', "0295cf24-6d51-4ce8-a923-772ebc71abb5") # find the view and the db return jsonify({"key": key }) # Simple embeddable viewer. style = request.args.get('style', "default") # See if editing will be enabled. edit = request.args.get('edit', False) # See if the user is requesting a view or session viewid = request.args.get('view', None) # get all the metadata to display a view in the webgl viewer. ajax = request.args.get('json', None) admindb = models.ImageStore._get_db() db = admindb if viewid: viewobj = readViewTree(db, viewid, -1) if ajax: return jsonifyView(db,viewid,viewobj) # default return glnote(db,viewid,viewobj,edit,style)
def getfavoriteviews(): collectionStr = request.args.get('col', "views") # "favorites" # Saving notes in admin db now. admindb = models.ImageStore._get_db() # get a list of the favorite view ids. viewItr = admindb[collectionStr].find( { 'User': getattr(security.current_user, 'id', ''), 'Type': 'Favorite' }, { '_id': True } ) viewArray = [] for viewId in viewItr: viewObj = readViewTree(admindb, viewId["_id"], -1) # There should be no legacy views, but keep the check just in case. if "Type" in viewObj: convertViewToPixelCoordinateSystem(viewObj) viewArray.append(viewObj) data = {'viewArray': viewArray} return jsonify(data)
def getchildnotes(): parentid = request.args.get('parentid', "") dbid = request.args.get('db', "") user = session["user"]["id"] admindb = conn[current_app.config["CONFIGDB"]] db = admindb #dbobj = admindb["databases"].Database.find_one({ "_id" : ObjectId(dbid) }) #db = conn[dbobj["dbname"]] notecursor = db["views"].find({ "ParentId": ObjectId(parentid), "User": ObjectId(user) }) # make a new structure to return. Convert the ids to strings. noteArray = [] for note in notecursor: note["Id"] = str(note["_id"]) note["_id"] = None note["ParentId"] = str(note["ParentId"]) noteArray.append(note) data = {} data["Notes"] = noteArray return jsonify(data)
def get(self, dbid, sessid=None): conn.register([Session, Database]) datadb = self.get_data_db(dbid) if datadb == None: return Response("{ \"error \" : \"Invalid database id %s\"}" % (dbid), status=405) if sessid == None: sessions = datadb["sessions"].Session.find({}, {'images':0, 'views':0, 'attachments':0}) sessionlist = list() for asession in sessions: sessionlist.append(asession) if len(sessionlist) > 0: return jsonify({'sessions' : sessionlist}) else: return jsonify({'sessions' : sessionlist, "error" : "You want You want a list of sessions in %s, but there are no sessions in it" %(dbid)}) else: # Get and return a list of sessions from given database # TODO: Filter for the user that is requesting sessobj = datadb["sessions"].find_one({"_id" : ObjectId(sessid)}) if sessobj == None: return Response("{ \"error \" : \"Session %s does not exist in db %s\"}" % (sessid, dbid), status=405) # Dereference the views for aview in sessobj["views"]: viewdetails = datadb["views"].find_one({"_id" : aview["ref"]}) # Viewdetails might not be a view if "img" in viewdetails: viewdetails["image"] = datadb["images"].find_one({"_id" : viewdetails["img"]}, { "thumb" : 0}) else: if "ViewerRecords" in viewdetails: viewdetails["image"] = viewdetails["ViewerRecords"][0]["Image"]["_id"] aview["details"] = viewdetails # Dereference the attachments attachments = [] if "attachments" in sessobj: gfs = GridFS(datadb, "attachments") for anattach in sessobj['attachments']: fileobj = gfs.get(anattach["ref"]) anattach["details"] = ({'name': fileobj.name, 'length' : fileobj.length}) else: sessobj["attachments"] = [] return jsonify(sessobj)
def view_all_sessions(): all_sessions_query = models.Session.objects\ .only('collection', 'label', 'image_store', 'type')\ .order_by('collection', 'label')\ .no_dereference() # disable dereferencing of of sessions, to prevent running a seperate # query for every single session's collection all_collections_query = models.Collection.objects\ .no_dereference() can_admin_collection_ids = [collection.id for collection in all_collections_query.can_access(g.identity.provides , models.Operation.admin)] editable_sessions_query = all_sessions_query.can_access(g.identity.provides, models.Operation.edit) viewable_sessions_query = all_sessions_query.can_access(g.identity.provides, models.Operation.view, strict_operation=True) # fetch the relevant collections in bulk collections_by_id = {collection.id: collection for collection in chain(editable_sessions_query.distinct('collection'), viewable_sessions_query.distinct('collection') )} all_sessions = defaultdict(dict) for sessions_query, can_admin in [ # viewable must come first, so editable can overwrite (viewable_sessions_query, False), (editable_sessions_query, True), ]: for collection_ref, sessions in groupby(sessions_query, attrgetter('collection')): collection = collections_by_id[collection_ref.id] all_sessions[collection].update(dict.fromkeys(sessions, can_admin)) all_sessions = [(collection, True if collection.id in can_admin_collection_ids else False, sorted(sessions_dict.iteritems(), key=lambda item: item[0].label) ) for collection, sessions_dict in sorted(all_sessions.iteritems(), key=lambda item: item[0].label)] # Whether to include administrative javascript is_admin = bool(len(can_admin_collection_ids)) if request.args.get('json'): ajax_session_list = [ { 'rule': collection.label, 'can_admin': can_admin, 'sessions': [ { 'sessdb': str(session.image_store.id), 'sessid': str(session.id), 'label': session.label } for session, can_admin in sessions], } for collection, can_admin, sessions in all_sessions] user_name = security.current_user.full_name if security.current_user.is_authenticated() else 'Guest' return jsonify(sessions=ajax_session_list, name=user_name, ajax=1) else: return render_template('sessionlist.html', all_sessions=all_sessions, is_admin=is_admin)
def image_query(): """ - /query?words=[] """ terms = request.args.get('terms', "").split() db = models.ImageStore._get_db() # I do not think the $text seach can work on individual fields # so I can not weight them separatly. I would like title # to have more weight that text. db["views"].ensure_index( [("Title", "text"), ("Text", "text")], name="titletext") # build up a list of images. imgDict = dict() # I may need to search the terms separatly and add the weights # if the weigths do not properly increase for matches of multiple terms. # build up a list of images. # search titles (pretty important). for term in terms: viewCursor = db["views"].find({'$text': {'$search': term}}, {'score': {"$meta": "textScore"}, "ViewerRecords": 1}) for view in viewCursor: for record in view["ViewerRecords"]: imgId = record["Image"] if not imgDict.has_key(str(imgId)): database = models.ImageStore.objects.get_or_404(id=ObjectId(record["Database"])) imgdb = database.to_pymongo() imgObj = imgdb["images"].find_one( {'_id': imgId}, { 'TileSize': True, 'levels': True, 'bounds': True, 'label': True, 'dimensions': True, 'components': True } ) if imgObj is not None: imgObj["_id"] = str(imgId) imgObj["database"] = str(record["Database"]) imgDict[str(imgId)] = imgObj imgObj["score"] = view["score"] # give extra score to iamges that have the term in # their labels. for t in terms: if imgObj["label"].lower().find(t.lower()) != -1: imgObj["score"] += 2.0 else: imgObj["score"] += view["score"] data = dict() data["images"] = sorted(imgDict.values(), key=itemgetter('score'), reverse=True) return jsonify(data)
def view_a_session(session): # TODO: the template doesn't seem use 'next' next_arg = int(request.args.get('next', 0)) session_son = apiv2.SessionItemAPI._get(session) if request.args.get('json'): images = [] for view_son in session_son['views']: database = models.ImageStore.objects.get_or_404(id=view_son['image_store_id']) imgdb = database.to_pymongo() imgObj = imgdb["images"].find_one({ "_id" : view_son['image_id']}) # these should not happen but to be safe. if not "dimensions" in imgObj : imgObj['dimensions'] = [0,0,0] if not "levels" in imgObj : imgObj['levels'] = 0 bounds = [0,imgObj['dimensions'][0], 0, imgObj['dimensions'][1]] if 'bounds' in imgObj: bounds = imgObj['bounds'] tileSize = 256 if 'tile_size' in imgObj: tileSize = imgObj['tile_size'] if 'tileSize' in imgObj: tileSize = imgObj['tileSize'] if 'TileSize' in imgObj: tileSize = imgObj['TileSize'] images.append({ 'db': view_son['image_store_id'], 'img': view_son['image_id'], 'label': view_son['label'], 'view': view_son['id'], 'bounds': bounds, 'tile_size': tileSize, 'levels': imgObj['levels'], 'dimensions': imgObj['dimensions'] }) ajax_data = { 'success': 1, 'session': session_son, 'images': images, 'attachments': session_son['attachments'], 'imagefiles': session_son["imagefiles"], 'db': session.image_store.id, # TODO: deprecate and remove 'sessid': session.id, 'hide': session_son['hide_annotations'], 'next': url_for('.sessions_view', sessid=str(session.id), ajax=1, next=next_arg + NUMBER_ON_PAGE) } return jsonify(ajax_data) else: return render_template('session.html', session=session, session_son=session_son)
def glstacksession(): """ - /webgl-viewer/stack-session?db=5123c81782778fd2f954a34a&sess=51256ae6894f5931098069d5 """ # Comparison is a modified view. sessid = request.args.get('sess', None) if not sessid: sessid = "51256ae6894f5931098069d5" # this is the same as the sessions db in the sessions page. dbid = request.args.get('db', None) admindb = conn[current_app.config["CONFIGDB"]] dbobj = admindb["databases"].Database.find_one({ "_id" : ObjectId(dbid) }) db = conn[dbobj["dbname"]] sessobj = db["sessions"].find_one({"_id" : ObjectId(sessid) }) views = []; for view in sessobj["views"]: viewid = view["ref"] viewobj = db["views"].find_one({"_id" : ObjectId(viewid) }) #viewobj["rotation"] = 0 # Having issues with jsonify imgdbid = dbid if 'db' in viewobj: imgdbid = str(viewobj["db"]) myview = {"_id": str(viewobj["_id"]), "center": viewobj["center"], "height": viewobj["height"], "rotation": 0, "db": imgdbid} imgobj = db["images"].find_one({"_id" : viewobj["img"] }) #imgobj["_id"] = str(imgobj["_id"]) #imgobj["thumb"] = "" myimg = {"dimensions": imgobj["dimension"], "_id": str(imgobj["_id"]), "levels": imgobj["levels"]} myview["img"] = myimg views.append(myview) for pair in sessobj["transformations"]: if 'view0' in pair: pair["view0"] = str(pair["view0"]) pair["view1"] = str(pair["view1"]) if not 'annotations' in sessobj: sessobj["annotations"] = [] for markup in sessobj["annotations"]: markup["view"] = str(markup["view"]) return jsonify({"views":views, "transformations": sessobj["transformations"], "annotations": sessobj["annotations"]})
def session_save_stack(): input_str = request.form['input'] # for post input_obj = json.loads(input_str) session_id = ObjectId(input_obj['sessId']) label = input_obj['label'] stack_items = input_obj['items'] admindb = models.ImageStore._get_db() session = models.Session.objects.with_id(session_id) security.EditSessionRequirement(session).test() records = list() for item in stack_items: camera = {'FocalPoint': [item['x'], item['y'], 0], 'Height': item['height'], 'Roll': item['roll']} viewer_record = { 'Image': ObjectId(item['img']), 'Database': ObjectId(item['db']), 'Camera' : camera} if 'widget' in item : viewer_record['Annotations'] = [item['widget']]; records.append(viewer_record) for idx in range(1,len(stack_items)) : item0 = stack_items[idx-1] item1 = stack_items[idx] correlationHeight = (item0['height']+item1['height'])*0.5; records[idx]['Transform'] = {'Correlations':[{'point0': [item0['x'], item0['y']], 'point1': [item1['x'], item1['y']], 'roll': item1['roll']-item0['roll'], 'height': correlationHeight } ]} # Now make the view user = security.current_user.id if security.current_user.is_authenticated() else 'Guest' view = { 'CoordinateSystem': 'Pixel', 'User': user, 'Type': 'Stack', 'ViewerRecords': records, 'Title': label, 'HiddenTitle': label } # TODO: don't save until the end, to make failure transactional admindb['views'].save(view, manipulate=True) # update the session session.views.insert(0, view['_id']) session.save() return jsonify(view)
def put(self, resid): # put requires admin access # Get json supplied data = request.json # Check for valid parameters # Check if no parameters if data is None: return Response("{\"error\" : \"No parameters ? \"}", status=405) # See if id matches the resource being modified try: if data["_id"] != resid: raise Exception(1) except: return Response("{\"error\" : \"_id mismatch with the location in the url \"}", status=405) # The object should exist for anobj in models.ImageStore.objects: current_app.logger.debug('%s %s', anobj.label, anobj.id) database = models.ImageStore.objects.with_id(ObjectId(data["_id"])) current_app.logger.debug('ID: %s %s', data['_id'], ObjectId(data['_id'])) # Unknown request if no parameters if database == None: return Response("{\"error\" : \"Resource _id: %s doesnot exist\"}" % (resid), status=403) # Create the database object from the supplied parameters try: database.label = data["label"] database.host = data["host"] database.dbname = data["dbname"] database.copyright = data["copyright"] database.username = data["username"] database.password = data["password"] if database._cls == "TileStore.Database.PtiffTileStore": database.root_path = data["root_path"] # Add additional fields if "_cls" in data: current_app.logger.debug('%s', data['_cls']) database.save() except Exception as inst: # If valid database object cannot be constructed it is invalid request return Response("{\"error\" : %s}" % str(inst), status=405) return jsonify(database.to_mongo())
def encodeSection(sectionObj) : sectionObj["_id"] = str(sectionObj["_id"]) if sectionObj.has_key("worldPointsFloat64") : sectionObj["worldPointsFloat64"] = base64.b64encode(str(sectionObj["worldPointsFloat64"])) for imageObj in sectionObj["images"] : if imageObj.has_key("meshPointsInt32") : imageObj["meshPointsInt32"] = base64.b64encode(str(imageObj["meshPointsInt32"])) if imageObj.has_key("meshPointIdsInt32") : imageObj["meshPointIdsInt32"] = base64.b64encode(str(imageObj["meshPointIdsInt32"])) if imageObj.has_key("meshTrianglesInt32") : imageObj["meshTrianglesInt32"] = base64.b64encode(str(imageObj["meshTrianglesInt32"])) return jsonify(sectionObj)
def getcomment(): dbid = request.form["db"] commentid = request.form["id"] database = models.ImageStore.objects.get_or_404(id=dbid) db = database.to_pymongo() comment = db["comments"].find_one({"_id": ObjectId(commentid) }) if comment: comment["_id"] = str(comment["_id"]) return jsonify(comment)
def get(self, restype, resid=None): # Restype has to be between allowed ones or the request will not come here if resid == None: objs = conn[current_app.config["CONFIGDB"]][restype].find() objarray = list() for anobj in objs: # Filter the list with passwd if type is user if restype == "users": if "passwd" in anobj: del anobj["passwd"] objarray.append(anobj) return jsonify({ restype : objarray}) else: obj = conn[current_app.config["CONFIGDB"]][restype].find_one({"_id" : ObjectId(resid)}) if obj : if restype == "users": if "passwd" in obj: del obj["passwd"] return jsonify(obj) else: return Response("{\"error\" : \"resource not found\"}" , status=405)
def jsonifyBookmarks(db, dbid, viewid, viewobj): # I do not think we can pass an array back. val = {} val["Bookmarks"] = [] if 'bookmarks' in viewobj : for bookmarkId in viewobj["bookmarks"] : bookmarkObj = db["bookmarks"].find_one({'_id': bookmarkId}) bookmark = bookmarkObj bookmark["_id"] = str(bookmark["_id"]) bookmark["img"] = str(bookmark["img"]) val["Bookmarks"].append(bookmark) return jsonify(val)
def getparentcomments(): dbid = request.form['db'] noteid = request.form["id"] database = models.ImageStore.objects.get_or_404(id=dbid) db = database.to_pymongo() toplevelcomments = db["comments"].find({"parent": noteid}) for obj in toplevelcomments: obj["_id"] = str(obj["_id"]) return jsonify(toplevelcomments)
def gettrackingdata(): admindb = models.ImageStore._get_db() viewItr = admindb['tracking'].find({"User": getattr(security.current_user, 'id', '')}) viewArray = [] for viewObj in viewItr: viewObj["_id"] = str(viewObj["_id"]) viewObj["User"] = str(viewObj["User"]) # viewObj["ParentId"] = str(viewObj["ParentId"]) viewArray.append(viewObj) data = {'viewArray': viewArray} return jsonify(data)
def jsonifyBookmarks(db, dbid, viewid, viewobj): # I do not think we can pass an array back. val = {} val["Bookmarks"] = [] if 'bookmarks' in viewobj: for bookmarkId in viewobj["bookmarks"]: bookmarkObj = db["bookmarks"].find_one({'_id': bookmarkId}) bookmark = bookmarkObj bookmark["_id"] = str(bookmark["_id"]) bookmark["img"] = str(bookmark["img"]) val["Bookmarks"].append(bookmark) return jsonify(val)
def getcomment(): dbid = request.form["db"] commentid = request.form["id"] admindb = conn[current_app.config["CONFIGDB"]] dbobj = admindb["databases"].Database.find_one({"_id": ObjectId(dbid)}) db = conn[dbobj["dbname"]] comment = db["comments"].find_one({"_id": ObjectId(commentid)}) if comment: comment["_id"] = str(comment["_id"]) return jsonify(comment)
def get(self, restype, resid=None): # Restype has to be between allowed ones or the request will not come here if resid == None: objs = conn[current_app.config["CONFIGDB"]][restype].find() # TODO: need to paginate in near future objarray = list() for anobj in objs: # Filter the list with passwd if type is user if restype == "users": if "passwd" in anobj: del anobj["passwd"] objarray.append(anobj) return jsonify({ restype : objarray}) else: obj = conn[current_app.config["CONFIGDB"]][restype].find_one({"_id" : ObjectId(resid)}) if obj : if restype == "users": if "passwd" in obj: del obj["passwd"] return jsonify(obj) else: return Response("{\"error\" : \"resource not found\"}" , status=405)
def getparentcomments(): dbid = request.form['db'] noteid = request.form["id"] admindb = conn[current_app.config["CONFIGDB"]] dbobj = admindb["databases"].Database.find_one({"_id": ObjectId(dbid)}) db = conn[dbobj["dbname"]] toplevelcomments = db["comments"].find({"parent": noteid}) for obj in toplevelcomments: obj["_id"] = str(obj["_id"]) return jsonify(toplevelcomments)
def getcomment(): dbid = request.form["db"] commentid = request.form["id"] admindb = conn[current_app.config["CONFIGDB"]] dbobj = admindb["databases"].Database.find_one({ "_id" : ObjectId(dbid) }) db = conn[dbobj["dbname"]] comment = db["comments"].find_one({"_id": ObjectId(commentid) }) if comment: comment["_id"] = str(comment["_id"]) return jsonify(comment)
def getimagenames(): dbid = request.args.get('db', "") database = models.ImageStore.objects.get_or_404(id=dbid) db = database.to_pymongo() # imgObj = db["images"].find_one() imgItr = db["images"].find({}, {"label":1}) imgArray = [] for img in imgItr: img["_id"] = str(img["_id"]) imgArray.append(img) data = {} data["Database"] = dbid data["Images"] = imgArray return jsonify(data)
def getparentcomments(): dbid = request.form['db'] noteid = request.form["id"] admindb = conn[current_app.config["CONFIGDB"]] dbobj = admindb["databases"].Database.find_one({ "_id" : ObjectId(dbid) }) db = conn[dbobj["dbname"]] toplevelcomments = db["comments"].find({ "parent": noteid }) for obj in toplevelcomments: obj["_id"] = str(obj["_id"]) return jsonify(toplevelcomments)
def put(self, resid): # put requires admin access # Get json supplied data = request.json # Check for valid parameters # Check if no parameters if data == None: return Response("{\"error\" : \"No parameters ? \"}", status=405) # See if id matches the resource being modified try: if data["_id"] != resid: raise Exception(1) except: return Response( "{\"error\" : \"_id mismatch with the location in the url \"}", status=405) # Try to see if the data can create valid object conn.register([Database]) # The object should exist dbobj = conn[ current_app.config["CONFIGDB"]]["databases"].Database.find_one( {"_id": ObjectId(resid)}) # Unknown request if no parameters if dbobj == None: return Response( "{\"error\" : \"Resource _id: %s doesnot exist\"}" % (resid), status=403) # Create the database object from the supplied parameters try: dbobj["label"] = data["label"] dbobj["host"] = data["host"] dbobj["dbname"] = data["dbname"] dbobj["copyright"] = data["copyright"] dbobj.validate() dbobj.save() except Exception as inst: # If valid database object cannot be constructed it is invalid request return Response("{\"error\" : %s}" % str(inst), status=405) return jsonify(dbobj)
def getimagenames(): dbid = request.args.get('db', "") admindb = conn[current_app.config["CONFIGDB"]] dbobj = admindb["databases"].Database.find_one({ "_id" : ObjectId(dbid) }) db = conn[dbobj["dbname"]] #imgObj = db["images"].find_one() imgItr = db["images"].find({}, {"label":1}) imgArray = [] for img in imgItr: img["_id"] = str(img["_id"]) imgArray.append(img) data = {}; data["Database"] = dbid data["Images"] = imgArray return jsonify(data)
def encodeSection(sectionObj): sectionObj["_id"] = str(sectionObj["_id"]) if sectionObj.has_key("worldPointsFloat64"): sectionObj["worldPointsFloat64"] = base64.b64encode( str(sectionObj["worldPointsFloat64"])) for imageObj in sectionObj["images"]: if imageObj.has_key("meshPointsInt32"): imageObj["meshPointsInt32"] = base64.b64encode( str(imageObj["meshPointsInt32"])) if imageObj.has_key("meshPointIdsInt32"): imageObj["meshPointIdsInt32"] = base64.b64encode( str(imageObj["meshPointIdsInt32"])) if imageObj.has_key("meshTrianglesInt32"): imageObj["meshTrianglesInt32"] = base64.b64encode( str(imageObj["meshTrianglesInt32"])) return jsonify(sectionObj)
def getimagenames(): dbid = request.args.get('db', "") admindb = conn[current_app.config["CONFIGDB"]] dbobj = admindb["databases"].Database.find_one({"_id": ObjectId(dbid)}) db = conn[dbobj["dbname"]] #imgObj = db["images"].find_one() imgItr = db["images"].find({}, {"label": 1}) imgArray = [] for img in imgItr: img["_id"] = str(img["_id"]) imgArray.append(img) data = {} data["Database"] = dbid data["Images"] = imgArray return jsonify(data)
def glcomparisonoption(): """ - /webgl-viewer/comparison-option?db=507619bb0a3ee10434ae0827&viewid=5074528302e3100db8429cb4 """ # Comparison is a modified view. viewid = request.args.get('viewid', None) # this is the same as the sessions db in the sessions page. dbid = request.args.get('db', None) admindb = conn[current_app.config["CONFIGDB"]] dbobj = admindb["databases"].Database.find_one({ "_id" : ObjectId(dbid) }) db = conn[dbobj["dbname"]] viewobj = db["views"].find_one({"_id" : ObjectId(viewid) }) imgobj = db["images"].find_one({'_id' : ObjectId(viewobj["img"])}) bookmarkobj = db["bookmarks"].find_one({'_id':ObjectId(viewobj["startup_view"])}) if 'dimension' in imgobj: dim = str(imgobj["dimension"]) elif 'dimensions' in imgobj: dim = str(imgobj["dimensions"]) # The base view is for the left panel data = { 'success': 1, 'db': dbid, 'label': imgobj["label"], 'img': str(imgobj["_id"]), 'center': bookmarkobj["center"], 'origin': imgobj["origin"], 'spacing': imgobj["spacing"], 'levels': imgobj["levels"], 'dimension': dim, 'rotation': bookmarkobj["rotation"] } if 'zoom' in bookmarkobj: data["viewHeight"] = 900 << int(bookmarkobj["zoom"]) if 'viewHeight' in bookmarkobj: data["viewHeight"] = bookmarkobj["viewHeight"] return jsonify(data)
def glcomparisonoption(): """ - /webgl-viewer/comparison-option?db=507619bb0a3ee10434ae0827&viewid=5074528302e3100db8429cb4 """ # Comparison is a modified view. viewid = request.args.get('viewid', None) # this is the same as the sessions db in the sessions page. dbid = request.args.get('db', None) admindb = conn[current_app.config["CONFIGDB"]] dbobj = admindb["databases"].Database.find_one({"_id": ObjectId(dbid)}) db = conn[dbobj["dbname"]] viewobj = db["views"].find_one({"_id": ObjectId(viewid)}) imgobj = db["images"].find_one({'_id': ObjectId(viewobj["img"])}) bookmarkobj = db["bookmarks"].find_one( {'_id': ObjectId(viewobj["startup_view"])}) if 'dimension' in imgobj: dim = str(imgobj["dimension"]) elif 'dimensions' in imgobj: dim = str(imgobj["dimensions"]) # The base view is for the left panel data = { 'success': 1, 'db': dbid, 'label': imgobj["label"], 'img': str(imgobj["_id"]), 'center': bookmarkobj["center"], 'origin': imgobj["origin"], 'spacing': imgobj["spacing"], 'levels': imgobj["levels"], 'dimension': dim, 'rotation': bookmarkobj["rotation"] } if 'zoom' in bookmarkobj: data["viewHeight"] = 900 << int(bookmarkobj["zoom"]) if 'viewHeight' in bookmarkobj: data["viewHeight"] = bookmarkobj["viewHeight"] return jsonify(data)
def thumb_from_view(): """ Gets a thumbnail from view directly, Chains the request to view objects helper method """ # Get parameters viewid = ObjectId(request.args.get("viewid", None)) # which = ObjectId(request.args.get("which","macro")) which = "macro" force = bool(request.args.get("force", False)) # Implementation without View viewcol = models.View._get_collection() viewobj = viewcol.find_one({"_id": viewid}) if "thumbs" not in viewobj: viewobj["thumbs"] = {} # Make thumbnail if force or which not in viewobj["thumbs"]: # Refresh the thumbnail if which not in ["macro"]: # Only know how to make macro image # Todo: add support for label supported raise Exception("%s thumbnail creation not supported" % which) # Make the thumb # Get the image store and image id and off load the request istore = models.ImageStore.objects.get(id=viewobj["ViewerRecords"][0]["Database"]) with istore: thumbimgdata = istore.make_thumb( models.Image.objects.get(id=viewobj["ViewerRecords"][0]["Image"])) viewcol.update({"_id": viewid}, {"$set": {"thumbs." + which: base64.b64encode(thumbimgdata)}}) viewobj = viewcol.find_one({"_id": viewid}) imagestr = viewobj["thumbs"][which] # current_app.logger.warning("Imagestr: " + imagestr) if int(request.args.get("binary", 0)): return Response(base64.b64decode(imagestr), mimetype="image/jpeg") else: return jsonify({which: imagestr})
def jsonifyView(db, dbid, viewid, viewobj): imgid = 0 if 'Type' in viewobj: if viewobj["Type"] == "Note" or viewobj["Type"] == "UserNote": imgid = viewobj["ViewerRecords"][0]["Image"] if imgid == 0: imgid = viewobj["img"] imgobj = db["images"].find_one({'_id': ObjectId(imgid)}) #pdb.set_trace() # the official schema says dimension not dimensions. correct the schema later. #if 'dimension' in imgobj: # imgobj['dimensions'] = imgobj['dimension'] # delete imgobj.dimension # db["images"].save(imgobj); img = {} img["db"] = dbid img["viewid"] = viewid img["image"] = str(imgobj["_id"]) img["origin"] = imgobj["origin"] img["spacing"] = imgobj["spacing"] img["levels"] = 1 if imgobj.has_key("levels"): img["levels"] = imgobj["levels"] if 'dimensions' in imgobj: img["dimensions"] = imgobj["dimensions"] elif 'dimension' in imgobj: img["dimensions"] = imgobj["dimension"] # I want to change the schema to get rid of this startup bookmark. if 'startup_view' in viewobj: bookmarkobj = db["bookmarks"].find_one( {'_id': ObjectId(viewobj["startup_view"])}) img["center"] = bookmarkobj["center"] img["rotation"] = bookmarkobj["rotation"] if 'zoom' in bookmarkobj: img["viewHeight"] = 900 << int(bookmarkobj["zoom"]) if 'viewHeight' in bookmarkobj: img["viewHeight"] = bookmarkobj["viewHeight"] return jsonify(img)
def get(self, restype, resid, listtype): # Restype has to be between allowed ones or the request will not come here # only rules and users is supported now # create a new user result = {} result["query"] = { "restype" : restype, "resid" : resid, "listtype" : listtype} if restype not in ["rules"] or listtype not in ["users"]: return Response("{\"error\" : \"Only restype itemtype supported is rules, users\"}" , status=405) # ruleobj or dbobj objarray = list() for anobj in conn[current_app.config["CONFIGDB"]][listtype].find({"rules" : ObjectId(resid)}): if "passwd" in anobj: del anobj["passwd"] objarray.append(anobj) result[listtype] = objarray return jsonify(result)
def jsonifyView(db,dbid,viewid,viewobj): imgid = 0 if 'Type' in viewobj : if viewobj["Type"] == "Note" or viewobj["Type"] == "UserNote": imgid = viewobj["ViewerRecords"][0]["Image"] if imgid == 0 : imgid = viewobj["img"] imgobj = db["images"].find_one({'_id' : ObjectId(imgid)}) #pdb.set_trace() # the official schema says dimension not dimensions. correct the schema later. #if 'dimension' in imgobj: # imgobj['dimensions'] = imgobj['dimension'] # delete imgobj.dimension # db["images"].save(imgobj); img = {} img["db"] = dbid img["viewid"] = viewid img["image"] = str(imgobj["_id"]) img["origin"] = imgobj["origin"] img["spacing"] = imgobj["spacing"] img["levels"] = 1 if imgobj.has_key("levels") : img["levels"] = imgobj["levels"] if 'dimensions' in imgobj: img["dimensions"] = imgobj["dimensions"] elif 'dimension' in imgobj: img["dimensions"] = imgobj["dimension"] # I want to change the schema to get rid of this startup bookmark. if 'startup_view' in viewobj: bookmarkobj = db["bookmarks"].find_one({'_id':ObjectId(viewobj["startup_view"])}) img["center"] = bookmarkobj["center"] img["rotation"] = bookmarkobj["rotation"] if 'zoom' in bookmarkobj: img["viewHeight"] = 900 << int(bookmarkobj["zoom"]) if 'viewHeight' in bookmarkobj: img["viewHeight"] = bookmarkobj["viewHeight"] return jsonify(img)
def post(self, dbid, sessid, restype, resid=None): if resid == None: # Supported for new creations if restype == "attachments" or restype == "rawfiles": data = request.form # Only insert command is supported if data == None: return Response("{\"error\" : \"Only create method is supported by post \"} " , status=405) if data.has_key("insert") : id = ObjectId() # No need to return conventional file list jsonresponse = {} jsonresponse["_id"] = id jsonresponse["type"] = restype return jsonify(jsonresponse) else: return Response("{\"error\" : \"Only create method is supported by post \"} " , status=405) else: return Response("{\"error\" : \"Only posting to all collections of %s are not implemented yet\"} " % (restype) , status=405)
def jsonifyView(db, viewid, viewobj): imgdb = viewobj['ViewerRecords'][0]['Database'] imgid = viewobj['ViewerRecords'][0]['Image'] imgobj = db['images'].find_one({'_id': ObjectId(imgid)}) img = { 'db': imgdb, 'viewid': viewid, 'image': str(imgobj['_id']), 'origin': imgobj['origin'], 'spacing': imgobj['spacing'], 'levels': 1, 'dimensions': imgobj['dimensions'], 'TileSize': imgobj.get('TileSize', 256) } if 'levels' in imgobj: img['levels'] = imgobj['levels'] return jsonify(img)
def saveviewnotes(): noteObj = request.form['note'] note = json.loads(noteObj) if note.has_key("ParentId"): note["ParentId"] = ObjectId(note["ParentId"]) admindb = models.ImageStore._get_db() db = admindb # I was going get the user id from the session, and pass it to the viewer. # I think I will just try to retreive the user from the "Save Note" method. email = getattr(security.current_user, 'email', '') viewObj = savenote(db,note, email) # I want the client editor to display the correct links immediatly after saving, so # I have to return the entire note tree with any new ids created. viewObj = readViewTree(db, viewObj, 0) return jsonify(viewObj)
def sessions(): """ - /sessions With no argument displays list of sessions accessible to current user - /sessions?sessid=10239094124 searches for the session id """ rules = [] # Compile the rules conn.register([Image, Session, User, Rule, Database]) admindb = conn[current_app.config["CONFIGDB"]] #pdb.set_trace() # Assert the user is logged in if 'user' in session: name = session['user']['label'] id = session['user']['id'] userobj = admindb["users"].User.find_one({"_id": ObjectId(id)}) if userobj == None: # If the user is not found then something wrong # Redirect the user to home with error message flash("Invalid login", "error") return redirect(url_for('login.login')) else: # Send the user back to login page # with some message flash("You must be logged in to see that resource", "error") return redirect(url_for('login.login')) # This code gets executed only if the user information is available # See if the user is requesting any session id sessid = request.args.get('sessid', None) sessdb = request.args.get('sessdb', "") ajax = request.args.get('json', None) next = int(request.args.get('next', 0)) if sessid: # Find and return image list from single session # TODO: Refactor this into a function db = admindb access = True # eventually sessdb will go away. if sessdb != "": access = False dbobj = admindb["databases"].Database.find_one( {"_id": ObjectId(sessdb)}) db = conn[dbobj["dbname"]] # From rules pertaining to current user try: for arule in userobj["rules"]: ruleobj = admindb["rules"].Rule.find_one({"_id": arule}) if str(ruleobj["db"]) == sessdb: if 'db_admin' in ruleobj and ruleobj[ "db_admin"] == True: access = True elif 'can_see_all' in ruleobj and ruleobj[ "can_see_all"] == True: access = True elif len(ruleobj["can_see"]) > 0: for asession in ruleobj["can_see"]: if str(asession) == sessid: access = True except: pass # Confirm that the user has access if access == False: flash("Unauthorized access", "error") return redirect("/home") coll = db["sessions"] asession = coll.find_one({'_id': ObjectId(sessid)}, { 'images': { '$slice': [next, NUMBER_ON_PAGE] }, '_id': 0 }) # Hide notes and descriptive title for student review hideAnnotations = False if "hideAnnotations" in asession: if asession["hideAnnotations"]: hideAnnotations = True else: asession["hideAnnotations"] = False # iterate through the session objects images = [] if asession.has_key("views"): for aview in asession['views']: hide = False if 'hide' in aview: if aview["hide"]: hide = True viewobj = db["views"].find_one({"_id": aview["ref"]}) # Crash here. Session had a viewid that did not exist. # Should we clean up the broken reference? Just skip for now. if viewobj: imgid = 0 imgdb = "" imgobj = None if "Type" in viewobj: # my new notes make it difficult to get the image. if viewobj["Type"] == "Note": if viewobj["ViewerRecords"][0].has_key("Database"): imgid = viewobj["ViewerRecords"][0]["Image"] imgdb = viewobj["ViewerRecords"][0]["Database"] else: imgid = viewobj["ViewerRecords"][0]["Image"][ "_id"] imgdb = viewobj["ViewerRecords"][0]["Image"][ "database"] if imgid == 0: imgdb = sessdb imgid = str(viewobj["img"]) if "imgdb" in viewobj: imgdb = viewobj["imgdb"] if imgdb == sessdb: imgobj = db["images"].find_one( {'_id': ObjectId(imgid)}, {'_id': 0}) else: dbobj2 = admindb["databases"].Database.find_one( {"_id": ObjectId(imgdb)}) #TODO: make sure the connection to host is available db2 = conn[dbobj2["dbname"]] imgobj = db2["images"].find_one( {'_id': ObjectId(imgid)}, {'_id': 0}) # so many legacy schemas (plus hiding annotation) label = "" if "label" in imgobj: label = imgobj["label"] if "label" in aview: label = aview["label"] if "Title" in viewobj: label = viewobj["Title"] if hideAnnotations: label = viewobj["HiddenTitle"] if 'hide' in imgobj: if imgobj["hide"]: hide = True if 'hide' in viewobj: if viewobj["hide"]: hide = True if not hide: if imgobj.has_key("thumb"): del imgobj['thumb'] animage = {} animage['db'] = imgdb animage["img"] = imgid animage["label"] = label animage["view"] = str(aview["ref"]) if "type" in viewobj: if viewobj["type"] == "comparison": animage["comparison"] = 1 images.append(animage) attachments = [] if asession.has_key("attachments"): gfs = GridFS(db, "attachments") for anattach in asession['attachments']: fileobj = gfs.get(anattach["ref"]) attachments.append({ 'name': fileobj.name, 'id': anattach["ref"] }) del asession["attachments"] if 'images' in asession: del asession["images"] data = { 'success': 1, 'session': asession, 'images': images, 'attachments': attachments, 'db': sessdb, 'sessid': sessid, 'next': url_for('session.sessions', sessid=sessid, ajax=1, next=next + NUMBER_ON_PAGE) } if ajax: return jsonify(data) else: return render_template('session.html', data=data, name=name) else: # Compile a list of session names / ids sessionlist = [] # sessions owned by this user. rule = {} rule["rule"] = "" sessions = [] for sessionobj in admindb["sessions"].find(): thissession = { 'sessid': str(sessionobj["_id"]), 'label': sessionobj["label"], 'sessdb': "" } sessions.append(thissession) rule["sessions"] = sessions sessionlist.append(rule) # From rules pertaining to current user if "rules" in userobj: for arule in userobj["rules"]: rule = {} ruleobj = admindb["rules"].Rule.find_one({"_id": arule}) if ruleobj == None: continue #flash(str(ruleobj), 'success') rule["rule"] = ruleobj["label"] # Find the db pertaining to this rule dbobj = admindb["databases"].Database.find_one( {"_id": ruleobj["db"]}) # TODO: initiate new connection if required with this database db = conn[dbobj["dbname"]] sessions = [] if 'can_see_all' in ruleobj and ruleobj["can_see_all"] == True: #flash("All" + ruleobj["label"], "success") # Gets access to see / admin all sessions in this DB for sessionobj in db["sessions"].Session.find(): thissession = { 'sessid': str(sessionobj["_id"]), 'label': sessionobj["label"], 'sessdb': str(dbobj["_id"]) } if 'type' in sessionobj: if (sessionobj["type"] == "stack"): thissession["stack"] = True sessions.append(thissession) elif len(ruleobj["can_see"]) > 0: # Gets access to a limited number of sessions for asession in ruleobj["can_see"]: sessionobj = db["sessions"].Session.find_one( {"_id": asession}) if sessionobj == None: continue thissession = { 'sessid': str(sessionobj["_id"]), 'label': sessionobj["label"], 'sessdb': str(dbobj["_id"]) } if 'type' in sessionobj: if (sessionobj["type"] == "stack"): thissession["stack"] = True sessions.append(thissession) # if db administrator if 'db_admin' in ruleobj and ruleobj["db_admin"] == True: # Update the administrative for asession in sessions: #flash("Admin session: " + asession["label"] , "success") asession["canadmin"] = True rule["sessions"] = sessions sessionlist.append(rule) # End of for loop over rules if ajax: return jsonify(sessions=sessionlist, name=name, ajax=1) else: return render_template('sessionlist.html', sessions=sessionlist, name=name)
def getview(): #pdb.set_trace() sessid = request.args.get('sessid', None) viewid = request.args.get('viewid', "") viewdb = request.args.get('db', "") admindb = conn[current_app.config["CONFIGDB"]] dbobj = admindb["databases"].Database.find_one({"_id": ObjectId(viewdb)}) db = conn[dbobj["dbname"]] # check the session to see if notes are hidden hideAnnotations = False if sessid: sessObj = db["sessions"].find_one({"_id": ObjectId(sessid)}) if sessObj.has_key("hideAnnotations"): if sessObj["hideAnnotations"]: hideAnnotations = True viewObj = db["views"].find_one({"_id": ObjectId(viewid)}) # Right now, only notes use "Type" if "Type" in viewObj: viewObj["_id"] = str(viewObj["_id"]) addviewimage(viewObj) if hideAnnotations: # use a cryptic label viewObj["Title"] = viewObj["HiddenTitle"] viewObj["ViewerRecords"] = [viewObj["ViewerRecords"][0]] viewObj["Children"] = [] return jsonify(viewObj) #--------------------------------------------------------- # legacy: Rework bookmarks into the same structure. # a pain, but necessary to generalize next/previous slide. # An array of children and an array of ViewerRecords imgdb = viewdb if "imgdb" in viewObj: # support for images in database different than view imgdb = viewObj["imgdb"] dbobj2 = admindb["databases"].Database.find_one( {"_id": ObjectId(imgdb)}) db2 = conn[dbobj2["dbname"]] imgobj = db2["images"].find_one({'_id': ObjectId(viewObj["img"])}) else: imgobj = db["images"].find_one({'_id': ObjectId(viewObj["img"])}) noteObj = {} noteObj["Id"] = viewid noteObj["ParentId"] = "" noteObj["Title"] = imgobj["label"] if viewObj.has_key("Title"): noteObj["Title"] = viewObj["Title"] noteObj["HiddenTitle"] = imgobj["label"] if viewObj.has_key("HiddenTitle"): noteObj["HiddenTitle"] = viewObj["HiddenTitle"] # Construct the ViewerRecord for the base view viewerRecord = {} viewerRecord["Annotations"] = [] if 'dimensions' in imgobj: viewerRecord["Dimensions"] = imgobj["dimensions"] viewerRecord["Bounds"] = [ 0, imgobj["dimensions"][0], 0, imgobj["dimensions"][1] ] elif 'dimension' in imgobj: viewerRecord["Dimensions"] = imgobj["dimension"] viewerRecord["Bounds"] = [ 0, imgobj["dimension"][0], 0, imgobj["dimension"][1] ] viewerRecord["NumberOfLevels"] = imgobj["levels"] viewerRecord["Image"] = str(imgobj["_id"]) viewerRecord["Database"] = imgdb # camera object. cam = {} if 'startup_view' in viewObj: bookmark = db["bookmarks"].find_one( {'_id': ObjectId(viewObj["startup_view"])}) cam["FocalPoint"] = bookmark["center"] cam["Roll"] = bookmark["rotation"] if 'zoom' in bookmark: cam["Height"] = 900 << int(bookmark["zoom"]) if 'viewHeight' in bookmark: cam["Height"] = bookmark["viewHeight"] else: cam["Height"] = viewerRecord["Dimensions"][1] cam["Roll"] = 0 cam["FocalPoint"] = [ viewerRecord["Dimensions"][0] / 2, viewerRecord["Dimensions"][1] / 2, 0 ] viewerRecord["Camera"] = cam noteObj["ViewerRecords"] = [viewerRecord] # Now for the children (Bookmarks). children = [] if 'bookmarks' in viewObj: for bookmarkid in viewObj["bookmarks"]: bookmark = db["bookmarks"].find_one({'_id': ObjectId(bookmarkid)}) if bookmark["annotation"]["type"] == "pointer": question = {} question["Title"] = "Question" question["Text"] = "" question["Type"] = "Bookmark" question["Id"] = str(bookmark["_id"]) question["ParentId"] = viewid vrq = {} vrq["AnnotationVisibility"] = 1 vrq["Dimensions"] = viewerRecord["Dimensions"] vrq["Bounds"] = viewerRecord["Bounds"] vrq["NumberOfLevels"] = viewerRecord["NumberOfLevels"] vrq["Image"] = viewerRecord["Image"] vrq["Database"] = viewerRecord["Database"] # camera object. cam = {} cam["FocalPoint"] = bookmark["center"] cam["Height"] = 900 << int(bookmark["zoom"]) cam["Roll"] = bookmark["rotation"] vrq["Camera"] = cam annot = {} annot["type"] = "text" # colors are wrong #annot["color"] = bookmark["annotation"]["color"] annot["color"] = "#1030FF" annot["size"] = 30 annot["position"] = bookmark["annotation"]["points"][0] annot["offset"] = [ bookmark["annotation"]["points"][1][0] - annot["position"][0], bookmark["annotation"]["points"][1][1] - annot["position"][1] ] # problem with offsets too big or small. (Screen pixels / fixed size) mag = math.sqrt((annot["offset"][0] * annot["offset"][0]) + (annot["offset"][1] * annot["offset"][1])) if mag == 0: annot["offset"][1] = 1 mag = 1 if mag > 200: annot["offset"][0] = annot["offset"][0] * 200 / mag annot["offset"][1] = annot["offset"][1] * 200 / mag if mag < 10: annot["offset"][0] = annot["offset"][0] * 10 / mag annot["offset"][1] = annot["offset"][1] * 10 / mag annot["string"] = bookmark["title"] annot["anchorVisibility"] = True vrq["Annotations"] = [annot] question["ViewerRecords"] = [vrq] children.append(question) answer = {} answer["Title"] = bookmark["title"] answer["Text"] = bookmark["details"] answer["Type"] = "Bookmark" answer["Id"] = str(bookmark["_id"]) answer["ParentId"] = viewid vra = {} vra["AnnotationVisibility"] = 2 vra["Type"] = "Answer" vra["Dimensions"] = viewerRecord["Dimensions"] vra["Bounds"] = viewerRecord["Bounds"] vra["NumberOfLevels"] = viewerRecord["NumberOfLevels"] vra["Image"] = viewerRecord["Image"] vra["Database"] = viewerRecord["Database"] vra["Camera"] = cam vra["Annotations"] = [annot] answer["ViewerRecords"] = [vra] question["Children"] = [answer] if bookmark["annotation"]["type"] == "circle": note = {} note["Title"] = bookmark["title"] note["Text"] = bookmark["details"] note["Type"] = "Bookmark" note["Id"] = str(bookmark["_id"]) note["ParentId"] = viewid vr = {} vr["AnnotationVisibility"] = 1 vr["Dimensions"] = viewerRecord["Dimensions"] vr["Bounds"] = viewerRecord["Bounds"] vr["NumberOfLevels"] = viewerRecord["NumberOfLevels"] vr["Image"] = viewerRecord["Image"] vr["Database"] = viewerRecord["Database"] # camera object. cam = {} cam["FocalPoint"] = bookmark["center"] cam["Height"] = 900 << int(bookmark["zoom"]) cam["Roll"] = bookmark["rotation"] vrq["Camera"] = cam annot = {} annot["type"] = "circle" annot["color"] = bookmark["annotation"]["color"] annot["outlinecolor"] = bookmark["annotation"]["color"] annot["origin"] = bookmark["annotation"]["points"][0] # why does radius have value False? if bookmark["annotation"]["radius"]: annot["radius"] = bookmark["annotation"]["radius"] else: annot["radius"] = 1000.0 annot["linewidth"] = annot["radius"] / 20 vr["Annotations"] = [annot] note["ViewerRecords"] = [vr] children.append(note) noteObj["Children"] = children # it is easier to delete annotations than not generate them in the first place. if hideAnnotations: # use a cryptic label noteObj["Title"] = viewObj["HiddenTitle"] noteObj["ViewerRecords"] = [noteObj["ViewerRecords"][0]] noteObj["Children"] = [] return jsonify(noteObj)
def post(self, resid=None): # post requires admin access # Parse the data in json format data = request.json # Unknown request if no parameters if data == None: abort(400) conn.register([Database]) # Only insert command is supported if data.has_key("insert"): # Create the database object from the supplied parameters try: if resid <> None: raise Exception( "Trying to create new resource at existing resource") newdb = conn[ current_app.config["CONFIGDB"]]["databases"].Database() newdb["label"] = data["insert"]["label"] newdb["host"] = data["insert"]["host"] newdb["dbname"] = data["insert"]["dbname"] newdb["copyright"] = data["insert"]["copyright"] newdb.validate() newdb.save() except Exception as inst: # If valid database object cannot be constructed it is invalid request return Response("{\"error\" : \"%s\"}" % str(inst), status=405) return jsonify(newdb) elif data.has_key("modify"): # Resid must be supplied if resid == None: return Response( "{\"error\" : \"No resource id supplied for modification\"}", status=405) try: # Locate the resource newdb = conn[current_app.config["CONFIGDB"]][ "databases"].Database.find_one({"_id": ObjectId(resid)}) if newdb == None: raise Exception(" Resource %s not found" % (resid)) except Exception as inst: # If valid database object cannot be constructed it is invalid request return Response("{\"error\" : \"%s\"}" % str(inst), status=405) # Now update try: for akey in data["modify"]: if akey == "_id": return Response("{\"error\" : \"Cannot modify _id \"}", status=405) # Update other keys if akey in newdb: newdb[akey] = data["modify"][akey] newdb.validate() newdb.save() except Exception as inst: # If valid database object cannot be constructed it is invalid request return Response("{\"error\" : \"%s\"}" % str(inst), status=405) return jsonify(newdb) else: # Only insert and modify commands supported so far abort(400)
def put(self, resid): # put requires admin access # Get json supplied data = request.json # Check for valid parameters # Check if no parameters if data == None: return Response("{\"error\" : \"No parameters ? \"}", status=405) # See if id matches the resource being modified try: if data["_id"] != resid: raise Exception(1) except: # # def delete(self, dbid, sessid, restype, resid=None): # if resid == None: # return Response("{ \"error \" : \"Deletion of all attachments not implemented Must provide resid\"}" , status=405) # else: # datadb = self.get_data_db(dbid) # if datadb == None: # return Response("{ \"error \" : \"Invalid database id %s\"}" % (dbid), status=405) # # # TODO: This block of code to common and can be abstrated # conn.register([Session]) # sessobj = datadb["sessions"].Session.find_one({"_id" : ObjectId(sessid)}) # if sessobj == None: # return Response("{ \"error \" : \"Session %s does not exist in db %s\"}" % (sessid, dbid), status=405) # # if restype == "attachments" or restype == "rawfiles": # # Remove from the gridfs # gf = gridfs.GridFS(datadb , restype) # gf.delete(ObjectId(resid)) # # # Remove the reference from session # attachments = [value for value in sessobj["attachments"] if value["ref"] != ObjectId(resid)] # # Find the index # # Remove that index # sessobj["attachments"] = attachments # # if not "images" in sessobj: # sessobj["images"] = [] # sessobj.validate() # sessobj.save() # return Response("{ \"Success \" : \" \"}", status=200) # else: # return "You want %s from views in %s/%s" % (resid, dbid, sessid) return Response("{\"error\" : \"_id mismatch with the location in the url \"}", status=405) # Try to see if the data can create valid object conn.register([Database]) # The object should exist dbobj = conn[current_app.config["CONFIGDB"]]["databases"].Database.find_one({"_id" : ObjectId(resid)}) # Unknown request if no parameters if dbobj == None: return Response("{\"error\" : \"Resource _id: %s doesnot exist\"}" % (resid), status=403) # Create the database object from the supplied parameters try: dbobj["label"] = data["label"] dbobj["host"] = data["host"] dbobj["dbname"] = data["dbname"] dbobj["copyright"] = data["copyright"] dbobj.validate() dbobj.save() except Exception as inst: # If valid database object cannot be constructed it is invalid request return Response("{\"error\" : %s}" % str(inst), status=405) return jsonify(dbobj)
def put(self, dbid, sessid, restype, resid): # we are expected to save the uploaded file and return some info about it: # this is the name for input type=file names = [] # Make sure to read the form before sending the reply jsonresponse = {} jsonresponse["_id"] = request.form['_id'] datadb = self.get_data_db(dbid) if datadb == None: return Response("{ \"error \" : \"Invalid database id %s\"}" % (dbid), status=405) conn.register([Session]) sessobj = datadb["sessions"].Session.find_one( {"_id": ObjectId(sessid)}) if sessobj == None: return Response( "{ \"error \" : \"Session %s does not exist in db %s\"}" % (sessid, dbid), status=405) # Parse headers try: #Get filename from content disposition fnameheader = request.headers["Content-Disposition"] disposition = re.search(r'filename="(.+?)"', fnameheader) filename = disposition.group(0)[10:-1] # Get the actual chunk position from Content-Range range = request.headers["Content-Range"] match = re.findall(r'\d+', range) start = int(match[0]) end = int(match[1]) total = int(match[2]) success = True except: success = False # Headers cannot be parsed, so try if not success: try: bfile = request.files['file'] gf = gridfs.GridFS(datadb, restype) afile = gf.new_file(chunk_size=1048576, filename=bfile.filename, _id=ObjectId(resid)) afile.write(bfile.read()) afile.close() if not sessobj.has_key("attachments"): sessobj["attachments"] = [{ "ref": ObjectId(resid), "pos": 0 }] sessobj.validate() sessobj.save() # print "Inserted attachments", str(sessobj["attachments"]) else: size_before = len(sessobj["attachments"]) sessobj["attachments"].append({ "ref": ObjectId(resid), "pos": size_before + 1 }) sessobj.validate() sessobj.save() return Response("{\"success\" : \" - \"}", status=200) except: return Response( "{\"error\" : \" Error processing single chunk header \"}", status=405) # No need to return conventional file list # Expect _id in the form try: jsonresponse["_id"] = request.form['_id'] except: return Response( "{\"error\" : \" each put request must include _id requested from server \"}", status=400) n = int(start / 1048576.0) # Craft the response json jsonresponse["start"] = start jsonresponse["end"] = end jsonresponse["total"] = total jsonresponse["done"] = end + 1 bfile = request.files['file'] first = False last = False # If first chunk if start == 0: first = True jsonresponse["first"] = 1 # Create a file gf = gridfs.GridFS(datadb, restype) afile = gf.new_file(chunk_size=1048576, filename=filename, _id=ObjectId(resid)) afile.write(bfile.read()) afile.close() if total == end + 1: last = True jsonresponse["last"] = 1 # Add the attachment id to the if not sessobj.has_key("attachments"): sessobj["attachments"] = [{"ref": ObjectId(resid), "pos": 0}] sessobj.validate() sessobj.save() # print "Inserted attachments", str(sessobj["attachments"]) else: size_before = len(sessobj["attachments"]) sessobj["attachments"].append({ "ref": ObjectId(resid), "pos": size_before + 1 }) sessobj.validate() sessobj.save() # print "Appended to attachments", str(sessobj["attachments"]) if not first: obj = {} obj["n"] = n obj["files_id"] = ObjectId(resid) obj["data"] = Binary(bfile.read()) datadb["attachments.chunks"].insert(obj) fileobj = datadb["attachments.files"].find_one( {"_id": obj["files_id"]}) datadb["attachments.files"].update( {"_id": obj["files_id"]}, {"$set": { "length": fileobj["length"] + len(obj["data"]) }}) # Finalize # Append to the chunks collection return jsonify(jsonresponse)
def post(self, restype, resid, listtype): # create a new user obj = {} obj["query"] = { "restype" : restype, "resid" : resid, "listtype" : listtype} return jsonify(obj)
def glstacksession(): """ - /webgl-viewer/stack-session?db=5123c81782778fd2f954a34a&sess=51256ae6894f5931098069d5 """ # Comparison is a modified view. sessid = request.args.get('sess', None) if not sessid: sessid = "51256ae6894f5931098069d5" # this is the same as the sessions db in the sessions page. dbid = request.args.get('db', None) admindb = conn[current_app.config["CONFIGDB"]] dbobj = admindb["databases"].Database.find_one({"_id": ObjectId(dbid)}) db = conn[dbobj["dbname"]] sessobj = db["sessions"].find_one({"_id": ObjectId(sessid)}) views = [] for view in sessobj["views"]: viewid = view["ref"] viewobj = db["views"].find_one({"_id": ObjectId(viewid)}) #viewobj["rotation"] = 0 # Having issues with jsonify imgdbid = dbid if 'db' in viewobj: imgdbid = str(viewobj["db"]) myview = { "_id": str(viewobj["_id"]), "center": viewobj["center"], "height": viewobj["height"], "rotation": 0, "db": imgdbid } imgobj = db["images"].find_one({"_id": viewobj["img"]}) #imgobj["_id"] = str(imgobj["_id"]) #imgobj["thumb"] = "" myimg = { "dimensions": imgobj["dimension"], "_id": str(imgobj["_id"]), "levels": imgobj["levels"] } myview["img"] = myimg views.append(myview) for pair in sessobj["transformations"]: if 'view0' in pair: pair["view0"] = str(pair["view0"]) pair["view1"] = str(pair["view1"]) if not 'annotations' in sessobj: sessobj["annotations"] = [] for markup in sessobj["annotations"]: markup["view"] = str(markup["view"]) return jsonify({ "views": views, "transformations": sessobj["transformations"], "annotations": sessobj["annotations"] })
def bookmark(): """ - /bookmark?key=0295cf24-6d51-4ce8-a923-772ebc71abb5 """ key = request.args.get('key', "0295cf24-6d51-4ce8-a923-772ebc71abb5") # find the view and the db return jsonify({"key": key}) # Check the user is logged in. rules = [] # Compile the rules conn.register([Image, Session, User, Rule, Database]) admindb = conn[current_app.config["CONFIGDB"]] # Assert the user is logged in if 'user' in session: name = session['user']['label'] id = session['user']['id'] userobj = admindb["users"].User.find_one({"_id": ObjectId(id)}) if userobj == None: # If the user is not found then something wrong # Redirect the user to home with error message flash("Invalid login", "error") return redirect(url_for('login.login')) else: # Send the user back to login page # with some message flash("You must be logged in to see that resource", "error") return redirect(url_for('login.login')) # See if editing will be enabled. edit = request.args.get('edit', False) # See if the user is requesting a view or session viewid = request.args.get('view', None) # get all the metadata to display a view in the webgl viewer. ajax = request.args.get('json', None) # get bookmarks. (Legacy) bookmarks = request.args.get('bookmarks', None) # this is the same as the sessions db in the sessions page. # TODO: Store database in the view and do not pass as arg. dbid = request.args.get('db', None) admindb = conn[current_app.config["CONFIGDB"]] dbobj = admindb["databases"].Database.find_one({"_id": ObjectId(dbid)}) db = conn[dbobj["dbname"]] conn.register([model.Database]) if viewid: viewobj = db["views"].find_one({"_id": ObjectId(viewid)}) if ajax: return jsonifyView(db, dbid, viewid, viewobj) if bookmarks: return jsonifyBookmarks(db, dbid, viewid, viewobj) # This will be the only path in the future. Everything else is legacy. if 'type' in viewobj: if viewobj["type"] == "comparison": return glcomparison(db, dbid, viewid, viewobj) # default return glnote(db, dbid, viewid, viewobj, edit)
def sessionsave(): inputStr = request.form['input'] # for post #inputStr = request.args.get('input', "{}") # for get #pdb.set_trace() inputObj = json.loads(inputStr) newFlag = inputObj["new"] dbId = inputObj["db"] sessId = inputObj["session"] label = inputObj["label"] views = inputObj["views"] hideAnnotation = inputObj["hideAnnotation"] admindb = conn[current_app.config["CONFIGDB"]] dbobj = admindb["databases"].Database.find_one({"_id": ObjectId(dbId)}) db = conn[dbobj["dbname"]] if 'user' in session: email = session["user"]["email"] admin = True if email == "all_bev1_admin": admin = True if email == "all_paul3_admin": admin = True if not admin: return "" # get the session in the database to modify. # Todo: if session is undefined, create a new session (copy views when available). sessObj = db["sessions"].find_one({"_id": ObjectId(sessId)}) # I am using the label for the annotated title, and name for hidde sessObj["label"] = label # create a new list of sessions. oldViews = [] if sessObj.has_key("views"): oldViews = sessObj["views"] newViews = [] newImages = [] for viewData in views: viewId = None if "view" in viewData: viewId = viewData["view"] # Look for matching old views in new session found = False for index, view in enumerate(oldViews): if str(view["ref"]) == viewId: # found one. Copy it over. found = True view["pos"] = len(newViews) # switch over to the new list. newViews.append(view) del oldViews[index] # What a pain. Why two lists? Deal with the image list. image = {} image["pos"] = len(newImages) image["hide"] = False viewObj = db["views"].find_one({"_id": ObjectId(viewId)}) viewObj["Title"] = viewData["label"] viewObj["HiddenTitle"] = viewData["hiddenLabel"] # if copying a session, copy the view objects too. if newFlag: del viewObj["_id"] # have to save the view, (Title might have changed.) view["ref"] = db["views"].save(viewObj) if "img" in viewObj: image["ref"] = viewObj["img"] else: # assume view has type note. image["ref"] = viewObj["ViewerRecords"][0]["Image"] newImages.append(image) if not found: if not viewId: # create a minimal new view (to be stored in db["views"]). viewObj = {} viewObj["img"] = viewData["img"] if viewData["db"] != dbId: viewObj["imgdb"] = viewData["db"] viewObj["label"] = viewData["label"] # need to clean up the schema: viewObj:label, Title, view:label viewObj["Title"] = viewData["label"] viewObj["HiddenTitle"] = viewData["hiddenLabel"] viewId = db["views"].save(viewObj) # make a view entry on the session list view = {} view["pos"] = len(newViews) view["ref"] = viewId view["hide"] = False view["label"] = viewData["label"] newViews.append(view) # image image = {} image["pos"] = len(newImages) image["hide"] = False image["ref"] = ObjectId(viewData["img"]) if viewData["db"] != dbId: image["db"] = viewData["db"] newImages.append(image) #else : # Todo: If viewId, copy view from another session. # Delete the views that are left over. # Views are owned by the session. # Images can be shared. if not newFlag: for view in oldViews: db["views"].remove({"_id": view["ref"]}) sessObj["views"] = newViews sessObj["images"] = newImages sessObj["hideAnnotations"] = hideAnnotation #pdb.set_trace() if newFlag: del sessObj["_id"] sessObj["user"] = email sessObj["_id"] = db["sessions"].save(sessObj) elif len(newViews) == 0: db["sessions"].remove({"_id": sessObj["_id"]}) sessObj = {} return "" else: db["sessions"].save(sessObj) return jsonify(sessObj)
def upload(): """ Assumes that a chunked upload is provided A unique gridfs id is created upon first chunk and later """ if request.method == 'POST': # TODO: Get the new method in paramters # Verfiy that the uploader has access id = ObjectId() form = request.form # No need to return conventional file list jsonresponse = {} jsonresponse["_id"] = id return jsonify(jsonresponse) if request.method == 'PUT': # we are expected to save the uploaded file and return some info about it: # this is the name for input type=file names = [] # Make sure to read the form before sending the reply # Parse headers #Get filename from content disposition fnameheader = request.headers["Content-Disposition"] disposition = re.search(r'filename="(.+?)"', fnameheader) filename = disposition.group(0)[10:-1] # Get the actual chunk position from Content-Range range = request.headers["Content-Range"] match = re.findall(r'\d+', range) start = int(match[0]) end = int(match[1]) total = int(match[2]) # No need to return conventional file list jsonresponse = {} # Expect _id in the form try: id = request.form['_id'] except: return Response( "{\"error\" : \" each put request must include _id requested from server \"}", status=400) # Craft the response json jsonresponse["done"] = end + 1 jsonresponse["_id"] = id return jsonify(jsonresponse) # print request.headers # Now create the file being uploaded or append etc # TODO: Decide the format to return # obj = {} # obj["boundary"] = request.headers["Content-Type"] # obj["size"] = False # obj["delete_type"] = "DELETE" # obj["delete_url"] = "?file=" + filename # obj["name"] = filename # print obj return jsonify(obj) for file in request.files.getlist('files[]'): filename = secure_filename(file.filename) print filename file.save( os.path.join(current_app.config['UPLOAD_FOLDER'], filename)) names.append({"name": filename}) return render_template("list.html", names=names) return render_template("upload.html")