Esempio n. 1
0
def serve_doc(req, id_source, annotated=False): 
    serve_dir =  settings.ANNOTATED_DIR if annotated else  settings.REPOSITORY_DIR
    qual = "_annotated" if annotated else  ""
    uid = UR.getUserId(req)
    if not auth.canDownloadPDF(uid, id_source): 
        return HttpResponse("Error: You don't have credentials to see file #%s" % (id_source, ))
    try:   
        response = serve(req, id_source,"%s/%s" % (settings.HTTPD_MEDIA, serve_dir))
        response["Content-Type"]='application/pdf'
        #the following makes sure that: 
        #- the downloaded file name always ends up w/ '.pdf'
        #- it conatains the qualif. '_annotated' if it's... er... well.... annotated : )                
        #- the filename only contains ascii characters, so that we don't get an UnicodeEncodeError since the 
        #  filename is part of the response headers and that HTTP response headers can only contain ascii characters. 
        filename = ""
        try:
            filename = M.Source.objects.get(pk=id_source).title.partition(".pdf")[0].encode("ascii").replace(" ", "_")
        except UnicodeEncodeError: 
            filename = id_source
        filename = "%s%s%s" % (filename, qual, ".pdf")        
        response['Content-Disposition'] = "attachment; filename=%s" % (filename, )
        signals.file_downloaded.send("file", req=req, uid=uid, id_source=id_source, annotated=annotated)
        return response
    except Http404: 
        logging.info("missing "+id_source)
        return HttpResponse("Error - No such file: #%s %s" % (id_source, qual) )
Esempio n. 2
0
def upload(req): 
    r = HttpResponse()
    f = req.FILES["file"]
    id_ensemble = req.GET["id_ensemble"]
    id_source = req.GET["id_source"]
    id_folder = req.GET.get("id_folder", None)
    uid = UR.getUserId(req);
    logging.info("upload uid=%s, id_source=%s, id_ensemble=%s, id_folder=%s" %  (uid,id_source,id_ensemble,id_folder))
    url = "http://%s:%s/%s?id_ensemble=%s" %("localhost", "8080",f.name, id_ensemble)
    payload = {"url": url, "id_source": id_source, "id_folder": id_folder }
    if auth.canInsertFile(uid, id_ensemble, id_folder):
        #the followong data will be deleted in utils_pdf if an PDF error happens later...
        annotations.createSource(uid, payload)
        annotations.addOwnership(id_source, id_ensemble, id_folder)
        REPOSITORY_DIR = "%s/%s" % (settings.HTTPD_MEDIA, "/pdf/repository")
        f2 = open("%s/%s" % (REPOSITORY_DIR, id_source,),"wb")    
        f2.write(f.read())
        f2.close()
        basedir = dirname(dirname(abspath(__file__)))
        #do the rest in the background, so server remains responsive                
        cmd = "(cd %s; python -m upload.jobs file_img %s >/tmp/uploadscript_%s.log 2>&1 &)" %(basedir, id_source,  id_log )
        logging.info(cmd)
        os.system(cmd)
        r.content =  UR.prepare_response({})
    else: 
        r.content =  UR.prepare_response({}, 1, "NOT ALLOWED to insert a file to this group")
    return r
Esempio n. 3
0
def serve_grades_spreadsheet(req, id_ensemble): 
    uid = UR.getUserId(req)
    if not auth.canSeeGrades(uid, id_ensemble):
        return HttpResponse("Error: You don't have credentials to see grades for class %s" % (id_ensemble,))
    import xlwt
    wbk = xlwt.Workbook()

    #first, generate the sheets with comment, words, char counts: 
    stats = add_count_sheets(id_ensemble, wbk)
 
    #now add a sheet for labeled comments if there are any: 
    add_labeledcomments_sheet(uid, id_ensemble, wbk)
    
    #now add sheets for the social graph
    # FIXME: this is broken for ensemble 6010 on nb.mit.edu. Disabling for now. 
    # https://github.com/nbproject/nbproject/issues/199
    #add_socialgraph_sheets(id_ensemble, stats["users"], wbk)

    import datetime
    a = datetime.datetime.now()
    fn = "stats_%s_%04d%02d%02d_%02d%02d.xls" % (id_ensemble,a.year, a.month, a.day, a.hour, a.minute)
    wbk.save("/tmp/%s" %(fn,))
    response = serve(req, fn,"/tmp/")
    os.remove("/tmp/%s" %(fn,))
    response["Content-Type"]='application/vnd.ms-excel'   
    response['Content-Disposition'] = "attachment; filename=%s" % (fn, )
    return response
Esempio n. 4
0
def serve_doc(req, id_source, annotated=False):
    serve_dir = settings.ANNOTATED_DIR if annotated else settings.REPOSITORY_DIR
    qual = "_annotated" if annotated else ""
    uid = UR.getUserId(req)
    if not auth.canDownloadPDF(uid, id_source):
        return HttpResponse(
            "Error: You don't have credentials to see file #%s" %
            (id_source, ))
    try:
        response = serve(req, id_source,
                         "%s/%s" % (settings.HTTPD_MEDIA, serve_dir))
        response["Content-Type"] = 'application/pdf'
        #the following makes sure that:
        #- the downloaded file name always ends up w/ '.pdf'
        #- it conatains the qualif. '_annotated' if it's... er... well.... annotated : )
        #- the filename only contains ascii characters, so that we don't get an UnicodeEncodeError since the
        #  filename is part of the response headers and that HTTP response headers can only contain ascii characters.
        filename = ""
        try:
            filename = M.Source.objects.get(pk=id_source).title.partition(
                ".pdf")[0].encode("ascii").replace(" ", "_")
        except UnicodeEncodeError:
            filename = id_source
        filename = "%s%s%s" % (filename, qual, ".pdf")
        response['Content-Disposition'] = "attachment; filename=%s" % (
            filename, )
        signals.file_downloaded.send("file",
                                     req=req,
                                     uid=uid,
                                     id_source=id_source,
                                     annotated=annotated)
        return response
    except Http404:
        logging.info("missing " + id_source)
        return HttpResponse("Error - No such file: #%s %s" % (id_source, qual))
