Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
  • Loading branch information
juliancoy committed Feb 6, 2024
2 parents 514792e + db42af6 commit e1a90c9
Show file tree
Hide file tree
Showing 7 changed files with 197 additions and 26 deletions.
17 changes: 17 additions & 0 deletions deismu/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# Use Python with Alpine Linux base image
FROM python:3.9-alpine

# Set the working directory in the container
WORKDIR /

# Install dependencies for headless operation
RUN apk add --no-cache \
chromium \
chromium-chromedriver \
&& pip install --no-cache-dir selenium==4.0.0 webdriver_manager

# Copy the script into the container
COPY verifyCert.py /verifyCert.py

# Command to run the script
CMD ["python", "/verifyCert.py"]
17 changes: 17 additions & 0 deletions deismu/testDocker.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
#!/bin/bash

# URL to test
TEST_URL="https://www.coursera.org/account/accomplishments/verify/GA668424ZUQH"

# Name of your Docker image
DOCKER_IMAGE="selenium"

# Run the Docker container and capture the output
output=$(docker run --rm -e TEST_URL="$TEST_URL" "$DOCKER_IMAGE")

# Check the output
echo "Output received: $output"

# Parse and check the output here
# Example: using jq to check a JSON output
# echo $output | jq 'Your conditions here'
61 changes: 61 additions & 0 deletions deismu/verifyCert.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
import json
import os
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC

# Set up Chrome options for headless operation
chrome_options = Options()
chrome_options.add_argument("--headless")
chrome_options.add_argument("--no-sandbox")
chrome_options.add_argument("--disable-dev-shm-usage")

def scrape_url(driver, url):
driver.get(url)
name_element = WebDriverWait(driver, 4).until(
EC.presence_of_element_located((By.CSS_SELECTOR, "h3.cds-119 strong"))
)
name = name_element.text if name_element else "Name not found"

course_name_element = driver.find_element(By.CSS_SELECTOR, "h2.course-name")
course_name = course_name_element.text if course_name_element else "Course name not found"

return {'name': name, 'course_name': course_name}

def lambda_handler(event, context):
results = []
urls = event.get('urls')
if not urls or not isinstance(urls, list):
return {
'statusCode': 400,
'body': json.dumps({'error': 'Missing or invalid URL list'})
}

# Initialize the headless browser
with webdriver.Chrome(options=chrome_options) as driver:
for url in urls:
try:
result = scrape_url(driver, url)
results.append(result)
except Exception as e:
results.append({'error': str(e)})

return {
'statusCode': 200,
'body': json.dumps(results)
}

# Main execution for direct run
if __name__ == '__main__':
# Get URL from environment variable
test_url = os.environ.get('TEST_URL')

if test_url:
# Simulate the event structure for direct invocation
event = {'urls': [test_url]}
result = lambda_handler(event, context=None)
print(json.dumps(result, indent=4))
else:
print("No URL provided.")
72 changes: 64 additions & 8 deletions src/deismu.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
function addURL() {
function addURL(auth0) {
// Prompt the user to enter a URL
var urlToAdd = prompt(
"Please enter the Coursera certificate URL to verify:"
Expand Down Expand Up @@ -37,6 +37,39 @@ function addURL() {
});
}
}

async function getCompletedCourses(auth0) {
try {
// Obtain the JWT token
const token = await auth0.getTokenSilently();

// Set up your API endpoint
const apiEndpoint = 'https://your-api-endpoint.com/user-courses';

// Make the API request
const response = await fetch(apiEndpoint, {
headers: {
Authorization: `Bearer ${token}`
}
});

// Check if the response is successful
if (!response.ok) {
throw new Error('Network response was not ok');
}

// Parse the JSON response
const courses = await response.json();

return courses;
} catch (error) {
console.error('Error fetching completed courses:', error);
throw error;
}
}



function getCurriculum() {
fetch("curriculum.json")
.then((response) => response.json())
Expand All @@ -52,11 +85,14 @@ function getCurriculum() {
error.message;
});
}

