Compare commits

..

1 Commits

Author SHA1 Message Date
Syed Muhammad Dawoud Sheraz Ali
09aae99235 chore: remove python 3.8 references and set py39 as minimum version 2024-11-11 17:00:20 +05:00
22 changed files with 101 additions and 223 deletions

View File

@ -1,12 +1,9 @@
name: Auto Add Issues and Pull Requests to Project
name: Auto Add Issues to Project
on:
issues:
types:
- opened
pull_request_target:
types:
- opened
jobs:
# https://github.com/actions/add-to-project

View File

@ -2,7 +2,7 @@ name: Sync with private repo
on:
push:
branches: [ release, main ]
branches: [ master, main, nightly ]
jobs:
sync:

View File

@ -2,9 +2,7 @@ name: Run tests
on:
pull_request:
branches: [ release, main ]
push:
branches: [ release, main ]
branches: [master]
jobs:
tests:
@ -18,6 +16,8 @@ jobs:
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
- name: Upgrade pip
run: python -m pip install --upgrade pip setuptools
- name: Install dependencies
run: |
pip install .[dev]

View File

@ -1,21 +0,0 @@
# https://hatch.pypa.io/latest/how-to/config/dynamic-metadata/
import os
import typing as t
from hatchling.metadata.plugin.interface import MetadataHookInterface
HERE = os.path.dirname(__file__)
class MetaDataHook(MetadataHookInterface):
def update(self, metadata: dict[str, t.Any]) -> None:
about = load_about()
metadata["version"] = about["__version__"]
def load_about() -> dict[str, str]:
about: dict[str, str] = {}
with open(os.path.join(HERE, "tutornotes", "__about__.py"), "rt", encoding="utf-8") as f:
exec(f.read(), about)
return about

View File

@ -19,41 +19,6 @@ instructions, because git commits are used to generate release notes:
<!-- scriv-insert-here -->
<a id='changelog-20.0.0'></a>
## v20.0.0 (2025-06-05)
- 💥[Feature] Upgrade to Teak. (by @jfavellar90)
<a id='changelog-19.0.2'></a>
## v19.0.2 (2025-03-12)
- [Improvement] Add hatch_build.py in sdist target to fix the installation issues (by @dawoudsheraz)
<a id='changelog-19.0.1'></a>
## v19.0.1 (2025-03-11)
- [Bugfix] Fix broken feature in `dev` mode, where the frontend is reporting a CORS error on loading the notes. (by @regisb)
- [Improvement] Migrate from `setup.py` (setuptools) to `pyproject.toml` (hatch). (by @jfavellar90)
<a id='changelog-19.0.0'></a>
## v19.0.0 (2024-10-24)
- [Bugfix] Fix legacy warnings during Docker build. (by @regisb)
- 💥[Feature] Update Notes Image to use Ubuntu 24.04 as base OS. (by @jfavellar90)
- [Bugfix] Actually mount edx-notes-api repositories from host on `tutor mounts add /path/to/edx-notes-api`. (by @regisb)
- 💥[Feature] Replace Elasticsearch by Meilisearch. The implementation is much more compact and readable. All content will be automatically re-indexed during init. (by @regisb)
- 💥 [Deprecation] Drop support for python 3.8 and set Python 3.9 as the minimum supported python version. (by @DawoudSheraz)
- 💥[Improvement] Rename Tutor's two branches (by @DawoudSheraz):
* Rename **master** to **release**, as this branch runs the latest official Open edX release tag.
* Rename **nightly** to **main**, as this branch runs the Open edX master branches, which are the basis for the next Open edX release.
- 💥[Feature] Upgrade to Sumac. (by @jfavellar90)
<a id='changelog-18.0.0'></a>
## v18.0.0 (2024-05-09)

2
MANIFEST.in Normal file
View File

@ -0,0 +1,2 @@
recursive-include tutornotes/patches *
recursive-include tutornotes/templates *

View File