Esempio n. 5
0
def set_comment_label(P, req):
    uid = UR.getUserId(req)
    cid = P["comment_id"]
    if not auth.canLabelComment(uid, cid):
        return UR.prepare_response({}, 1,  "NOT ALLOWED")
    record = None
    try: 
        record = M.CommentLabel.objects.get(grader__id=uid, comment__id=cid, category_id=P["category_id"])
        rh = M.CommentLabelHistory()        
        rh.grader = record.grader
        rh.ctime = record.ctime
        rh.grade = record.grade
        rh.category = record.category
        rh.comment = record.comment
        rh.save()
        record.ctime = datetime.datetime.now()
    except M.CommentLabel.DoesNotExist: 
        record = M.CommentLabel()
        record.category_id = P["category_id"]
        record.comment_id = cid
    record.grade = P["grade"]
    record.grader_id = uid
    record.save()
    retval = {"commentlabels":{record.id: UR.model2dict(record)}}
    return UR.prepare_response(retval)    
Esempio n. 6
0
def getHTML5Info(payload, req):
    if "url" not in payload:
        return UR.prepare_response({}, 1, "missing url !")
    url = payload["url"].partition("#")[0].rstrip(
        "/"
    )  # remove hash part of the URL by default, as well as trailing slash.
    #TODO: use optional argument id_ensemble to disambiguate if provided.
    sources_info = M.HTML5Info.objects.filter(url=url)
    ownerships = M.Ownership.objects.select_related(
        "source", "ensemble",
        "folder").filter(source__html5info__in=sources_info, deleted=False)
    if not ownerships.exists():
        return UR.prepare_response({}, 1, "this URL is not recognized: ")

    output = {
        "files":
        UR.qs2dict(ownerships, annotations.__NAMES["files2"], "ID"),
        "ensembles":
        UR.qs2dict(ownerships, annotations.__NAMES["ensembles2"], "ID"),
        "folders":
        UR.qs2dict(ownerships, annotations.__NAMES["folders2"], "ID"),
    }
    for i in output["ensembles"]:
        if not (output["ensembles"][i]["allow_guest"]
                or auth.isMember(UR.getUserId(req), i)):
            return UR.prepare_response(
                {}, 1,
                "not allowed: guest access isn't allowed for this file.")
    return UR.prepare_response(output)
Esempio n. 7
0
def getHTML5Info(payload, req):
    if "url" not in payload:
        return UR.prepare_response({}, 1, "missing url !")
    url = payload["url"].partition("#")[0].rstrip(
        "/"
    )  # remove hash part of the URL by default, as well as trailing slash.
    #TODO: use optional argument id_ensemble to disambiguate if provided.
    sources_info = M.HTML5Info.objects.filter(url=url)
    ownerships = M.Ownership.objects.select_related(
        "source", "ensemble",
        "folder").filter(source__html5info__in=sources_info, deleted=False)
    #TODO: with django 1.9, you can use Q objects to OR two conditions
    #so instead of iterating to test below, just add .filter(Q(ensemble__memberships__user=UR.getUserId(req)) | Q(ensemble.allow_guest))
    #then use UR.qs2dict as was done previously

    if not ownerships.exists():
        return UR.prepare_response({}, 1, "this URL is not recognized: ")

    output = {"files": {}, "ensembles": {}, "folders": {}}
    for r in ownerships:
        if (r.ensemble.allow_guest
                or auth.isMember(UR.getUserId(req), r.ensemble_id)):
            output["ensembles"][r.ensemble_id] = UR.model2dict(
                r, annotations.__NAMES["ensembles2"])
            output["files"][r.source_id] = UR.model2dict(
                r, annotations.__NAMES["files2"])
            output["folders"][r.folder_id] = UR.model2dict(
                r, annotations.__NAMES["folders2"])
    if (output["ensembles"]):
        return UR.prepare_response(output)
    else:
        return UR.prepare_response(
            {}, 1, "not allowed: guest access isn't allowed for this file.")
Esempio n. 8
0
def set_grade_assignment(P, req):
    uid = UR.getUserId(req)
    if not auth.canGrade(uid, P["id_source"], P["id_user"]):
        return UR.prepare_response({}, 1,  "NOT ALLOWED")
    retval = {}
    retval["grades"] = annotations.set_grade_assignment(uid, {"id_source": P["id_source"], "id_user":  P["id_user"], "grade": P["grade"]})
    return UR.prepare_response(retval)
Esempio n. 9
0
def get_stats_ensemble(payload, req): 
    uid = UR.getUserId(req)
    id_ensemble = payload["id_ensemble"]
    if not auth.canSeeGrades(uid, id_ensemble):
        return UR.prepare_response({}, 1,  "NOT ALLOWED")
    retval = annotations.get_stats_ensemble(payload)
    return UR.prepare_response(retval)
Esempio n. 10
0
def set_location_section(P, req):
    uid = UR.getUserId(req)
    if not auth.canAdministrateLocation(uid, P["id_location"]):
        return UR.prepare_response({}, 1, "NOT ALLOWED")
    result = annotations.setLocationSection(P["id_location"], P["id_section"])
    locations, html5locations = annotations.getLocation(result.pk)
    return UR.prepare_response( locations )
