Skip to content

Commit

Permalink
Adding baisc Course Content Activation and Deactivation in Course Con…
Browse files Browse the repository at this point in the history
…tent Page

Signed-off-by: Satish Surath <connect@sati.sh>
  • Loading branch information
satishsurath committed Aug 14, 2023
1 parent f92e8ed commit ed86102
Show file tree
Hide file tree
Showing 4 changed files with 148 additions and 27 deletions.
47 changes: 47 additions & 0 deletions app/file_operations.py
Original file line number Diff line number Diff line change
Expand Up @@ -165,4 +165,51 @@ def delete_files_in_folder(folder_path):
except Exception as e:
print(f'Failed to delete: Reason: {e}')



def get_content_files(folder_path):
"""Get a list of content files from the given folder, excluding specific and hidden files."""
return [
f for f in os.listdir(folder_path)
if os.path.isfile(os.path.join(folder_path, f))
and not f.startswith('.')
and f != 'Textchunks.npy'
and f != 'Textchunks-originaltext.csv'
and f != app.config['ACTIVATIONS_FILE']
]

def check_and_update_activations_file(folder_path):
"""
Check and update the course activation status JSON file based on the current content in the specified folder.
Parameters:
- folder_path (str): Path to the directory containing content files.
Returns:
- dict: Updated activations with keys being content file names and values being their activation status (True/False).
The function does the following:
1. Retrieves the list of content files present in the directory, ignoring specific and hidden files.
2. Loads the existing activations from the ACTIVATIONS_FILE if it exists, otherwise initializes an empty dictionary.
3. Updates the activations based on the current content, setting the status to False for any new content.
4. Saves the updated activations back to the ACTIVATIONS_FILE.
"""
contents = get_content_files(folder_path)
# Load existing activations if they exist
activations_path = os.path.join(folder_path, app.config['ACTIVATIONS_FILE'])
if os.path.exists(activations_path):
with open(activations_path, 'r') as f:
activations = json.load(f)
else:
activations = {}

# Update activations based on existing content
for content in contents:
if content not in activations:
activations[content] = False

# Save updated activations
with open(activations_path, 'w') as f:
json.dump(activations, f)

return activations
84 changes: 57 additions & 27 deletions app/routes.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import time
import threading
import csv
import json


from csv import reader
Expand Down Expand Up @@ -41,7 +42,9 @@
delete_file,
get_first_txt_file,
get_file_path,
delete_files_in_folder
delete_files_in_folder,
get_content_files,
check_and_update_activations_file
)

from pdfminer.high_level import extract_text
Expand Down Expand Up @@ -196,6 +199,50 @@ def delete_item():
delete_folder(path)
return redirect(request.referrer)



@app.route('/debug_toggle_activation/<course_name>/<file_name>', methods=['POST'])
def debug_toggle_activation(course_name, file_name):
app.logger.info("Debug endpoint triggered!")
return jsonify(success=True, message="Debug endpoint!")

@app.errorhandler(400)
def bad_request_error(error):
app.logger.error(f"Bad Request Error: {error}")
return jsonify(success=False, error="Bad Request"), 400


@app.route('/toggle_activation/<course_name>/<file_name>', methods=['POST'])
#@login_required
def toggle_activation(course_name, file_name):
app.logger.info(f"Raw request values: {request.values}")
app.logger.info(f"Entered toggle_activation for course {course_name} and file {file_name}")
try:
app.logger.info("Starting toggle_activation logic...")
app.logger.info(f"Entering toggle_activation with course_name: {course_name}, file_name: {file_name}")

folder_path = os.path.join(app.config["FOLDER_UPLOAD"], course_name)
activations_path = os.path.join(folder_path, app.config['ACTIVATIONS_FILE'])
if os.path.exists(activations_path):
with open(activations_path, 'r') as f:
activations = json.load(f)

activations[file_name] = not activations.get(file_name, False)

with open(activations_path, 'w') as f:
json.dump(activations, f)

app.logger.info(f"Updated activations for {file_name}. New status: {activations[file_name]}")

return jsonify(success=True, status=activations[file_name])
else:
app.logger.warning(f"Activation file not found for course: {course_name}")
return jsonify(success=False, error="Activation file not found!")
except Exception as e:
app.logger.error(f"Exception in toggle_activation: {str(e)}", exc_info=True)
return jsonify(success=False, error=str(e))