@ -1,31 +1,22 @@
.DEFAULT_GOAL := help
.PHONY: docs
SRC_DIRS = ./tutornotes
RUFF_OPTS = --exclude templates ${SRC_DIRS}
BLACK_OPTS = --exclude templates ${SRC_DIRS}
# Warning: These checks are run on every PR.
test: test-lint test-types test-format test-pythonpackage
test: test-lint test-types test-format # Run some static checks.
test-format: ## Run code formatting tests.
ruff format --check --diff $(RUFF_OPTS)
black --check --diff $(BLACK_OPTS)
test-lint:
ruff check ${SRC_DIRS}
test-lint: ## Run code linting tests
pylint --errors-only --enable=unused-import,unused-argument --ignore=templates --ignore=docs/_ext ${SRC_DIRS}
test-types: ## Run type checks.
mypy --exclude=templates --ignore-missing-imports --implicit-reexport --strict ${SRC_DIRS}
build-pythonpackage:
python -m build --sdist
test-pythonpackage: build-pythonpackage
twine check dist/tutor_notes-$(shell make version).tar.gz
format: ## Format code automatically.
ruff format $(RUFF_OPTS)
fix-lint: ## Fix linting issues automatically.
ruff check --fix $(RUFF_OPTS)
black $(BLACK_OPTS)
isort: ## Sort imports. This target is not mandatory because the output may be incompatible with black formatting. Provided for convenience purposes.
isort --skip=templates ${SRC_DIRS}
@ -36,9 +27,6 @@ changelog-entry: ## Create a new changelog entry.
changelog: ## Collect changelog entries in the CHANGELOG.md file.
scriv collect
version: ## Print the current tutor-notes version
@python -c 'import io, os; about = {}; exec(io.open(os.path.join("tutornotes", "__about__.py"), "rt", encoding="utf-8").read(), about); print(about["__version__"])'
ESCAPE = 
help: ## Print this help.
@grep -E '^([a-zA-Z_-]+:.*?## .*|######* .+)$$' Makefile \

View File

@ -1,9 +1,9 @@
Students notes plugin for `Tutor <https://docs.tutor.edly.io>`_
===================================================================
This is a plugin for `Tutor <https://docs.tutor.edly.io>`_ to easily add the `Open edX note-taking app <https://github.com/openedx/edx-notes-api>`_ to an Open edX platform. This app allows students to annotate portions of the courseware (see `the official documentation <https://docs.openedx.org/en/latest/educators/how-tos/course_development/exercise_tools/enable_notes.html>`_).
This is a plugin for `Tutor <https://docs.tutor.edly.io>`_ to easily add the `Open edX note-taking app <https://github.com/openedx/edx-notes-api>`_ to an Open edX platform. This app allows students to annotate portions of the courseware (see `the official documentation <https://edx.readthedocs.io/projects/open-edx-building-and-running-a-course/en/open-release-redwood.master/exercises_tools/notes.html>`_).
.. image:: https://docs.openedx.org/en/latest/_images/SFD_SN_bodyexample.png
.. image:: https://edx.readthedocs.io/projects/open-edx-building-and-running-a-course/en/open-release-redwood.master/_images/SFD_SN_bodyexample.png
:alt: Notes in action
Installation
@ -23,7 +23,7 @@ Then, to make migrations & tasks::
You should beware that the ``notes.<LMS_HOST>`` domain name should exist and point to your server. For instance, if your LMS is hosted at http://myopenedx.com, the notes service should be found at http://notes.myopenedx.com.
If you would like to host the notes service at a different domain name, you can set the ``NOTES_HOST`` configuration variable (see below). When testing Tutor on a local computer, this will be automatically set to notes.local.openedx.io.
If you would like to host the notes service at a different domain name, you can set the ``NOTES_HOST`` configuration variable (see below). When testing Tutor on a local computer, this will be automatically set to notes.local.edly.io.
To enable student notes for a specific course, you should go to the course advanced settings in the studio, and set "Enable Student Notes" to "true". Then, hit "save changes".
@ -59,4 +59,4 @@ This Tutor plugin is maintained by Jhony Avella from `eduNEXT <https://www.edune
License
-------
This software is licensed under the terms of the `GNU Affero General Public License (AGPL) <https://github.com/overhangio/tutor-notes/blob/release/LICENSE.txt>`_.
This software is licensed under the terms of the `GNU Affero General Public License (AGPL) <https://github.com/overhangio/tutor-notes/blob/master/LICENSE.txt>`_.