Esempio n. 11
0
def upload(req): 
    r = HttpResponse()
    f = req.FILES["file"]
    id_ensemble = req.GET["id_ensemble"]
    id_source = req.GET["id_source"]
    id_folder = req.GET.get("id_folder", None)
    uid = UR.getUserId(req);
    logging.info("upload uid=%s, id_source=%s, id_ensemble=%s, id_folder=%s" %  (uid,id_source,id_ensemble,id_folder))
    url = "http://%s:%s/%s?id_ensemble=%s" %("localhost", "8080",f.name, id_ensemble)
    payload = {"url": url, "id_source": id_source, "id_folder": id_folder }
    if auth.canInsertFile(uid, id_ensemble, id_folder):
        #the followong data will be deleted in utils_pdf if an PDF error happens later...
        annotations.createSource(uid, payload)
        annotations.addOwnership(id_source, id_ensemble, id_folder)
        REPOSITORY_DIR = "%s/%s" % (settings.HTTPD_MEDIA, "/pdf/repository")
        f2 = open("%s/%s" % (REPOSITORY_DIR, id_source,),"wb")    
        f2.write(f.read())
        f2.close()
        basedir = dirname(dirname(abspath(__file__)))
        #do the rest in the background, so server remains responsive                
        cmd = "(cd %s; python -m upload.jobs file_img %s >/tmp/uploadscript_%s.log 2>&1 &)" %(basedir, id_source,  id_log )
        logging.info(cmd)
        os.system(cmd)
        r.content =  UR.prepare_response({})
    else: 
        r.content =  UR.prepare_response({}, 1, "NOT ALLOWED to insert a file to this group")
    return r
Esempio n. 12
0
def get_class_settings(payload, req):
    uid = UR.getUserId(req)
    if "id_ensemble" in payload:
        if auth.canGetMembers(uid, payload["id_ensemble"]):
            class_settings = annotations.get_class_settings(uid, payload)
            return UR.prepare_response(class_settings)
    return UR.prepare_response({}, 1,  "NOT ALLOWED")
Esempio n. 13
0
def update_ensemble(P, req):
    uid = UR.getUserId(req)
    eid = P["id_ensemble"]
    if uid is None or eid is None:
        return UR.prepare_response({}, 1,  "NOT ALLOWED")
    ensemble = M.Ensemble.objects.get(pk=eid)
    if "name" in P:
        ensemble.name = P["name"]
    if "description" in P:
        ensemble.description = P["description"]
    if "allow_staffonly" in P:
        ensemble.allow_staffonly = P["allow_staffonly"]
    if "allow_anonymous" in P:
        ensemble.allow_anonymous = P["allow_anonymous"]
    if "allow_tag_private" in P:
        ensemble.allow_tag_private = P["allow_tag_private"]
    if "allow_guest" in P:
        ensemble.allow_guest = P["allow_guest"]
    if "use_invitekey" in P:
        ensemble.use_invitekey = P["use_invitekey"]
    if "allow_download" in P:
        ensemble.allow_download = P["allow_download"]
    if "allow_ondemand" in P:
        ensemble.allow_ondemand = P["allow_ondemand"]
    if "default_pause" in P:
        ensemble.default_pause = P["default_pause"]
    if "section_assignment" in P:
        ensemble.section_assignment = P["section_assignment"]
    if "metadata" in P:
        ensemble.metadata = P["metadata"]
    ensemble.save()
    return UR.prepare_response(annotations.get_class_settings(uid, {"id_ensemble":P["id_ensemble"]}))
Esempio n. 14
0
def get_section_participants(payload, req):
    uid = UR.getUserId(req)
    if "id_ensemble" in payload:
        if auth.canGetMembers(uid, payload["id_ensemble"]):
            section_participants = annotations.get_section_participants(uid, payload)
            return UR.prepare_response(section_participants)
    return UR.prepare_response({}, 1,  "NOT ALLOWED")
Esempio n. 15
0
def deleteThread(payload, req):
    uid = UR.getUserId(req)
    if not auth.canDeleteThread(uid, payload["id_location"]):
        return UR.prepare_response({}, 1, "NOT ALLOWED")
    else:
        annotations.deleteThread(payload)
        return UR.prepare_response({"id_location": payload["id_location"]})
Esempio n. 16
0
def saveNote(payload, req):
    uid = UR.getUserId(req)
    if not auth.canAnnotate(uid,  payload["id_ensemble"]):
        return UR.prepare_response({}, 1,  "NOT ALLOWED")
    payload["id_author"] = uid
    retval = {}
    a = annotations.addNote(payload)
    if len(a) == 0:
        return UR.prepare_response({}, 2,  "DUPLICATE")
    tms = {}
    for mark in payload["marks"]:
        tm = M.ThreadMark()
        m_types = [c[0] for c in tm.TYPES if c[1]==mark]
        if len(m_types): #old clients may return types we don't have in DB so ignore them
            tm.type = m_types[0]
            tm.user_id = uid
            tm.comment=a[0]
            tm.location_id=tm.comment.location_id
            tm.save()
            tms[tm.id] = UR.model2dict(tm)
    retval["locations"], html5 = annotations.getLocation(a[0].location_id)
    if (html5 is not None):
        retval["html5locations"]=html5
    retval["comments"] = {}
    retval["tags"] = {}
    for annotation in a:
        retval["comments"].update(annotations.getComment(annotation.id, uid))
        retval["tags"].update(annotations.getTagsByComment(annotation.id))
    retval["threadmarks"] =  tms
    return UR.prepare_response(retval)
Esempio n. 17
0
def save_settings(payload, req):
    uid = UR.getUserId(req)
    if uid is None:
        return UR.prepare_response({}, 1, "NOT ALLOWED")
    else:
        return UR.prepare_response(
            {"settings": annotations.save_settings(uid, payload)})
