From 21000a60a9464381ac029ff3c67f0f4525224a07 Mon Sep 17 00:00:00 2001 From: Anurag Nandi Date: Fri, 28 Aug 2026 10:57:48 +0530 Subject: [PATCH 1/3] Updated requirements.txt, UI as in the present version,etc. --- .gitignore | 6 +- LICENSE | 0 README.md | 14 +- add_courses_and_items.py | 237 ++++++ arc/settings.py | 11 + arc/urls.py | 6 + main/assets/3la | 0 main/assets/3ln | 0 main/assets/4la | 0 main/assets/4ln | 0 main/assets/README.md | 0 main/assets/ma34 | 0 main/assets/mm34 | 0 main/assets/simple-adj | 0 main/assets/wiki-animals-34 | 0 main/gen.py | 0 main/recom.py | 48 +- main/static/main/css/file.css | 0 main/static/main/css/main.css | 0 main/static/main/js/course.js | 0 main/static/main/js/main.js | 0 main/static/main/js/school.js | 0 main/static/main/js/user.js | 0 main/static/main/package.json | 10 + main/templates/main/404.htm | 0 main/templates/main/500.htm | 0 main/templates/main/add-crs.htm | 96 +-- main/templates/main/add-item.htm | 90 ++- main/templates/main/add-itr.htm | 107 ++- main/templates/main/base.htm | 704 +++++++++++++++--- main/templates/main/contact.htm | 13 + main/templates/main/course.htm | 78 +- main/templates/main/faq.htm | 0 main/templates/main/file.htm | 65 +- main/templates/main/index.htm | 88 ++- main/templates/main/itr.htm | 487 ++++++------ main/templates/main/log.htm | 4 +- main/templates/main/login.htm | 74 +- main/templates/main/modal-base.htm | 0 .../main/password-reset-complete.htm | 0 .../templates/main/password-reset-confirm.htm | 0 main/templates/main/password-reset-done.htm | 0 main/templates/main/password-reset-email.htm | 2 +- main/templates/main/password-reset.htm | 0 main/templates/main/pw-reset-subj.txt | 0 main/templates/main/recom.htm | 0 main/templates/main/school.htm | 78 +- main/templates/main/search.htm | 67 ++ main/templates/main/signup.htm | 65 +- main/templates/main/stat.htm | 8 +- main/templates/main/user.htm | 97 +-- main/templates/main/verify.txt | 2 +- main/urls.py | 11 +- main/views.py | 65 +- requirements.txt | 0 55 files changed, 1734 insertions(+), 799 deletions(-) mode change 100644 => 100755 .gitignore mode change 100644 => 100755 LICENSE mode change 100644 => 100755 README.md create mode 100755 add_courses_and_items.py mode change 100644 => 100755 main/assets/3la mode change 100644 => 100755 main/assets/3ln mode change 100644 => 100755 main/assets/4la mode change 100644 => 100755 main/assets/4ln mode change 100644 => 100755 main/assets/README.md mode change 100644 => 100755 main/assets/ma34 mode change 100644 => 100755 main/assets/mm34 mode change 100644 => 100755 main/assets/simple-adj mode change 100644 => 100755 main/assets/wiki-animals-34 mode change 100644 => 100755 main/gen.py mode change 100644 => 100755 main/recom.py mode change 100644 => 100755 main/static/main/css/file.css mode change 100644 => 100755 main/static/main/css/main.css mode change 100644 => 100755 main/static/main/js/course.js mode change 100644 => 100755 main/static/main/js/main.js mode change 100644 => 100755 main/static/main/js/school.js mode change 100644 => 100755 main/static/main/js/user.js create mode 100755 main/static/main/package.json mode change 100644 => 100755 main/templates/main/404.htm mode change 100644 => 100755 main/templates/main/500.htm create mode 100755 main/templates/main/contact.htm mode change 100644 => 100755 main/templates/main/faq.htm mode change 100644 => 100755 main/templates/main/file.htm mode change 100644 => 100755 main/templates/main/log.htm mode change 100644 => 100755 main/templates/main/modal-base.htm mode change 100644 => 100755 main/templates/main/password-reset-complete.htm mode change 100644 => 100755 main/templates/main/password-reset-confirm.htm mode change 100644 => 100755 main/templates/main/password-reset-done.htm mode change 100644 => 100755 main/templates/main/password-reset-email.htm mode change 100644 => 100755 main/templates/main/password-reset.htm mode change 100644 => 100755 main/templates/main/pw-reset-subj.txt mode change 100644 => 100755 main/templates/main/recom.htm create mode 100755 main/templates/main/search.htm mode change 100644 => 100755 main/templates/main/signup.htm mode change 100644 => 100755 main/templates/main/stat.htm mode change 100644 => 100755 main/templates/main/user.htm mode change 100644 => 100755 requirements.txt diff --git a/.gitignore b/.gitignore old mode 100644 new mode 100755 index 09d2138..487d1ea --- a/.gitignore +++ b/.gitignore @@ -5,7 +5,6 @@ __pycache__/ __init__.py local_settings.py -.env db.sqlite3 /static/ @@ -13,7 +12,6 @@ db.sqlite3 /main/log /main/migrations -env/ node_modules/ package-lock.json @@ -22,3 +20,7 @@ tags gunicorn/gunicorn.conf.py gunicorn/gunicorn.env recom_data.csv + +data/ +venv/ +staticfiles/ diff --git a/LICENSE b/LICENSE old mode 100644 new mode 100755 diff --git a/README.md b/README.md old mode 100644 new mode 100755 index 113a584..1320cb7 --- a/README.md +++ b/README.md @@ -4,18 +4,22 @@ NISER Archive #### How to run a local instance? * Sit tight. ~~If migrations fail, delete everything (the repo, the database, etc.) and start over.~~ (I have learnt this the hard way: DO NOT TRACK MIGRATIONS FILES, and everything works fine.) - * Install: `python`, `postgresql` + * Install: + * `python` : Install python 3.9.25 or lower preferably using pyenv(or the more modern uv) as django 2.2.28 does not support python 3.10 and above + * `postgresql` : Last checked with postgresql17 * Clone the repo. - * Create a [virtual environment](https://docs.python.org/3/tutorial/venv.html) and run `pip install -r requirements.txt`. - * You'll have to provide [`/arc/local_settings.py`](https://pastebin.com/S9yV4yj5). - * ~~You'll also have to fix some of the absolute paths in `/arc/settings.py` because~~ I am lazy. - * `cd` to `/main/static/main` and + * Create a [virtual environment](https://docs.python.org/3/tutorial/venv.html) using the python version you installed and run `pip install -r requirements.txt`. + * You'll have to provide `/arc/local_settings.py`(look at the example file attached). + * Install nodejs and npm systemwide(if not present already) and then + `cd` to `/main/static/main` and `npm install jquery popper.js bootstrap katex showdown open-iconic`. + * Make a new database in postgresql and register the database and db account credentials in local_settings.py * `cd` to the cloned repo (while you're still in virtual env) and run: `python manage.py collectstatic`, `python manage.py makemigrations main`, `python manage.py migrate` * Start the server: `python manage.py runserver` or you can run an apache server, thats how the deployed server is running presently. Configuring an apache server is very machine-specific. Google how to do it on your machine.) + * For verification mails, update the 'dmn' variable in views.py to * Please let me know if you're unable to run it on your machine. #### TODO: diff --git a/add_courses_and_items.py b/add_courses_and_items.py new file mode 100755 index 0000000..3bc13c8 --- /dev/null +++ b/add_courses_and_items.py @@ -0,0 +1,237 @@ +# Django script to add all courses and items from data/SDG_NISER/*/* +# Run this in `python manage.py shell` or as a Django management command + +import os +import re +import sys +import django + +# 1. Point Django to your settings module ('arc.settings') +os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'arc.settings') + +# 2. Add the project root to the system path if your script is in a subfolder +# (Adjust this path if your script lives somewhere else!) +sys.path.append('/home/ccarchive/archive/arc') + +# 3. Initialize Django +django.setup() + +from django.core.files import File +from django.utils import timezone +from main.models import School, Course, Itr, Item +from authtools.models import User + +# Set operator user +op = User.objects.get(email="sandipan.samanta@niser.ac.in") + +# Path to the data root +base_dir = "/home/ccarchive/archive/arc/staticfiles/SDG_NISER" + +# print("Checking and initializing Schools...") + +# SCHOOLS_DATA = { +# "SBS": "School of Biological Sciences", +# "SCS": "School of Chemical Sciences", +# "SMS": "School of Mathematical Sciences", +# "SPS": "School of Physical Sciences", +# "SEPS": "School of Earth and Planetary Sciences", +# "SCoS": "School of Computer Sciences", +# "SHSS": "School of Humanities and Social Sciences", +# "CMRP": "Centre for Medical and Radiation Physics" +# } + +# for abbr, full_name in SCHOOLS_DATA.items(): +# # If your School model requires the 'op' or 'appr' fields like your Course model does, +# # add them to the defaults dictionary below. +# school, created = School.objects.get_or_create( +# abbr=abbr, +# defaults={"name": full_name} +# ) +# if created: +# print(f" + Created new school: {abbr} - {full_name}") + +# Regex for _ +course_pattern = re.compile(r"^([A-Za-z0-9]+)_(.+)$") + +# Fixed regex pattern for files +# Matches: coursecode_itemname_year.pdf, coursecode_itemname_year_.pdf, etc. +# Examples: b202_endsem_2016.pdf, b202_endsem_2021_.pdf, b202_quiz_1_2021.pdf +# file_pattern = re.compile(r"^([a-z0-9]+)_(.+?)_(\d{4})_?\.pdf$", re.IGNORECASE) +# A list of patterns to try, from most specific to least specific +FILE_PATTERNS = [ + # 1. Standard (Code, Item, Year): b202_endsem_2021.pdf, b202-quiz 1-2021_sol.pdf + re.compile(r"^([a-z0-9]+)[_\-\s]+(.+?)[_\-\s]+(\d{4}).*\.pdf$", re.IGNORECASE), + + # 2. Year at the front (Year, Code, Item): 2021_b202_endsem.pdf + re.compile(r"^(\d{4})[_\-\s]+([a-z0-9]+)[_\-\s]+(.+)\.pdf$", re.IGNORECASE), + + # 3. No Year included (Code, Item): b202_endsem.pdf + re.compile(r"^([a-z0-9]+)[_\-\s]+(.+)\.pdf$", re.IGNORECASE) +] + +# ========================================== +# File Tracking Statistics +# ========================================== +stats = { + "total_seen": 0, + "added": 0, + "skipped_existing": 0, + "skipped_regex": 0, + "skipped_non_pdf": 0, + "skipped_mismatch": 0, + "errors": 0 +} + +print("\nStarting course and item import...") + +for school in School.objects.all(): + school_dir = os.path.join(base_dir, school.abbr) + if not os.path.isdir(school_dir): + print(f"Skipping {school.abbr}: directory not found") + continue + + print(f"\nProcessing school: {school.abbr}") + + for course_dir in os.listdir(school_dir): + course_match = course_pattern.match(course_dir) + if not course_match: + print(f" Skipping directory {course_dir}: doesn't match course pattern") + continue + + code = course_match.group(1).upper() # Convert to uppercase for consistency + if len(code) > 6: + print(f" Skipping {course_dir}: code '{code}' too long for Course.code field") + continue + + name_snake = course_match.group(2) + name = name_snake.replace("_", " ").title() # Better capitalization + + # Get or create course + course, created = Course.objects.get_or_create( + code=code, + school=school, + defaults={"op": op, "name": name, "appr": True} + ) + + if created: + print(f" Created course: {course}") + else: + print(f" Found existing course: {course}") + + full_course_dir = os.path.join(school_dir, course_dir) + + # Pass 1: Collect all years from files and create iterations + years_found = set() + valid_files = [] + + for fname in os.listdir(full_course_dir): + stats["total_seen"] += 1 # Count every file we look at + + if not fname.lower().endswith('.pdf'): + print(f" Skipping non-PDF: {fname}") + stats["skipped_non_pdf"] += 1 + continue + + file_code = None + item_name_raw = None + year = None + + # (Assuming you are using the updated FILE_PATTERNS list from earlier) + match = FILE_PATTERNS[0].match(fname) + if match: + file_code, item_name_raw, year = match.groups() + elif FILE_PATTERNS[1].match(fname): + match = FILE_PATTERNS[1].match(fname) + year, file_code, item_name_raw = match.groups() + elif FILE_PATTERNS[2].match(fname): + match = FILE_PATTERNS[2].match(fname) + file_code, item_name_raw = match.groups() + year = "0000" + + if not file_code: + print(f" ⚠️ UNMATCHED FORMAT, SKIPPING: {fname}") + stats["skipped_regex"] += 1 + continue + + file_code = file_code.upper() + + if file_code != code: + print(f" Skipped (code mismatch): {file_code} != {code} for {fname}") + stats["skipped_mismatch"] += 1 + continue + + years_found.add(year) + valid_files.append((fname, file_code, item_name_raw, year)) + + print(f" Found years: {sorted(years_found)}") + + # Create all iterations for this course + for year in years_found: + itr, created = Itr.objects.get_or_create( + course=course, + year=year, + defaults={ + "op": op, + "appr": True, + "sem": "FA", # Default to Fall semester + "inst": "Unknown" # Default instructor + } + ) + if created: + print(f" Created iteration: {itr}") + + # Pass 2: Add items to each iteration + for fname, file_code, item_name_raw, year in valid_files: + item_name = item_name_raw.replace("_", " ").replace("-", " ").strip() + item_name = " ".join(word.capitalize() for word in item_name.split()) + + itr = Itr.objects.get(course=course, year=year) + + # Check if item already exists + if Item.objects.filter(itr=itr, name=item_name).exists(): + print(f" Skipped existing item: {item_name} in {itr}") + stats["skipped_existing"] += 1 + continue + + # Create the item + src_path = os.path.join(full_course_dir, fname) + try: + with open(src_path, "rb") as f: + django_file = File(f, name=fname) + item = Item( + op=op, + itr=itr, + name=item_name, + appr=True, + time=timezone.now(), + desc=f"Imported from {fname}" + ) + item.fl.save(fname, django_file, save=False) + item.save() + + print(f" ✓ Added item: {item_name} to {itr}") + stats["added"] += 1 # Track success! + + except Exception as e: + print(f" ✗ Error adding {fname}: {str(e)}") + stats["errors"] += 1 # Track errors + +print("\n✅ Import completed!") + +print(f"\n{'='*50}") +print(" 📊 IMPORT EXECUTION SUMMARY") +print(f"{'='*50}") +print(f"Total Files Scanned in Folders: {stats['total_seen']}") +print(f" ✓ Successfully Added to DB: {stats['added']}") +print(f" ⏭ Skipped (Already in DB): {stats['skipped_existing']}") +print(f" ⏭ Skipped (Not a PDF file): {stats['skipped_non_pdf']}") +print(f" ⚠️ Skipped (Unmatched Regex): {stats['skipped_regex']}") +print(f" ⚠️ Skipped (Folder Mismatch): {stats['skipped_mismatch']}") +print(f" ❌ Errors during upload: {stats['errors']}") +print(f"{'-'*50}") +print(" 🗄️ CURRENT DATABASE TOTALS") +print(f"{'-'*50}") +print(f"Total Courses: {Course.objects.count()}") +print(f"Total Iterations: {Itr.objects.count()}") +print(f"Total Items: {Item.objects.count()}") +print(f"{'='*50}\n") \ No newline at end of file diff --git a/arc/settings.py b/arc/settings.py index 7924943..3556df0 100755 --- a/arc/settings.py +++ b/arc/settings.py @@ -111,3 +111,14 @@ } DEFAULT_FROM_EMAIL = 'NISER Archive' + +# Ensure these are locked to your project's BASE_DIR +STATIC_URL = '/arc/static/' +STATIC_ROOT = os.path.join(BASE_DIR, 'staticfiles') + +STATICFILES_DIRS = [ + "/media/data/Anurag/Downloads/archive/arc/main/static", +] + +MEDIA_URL = '/arc/media/' +MEDIA_ROOT = os.path.join(BASE_DIR, 'media') diff --git a/arc/urls.py b/arc/urls.py index 835eba5..7c192eb 100755 --- a/arc/urls.py +++ b/arc/urls.py @@ -13,8 +13,11 @@ 1. Import the include() function: from django.urls import include, path 2. Add a URL to urlpatterns: path('blog/', include('blog.urls')) """ + from django.contrib import admin from django.urls import include, path +from django.conf import settings +from django.conf.urls.static import static urlpatterns = [ path('arc/admin/', admin.site.urls), @@ -22,3 +25,6 @@ ] handler404 = 'main.views.error404' + +# Serve media files in development +urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT) diff --git a/main/assets/3la b/main/assets/3la old mode 100644 new mode 100755 diff --git a/main/assets/3ln b/main/assets/3ln old mode 100644 new mode 100755 diff --git a/main/assets/4la b/main/assets/4la old mode 100644 new mode 100755 diff --git a/main/assets/4ln b/main/assets/4ln old mode 100644 new mode 100755 diff --git a/main/assets/README.md b/main/assets/README.md old mode 100644 new mode 100755 diff --git a/main/assets/ma34 b/main/assets/ma34 old mode 100644 new mode 100755 diff --git a/main/assets/mm34 b/main/assets/mm34 old mode 100644 new mode 100755 diff --git a/main/assets/simple-adj b/main/assets/simple-adj old mode 100644 new mode 100755 diff --git a/main/assets/wiki-animals-34 b/main/assets/wiki-animals-34 old mode 100644 new mode 100755 diff --git a/main/gen.py b/main/gen.py old mode 100644 new mode 100755 diff --git a/main/recom.py b/main/recom.py old mode 100644 new mode 100755 index 6017dd0..ae884c2 --- a/main/recom.py +++ b/main/recom.py @@ -5,27 +5,24 @@ import os import pandas as pd +# Dynamically get the directory where recom.py lives +BASE_DIR = os.path.dirname(os.path.abspath(__file__)) +# Create an absolute path for the CSV file +CSV_PATH = os.path.join(BASE_DIR, "recom_data.csv") + def start(): """ Function to check if the file to store the user file access data already exists or not, if not then create one. - - Parameters - ---------- - None - - Returns - ------- - None """ - if not os.path.exists("recom_data.csv"): - with open("recom_data.csv", "a") as fp: + if not os.path.exists(CSV_PATH): + with open(CSV_PATH, "a") as fp: fp.write("Files") global df, val_count val_count = 0 - df = pd.read_csv("recom_data.csv", index_col="Files") + df = pd.read_csv(CSV_PATH, index_col="Files") start() # Call the start function @@ -34,19 +31,7 @@ def start(): def get_recom(user_id): """ Function to get the list of recommended files for a given user. - - Parameters - ---------- - user_id : int, str - Unique ID of the user. - - Returns - ------- - list - A list of recommended files sorted in descending order of priority. - With max length of list equals to 10. """ - user_id = str(user_id) if user_id in df.columns: @@ -71,19 +56,7 @@ def get_recom(user_id): def update(file, user_id): """ Function to update the list of files accessed by user. - - Parameters - ---------- - file : str - Name of the file being accessed by user. - user_id : int, str - Unique ID of the user accessing the file. - - Returns - ------- - None """ - user_id = str(user_id) if user_id in df.columns: @@ -100,5 +73,6 @@ def update(file, user_id): val_count += 1 if val_count >= 5: - df.to_csv("recom_data.csv") - val_count = 0 + # Update to use the absolute path when saving! + df.to_csv(CSV_PATH) + val_count = 0 \ No newline at end of file diff --git a/main/static/main/css/file.css b/main/static/main/css/file.css old mode 100644 new mode 100755 diff --git a/main/static/main/css/main.css b/main/static/main/css/main.css old mode 100644 new mode 100755 diff --git a/main/static/main/js/course.js b/main/static/main/js/course.js old mode 100644 new mode 100755 diff --git a/main/static/main/js/main.js b/main/static/main/js/main.js old mode 100644 new mode 100755 diff --git a/main/static/main/js/school.js b/main/static/main/js/school.js old mode 100644 new mode 100755 diff --git a/main/static/main/js/user.js b/main/static/main/js/user.js old mode 100644 new mode 100755 diff --git a/main/static/main/package.json b/main/static/main/package.json new file mode 100755 index 0000000..8ee375c --- /dev/null +++ b/main/static/main/package.json @@ -0,0 +1,10 @@ +{ + "dependencies": { + "bootstrap": "^5.3.8", + "jquery": "^3.7.1", + "katex": "^0.16.28", + "open-iconic": "^1.1.1", + "popper.js": "^1.16.1", + "showdown": "^2.1.0" + } +} diff --git a/main/templates/main/404.htm b/main/templates/main/404.htm old mode 100644 new mode 100755 diff --git a/main/templates/main/500.htm b/main/templates/main/500.htm old mode 100644 new mode 100755 diff --git a/main/templates/main/add-crs.htm b/main/templates/main/add-crs.htm index a1ed1d2..dda2f80 100755 --- a/main/templates/main/add-crs.htm +++ b/main/templates/main/add-crs.htm @@ -1,44 +1,56 @@ +{% extends 'main/base.htm' %} {% load widget_tweaks %} - -{% if success %} - -{% elif exists %} - -{% else %} - - {% if form.errors %} - {% for field in form %} - {% for error in field.errors %} -
- {{ error|escape }} -
- {% endfor %} - {% endfor %} - - {% for error in form.non_field_errors %} -
- {{ error|escape }} +{% block title %}Add Course{% endblock %} +{% block l3h %}Add Course{% endblock %} +{% block content %} +
+
+
+
+ {% if success %} + + {% elif exists %} + + {% else %} + {% if form.errors %} + {% for field in form %} + {% for error in field.errors %} +
+ {{ error|escape }} +
+ {% endfor %} + {% endfor %} + {% for error in form.non_field_errors %} +
+ {{ error|escape }} +
+ {% endfor %} + {% endif %} +
+ {% csrf_token %} + {% for field in form %} +
+ + {{ field|add_class:'form-control' }} + {% if field.help_text %} +
{{ field.help_text }}
+ {% endif %} +
+ {% endfor %} + +
+ {% endif %}
- {% endfor %} - {% endif %} - -
- {% csrf_token %} - {% for field in form %} -
- - {{field|add_class:'form-control'}} -
- {% endfor %} - -
-{% endif %} +
+
+
+{% endblock %} diff --git a/main/templates/main/add-item.htm b/main/templates/main/add-item.htm index 4468d0b..969df05 100755 --- a/main/templates/main/add-item.htm +++ b/main/templates/main/add-item.htm @@ -1,50 +1,48 @@ +{% extends 'main/base.htm' %} {% load widget_tweaks %} - -{% if success %} - -{% else %} - -{% if form.errors %} - - {% for field in form %} - {% for error in field.errors %} -
- {{ error|escape }} -
- {% endfor %} - {% endfor %} - - {% for error in form.non_field_errors %} -
- {{ error|escape }} -
- {% endfor %} - -{% endif %} - -
- {% csrf_token %} - {% for field in form %} -
-
-
-
- +{% block title %}Add Resource{% endblock %} +{% block l3h %}Add Resource{% endblock %} +{% block content %} +
+
+
+
+ {% if success %} + -
- -
-
+ {% else %} + {% if form.errors %} + {% for field in form %} + {% for error in field.errors %} +
+ {{ error|escape }} +
+ {% endfor %} + {% endfor %} + {% for error in form.non_field_errors %} +
+ {{ error|escape }} +
+ {% endfor %} + {% endif %} + + {% csrf_token %} + {% for field in form %} +
+ + {{ field|add_class:'form-control' }} + {% if field.help_text %} +
{{ field.help_text }}
+ {% endif %} +
+ {% endfor %} + + + {% endif %}
- {{ field }}
- {% endfor %} - - - -{% endif %} +
+
+{% endblock %} diff --git a/main/templates/main/add-itr.htm b/main/templates/main/add-itr.htm index 8eea750..06a7ad7 100755 --- a/main/templates/main/add-itr.htm +++ b/main/templates/main/add-itr.htm @@ -1,61 +1,56 @@ +{% extends 'main/base.htm' %} {% load widget_tweaks %} - -{% if success %} - -{% elif exists %} - -{% else %} - - {% if form.errors %} - - {% for field in form %} - {% for error in field.errors %} -
- {{ error|escape }} -
- {% endfor %} - {% endfor %} - - {% for error in form.non_field_errors %} -
- {{ error|escape }} -
- {% endfor %} - - {% endif %} - -
- {% csrf_token %} - {% for field in form %} -
-
-
-
- +{% block title %}Add Iteration{% endblock %} +{% block l3h %}Add Iteration{% endblock %} +{% block content %} +
+
+
+
+ {% if success %} + -
- {% if field.help_text %} {% endif %} + {% elif exists %} + -
+ {% else %} + {% if form.errors %} + {% for field in form %} + {% for error in field.errors %} +
+ {{ error|escape }} +
+ {% endfor %} + {% endfor %} + {% for error in form.non_field_errors %} +
+ {{ error|escape }} +
+ {% endfor %} + {% endif %} + + {% csrf_token %} + {% for field in form %} +
+ + {{ field|add_class:'form-control' }} + {% if field.help_text %} +
{{ field.help_text }}
+ {% endif %} +
+ {% endfor %} + + + {% endif %}
- {{ field }}
- {% endfor %} - - - -{% endif %} +
+
+{% endblock %} diff --git a/main/templates/main/base.htm b/main/templates/main/base.htm index 805b52e..52faeef 100755 --- a/main/templates/main/base.htm +++ b/main/templates/main/base.htm @@ -1,110 +1,616 @@ {% load static %} - - - - - - - - {% block css %} {% endblock %} - {% block title %} {% endblock %} | NISER Archive - - - -
- -
- -
- {% block alerts %} {% endblock %} - {% block recom %} {% endblock %} -