View File

@ -0,0 +1 @@
- [Bugfix] Fix legacy warnings during Docker build. (by @regisb)

View File

@ -0,0 +1 @@
- 💥 [Deprecation] Drop support for python 3.8 and set Python 3.9 as the minimum supported python version. (by @DawoudSheraz)

View File

@ -1,2 +0,0 @@
- [Improvement] Migrate from pylint and black to ruff. (by @dawoudsheraz)
- [Improvement] Test python package distribution build when running make-test. (by @dawoudsheraz)

View File

@ -1,87 +1,2 @@
# https://packaging.python.org/en/latest/tutorials/packaging-projects/
# https://hatch.pypa.io/latest/config/build/
[project]
name = "tutor-notes"
description = "A Tutor plugin for student notes"
authors = [
{ name = "Edly" },
{ email = "hello@edly.io"},
]
maintainers = [
{ name = "Jhony Avella" },
{ email = "jhony.avella@edunext.co" },
]
license = {text = "AGPL-3.0-only"}
readme = {file = "README.rst", content-type = "text/x-rst"}
requires-python = ">=3.9"
classifiers = [
"Development Status :: 5 - Production/Stable",
"Intended Audience :: Developers",
"License :: OSI Approved :: GNU Affero General Public License v3",
"Operating System :: OS Independent",
"Programming Language :: Python",
"Programming Language :: Python :: 3.9",
"Programming Language :: Python :: 3.10",
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
]
dependencies = [
"tutor>=20.0.0,<21.0.0",
]
# These fields will be set by hatch_build.py
dynamic = ["version"]
[project.optional-dependencies]
dev = [
"tutor[dev]>=20.0.0,<21.0.0",
"ruff"
]
# https://packaging.python.org/en/latest/specifications/well-known-project-urls/#well-known-labels
[project.urls]
Homepage = "https://docs.tutor.edly.io/"
Documentation = "https://github.com/overhangio/tutor-notes#readme"
Issues = "https://github.com/overhangio/tutor-notes/issues"
Source = "https://github.com/overhangio/tutor-notes"
Changelog = "https://github.com/overhangio/tutor-notes/blob/release/CHANGELOG.md"
Community = "https://discuss.openedx.org/tag/tutor"
[build-system]
requires = ["hatchling"]
build-backend = "hatchling.build"
# hatch-specific configuration
[tool.hatch.metadata.hooks.custom]
path = ".hatch_build.py"
[tool.hatch.build.targets.wheel]
packages = ["tutornotes"]
[tool.hatch.build.targets.sdist]
# Disable strict naming, otherwise twine is not able to detect name/version
strict-naming = false
include = [ "/tutornotes", ".hatch_build.py"]
exclude = ["tests*"]
[project.entry-points."tutor.plugin.v1"]
notes = "tutornotes.plugin"
[tool.ruff]
exclude = ["templates", "docs/_ext"]
[tool.ruff.lint]
# E: pycodestyle errors
# I: isort
# N: pep8-naming
select = ["E", "I", "N"]
# F401: unused-import
# F841: unused-variable
# W292: missing-newline-at-end-of-file
extend-select = ["F401", "F841", "W292"]
[tool.ruff.format]
# Default config is automatically taken from https://docs.astral.sh/ruff/configuration/
requires = ["setuptools", "wheel"]

50
setup.py Normal file
View File

