301 lines
7.7 KiB
Python
301 lines
7.7 KiB
Python
"""API methods for the LMS.
|
|
"""
|
|
|
|
import frappe
|
|
from frappe.translate import get_all_translations
|
|
from frappe import _
|
|
|
|
|
|
@frappe.whitelist()
|
|
def autosave_section(section, code):
|
|
"""Saves the code edited in one of the sections."""
|
|
doc = frappe.get_doc(
|
|
doctype="Code Revision", section=section, code=code, author=frappe.session.user
|
|
)
|
|
doc.insert()
|
|
return {"name": doc.name}
|
|
|
|
|
|
@frappe.whitelist()
|
|
def submit_solution(exercise, code):
|
|
"""Submits a solution.
|
|
|
|
@exerecise: name of the exercise to submit
|
|
@code: solution to the exercise
|
|
"""
|
|
ex = frappe.get_doc("LMS Exercise", exercise)
|
|
if not ex:
|
|
return
|
|
doc = ex.submit(code)
|
|
return {"name": doc.name, "creation": doc.creation}
|
|
|
|
|
|
@frappe.whitelist()
|
|
def save_current_lesson(course_name, lesson_name):
|
|
"""Saves the current lesson for a student/mentor."""
|
|
name = frappe.get_value(
|
|
doctype="LMS Enrollment",
|
|
filters={"course": course_name, "member": frappe.session.user},
|
|
fieldname="name",
|
|
)
|
|
if not name:
|
|
return
|
|
frappe.db.set_value("LMS Enrollment", name, "current_lesson", lesson_name)
|
|
|
|
|
|
@frappe.whitelist()
|
|
def join_cohort(course, cohort, subgroup, invite_code):
|
|
"""Creates a Cohort Join Request for given user."""
|
|
course_doc = frappe.get_doc("LMS Course", course)
|
|
cohort_doc = course_doc and course_doc.get_cohort(cohort)
|
|
subgroup_doc = cohort_doc and cohort_doc.get_subgroup(subgroup)
|
|
|
|
if not subgroup_doc or subgroup_doc.invite_code != invite_code:
|
|
return {"ok": False, "error": "Invalid join link"}
|
|
|
|
data = {
|
|
"doctype": "Cohort Join Request",
|
|
"cohort": cohort_doc.name,
|
|
"subgroup": subgroup_doc.name,
|
|
"email": frappe.session.user,
|
|
"status": "Pending",
|
|
}
|
|
# Don't insert duplicate records
|
|
if frappe.db.exists(data):
|
|
return {"ok": True, "status": "record found"}
|
|
else:
|
|
doc = frappe.get_doc(data)
|
|
doc.insert()
|
|
return {"ok": True, "status": "record created"}
|
|
|
|
|
|
@frappe.whitelist()
|
|
def approve_cohort_join_request(join_request):
|
|
r = frappe.get_doc("Cohort Join Request", join_request)
|
|
sg = r and frappe.get_doc("Cohort Subgroup", r.subgroup)
|
|
if not sg or r.status not in ["Pending", "Accepted"]:
|
|
return {"ok": False, "error": "Invalid Join Request"}
|
|
if (
|
|
not sg.is_manager(frappe.session.user) and "System Manager" not in frappe.get_roles()
|
|
):
|
|
return {"ok": False, "error": "Permission Deined"}
|
|
|
|
r.status = "Accepted"
|
|
r.save()
|
|
return {"ok": True}
|
|
|
|
|
|
@frappe.whitelist()
|
|
def reject_cohort_join_request(join_request):
|
|
r = frappe.get_doc("Cohort Join Request", join_request)
|
|
sg = r and frappe.get_doc("Cohort Subgroup", r.subgroup)
|
|
if not sg or r.status not in ["Pending", "Rejected"]:
|
|
return {"ok": False, "error": "Invalid Join Request"}
|
|
if (
|
|
not sg.is_manager(frappe.session.user) and "System Manager" not in frappe.get_roles()
|
|
):
|
|
return {"ok": False, "error": "Permission Deined"}
|
|
|
|
r.status = "Rejected"
|
|
r.save()
|
|
return {"ok": True}
|
|
|
|
|
|
@frappe.whitelist()
|
|
def undo_reject_cohort_join_request(join_request):
|
|
r = frappe.get_doc("Cohort Join Request", join_request)
|
|
sg = r and frappe.get_doc("Cohort Subgroup", r.subgroup)
|
|
# keeping Pending as well to consider the case of duplicate requests
|
|
if not sg or r.status not in ["Pending", "Rejected"]:
|
|
return {"ok": False, "error": "Invalid Join Request"}
|
|
if (
|
|
not sg.is_manager(frappe.session.user) and "System Manager" not in frappe.get_roles()
|
|
):
|
|
return {"ok": False, "error": "Permission Deined"}
|
|
|
|
r.status = "Pending"
|
|
r.save()
|
|
return {"ok": True}
|
|
|
|
|
|
@frappe.whitelist()
|
|
def add_mentor_to_subgroup(subgroup, email):
|
|
try:
|
|
sg = frappe.get_doc("Cohort Subgroup", subgroup)
|
|
except frappe.DoesNotExistError:
|
|
return {"ok": False, "error": f"Invalid subgroup: {subgroup}"}
|
|
|
|
if (
|
|
not sg.get_cohort().is_admin(frappe.session.user)
|
|
and "System Manager" not in frappe.get_roles()
|
|
):
|
|
return {"ok": False, "error": "Permission Deined"}
|
|
|
|
try:
|
|
user = frappe.get_doc("User", email)
|
|
except frappe.DoesNotExistError:
|
|
return {"ok": False, "error": f"Invalid user: {email}"}
|
|
|
|
sg.add_mentor(email)
|
|
return {"ok": True}
|
|
|
|
|
|
@frappe.whitelist(allow_guest=True)
|
|
def get_user_info():
|
|
if frappe.session.user == "Guest":
|
|
return None
|
|
|
|
user = frappe.db.get_value(
|
|
"User",
|
|
frappe.session.user,
|
|
["name", "email", "enabled", "user_image", "full_name", "user_type", "username"],
|
|
as_dict=1,
|
|
)
|
|
user["roles"] = frappe.get_roles(user.name)
|
|
user.is_instructor = "Course Creator" in user.roles
|
|
user.is_moderator = "Moderator" in user.roles
|
|
user.is_evaluator = "Batch Evaluator" in user.roles
|
|
return user
|
|
|
|
|
|
@frappe.whitelist(allow_guest=True)
|
|
def get_translations():
|
|
if frappe.session.user != "Guest":
|
|
language = frappe.db.get_value("User", frappe.session.user, "language")
|
|
else:
|
|
language = frappe.db.get_single_value("System Settings", "language")
|
|
return get_all_translations(language)
|
|
|
|
|
|
@frappe.whitelist()
|
|
def validate_billing_access(type, name):
|
|
access = True
|
|
message = ""
|
|
doctype = "LMS Course" if type == "course" else "LMS Batch"
|
|
|
|
if frappe.session.user == "Guest":
|
|
access = False
|
|
message = _("Please login to continue with payment.")
|
|
|
|
if type not in ["course", "batch"]:
|
|
access = False
|
|
message = _("Module is incorrect.")
|
|
|
|
if not frappe.db.exists(doctype, name):
|
|
access = False
|
|
message = _("Module Name is incorrect or does not exist.")
|
|
|
|
if type == "course":
|
|
membership = frappe.db.exists(
|
|
"LMS Enrollment", {"member": frappe.session.user, "course": name}
|
|
)
|
|
if membership:
|
|
access = False
|
|
message = _("You are already enrolled for this course.")
|
|
|
|
else:
|
|
membership = frappe.db.exists(
|
|
"Batch Student", {"student": frappe.session.user, "parent": name}
|
|
)
|
|
if membership:
|
|
access = False
|
|
message = _("You are already enrolled for this batch.")
|
|
|
|
address = frappe.db.get_value(
|
|
"Address",
|
|
{"email_id": frappe.session.user},
|
|
[
|
|
"name",
|
|
"address_title as billing_name",
|
|
"address_line1",
|
|
"address_line2",
|
|
"city",
|
|
"state",
|
|
"country",
|
|
"pincode",
|
|
"phone",
|
|
],
|
|
as_dict=1,
|
|
)
|
|
|
|
return {"access": access, "message": message, "address": address}
|
|
|
|
|
|
@frappe.whitelist(allow_guest=True)
|
|
def get_job_details(job):
|
|
return frappe.db.get_value(
|
|
"Job Opportunity",
|
|
job,
|
|
[
|
|
"job_title",
|
|
"location",
|
|
"type",
|
|
"company_name",
|
|
"company_logo",
|
|
"name",
|
|
"creation",
|
|
"description",
|
|
"owner",
|
|
],
|
|
as_dict=1,
|
|
)
|
|
|
|
|
|
@frappe.whitelist(allow_guest=True)
|
|
def get_job_opportunities():
|
|
jobs = frappe.get_all(
|
|
"Job Opportunity",
|
|
{"status": "Open", "disabled": False},
|
|
["job_title", "location", "type", "company_name", "company_logo", "name", "creation"],
|
|
order_by="creation desc",
|
|
)
|
|
return jobs
|
|
|
|
|
|
@frappe.whitelist(allow_guest=True)
|
|
def get_chart_details():
|
|
details = frappe._dict()
|
|
details.enrollments = frappe.db.count("LMS Enrollment")
|
|
details.courses = frappe.db.count(
|
|
"LMS Course",
|
|
{
|
|
"published": 1,
|
|
"upcoming": 0,
|
|
},
|
|
)
|
|
details.users = frappe.db.count("User", {"enabled": 1})
|
|
details.completions = frappe.db.count(
|
|
"LMS Enrollment", {"progress": ["like", "%100%"]}
|
|
)
|
|
details.lesson_completions = frappe.db.count("LMS Course Progress")
|
|
return details
|
|
|
|
|
|
@frappe.whitelist()
|
|
def get_file_info(file_url):
|
|
"""Get file info for the given file URL."""
|
|
file_info = frappe.db.get_value(
|
|
"File", {"file_url": file_url}, ["file_name", "file_size", "file_url"], as_dict=1
|
|
)
|
|
return file_info
|
|
|
|
|
|
@frappe.whitelist(allow_guest=True)
|
|
def get_branding():
|
|
"""Get branding details."""
|
|
return {
|
|
"brand_name": frappe.db.get_single_value("Website Settings", "app_name"),
|
|
"brand_html": frappe.db.get_single_value("Website Settings", "brand_html"),
|
|
"favicon": frappe.db.get_single_value("Website Settings", "favicon"),
|
|
}
|
|
|
|
|
|
@frappe.whitelist()
|
|
def get_unsplash_photos(keyword=None):
|
|
from lms.unsplash import get_list, get_by_keyword
|
|
|
|
if keyword:
|
|
return get_by_keyword(keyword)
|
|
|
|
return frappe.cache().get_value("unsplash_photos", generator=get_list)
|