{% block l3h %} {% endblock %}

-
{% block l5h %} {% endblock %}
- {% block content %} {% endblock %} - - -
-
- -
-
- Coding Club | NISER, Bhubaneswar - FAQ -
-
- - - - - - - {% block js %} {% endblock %} - + + + + + + + + + + {% block js %}{% endblock %} + diff --git a/main/templates/main/contact.htm b/main/templates/main/contact.htm new file mode 100755 index 0000000..824183e --- /dev/null +++ b/main/templates/main/contact.htm @@ -0,0 +1,13 @@ +{% extends 'main/base.htm' %} +{% block title %}Contact{% endblock %} +{% block l3h %}Contact{% endblock %} +{% block content %} +
+

Contact Us

+

+ For any queries, suggestions, or issues, please email us at: +
+ code@niser.ac.in +

+
+{% endblock %} diff --git a/main/templates/main/course.htm b/main/templates/main/course.htm index b5c5456..bf449e0 100755 --- a/main/templates/main/course.htm +++ b/main/templates/main/course.htm @@ -5,51 +5,43 @@ {% block title %}{{ crs }}{% endblock %} {% block l3h %}{{ crs }}{% endblock %} -{% block content %} - {% if itr_list %} - - {% else %} -

There are no iterations.

- {% endif %} - - {% if user.is_authenticated %} -
- -
- - -
-