Esempio n. 18
0
def set_location_section(P, req):
    uid = UR.getUserId(req)
    if not auth.canAdministrateLocation(uid, P["id_location"]):
        return UR.prepare_response({}, 1, "NOT ALLOWED")
    result = annotations.setLocationSection(P["id_location"], P["id_section"])
    locations, html5locations = annotations.getLocation(result.pk)
    return UR.prepare_response(locations)
Esempio n. 19
0
def getMembers(payload, req):
    uid = UR.getUserId(req)
    if "id_ensemble" in payload:
        if auth.canGetMembers(uid, payload["id_ensemble"]):
            return UR.prepare_response(
                annotations.get_members(payload["id_ensemble"]))
    return UR.prepare_response({}, 1, "NOT ALLOWED")
Esempio n. 20
0
def deleteThread(payload, req):
    uid = UR.getUserId(req)
    if not auth.canDeleteThread(uid, payload["id_location"]):
        return UR.prepare_response({}, 1, "NOT ALLOWED")
    else:
        annotations.deleteThread(payload)
        return UR.prepare_response({"id_location": payload["id_location"]})
Esempio n. 21
0
def serve_img(req, res, scale, id_source):
    #print "img request of page %s of file %s at res %s and scale %s w/ invite_key=%s and req=%s" % (req.GET["page"], id_file, res, scale, req.GET["invite_key"], req  )
    #TODO: check permissions. 
    uid = UR.getUserId(req);
    if not auth.canReadFile(uid, id_source): 
        return HttpResponse("Error: You don't have credentials to see this file %s " % (id_source,))
    page = int(req.GET["page"])-1
    page_str =  settings.IMG_FMT_STRING %  (page,)
    filename = req.META["PATH_INFO"].rstrip('/')
    filename = "%s_%s.png" % (filename, page_str)
    response = None
    try: 
        response = serve(req, filename,settings.HTTPD_MEDIA_CACHE)
        return response
    except Http404: 
        #let's generate on demand
        try: 
            pdf_dir =  "%s/%s" % (settings.HTTPD_MEDIA,settings.REPOSITORY_DIR)
            img_dir =  "%s/%s" % (settings.HTTPD_MEDIA_CACHE,settings.CACHE_DIR)
            process_page(id_source, page,  res, scale, pdf_dir, img_dir, settings.IMG_FMT_STRING)
            response = serve(req, filename,settings.HTTPD_MEDIA_CACHE)
            return response
        except Http404:             
            basedir = dirname(dirname(dirname(abspath(__file__))))
            #TODO: would be better to do a redirect to the not_available page
            f = open("%s/content/data/icons/png/not_available.png" % basedir)
            s = f.read()
            f.close()
        return HttpResponse(s)
Esempio n. 22
0
def set_grade_assignment(P, req):
    uid = UR.getUserId(req)
    if not auth.canGrade(uid, P["id_source"], P["id_user"]):
        return UR.prepare_response({}, 1,  "NOT ALLOWED")
    retval = {}
    retval["grades"] = annotations.set_grade_assignment(uid, {"id_source": P["id_source"], "id_user":  P["id_user"], "grade": P["grade"]})
    return UR.prepare_response(retval)
Esempio n. 23
0
def presearch(payload, req):
    #cid = req.getConnectionId()
    cid = UR.CID
    uid = UR.getUserId(req);
    id_search = annotations.save_presearch(cid, payload)
    output = annotations.presearch(uid, id_search, payload) #{"total": 130, "items": "blahblah"}
    return UR.prepare_response(output)
Esempio n. 24
0
def delete_file(P, req): 
    #this method is used to rename both files and folders. 
    uid = UR.getUserId(req)
    f_auth = auth.canDeleteFile if P["item_type"]=="file" else auth.canDeleteFolder
    if not f_auth(uid, P["id"]):
        return UR.prepare_response({}, 1,  "NOT ALLOWED")
    return UR.prepare_response({"id": annotations.delete_file(uid, P)}) #special form since file isn't in there anymore
Esempio n. 25
0
def getHTML5Info(payload, req):
    if "url" not in payload:
        return UR.prepare_response({}, 1, "missing url !")
    url = payload["url"].partition("#")[0].rstrip("/") # remove hash part of the URL by default, as well as trailing slash.
    #TODO: use optional argument id_ensemble to disambiguate if provided.
    sources_info = M.HTML5Info.objects.filter(url=url)
    ownerships =  M.Ownership.objects.select_related("source", "ensemble", "folder").filter(source__html5info__in=sources_info, deleted=False)
    #TODO: with django 1.9, you can use Q objects to OR two conditions
    #so instead of iterating to test below, just add .filter(Q(ensemble__memberships__user=UR.getUserId(req)) | Q(ensemble.allow_guest))
    #then use UR.qs2dict as was done previously

    if not ownerships.exists():
        return UR.prepare_response({}, 1, "this URL is not recognized: ")

    output = {
        "files": {},
        "ensembles": {},
        "folders": {}
        }
    for r in ownerships:
        if (r.ensemble.allow_guest or 
            auth.isMember(UR.getUserId(req),r.ensemble_id)):
            output["ensembles"][r.ensemble_id]=UR.model2dict(r,annotations.__NAMES["ensembles2"])
            output["files"][r.source_id]=UR.model2dict(r,annotations.__NAMES["files2"])
            output["folders"][r.folder_id]=UR.model2dict(r,annotations.__NAMES["folders2"])
    if (output["ensembles"]):
        return UR.prepare_response(output)
    else:
        return  UR.prepare_response({}, 1, "not allowed: guest access isn't allowed for this file.")
