def collections_post_api(request, user_id, slug=None): if request.method == "POST": j = request.POST.get("json") if not j: return jsonResponse({"error": "No JSON given in post data."}) collection_data = json.loads(j) if "slug" in collection_data: collection = Collection().load({"slug": collection_data["slug"]}) if not collection: return jsonResponse({ "error": "Collection with slug `{}` not found.".format( collection["slug"]) }) # check poster is a collection admin if user_id not in collection.admins: return jsonResponse({ "error": "You do not have permission to edit this collection." }) collection.load_from_dict(collection_data) collection.save() else: collection_data["admins"] = [user_id] collection = Collection(collection_data) collection.save() return jsonResponse({ "status": "ok", "collection": collection.listing_contents(request.user.id) }) elif request.method == "DELETE": if not slug: return jsonResponse( {"error": "Please specify a collection in the URL."}) existing = Collection().load({"slug": slug}) if existing: if user_id not in existing.admins: return jsonResponse({ "error": "You do not have permission to delete this collection." }) else: CollectionSet({"slug": slug}).delete() return jsonResponse({"status": "ok"}) else: return jsonResponse({ "error": "Collection with the slug `{}` does not exist".format(slug) }) else: return jsonResponse({"error": "Unsupported HTTP method."})
def get_sheet_for_panel(id=None): sheet = get_sheet(id) if "error" in sheet: return sheet if "assigner_id" in sheet: asignerData = public_user_data(sheet["assigner_id"]) sheet["assignerName"] = asignerData["name"] if "viaOwner" in sheet: viaOwnerData = public_user_data(sheet["viaOwner"]) sheet["viaOwnerName"] = viaOwnerData["name"] ownerData = public_user_data(sheet["owner"]) sheet["ownerName"] = ownerData["name"] sheet["ownerProfileUrl"] = public_user_data(sheet["owner"])["profileUrl"] sheet["ownerImageUrl"] = public_user_data(sheet["owner"])["imageUrl"] sheet["naturalDateCreated"] = naturaltime(datetime.strptime(sheet["dateCreated"], "%Y-%m-%dT%H:%M:%S.%f")) sheet["sources"] = annotate_user_links(sheet["sources"]) sheet["topics"] = add_langs_to_topics(sheet.get("topics", [])) if "displayedCollection" in sheet: collection = Collection().load({"slug": sheet["displayedCollection"]}) if collection: sheet["collectionImage"] = getattr(collection, "imageUrl", None) sheet["collectionName"] = collection.name else: del sheet["displayedCollection"] return sheet
def collections_role_api(request, slug, uid, role): """ API for setting a collection members role, or removing them from a collection. """ if request.method != "POST": return jsonResponse({"error": "Unsupported HTTP method."}) collection = Collection().load({"slug": slug}) if not collection: return jsonResponse({"error": "No collection with slug `{}`.".format(slug)}) uid = int(uid) if request.user.id not in collection.admins: if not (uid == request.user.id and role == "remove"): # non admins can remove themselves return jsonResponse({"error": "You must be a collection owner to change contributor roles."}) user = UserProfile(id=uid) if not user.exists(): return jsonResponse({"error": "No user with the specified ID exists."}) if role not in ("member", "publisher", "admin", "remove"): return jsonResponse({"error": "Unknown collection contributor role."}) if uid == request.user.id and collection.admins == [request.user.id] and role != "admin": return jsonResponse({"error": _("Leaving this collection would leave it without any owners. Please appoint another owner before leaving, or delete the collection.")}) if role == "remove": collection.remove_member(uid) else: collection.add_member(uid, role) collection_content = collection.contents(with_content=True, authenticated=True) return jsonResponse(collection_content)
def view_sheet(request, sheet_id, editorMode = False): """ View the sheet with sheet_id. """ editor = request.GET.get('editor', '0') embed = request.GET.get('embed', '0') if editor != '1' and embed !='1' and editorMode is False: return catchall(request, sheet_id, True) sheet_id = int(sheet_id) sheet = get_sheet(sheet_id) if "error" in sheet and sheet["error"] != "Sheet updated.": return HttpResponse(sheet["error"]) sheet["sources"] = annotate_user_links(sheet["sources"]) # Count this as a view db.sheets.update({"id": sheet_id}, {"$inc": {"views": 1}}) try: owner = User.objects.get(id=sheet["owner"]) author = owner.first_name + " " + owner.last_name except User.DoesNotExist: author = "Someone Mysterious" sheet_class = make_sheet_class_string(sheet) sheet_collections = get_user_collections_for_sheet(request.user.id, sheet_id) if sheet["owner"] == request.user.id else None displayed_collection = Collection().load({"slug": sheet["displayedCollection"]}) if sheet.get("displayedCollection", None) else None embed_flag = "embed" in request.GET likes = sheet.get("likes", []) like_count = len(likes) if request.user.is_authenticated: can_edit_flag = can_edit(request.user, sheet) can_add_flag = can_add(request.user, sheet) viewer_is_liker = request.user.id in likes else: can_edit_flag = False can_add_flag = False viewer_is_liker = False canonical_url = request.get_full_path().replace("?embed=1", "").replace("&embed=1", "") return render_template(request,'sheets.html', None, { "sheetJSON": json.dumps(sheet), "sheet": sheet, "sheet_class": sheet_class, "can_edit": can_edit_flag, "can_add": can_add_flag, "title": sheet["title"], "author": author, "is_owner": request.user.id == sheet["owner"], "sheet_collections": sheet_collections, "displayed_collection": displayed_collection, "like_count": like_count, "viewer_is_liker": viewer_is_liker, "current_url": request.get_full_path, "canonical_url": canonical_url, "assignments_from_sheet":assignments_from_sheet(sheet_id), })
def collections_get_api(request, slug=None): if not slug: return jsonResponse(CollectionSet.get_collection_listing(request.user.id)) collection_obj = Collection().load({"slug": unquote(slug)}) if not collection_obj: return jsonResponse({"error": "No collection with slug '{}'".format(slug)}) is_member = request.user.is_authenticated and collection_obj.is_member(request.user.id) collection_content = collection_obj.contents(with_content=True, authenticated=is_member) return jsonResponse(collection_content)
def collections_pin_sheet_api(request, slug, sheet_id): if request.method != "POST": return jsonResponse({"error": "Unsupported HTTP method."}) collection = Collection().load({"slug": slug}) if not collection: return jsonResponse({"error": "No collection with slug `{}`.".format(slug)}) if not collection.is_member(request.user.id): return jsonResponse({"error": "You must be a collection editor to pin sheets."}) sheet_id = int(sheet_id) collection.pin_sheet(sheet_id) collection_content = collection.contents(with_content=True, authenticated=True) del collection_content["lastModified"] return jsonResponse({"collection": collection_content, "status": "success"})
def collections_inclusion_api(request, slug, action, sheet_id): """ API for adding or removing a sheet from a collection """ if request.method != "POST": return jsonResponse({"error": "Unsupported HTTP method."}) collection = Collection().load({"slug": slug}) if not collection: return jsonResponse({"error": "No collection with slug `{}`.".format(slug)}) if not collection.is_member(request.user.id): return jsonResponse({"error": "Only members of this collection my change its contents."}) sheet_id = int(sheet_id) sheet = db.sheets.find_one({"id": sheet_id}) if not sheet: return jsonResponse({"error": "No sheet with id {}.".format(sheet_id)}) if action == "remove": if sheet_id in collection.sheets: collection.sheets.remove(sheet_id) if request.user.id == sheet["owner"] and sheet.get("displayedCollection", None) == collection.slug: sheet["displayedCollection"] = None db.sheets.find_one_and_replace({"id": sheet["id"]}, sheet) else: return jsonResponse({"error": "Sheet with id {} is not in this collection.".format(sheet_id)}) if action == "add": if sheet_id not in collection.sheets: collection.sheets.append(sheet_id) # If a sheet's owner adds it to a collection, and the sheet is not highlighted # in another collection, set it to highlight this collection. if request.user.id == sheet["owner"] and not sheet.get("displayedCollection", None): sheet["displayedCollection"] = collection.slug db.sheets.find_one_and_replace({"id": sheet["id"]}, sheet) collection.save() is_member = request.user.is_authenticated and collection.is_member(request.user.id) sheet = get_sheet_for_panel(int(sheet_id)) sheet_listing = annotate_user_collections([sheet_to_dict(sheet)], request.user.id)[0] return jsonResponse({ "status": "ok", "action": action, "collectionListing": collection.listing_contents(request.user.id), "collection": collection.contents(with_content=True, authenticated=is_member), "sheet": sheet, "sheetListing": sheet_listing, })
def collections_invite_api(request, slug, uid_or_email, uninvite=False): """ API for adding or removing collection members, or collection invitations """ if request.method != "POST": return jsonResponse({"error": "Unsupported HTTP method."}) collection = Collection().load({"slug": slug}) if not collection: return jsonResponse( {"error": "No collection with slug {}.".format(slug)}) if request.user.id not in collection.admins: return jsonResponse( {"error": "You must be a collection owner to invite new members."}) user = UserProfile(email=uid_or_email) if not user.exists(): if uninvite: collection.remove_invitation(uid_or_email) message = "Invitation removed." else: collection.invite_member(uid_or_email, request.user.id) message = "Invitation sent." else: is_new_member = not collection.is_member(user.id) if is_new_member: collection.add_member(user.id) from sefaria.model.notification import Notification notification = Notification({"uid": user.id}) notification.make_collection_add(adder_id=request.user.id, collection_slug=collection.slug) notification.save() message = "Collection editor added." else: message = "%s is already a editor of this collection." % user.full_name collection_content = collection.contents(with_content=True, authenticated=True) del collection_content["lastModified"] return jsonResponse({"collection": collection_content, "message": message})
def get_sheets_for_ref(tref, uid=None, in_collection=None): """ Returns a list of sheets that include ref, formating as need for the Client Sidebar. If `uid` is present return user sheets, otherwise return public sheets. If `in_collection` (list of slugs) is present, only return sheets in one of the listed collections. """ oref = model.Ref(tref) # perform initial search with context to catch ranges that include a segment ref segment_refs = [r.normal() for r in oref.all_segment_refs()] query = {"expandedRefs": {"$in": segment_refs}} if uid: query["owner"] = uid else: query["status"] = "public" if in_collection: collections = CollectionSet({"slug": {"$in": in_collection}}) sheets_list = [collection.sheets for collection in collections] sheets_ids = [sheet for sublist in sheets_list for sheet in sublist] query["id"] = {"$in": sheets_ids} sheetsObj = db.sheets.find( query, { "id": 1, "title": 1, "owner": 1, "viaOwner": 1, "via": 1, "dateCreated": 1, "includedRefs": 1, "expandedRefs": 1, "views": 1, "topics": 1, "status": 1, "summary": 1, "attribution": 1, "assigner_id": 1, "likes": 1, "displayedCollection": 1, "options": 1 }).sort([["views", -1]]) sheetsObj.hint("expandedRefs_1") sheets = [s for s in sheetsObj] user_ids = list({s["owner"] for s in sheets}) django_user_profiles = User.objects.filter(id__in=user_ids).values( 'email', 'first_name', 'last_name', 'id') user_profiles = {item['id']: item for item in django_user_profiles} mongo_user_profiles = list( db.profiles.find({"id": { "$in": user_ids }}, { "id": 1, "slug": 1, "profile_pic_url_small": 1 })) mongo_user_profiles = {item['id']: item for item in mongo_user_profiles} for profile in user_profiles: try: user_profiles[profile]["slug"] = mongo_user_profiles[profile][ "slug"] except: user_profiles[profile]["slug"] = "/" try: user_profiles[profile][ "profile_pic_url_small"] = mongo_user_profiles[profile].get( "profile_pic_url_small", '') except: user_profiles[profile]["profile_pic_url_small"] = "" results = [] for sheet in sheets: anchor_ref_list, anchor_ref_expanded_list = oref.get_all_anchor_refs( segment_refs, sheet.get("includedRefs", []), sheet.get("expandedRefs", [])) ownerData = user_profiles.get( sheet["owner"], { 'first_name': 'Ploni', 'last_name': 'Almoni', 'email': '*****@*****.**', 'slug': 'Ploni-Almoni', 'id': None, 'profile_pic_url_small': '' }) if "assigner_id" in sheet: asignerData = public_user_data(sheet["assigner_id"]) sheet["assignerName"] = asignerData["name"] sheet["assignerProfileUrl"] = asignerData["profileUrl"] if "viaOwner" in sheet: viaOwnerData = public_user_data(sheet["viaOwner"]) sheet["viaOwnerName"] = viaOwnerData["name"] sheet["viaOwnerProfileUrl"] = viaOwnerData["profileUrl"] if "displayedCollection" in sheet: collection = Collection().load( {"slug": sheet["displayedCollection"]}) sheet["collectionTOC"] = getattr(collection, "toc", None) topics = add_langs_to_topics(sheet.get("topics", [])) for anchor_ref, anchor_ref_expanded in zip(anchor_ref_list, anchor_ref_expanded_list): sheet_data = { "owner": sheet["owner"], "_id": str(sheet["_id"]), "id": str(sheet["id"]), "public": sheet["status"] == "public", "title": strip_tags(sheet["title"]), "sheetUrl": "/sheets/" + str(sheet["id"]), "anchorRef": anchor_ref.normal(), "anchorRefExpanded": [r.normal() for r in anchor_ref_expanded], "options": sheet["options"], "collectionTOC": sheet.get("collectionTOC", None), "ownerName": ownerData["first_name"] + " " + ownerData["last_name"], "via": sheet.get("via", None), "viaOwnerName": sheet.get("viaOwnerName", None), "assignerName": sheet.get("assignerName", None), "viaOwnerProfileUrl": sheet.get("viaOwnerProfileUrl", None), "assignerProfileUrl": sheet.get("assignerProfileUrl", None), "ownerProfileUrl": "/profile/" + ownerData["slug"], "ownerImageUrl": ownerData.get('profile_pic_url_small', ''), "status": sheet["status"], "views": sheet["views"], "topics": topics, "likes": sheet.get("likes", []), "summary": sheet.get("summary", None), "attribution": sheet.get("attribution", None), "is_featured": sheet.get("is_featured", False), "category": "Sheets", # ditto "type": "sheet", # ditto } results.append(sheet_data) return results
def collection_link(collection_slug): c = Collection().load({"slug": collection_slug}) if not c: return mark_safe("[unknown collection: {}".format(collection_slug)) return mark_safe("<a href='/collections/{}'>{}</a>".format( collection_slug, c.name))
def annotate_collection(n, collection_slug): c = Collection().load({"slug": collection_slug}) n["content"]["collection_name"] = c.name