import frappe from . import __version__ as app_version app_name = "frappe_lms" app_title = "Learning" app_publisher = "Frappe" app_description = "Open Source Learning Management System built with Frappe Framework" app_icon_url = "/assets/lms/images/lms-logo.png" app_icon_title = "Learning" app_color = "grey" app_email = "jannat@frappe.io" app_license = "AGPL" def get_lms_path(): return (frappe.conf.get("lms_path") or "lms").strip("/") app_icon_route = f"/{get_lms_path()}" # Includes in # ------------------ # include js, css files in header of desk.html # app_include_css = "/assets/lms/css/lms.css" # app_include_js = "/assets/lms/js/lms.js" # include js, css files in header of web template web_include_css = "lms.bundle.css" # web_include_css = "/assets/lms/css/lms.css" web_include_js = [] # include custom scss in every website theme (without file extension ".scss") # website_theme_scss = "lms/public/scss/website" # include js, css files in header of web form # webform_include_js = {"doctype": "public/js/doctype.js"} # webform_include_css = {"doctype": "public/css/doctype.css"} # include js in page # page_js = {"page" : "public/js/file.js"} # include js in doctype views # doctype_js = {"doctype" : "public/js/doctype.js"} # doctype_list_js = {"doctype" : "public/js/doctype_list.js"} # doctype_tree_js = {"doctype" : "public/js/doctype_tree.js"} # doctype_calendar_js = {"doctype" : "public/js/doctype_calendar.js"} # Home Pages # ---------- # application home page (will override Website Settings) # home_page = "login" # website user home page (by Role) # role_home_page = { # "Role": "home_page" # } # Generators # ---------- # automatically create page for each record of this doctype # website_generators = ["Web Page"] # Installation # ------------ # before_install = "lms.install.before_install" after_install = "lms.install.after_install" after_sync = "lms.install.after_sync" before_uninstall = "lms.install.before_uninstall" setup_wizard_requires = "assets/lms/js/setup_wizard.js" after_migrate = [ "lms.sqlite.build_index_in_background", ] # Desk Notifications # ------------------ # See frappe.core.notifications.get_notification_config # notification_config = "lms.notifications.get_notification_config" # Permissions # ----------- # Permissions evaluated in scripted ways permission_query_conditions = { "LMS Certificate": "lms.lms.doctype.lms_certificate.lms_certificate.get_permission_query_conditions", } has_permission = { "LMS Live Class": "lms.lms.doctype.lms_live_class.lms_live_class.has_permission", "LMS Batch": "lms.lms.doctype.lms_batch.lms_batch.has_permission", "LMS Program": "lms.lms.doctype.lms_program.lms_program.has_permission", "LMS Certificate": "lms.lms.doctype.lms_certificate.lms_certificate.has_permission", } # DocType Class # --------------- # Override standard doctype classes override_doctype_class = { "Web Template": "lms.overrides.web_template.CustomWebTemplate", } # Document Events # --------------- # Hook on document methods and events doc_events = { "*": { "on_change": [ "lms.lms.doctype.lms_badge.lms_badge.process_badges", ] }, "Discussion Reply": { "after_insert": "lms.lms.utils.handle_notifications", "validate": "lms.lms.utils.validate_discussion_reply", }, "Notification Log": {"on_change": "lms.lms.utils.publish_notifications"}, "User": { "validate": "lms.lms.user.validate_username_duplicates", #"after_insert": "lms.lms.user.after_insert", }, } # Scheduled Tasks # --------------- scheduler_events = { "all": [ "lms.sqlite.build_index_in_background", ], "hourly": [ "lms.lms.doctype.lms_certificate_request.lms_certificate_request.schedule_evals", "lms.lms.api.update_course_statistics", "lms.lms.doctype.lms_certificate_request.lms_certificate_request.mark_eval_as_completed", "lms.lms.doctype.lms_live_class.lms_live_class.update_attendance", ], "daily": [ "lms.job.doctype.job_opportunity.job_opportunity.update_job_openings", "lms.lms.doctype.lms_payment.lms_payment.send_payment_reminder", "lms.lms.doctype.lms_batch.lms_batch.send_batch_start_reminder", "lms.lms.doctype.lms_live_class.lms_live_class.send_live_class_reminder", "lms.lms.doctype.lms_course.lms_course.send_notification_for_published_courses", ], } fixtures = ["Custom Field", "Function", "Industry", "LMS Category"] # Testing # ------- # before_tests = "lms.install.before_tests" # Overriding Methods # ------------------------------ # override_whitelisted_methods = { # "frappe.desk.search.get_names_for_mentions": "lms.lms.utils.get_names_for_mentions", } # # each overriding function accepts a `data` argument; # generated from the base implementation of the doctype dashboard, # along with any modifications made in other Frappe apps # override_doctype_dashboards = { # "Task": "lms.task.get_dashboard_data" # } # exempt linked doctypes from being automatically cancelled # # auto_cancel_exempted_doctypes = ["Auto Repeat"] # Add all simple route rules here website_route_rules = [ {"from_route": f"/{get_lms_path()}/", "to_route": "_lms"}, {"from_route": f"/{get_lms_path()}", "to_route": "_lms"}, { "from_route": "/courses//", "to_route": "certificate", }, ] website_redirects = [ {"source": "/update-profile", "target": "/edit-profile"}, {"source": "/courses", "target": f"/{get_lms_path()}/courses"}, { "source": r"^/courses/.*$", "target": f"/{get_lms_path()}/courses", }, {"source": "/batches", "target": f"/{get_lms_path()}/batches"}, { "source": r"/batches/(.*)", "target": f"/{get_lms_path()}/batches", "match_with_query_string": True, }, {"source": "/job-openings", "target": f"/{get_lms_path()}/job-openings"}, { "source": r"/job-openings/(.*)", "target": f"/{get_lms_path()}/job-openings", "match_with_query_string": True, }, {"source": "/statistics", "target": f"/{get_lms_path()}/statistics"}, {"source": "_lms", "target": f"/{get_lms_path()}"}, ] update_website_context = [ "lms.widgets.update_website_context", ] jinja = { "methods": [ "lms.lms.utils.get_lesson_count", "lms.lms.utils.get_instructors", "lms.lms.utils.get_lesson_index", "lms.lms.utils.get_lesson_url", "lms.lms.utils.get_lms_route", "lms.lms.utils.is_instructor", "lms.lms.utils.get_palette", ], "filters": [], } extend_bootinfo = [ "lms.lms.utils.extend_bootinfo", ] ## Specify the additional tabs to be included in the user profile page. ## Each entry must be a subclass of lms.lms.plugins.ProfileTab # profile_tabs = [] ## Specify the extension to be used to control what scripts and stylesheets ## to be included in lesson pages. The specified value must be be a ## subclass of lms.plugins.PageExtension # lms_lesson_page_extension = None # lms_lesson_page_extensions = [ # "lms.plugins.LiveCodeExtension" # ] has_website_permission = { "LMS Certificate Evaluation": "lms.lms.doctype.lms_certificate_evaluation.lms_certificate_evaluation.has_website_permission", "LMS Certificate": "lms.lms.doctype.lms_certificate.lms_certificate.has_website_permission", } ## Markdown Macros for Lessons lms_markdown_macro_renderers = { "Exercise": "lms.plugins.exercise_renderer", "Quiz": "lms.plugins.quiz_renderer", "YouTubeVideo": "lms.plugins.youtube_video_renderer", "RuTubeVideo": "lms.plugins.rutube_video_renderer", "Video": "lms.plugins.video_renderer", "Assignment": "lms.plugins.assignment_renderer", "Embed": "lms.plugins.embed_renderer", "Audio": "lms.plugins.audio_renderer", "PDF": "lms.plugins.pdf_renderer", } page_renderer = [ "lms.page_renderers.SCORMRenderer", ] # set this to "/" to have profiles on the top-level profile_url_prefix = "/users/" signup_form_template = "lms.plugins.show_custom_signup" on_login = "lms.lms.user.on_login" get_site_info = "lms.activation.get_site_info" add_to_apps_screen = [ { "name": "lms", "logo": "/assets/lms/frontend/learning.svg", "title": "Learning", "route": f"/{get_lms_path()}", "has_permission": "lms.lms.api.check_app_permission", } ] sqlite_search = ["lms.sqlite.LearningSearch"] auth_hooks = ["lms.auth.authenticate"] require_type_annotated_api_methods = True