Esempio n. 26
0
def delete_file(P, req): 
    #this method is used to rename both files and folders. 
    uid = UR.getUserId(req)
    f_auth = auth.canDeleteFile if P["item_type"]=="file" else auth.canDeleteFolder
    if not f_auth(uid, P["id"]):
        return UR.prepare_response({}, 1,  "NOT ALLOWED")
    return UR.prepare_response({"id": annotations.delete_file(uid, P)}) #special form since file isn't in there anymore
Esempio n. 27
0
def rename_file(P, req): 
    #this method is used to rename both files and folders. 
    uid = UR.getUserId(req)
    f_auth = auth.canRenameFile if P["item_type"]=="file" else auth.canRenameFolder
    if not f_auth(uid, P["id"]):
        return UR.prepare_response({}, 1,  "NOT ALLOWED")
    return UR.prepare_response({P["item_type"]+"s": annotations.rename_file(uid, P)})
Esempio n. 28
0
def serve_grades_spreadsheet(req, id_ensemble):
    uid = UR.getUserId(req)
    if not auth.canSeeGrades(uid, id_ensemble):
        return HttpResponse(
            "Error: You don't have credentials to see grades for class %s" %
            (id_ensemble, ))
    import xlwt
    wbk = xlwt.Workbook()

    #first, generate the sheets with comment, words, char counts:
    stats = add_count_sheets(id_ensemble, wbk)

    #now add a sheet for labeled comments if there are any:
    add_labeledcomments_sheet(uid, id_ensemble, wbk)

    #now add sheets for the social graph
    # FIXME: this is broken for ensemble 6010 on nb.mit.edu. Disabling for now.
    # https://github.com/nbproject/nbproject/issues/199
    #add_socialgraph_sheets(id_ensemble, stats["users"], wbk)

    import datetime
    a = datetime.datetime.now()
    fn = "stats_%s_%04d%02d%02d_%02d%02d.xls" % (id_ensemble, a.year, a.month,
                                                 a.day, a.hour, a.minute)
    wbk.save("/tmp/%s" % (fn, ))
    response = serve(req, fn, "/tmp/")
    os.remove("/tmp/%s" % (fn, ))
    response["Content-Type"] = 'application/vnd.ms-excel'
    response['Content-Disposition'] = "attachment; filename=%s" % (fn, )
    return response
Esempio n. 29
0
def set_comment_label(P, req):
    uid = UR.getUserId(req)
    cid = P["comment_id"]
    if not auth.canLabelComment(uid, cid):
        return UR.prepare_response({}, 1,  "NOT ALLOWED")
    record = None
    try: 
        record = M.CommentLabel.objects.get(grader__id=uid, comment__id=cid, category_id=P["category_id"])
        rh = M.CommentLabelHistory()        
        rh.grader = record.grader
        rh.ctime = record.ctime
        rh.grade = record.grade
        rh.category = record.category
        rh.comment = record.comment
        rh.save()
        record.ctime = datetime.datetime.now()
    except M.CommentLabel.DoesNotExist: 
        record = M.CommentLabel()
        record.category_id = P["category_id"]
        record.comment_id = cid
    record.grade = P["grade"]
    record.grader_id = uid
    record.save()
    retval = {"commentlabels":{record.id: UR.model2dict(record)}}
    return UR.prepare_response(retval)    
Esempio n. 30
0
def saveNote(payload, req):
    uid = UR.getUserId(req)
    if not auth.canAnnotate(uid, payload["id_ensemble"]):
        return UR.prepare_response({}, 1, "NOT ALLOWED")
    payload["id_author"] = uid
    retval = {}
    a = annotations.addNote(payload)
    if len(a) == 0:
        return UR.prepare_response({}, 2, "DUPLICATE")
    tms = {}
    for mark in payload["marks"]:
        tm = M.ThreadMark()
        m_types = [c[0] for c in tm.TYPES if c[1] == mark]
        if len(
                m_types
        ):  #old clients may return types we don't have in DB so ignore them
            tm.type = m_types[0]
            tm.user_id = uid
            tm.comment = a[0]
            tm.location_id = tm.comment.location_id
            tm.save()
            tms[tm.id] = UR.model2dict(tm)
    retval["locations"], html5 = annotations.getLocation(a[0].location_id)
    if (html5 is not None):
        retval["html5locations"] = html5
    retval["comments"] = {}
    retval["tags"] = {}
    for annotation in a:
        retval["comments"].update(annotations.getComment(annotation.id, uid))
        retval["tags"].update(annotations.getTagsByComment(annotation.id))
    retval["threadmarks"] = tms
    return UR.prepare_response(retval)
Esempio n. 31
0
def get_class_settings(payload, req):
    uid = UR.getUserId(req)
    if "id_ensemble" in payload:
        if auth.canGetMembers(uid, payload["id_ensemble"]):
            class_settings = annotations.get_class_settings(uid, payload)
            return UR.prepare_response(class_settings)
    return UR.prepare_response({}, 1, "NOT ALLOWED")
Esempio n. 32
0
def get_stats_ensemble(payload, req): 
    uid = UR.getUserId(req)
    id_ensemble = payload["id_ensemble"]
    if not auth.canSeeGrades(uid, id_ensemble):
        return UR.prepare_response({}, 1,  "NOT ALLOWED")
    retval = annotations.get_stats_ensemble(payload)
    return UR.prepare_response(retval)