function createExpandableList(data, container) {
function createList(itemData, parentElement) {
Object.keys(itemData).forEach((key) => {
// Check if the current item has a meta dictionary with a reference list
let hasReference = itemData[key]?.meta?.reference?.length > 0;

if (key !== "meta") {
// Exclude 'meta' nodes
if (
typeof itemData[key] === "object" &&
itemData[key] !== null &&
Expand All @@ -69,9 +105,18 @@ function createExpandableList(data, container) {
let sectionTitle = document.createElement("button");
sectionTitle.className = "section-title";
sectionTitle.innerText = key;
sectionTitle.onclick = function () {
this.nextElementSibling.classList.toggle("active");
};

if (hasReference) {
sectionTitle.onclick = function () {
window.open(itemData[key].meta.reference[0], '_blank');
};
sectionTitle.style.textDecoration = "underline";
sectionTitle.style.cursor = "pointer";
} else {
sectionTitle.onclick = function () {
this.nextElementSibling.classList.toggle("active");
};
}

let itemList = document.createElement("div");
itemList.className = "item-list";
Expand All @@ -86,7 +131,18 @@ function createExpandableList(data, container) {
// Create item for non-object data
let item = document.createElement("div");
item.className = "item";
item.innerText = key + ": " + itemData[key];

if (hasReference) {
item.onclick = function () {
window.open(itemData.meta.reference[0], '_blank');
};
item.style.textDecoration = "underline";
item.style.cursor = "pointer";
item.innerText = key + ": " + itemData[key];
} else {
item.innerText = key + ": " + itemData[key];
}

parentElement.appendChild(item);
}
}
Expand All @@ -96,12 +152,12 @@ function createExpandableList(data, container) {
createList(data, container);
}

function addListeners(){

function addListeners(auth0){
document.body.addEventListener('click', function(event) {
switch (event.target.id) {
case 'btn-verify-certificate':
addURL(); // Function for verifying certificate
addURL(auth0); // Function for verifying certificate
break;
}
});
Expand Down
1 change: 1 addition & 0 deletions src/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
rel="stylesheet"
/>
<link rel="stylesheet" type="text/css" href="style.css" />
<link rel="stylesheet" type="text/css" href="navbar.css" />
<script
type="text/javascript"
src="//translate.google.com/translate_a/element.js?cb=googleTranslateElementInit"
Expand Down
5 changes: 3 additions & 2 deletions src/navbar.css
Original file line number Diff line number Diff line change
Expand Up @@ -36,15 +36,16 @@
.dropdown-content {
display: none;
position: absolute;
background-color: #333; /* Set to black (#333) for consistency
*/
background-color: #333; /* Set to black (#333) for consistency */
z-index: 1;
}

.dropdown-content a {
color: white; /* Ensure text is white for readability */
text-align: left;
transition: background-color 0.3s;
padding: 10px 15px; /* Add padding to dropdown items */

}

.dropdown-content a:hover {
Expand Down
50 changes: 34 additions & 16 deletions src/navbar.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,29 @@
// Function to populate chapter dropdown
function toggleHamburgerMenu() {
const menuItems = document.querySelector('.menu-items'); // Adjust the selector as needed
const hamburgerIcon = document.querySelector('.hamburger'); // Adjust the selector as needed

// Toggle a class that controls the visibility of the menu items
menuItems.classList.toggle('active');

// Optional: Change the icon or appearance of the hamburger button when the menu is open
// For example, if you want to change the icon to an 'X' when the menu is open, you could toggle another class here
hamburgerIcon.classList.toggle('open');
}


function createDropdownOption(dropdown, itemName, itemText, onClickAction) {
const chapterDropdown = document.getElementById("chapterDropdown");
const pillarDropdown = document.getElementById("pillarDropdown");
const option = document.createElement("a");
option.textContent = itemName;
option.href = "javascript:void(0);";
option.onclick = onClickAction;
dropdown.appendChild(option);
}

function populateChapterSelect(chapters, alltext) {
const chapterDropdown = document.getElementById("chapterDropdown");
const chapterSelect = document.getElementById("chapterSelect");
const selectedNodeText = document.getElementById("selected-node-text");

chapterSelect.onclick = function () {
Expand All @@ -11,52 +34,45 @@ function populateChapterSelect(chapters, alltext) {

chapterDropdown.innerHTML = '';
chapters.forEach((chapter) => {
const option = document.createElement("a");
option.textContent = chapter.name;
option.href = "javascript:void(0);";
option.onclick = function () {
createDropdownOption(chapterDropdown, chapter.name, chapter.text, function () {
chapterSelect.textContent = chapter.name;
selectedNodeText.innerHTML = chapter.text;
};
chapterDropdown.appendChild(option);
});
});
}

function populatePillarSelect(pillars, alltext) {
const selectedNodeText = document.getElementById("selected-node-text");
const pillarDropdown = document.getElementById("pillarDropdown");
const pillarSelect = document.getElementById("pillarSelect");
const selectedNodeText = document.getElementById("selected-node-text");
const chapterDropdown = document.getElementById("chapterDropdown");
const chapterSelect = document.getElementById("chapterSelect");

pillarSelect.onclick = function () {
pillarSelect.textContent = "All Pillars"
pillarSelect.textContent = "All Pillars";
selectedNodeText.innerHTML = alltext;
chapterDropdown.innerHTML = '';
chapterSelect.textContent = "All Chapters";
};
pillarSelect.onclick();

pillars.forEach((pillar) => {
const option = document.createElement("a");
option.textContent = pillar.name;
option.href = "javascript:void(0);";
option.onclick = function () {
createDropdownOption(pillarDropdown, pillar.name, pillar.text, function () {
pillarSelect.textContent = pillar.name;
selectedNodeText.innerHTML = pillar.text;
populateChapterSelect(pillar.children, pillar.text);
};
pillarDropdown.appendChild(option);
});
});
}


function loadDeismUContent() {
fetch('deismu.html?_=' + new Date().getTime())
.then(response => response.text())
.then(html => {
const selectedNodeText = document.getElementById('selected-node-text');
selectedNodeText.innerHTML = html;
addListeners();
addListeners(auth0);
getCurriculum();
})
.catch(error => console.error('Error loading DeismU:', error));
Expand Down Expand Up @@ -176,3 +192,5 @@ document.getElementById('bojButton').addEventListener('click', function () {
document.getElementById('deismuButton').addEventListener('click', loadDeismUContent);

configureAuth0();


0 comments on commit e1a90c9

Please sign in to comment.