@app.route('/course-contents/<course_name>', methods=['GET', 'POST'])
@login_required
def course_contents(course_name):
Expand All @@ -205,26 +252,21 @@ def course_contents(course_name):
save_pdf_and_extract_text(form, course_name)
# Part 2: Load Course Content:
folder_path = os.path.join(app.config["FOLDER_UPLOAD"], course_name)
#part 3: check for
#print(folder_path)
file_info = detect_final_data_files(folder_path)
#print(file_info)
#hiding other folders and hidden files
if os.path.exists(folder_path):
#contents = [f for f in os.listdir(folder_path) if os.path.isfile(os.path.join(folder_path, f)) and not f.startswith('.')]
contents = [f for f in os.listdir(folder_path)
if os.path.isfile(os.path.join(folder_path, f))
and not f.startswith('.')
and f != 'Textchunks.npy'
and f != 'Textchunks-originaltext.csv']
else:
contents = []
contents = get_content_files(folder_path)
file_info = detect_final_data_files(folder_path) # for 'textchunks.npy' and 'textchunks-originaltext.csv' if they exist
activations = check_and_update_activations_file(folder_path)
contents_info = check_processed_files(contents, folder_path)
for info in contents_info:
filename = info[0]
info.append(activations.get(filename, False))

if get_first_txt_file(os.path.join(app.config['FOLDER_PROCESSED_SYLLABUS'], course_name)):
syllabus = read_from_file_text(get_first_txt_file(os.path.join(app.config['FOLDER_PROCESSED_SYLLABUS'], course_name))).replace('\n', '<br>')
else:
syllabus = None
# we have now processed PDF Uploads, Syllabus Loading, Course Content Loading.
# When checking and updating activations

return render_template(
'course_contents.html',
course_name=course_name,
Expand Down Expand Up @@ -266,18 +308,6 @@ def preview_chunks(course_name):
return render_template('preview_chunks.html', course_name=course_name, zip=zip, csv_files=csv_files, second_entries=second_entries, name=session.get('name'))


@app.route('/toggle_activation', methods=['POST'])
def toggle_activation():
filename = request.form.get('filename')
course_name = request.form.get('course_name')
status = request.form.get('status') == 'true'

# TODO: Update the status in your JSON file

return jsonify({'success': True})



@app.route('/course-syllabus/<course_name>', methods=['GET', 'POST'])
@login_required
def course_syllabus(course_name):
Expand Down
43 changes: 43 additions & 0 deletions app/templates/base.html
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
<meta name="theme-color" content="#ffffff">
<meta name="description" content="All-Day-TA - Virtual Teaching Assistant">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="csrf-token" content="{{ csrf_token() }}">
<link rel="stylesheet" type="text/css" href="/static/style.css">
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Cabin&display=swap">
<script src="https://cdn.jsdelivr.net/gh/google/code-prettify@master/loader/run_prettify.js"></script>
Expand Down Expand Up @@ -207,6 +208,48 @@
const savedTheme = localStorage.getItem('theme') || 'dark';
setTheme(savedTheme);
}




function toggleActivation(fileName, courseName) {
let csrfToken = $('meta[name="csrf-token"]').attr('content');

console.log(`Attempting to toggle activation for course: ${courseName}, file: ${fileName}`);

let encodedCourseName = encodeURIComponent(courseName);
let encodedFileName = encodeURIComponent(fileName);
let link = $("#activation-" + fileName);

console.log(`Encoding completed ${encodedCourseName}, file: ${encodedFileName}`);

$.ajax({
url: "/toggle_activation/" + encodedCourseName + "/" + encodedFileName,
type: 'POST',
headers: {
"X-CSRFToken": csrfToken
},
success: function(data) {
if (data.success) {
if (data.status) {
console.log(`Received data.status: ${data.status}`);
console.log(`Successfully toggled activation for file: ${fileName}. New status: ${data.status}`);
link.text(data.status ? "Activate" : "Deactivate");
} else {
console.error(`Failed to toggle activation for file: ${fileName}. Error: ${data.error}`);
}
} else {
console.error("Error while toggling activation: " + data.error);
}
},
error: function(xhr, status, error) {
console.error(`AJAX request failed with status: ${status}, error: ${error}`);
}
});
}



</script>
</head>
<body>
Expand Down
1 change: 1 addition & 0 deletions config.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ class Config(object):
FOLDER_PROCESSED_CONTENT = 'app/content'
FOLDER_PROCESSED_SYLLABUS = 'app/syllabus'
FOLDER_SETTINGS = 'app/settings'
ACTIVATIONS_FILE = 'CourseContentActivations.JSON' #file name used to store the activation status of course contents


# Configure session options
Expand Down

0 comments on commit ed86102

Please sign in to comment.