Esempio n. 33
0
def serve_img(req, res, scale, id_source):
    #print "img request of page %s of file %s at res %s and scale %s w/ invite_key=%s and req=%s" % (req.GET["page"], id_file, res, scale, req.GET["invite_key"], req  )
    #TODO: check permissions.
    uid = UR.getUserId(req)
    if not auth.canReadFile(uid, id_source):
        return HttpResponse(
            "Error: You don't have credentials to see this file %s " %
            (id_source, ))
    page = int(req.GET["page"]) - 1
    page_str = settings.IMG_FMT_STRING % (page, )
    filename = req.META["PATH_INFO"].rstrip('/')
    filename = "%s_%s.png" % (filename, page_str)
    response = None
    try:
        response = serve(req, filename, settings.HTTPD_MEDIA_CACHE)
        return response
    except Http404:
        #let's generate on demand
        try:
            pdf_dir = "%s/%s" % (settings.HTTPD_MEDIA, settings.REPOSITORY_DIR)
            img_dir = "%s/%s" % (settings.HTTPD_MEDIA_CACHE,
                                 settings.CACHE_DIR)
            process_page(id_source, page, res, scale, pdf_dir, img_dir,
                         settings.IMG_FMT_STRING)
            response = serve(req, filename, settings.HTTPD_MEDIA_CACHE)
            return response
        except Http404:
            basedir = dirname(dirname(dirname(abspath(__file__))))
            #TODO: would be better to do a redirect to the not_available page
            f = open("%s/content/data/icons/png/not_available.png" % basedir)
            s = f.read()
            f.close()
        return HttpResponse(s)
Esempio n. 34
0
def rename_file(P, req): 
    #this method is used to rename both files and folders. 
    uid = UR.getUserId(req)
    f_auth = auth.canRenameFile if P["item_type"]=="file" else auth.canRenameFolder
    if not f_auth(uid, P["id"]):
        return UR.prepare_response({}, 1,  "NOT ALLOWED")
    return UR.prepare_response({P["item_type"]+"s": annotations.rename_file(uid, P)})
Esempio n. 35
0
def presearch(payload, req):
    #cid = req.getConnectionId()
    cid = UR.CID
    uid = UR.getUserId(req);
    id_search = annotations.save_presearch(cid, payload)
    output = annotations.presearch(uid, id_search, payload) #{"total": 130, "items": "blahblah"}
    return UR.prepare_response(output)
Esempio n. 36
0
def update_ensemble(P, req):
    uid = UR.getUserId(req)
    eid = P["id_ensemble"]
    if uid is None or eid is None:
        return UR.prepare_response({}, 1, "NOT ALLOWED")
    ensemble = M.Ensemble.objects.get(pk=eid)
    if "name" in P:
        ensemble.name = P["name"]
    if "description" in P:
        ensemble.description = P["description"]
    if "allow_staffonly" in P:
        ensemble.allow_staffonly = P["allow_staffonly"]
    if "allow_anonymous" in P:
        ensemble.allow_anonymous = P["allow_anonymous"]
    if "allow_tag_private" in P:
        ensemble.allow_tag_private = P["allow_tag_private"]
    if "allow_guest" in P:
        ensemble.allow_guest = P["allow_guest"]
    if "use_invitekey" in P:
        ensemble.use_invitekey = P["use_invitekey"]
    if "allow_download" in P:
        ensemble.allow_download = P["allow_download"]
    if "allow_ondemand" in P:
        ensemble.allow_ondemand = P["allow_ondemand"]
    if "default_pause" in P:
        ensemble.default_pause = P["default_pause"]
    if "section_assignment" in P:
        ensemble.section_assignment = P["section_assignment"]
    if "metadata" in P:
        ensemble.metadata = P["metadata"]
    ensemble.save()
    return UR.prepare_response(
        annotations.get_class_settings(uid, {"id_ensemble": P["id_ensemble"]}))
Esempio n. 37
0
def deleteNote(payload, req): 
    uid = UR.getUserId(req)
    #print "trying  to delete %s" %( payload["id_comment"],)
    if not auth.canDelete(uid,  payload["id_comment"]):
        return UR.prepare_response({}, 1,  "NOT ALLOWED")
    else:
        annotations.deleteNote(payload)
        return UR.prepare_response({"id_comment": payload["id_comment"] })
Esempio n. 38
0
def add_folder(payload, req): 
    uid = UR.getUserId(req)
    id_ensemble = payload["id_ensemble"]
    id_parent = payload["id_parent"]
    if not auth.canAddFolder(uid, id_ensemble, id_parent):
        return UR.prepare_response({}, 1,  "NOT ALLOWED")
    id_folder = annotations.create_folder(id_ensemble, id_parent, payload["name"])
    return UR.prepare_response(annotations.get_folders(uid, {"id": id_folder}))
Esempio n. 39
0
def add_folder(payload, req): 
    uid = UR.getUserId(req)
    id_ensemble = payload["id_ensemble"]
    id_parent = payload["id_parent"]
    if not auth.canAddFolder(uid, id_ensemble, id_parent):
        return UR.prepare_response({}, 1,  "NOT ALLOWED")
    id_folder = annotations.create_folder(id_ensemble, id_parent, payload["name"])
    return UR.prepare_response(annotations.get_folders(uid, {"id": id_folder}))
Esempio n. 40
0
def move_file(P, req):
    uid = UR.getUserId(req)
    f_auth = auth.canMoveFile if P[
        "item_type"] == "file" else auth.canMoveFolder
    if not f_auth(uid, P["id"], P["dest"]):
        return UR.prepare_response({}, 1, "NOT ALLOWED")
    return UR.prepare_response(
        {P["item_type"] + "s": annotations.move_file(uid, P)})
Esempio n. 41
0
def editNote(payload, req): 
    uid = UR.getUserId(req)
    if not auth.canEdit(uid,  payload["id_comment"]):
        return UR.prepare_response({}, 1,  "NOT ALLOWED")
    else:
        annotations.editNote(payload)
    #no need to worry about threadmarks: they can't be changed from an "edit-mode" editor        
    return UR.prepare_response({"comments":  annotations.getComment(payload["id_comment"], uid)})