@ -0,0 +1,50 @@
import io
import os
from setuptools import setup, find_packages
here = os.path.abspath(os.path.dirname(__file__))
with io.open(os.path.join(here, "README.rst"), "rt", encoding="utf8") as f:
readme = f.read()
about = {}
with io.open(
os.path.join(here, "tutornotes", "__about__.py"), "rt", encoding="utf-8"
) as f:
exec(f.read(), about)
setup(
name="tutor-notes",
version=about["__version__"],
url="https://docs.tutor.edly.io/",
project_urls={
"Documentation": "https://docs.tutor.edly.io/",
"Code": "https://github.com/overhangio/tutor-notes",
"Issue tracker": "https://github.com/overhangio/tutor-notes/issues",
"Community": "https://discuss.openedx.org",
},
license="AGPLv3",
author="Edly",
author_email="hello@edly.io",
maintainer="eduNEXT",
description="A Tutor plugin for student notes",
long_description=readme,
long_description_content_type="text/x-rst",
packages=find_packages(exclude=["tests*"]),
include_package_data=True,
python_requires=">=3.9",
install_requires=["tutor>=18.0.0,<19.0.0"],
extras_require={"dev": ["tutor[dev]>=18.0.0,<19.0.0"]},
entry_points={"tutor.plugin.v1": ["notes = tutornotes.plugin"]},
classifiers=[
"Development Status :: 5 - Production/Stable",
"Intended Audience :: Developers",
"License :: OSI Approved :: GNU Affero General Public License v3",
"Operating System :: OS Independent",
"Programming Language :: Python",
"Programming Language :: Python :: 3.9",
"Programming Language :: Python :: 3.10",
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
],
)

View File

@ -1 +1 @@
__version__ = "20.0.0"
__version__ = "18.0.0"

View File

@ -15,8 +15,8 @@ spec:
app.kubernetes.io/name: notes
spec:
securityContext:
runAsUser: {{ APP_USER_ID }}
runAsGroup: {{ APP_USER_ID }}
runAsUser: 1000
runAsGroup: 1000
containers:
- name: notes
image: {{ NOTES_DOCKER_IMAGE }}

View File

@ -4,7 +4,4 @@ notes-job:
DJANGO_SETTINGS_MODULE: notesserver.settings.tutor
volumes:
- ../plugins/notes/apps/settings/tutor.py:/app/edx-notes-api/notesserver/settings/tutor.py:ro
{%- for mount in iter_mounts(MOUNTS, "notes") %}
- {{ mount }}
{%- endfor %}
depends_on: {{ [("mysql", RUN_MYSQL)]|list_if }}

View File

@ -1 +1 @@
setowner {{ APP_USER_ID }} /mounts/notes
setowner 1000 /mounts/notes

View File

@ -6,8 +6,5 @@ notes:
volumes:
- ../plugins/notes/apps/settings/tutor.py:/app/edx-notes-api/notesserver/settings/tutor.py:ro
- ../../data/notes:/app/data
{%- for mount in iter_mounts(MOUNTS, "notes") %}
- {{ mount }}
{%- endfor %}
restart: unless-stopped
depends_on: {{ [("mysql", RUN_MYSQL)]|list_if }}

View File