Esempio n. 42
0
def get_section_participants(payload, req):
    uid = UR.getUserId(req)
    if "id_ensemble" in payload:
        if auth.canGetMembers(uid, payload["id_ensemble"]):
            section_participants = annotations.get_section_participants(
                uid, payload)
            return UR.prepare_response(section_participants)
    return UR.prepare_response({}, 1, "NOT ALLOWED")
Esempio n. 43
0
def editPoll(payload, req):
    uid = UR.getUserId(req)
    if uid is None or ("id_poll"
                       not in payload) or not annotations.canEditPoll(
                           uid, payload["id_poll"]):
        return UR.prepare_response({}, 1, "NOT ALLOWED")
    annotations.editPoll(uid, payload)
    return UR.prepare_response({})
Esempio n. 44
0
def deleteNote(payload, req): 
    uid = UR.getUserId(req)
    #print "trying  to delete %s" %( payload["id_comment"],)
    if not auth.canDelete(uid,  payload["id_comment"]):
        return UR.prepare_response({}, 1,  "NOT ALLOWED")
    else:
        annotations.deleteNote(payload)
        return UR.prepare_response({"id_comment": payload["id_comment"] })
Esempio n. 45
0
def editNote(payload, req): 
    uid = UR.getUserId(req)
    if not auth.canEdit(uid,  payload["id_comment"]):
        return UR.prepare_response({}, 1,  "NOT ALLOWED")
    else:
        annotations.editNote(payload)
    #no need to worry about threadmarks: they can't be changed from an "edit-mode" editor        
    return UR.prepare_response({"comments":  annotations.getComment(payload["id_comment"], uid)})
Esempio n. 46
0
def getMyNotes(payload, req): 
    uid = UR.getUserId(req)
    if uid is None or payload.get("query") not in __AVAILABLE_STATS: 
        return UR.prepare_response({}, 1,  "NOT ALLOWED")
    else:
        output= getattr(annotations, "get_comments_"+payload.get("query"))(uid, payload)
        #referer = None if "referer" not in req.META else  req.META["referer"]
        #TODO annotations.addCollageHistory(uid, referer, query)        
        return UR.prepare_response(output)
Esempio n. 47
0
def getGuestFileInfo(payload, req):
    if "id_source" not in payload: 
        return UR.prepare_response({}, 1, "missing id_source  !")
    id_source = payload["id_source"]
    output =  annotations.get_guestfileinfo(id_source)
    for i in output["ensembles"]: 
        if  not (output["ensembles"][i]["allow_guest"] or  auth.isMember(UR.getUserId(req), i)): 
            return  UR.prepare_response({}, 1, "not allowed: guest access isn't allowed for this file.")
    return UR.prepare_response(output)
Esempio n. 48
0
def bulk_import_annotations(P, req):
    uid = UR.getUserId(req)
    if not auth.canImportAnnotation(uid, P["from_source_id"],
                                    P["to_source_id"]):
        return UR.prepare_response({}, 1, "NOT ALLOWED")
    return UR.prepare_response(
        annotations.bulkImportAnnotations(P["from_source_id"],
                                          P["to_source_id"], P["locs_array"],
                                          P["import_type"]))
Esempio n. 49
0
def getMyNotes(payload, req): 
    uid = UR.getUserId(req)
    if uid is None or payload.get("query") not in __AVAILABLE_STATS: 
        return UR.prepare_response({}, 1,  "NOT ALLOWED")
    else:
        output= getattr(annotations, "get_comments_"+payload.get("query"))(uid, payload)
        #referer = None if "referer" not in req.META else  req.META["referer"]
        #TODO annotations.addCollageHistory(uid, referer, query)        
        return UR.prepare_response(output)
Esempio n. 50
0
def get_location_info(payload, req): 
    id = payload["id"]
    uid = UR.getUserId(req);
    #SACHA TODO: check I'm allowed to know this
    retval={}
    retval["locations"], retval["html5locations"] = annotations.getLocation(id)
    if "org" in payload:
        annotations.logDirectURL(uid, id, payload["org"])
    return UR.prepare_response(retval)
Esempio n. 51
0
def getGuestFileInfo(payload, req):
    if "id_source" not in payload: 
        return UR.prepare_response({}, 1, "missing id_source  !")
    id_source = payload["id_source"]
    output =  annotations.get_guestfileinfo(id_source)
    for i in output["ensembles"]: 
        if  not (output["ensembles"][i]["allow_guest"] or  auth.isMember(UR.getUserId(req), i)): 
            return  UR.prepare_response({}, 1, "not allowed: guest access isn't allowed for this file.")
    return UR.prepare_response(output)
Esempio n. 52
0
def get_location_info(payload, req): 
    id = payload["id"]
    uid = UR.getUserId(req);
    #SACHA TODO: check I'm allowed to know this
    retval={}
    retval["locations"], retval["html5locations"] = annotations.getLocation(id)
    if "org" in payload:
        annotations.logDirectURL(uid, id, payload["org"])
    return UR.prepare_response(retval)
Esempio n. 53
0
def markNote(payload, req):
    uid = UR.getUserId(req)
    id_comment =  payload["id_comment"]
    if not auth.canMark(uid,id_comment ):
        return UR.prepare_response({}, 1,  "NOT ALLOWED")
    else: 
        annotations.markNote(uid, payload);        
        comments = annotations.getComment(id_comment,uid)
        p = {"locations":annotations.getLocation(comments[int(id_comment)]["ID_location"]), "marks": annotations.getMark(uid, payload), "comments": comments}
        return UR.prepare_response(p)
Esempio n. 54
0
def getSectionsInfo(payload, req): 
    uid = UR.getUserId(req)
    if "id_ensemble" not in payload: 
        return UR.prepare_response({}, 1, "MISSING id_ensemble")
    id_ensemble = payload["id_ensemble"]
    if auth.canGetSectionsInfo(uid, id_ensemble):  
        m = M.Membership.objects.filter(user__id=uid, ensemble__id=id_ensemble, deleted=False)
        output={"sections": UR.qs2dict(m[0].ensemble.section_set.all())};
        return UR.prepare_response(output)
    return UR.prepare_response({}, 1, "NOT ALLOWED")
Esempio n. 55
0
def approveNote(payload, req):
    uid = UR.getUserId(req)
    id_comment =  payload["id_comment"]
    if not auth.canApprove(uid,id_comment ):
        return UR.prepare_response({}, 1,  "NOT ALLOWED")
    else: 
        annotations.approveNote(uid, payload);        
        p = {"comments":annotations.getComment(id_comment,uid) }
        return UR.prepare_response(p)
        annotations.addApproveHistory(uid, payload)
Esempio n. 56
0
def approveNote(payload, req):
    uid = UR.getUserId(req)
    id_comment =  payload["id_comment"]
    if not auth.canApprove(uid,id_comment ):
        return UR.prepare_response({}, 1,  "NOT ALLOWED")
    else: 
        annotations.approveNote(uid, payload);        
        p = {"comments":annotations.getComment(id_comment,uid) }
        return UR.prepare_response(p)
        annotations.addApproveHistory(uid, payload)
Esempio n. 57
0
def sendInvites(payload, req):
    from django.core import mail
    from django.core.mail import EmailMessage
    uid = UR.getUserId(req);
    id_ensemble = payload["id_ensemble"]
    id_section = payload.get("id_section", None)
    admin = 0 if "admin" not in payload else payload["admin"]
    if not auth.canSendInvite(uid,id_ensemble):
        return UR.prepare_response({}, 1,  "NOT ALLOWED")
    #extract emails in a somewhat robust fashion (i.e. using several possible delimiters)
    emails = parseEntities(payload["to"], [",", "\n", " "])
    #remove spurious stuff: strings that don't have an "@" and trailings "<" and ">" characters,
    #because some emails the following format: John Doe <*****@*****.**>
    emails = [o.replace("<", "").replace(">", "") for o in emails if "@" in o]
    logging.info("to: %s, extracted: %s" %  (payload["to"], emails))
    #add new users to DB w/ pending status
    connection = mail.get_connection()
    emailmessages = []
    for email in emails:
        user = auth.user_from_email(email)
        password=""
        if user is None:
            ckey = "".join([ random.choice(string.ascii_letters+string.digits) for i in xrange(0,32)])
            password = "".join([ random.choice(string.ascii_letters+string.digits) for i in xrange(0,4)])
            user = auth.addUser(email, password, ckey)
        invite_key      = "".join([ random.choice(string.ascii_letters+string.digits) for i in xrange(0,50)])
        auth.addInvite(invite_key, user.id, id_ensemble, id_section, admin)
        link = "http://%s/confirm_invite?invite_key=%s" % (settings.HOSTNAME, invite_key,)
        ensemble = M.Ensemble.objects.get(pk=id_ensemble)

        p = {
            "name": ensemble.name,
            "description": ensemble.description,
            "link": link,
            "contact": user.firstname if user.firstname != None else user.email
        }

        if payload["msg"] != "":
            p["msg_perso"] = payload["msg"]

        # TODO: We still include the password in the e-mail, should we stop doing that?
        if password != "":
            p["password"] = password
            p["email"] = email
        msg = render_to_string("email/msg_invite",p)
        bcc = [] if settings.SMTP_CC_USER is None else (settings.SMTP_CC_USER,)
        e = EmailMessage("You're invited on the %s channel !" % (p["name"],),
                         msg,
                         settings.EMAIL_FROM,
                         (email, ),
                         bcc,connection=connection)
        emailmessages.append(e)
        #time.sleep(SLEEPTIME) #in order not to stress out the email server
    connection.send_messages(emailmessages)
    return UR.prepare_response({"msg": "Invite for %s sent to %s" % (ensemble.name, emails,)})
Esempio n. 58
0
def editNote(payload, req): 
    uid = UR.getUserId(req)
    if not auth.canEdit(uid,  payload["id_comment"]):
        return UR.prepare_response({}, 1,  "NOT ALLOWED")
    else:
        annotations.editNote(payload)
        #for mark in payload["marks"]:
        #    annotations.markNote(uid, {"action": payload["marks"][mark], "id_comment": payload["id_comment"]})
        return UR.prepare_response({"comments":  annotations.getComment(payload["id_comment"], uid), 
                   "marks": annotations.getMark(uid,{"id_comment":  payload["id_comment"]}) 
                   })
Esempio n. 59
0
def markThread(payload, req):
    uid = UR.getUserId(req)
    id_location =  payload["id_location"]
    if not auth.canMarkThread(uid,id_location ):
        return UR.prepare_response({}, 1,  "NOT ALLOWED")
    else: 
        mark = annotations.markThread(uid, payload);
        tms = {}
        tms[mark["id"]] = mark                
        p = {"threadmarks": tms}
        return UR.prepare_response(p)
Esempio n. 60
0
def get_comment_info(payload, req): 
    id = int(payload["id"])
    uid = UR.getUserId(req);
    #SACHA TODO: check I'm allowed to know this
    retval={}
    comments = annotations.getComment(id, uid)
    id_location = comments[id]["ID_location"]
    retval["comments"] = {id: {"ID": id, "ID_location": id_location}} #share only what's needed
    #print retval["comments"]
    retval["locations"] , retval["html5locations"] = annotations.getLocation( id_location)
    if "org" in payload:
        annotations.logDirectURL(uid, id, payload["org"])
    return UR.prepare_response(retval)