@ -10,14 +10,14 @@ from tutor.__about__ import __version_suffix__
from .__about__ import __version__
# Handle version suffix in main mode, just like tutor core
# Handle version suffix in nightly mode, just like tutor core
if __version_suffix__:
__version__ += "-" + __version_suffix__
config = {
"defaults": {
"VERSION": __version__,
"DOCKER_IMAGE": "{{ DOCKER_REGISTRY }}overhangio/openedx-notes:{{ NOTES_VERSION }}", # noqa: E501
"DOCKER_IMAGE": "{{ DOCKER_REGISTRY }}overhangio/openedx-notes:{{ NOTES_VERSION }}",
"HOST": "notes.{{ LMS_HOST }}",
"MYSQL_DATABASE": "notes",
"MYSQL_USERNAME": "notes",

View File

@ -4,14 +4,13 @@ SECRET_KEY = "{{ NOTES_SECRET_KEY }}"
ALLOWED_HOSTS = [
"notes",
"{{ NOTES_HOST }}",
"{{ NOTES_HOST }}:8120",
]
DATABASES = {
"default": {
"ENGINE": "django.db.backends.mysql",
"HOST": "{{ MYSQL_HOST }}",
"PORT": {{ MYSQL_PORT }},
"PORT": {{MYSQL_PORT}},
"NAME": "{{ NOTES_MYSQL_DATABASE }}",
"USER": "{{ NOTES_MYSQL_USERNAME }}",
"PASSWORD": "{{ NOTES_MYSQL_PASSWORD }}",
@ -24,12 +23,11 @@ DATABASES = {
CLIENT_ID = "notes"
CLIENT_SECRET = "{{ NOTES_OAUTH2_SECRET }}"
# Meilisearch credentials
ES_DISABLED = True
MEILISEARCH_ENABLED = True
MEILISEARCH_URL = "{{ MEILISEARCH_URL }}"
MEILISEARCH_API_KEY = "{{ MEILISEARCH_API_KEY }}"
MEILISEARCH_INDEX = "{{ MEILISEARCH_INDEX_PREFIX }}student_notes"
ELASTICSEARCH_DSL = {
'default': {
'hosts': '{{ ELASTICSEARCH_SCHEME }}://{{ ELASTICSEARCH_HOST }}:{{ ELASTICSEARCH_PORT }}'
}
}
LOGGING = {
"version": 1,

View File

@ -1,27 +1,24 @@
# syntax=docker/dockerfile:1
FROM docker.io/ubuntu:24.04
# syntax=docker/dockerfile:1.4
FROM docker.io/python:3.12-slim-bookworm
ENV DEBIAN_FRONTEND=noninteractive
# Delete default UID=1000 `ubuntu` user to ensure we can use id 1000 for app user
RUN userdel -r ubuntu
RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \
--mount=type=cache,target=/var/lib/apt,sharing=locked \
apt update && \
apt upgrade -y && \
apt install -y \
language-pack-en \
git \
python3 \
python3-pip \
python3-venv \
libmysqlclient-dev \
pkg-config
RUN ln -s /usr/bin/python3 /usr/bin/python
--mount=type=cache,target=/var/lib/apt,sharing=locked \
apt update && \
apt upgrade -y && \
apt install -y \
locales \
git \
python3-dev \
build-essential \
default-libmysqlclient-dev \
pkg-config && \
sed -i '/en_US.UTF-8/s/^# //g' /etc/locale.gen && \
locale-gen
ENV LC_ALL=en_US.UTF-8
###### Git-clone Notes repo ######
ARG APP_USER_ID={{ HOST_USER_ID }}
ARG APP_USER_ID=1000
RUN useradd --home-dir /app --create-home --shell /bin/bash --uid ${APP_USER_ID} app
USER ${APP_USER_ID}
@ -34,13 +31,8 @@ ENV PATH=/app/venv/bin:${PATH}
# https://pypi.org/project/setuptools/
# https://pypi.org/project/pip/
# https://pypi.org/project/wheel/
RUN --mount=type=cache,target=/app/.cache/pip,sharing=shared pip install setuptools==78.1.0 pip==25.0.1 wheel==0.46.0
RUN --mount=type=cache,target=/app/.cache/pip,sharing=shared pip install setuptools==69.2.0 pip==24.0 wheel==0.43.0
RUN --mount=type=cache,target=/app/.cache/pip,sharing=shared pip install -r requirements/base.txt
EXPOSE 8000
CMD ["gunicorn", \
"--workers=2", \
"--name", "notes", \
"--bind=0.0.0.0:8000", \
"--max-requests=1000", \
"notesserver.wsgi:application"]
CMD gunicorn --workers=2 --name notes --bind=0.0.0.0:8000 --max-requests=1000 notesserver.wsgi:application

View File

@ -1,4 +1,2 @@
./manage.py migrate
# Re-index with meilisearch
./manage.py shell -c "from notesapi.v1.views.meilisearch import reindex; reindex()"
./manage.py search_index --rebuild -f