Skip to content
Snippets Groups Projects
Commit 55e29b09 authored by Rhiannon Austin's avatar Rhiannon Austin
Browse files

Trying to fix merge conflicts

parents 9b690021 616dd5a5
No related branches found
No related tags found
No related merge requests found
Showing
with 403 additions and 19 deletions
{
"CurrentProjectSetting": null
}
\ No newline at end of file
{
"ExpandedNodes": [
""
],
"SelectedNode": "\\README.md",
"PreviewInSolutionExplorer": false
}
File added
File added
import os
import sqlite3
from typing import List
from typing import List, Tuple
DATABASE = os.path.join(os.path.dirname(os.path.abspath(__file__)), "database.db")
......@@ -50,8 +50,25 @@ with Connection() as conn:
url text NOT NULL,
workspace_id integer NOT NULL,
FOREIGN KEY (workspace_id) REFERENCES Workspaces(id))''')
conn.execute('''CREATE TABLE IF NOT EXISTS AddressToLatLong (
id integer NOT NULL PRIMARY KEY AUTOINCREMENT,
address text NOT NULL,
latlong text NOT NULL)''')
conn.commit()
def lookup_address(address: str):
with Connection() as conn:
conn.execute("SELECT latlong FROM AddressToLatLong WHERE address = ?", (address,))
res = conn.cursor.fetchone()[0]
(lat, long) = res.split(",")
return (float(lat), float(long))
def set_address_latlong(address: str, latlong: Tuple[float, float]):
with Connection() as conn:
latlong_str = f"{ repr(latlong[0]) },{ repr(latlong[1]) }"
conn.execute("INSERT INTO AddressToLatLong (address, latlong) VALUES (?, ?)", (address, latlong_str))
conn.commit()
class Workspace:
def __init__(self, name: str,
address: str, main_photo: str, additional_photos: List[str], description: str,
......@@ -68,10 +85,35 @@ class Workspace:
self.opening_hours = opening_hours
self.checkin_instructions = checkin_instructions
def validate(self):
errors = []
if len(self.name.strip()) <= 0:
errors.append("Name must not be empty")
if len(self.address.strip()) <= 0:
errors.append("Address must not be empty")
if len(self.main_photo.strip()) <= 0:
errors.append("Main photo must not be empty")
if len(self.description.strip()) <= 0:
errors.append("Description must not be empty")
if len(self.website.strip()) <= 0:
errors.append("Website must not be empty")
if len(self.email.strip()) <= 0:
errors.append("Email must not be empty")
if len(self.phone_number.strip()) <= 0:
errors.append("Phone number must not be empty")
if len(self.opening_hours.strip()) <= 0:
errors.append("Opening hours must not be empty")
for x in self.additional_photos:
if len(x.strip()) <= 0:
errors.append("Each edditional photos must not be empty")
return errors
def from_query(conn, tuple):
(id, name, address, main_photo, description, website, email, phone_number, opening_hours, checkin_instructions) = tuple
additional_photos = []
conn.execute("SELECT url FROM AdditionalPhotos WHERE workspace_id = ?", (str(id)))
for x in conn.cursor.fetchall():
additional_photos.append(x[0])
......@@ -96,5 +138,6 @@ def get_workspaces():
with Connection() as conn:
conn.execute("SELECT * FROM Workspaces")
return [Workspace.from_query(conn, x) for x in conn.cursor.fetchall()]
print(get_workspaces())
image-asset.png

50 KiB

import database
import os
import json
print(database.add_workspace(database.Workspace(
"CodeBase",
"CodeBase Edinburgh, 37a Castle Terrace, Edinburgh, EH1 2EL",
"https://images.squarespace-cdn.com/content/v1/55439320e4b0f92b5d6c4c8b/1505921023376-PAHUDHVOOKIYF4XQPHOO/5951229048_3e3d50fcb1_o.jpg?format=750w",
["https://images.squarespace-cdn.com/content/v1/55439320e4b0f92b5d6c4c8b/1636387943314-W9JWMS6ZX4DEZSPUV7T0/Copy+of+Unfiltered_square+%281%29.png?format=500w"],
"We've been exploring the world of startups...",
"https://www.thisiscodebase.com",
"hannah@thisiscodebase.com",
"+44 131 560 2003",
"Monday - Friday, 9am - 5pm",
"Tramsched members should contact Hannah using the email address listed."
)))
def import_workspace(data):
workspace = database.Workspace(
data["name"],
data["address"],
data["main_photo"],
data["additional_photos"],
data["description"],
data["website"],
data["email"],
data["phone_number"],
data["opening_hours"],
data["checkin_instructions"]
)
latlong = data["latlong"]
if latlong != None:
database.set_address_latlong(workspace.address, (latlong[0], latlong[1]))
database.add_workspace(workspace)
file = os.path.join(os.path.dirname(os.path.abspath(__file__)), "workspaces.json")
with open(file, "r", encoding="utf8") as stream:
data = json.load(stream)
for workspace in data:
import_workspace(workspace)
print(f"Imported {len(data)} workspace(s)")
from flask import Flask, request, render_template, redirect
import database
import json
import re
app = Flask(__name__)
......@@ -16,7 +18,69 @@ def login():
return redirect("/")
else:
message = "Wrong Username"
return render_template("login.html")
return render_template("/login.html")
@app.route("/about", methods = ["GET"])
def about():
return render_template("about.html")
@app.route("/Locations", methods = ["GET"])
def Locations():
return render_template("Locations.html")
@app.route("/contact-us", methods = ["GET"])
def contact():
return render_template("contact-us.html")
@app.route("/map", methods = ["GET"])
def map():
if request.method == "GET":
workspaces = database.get_workspaces()
data = [{"id": x.id, "name": x.name, "address": x.address, "phoneNumber": x.phone_number, "email": x.email, "website": x.website, "latlong": database.lookup_address(x.address)} for x in workspaces]
dumped = json.dumps(data)
return render_template("map.html", json = re.sub(r"(?i)\</script\>", "<\/script>", dumped)) # escape </script>
@app.route("/admin/add-workspace", methods = ["GET", "POST"])
def add_workspace():
if request.method == "GET":
return render_template("add-workspace.html")
if request.method == "POST":
additional_photos = request.form["additional_photos"]
additional_photos = [x.strip() for x in additional_photos.split("\n")] if len(additional_photos) > 0 else []
workspace = database.Workspace(
request.form["name"],
request.form["address"],
request.form["main_photo"],
additional_photos,
request.form["description"],
request.form["website"],
request.form["email"],
request.form["phone_number"],
request.form["opening_hours"],
request.form["checkin_instructions"]
)
errors = workspace.validate()
try:
latitude = float(request.form["latitude"])
except ValueError:
errors.append("Latitude must be a number")
try:
longitude = float(request.form["longitude"])
except ValueError:
errors.append("Longitude must be a number")
if len(errors) > 0:
messages = ["Errors were found:"]
messages.extend(errors)
else:
database.set_address_latlong(workspace.address, (latitude, longitude))
database.add_workspace(workspace)
messages = ["Workspace added successfully"]
return render_template("add-workspace-result.html", messages = messages)
if __name__ == "__main__":
app.run(debug = True)
.container {
overflow: hidden;
}
.filterDiv {
float: left;
background-color: #2196F3;
color: #ffffff;
width: 100px;
line-height: 100px;
text-align: center;
margin: 2px;
display: none; /* Hidden by default */
}
.show {
display: block;
}
.btn {
border: none;
outline: none;
padding: 12px 16px;
background-color: #f1f1f1;
cursor: pointer;
}
.btn:hover {
background-color: #ddd;
}
.btn.active {
background-color: #666;
color: white;
}
File added
File added
File added
File added
File added
File added
filterSelection("all")
function filterSelection(c) {
var x, i;
x = document.getElementsByClassName("filterDiv");
if (c == "all") c = "";
// Add the Show class
for (i = 0; i < x.length; i++) {
RemoveClass(x[i], "show");
if (x[i].className.indexOf(c) > -1) AddClass(x[i], "show");
}
}
// Showing filtered elements
function AddClass(element, name) {
var i, arr1, arr2;
arr1 = element.className.split(" ");
arr2 = name.split(" ");
for (i = 0; i < arr2.length; i++) {
if (arr1.indexOf(arr2[i]) == -1) {
element.className += " " + arr2[i];
}
}
}
// Removing elements that are not selected
function RemoveClass(element, name) {
var i, arr1, arr2;
arr1 = element.className.split(" ");
arr2 = name.split(" ");
for (i = 0; i < arr2.length; i++) {
while (arr1.indexOf(arr2[i]) > -1) {
arr1.splice(arr1.indexOf(arr2[i]), 1);
}
}
element.className = arr1.join(" ");
}
// Add active class to current control button
var btnContainer = document.getElementById("myBtnContainer");
var btns = btnContainer.getElementsByClassName("btn");
for (var i = 0; i < btns.length; i++) {
btns[i].addEventListener("click", function() {
var current = document.getElementsByClassName("active");
current[0].className = current[0].className.replace(" active", "");
this.className += " active";
});
}
var map = L.map("map").setView([54.004, -2.55], 5);
L.tileLayer("https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png", {
attribution: "&copy; <a href=\"https://www.openstreetmap.org/copyright\">OpenStreetMap</a> contributors"
}).addTo(map);
for (let workspace of mapData) {
L.marker(workspace.latlong).addTo(map)
.bindPopup(`<div class="popup"><div><a href="/workspace/${ encodeURIComponent(workspace.id) }" class="popup-title">${
escapeHTML(workspace.name)
}</a></div><div>Phone: <a href="tel:${ escapeHTML(workspace.phoneNumber) }">${
escapeHTML(workspace.phoneNumber)
}</a></div><div>Email: <a href="mailto:${ escapeHTML(workspace.email) }">${
escapeHTML(workspace.email)
}</a></div><div>Website: <a href="${ escapeHTML(workspace.website) }" target="_blank">${
escapeHTML(workspace.website)
}</a></div><div>${ escapeHTML(workspace.address) }</div></div>`);
}
function escapeHTML(html) {
let lookup = Object.create(null);
lookup["<"] = "&lt;"
lookup[">"] = "&gt;"
lookup["\""] = "&quot;"
lookup["&"] = "&amp";
return html.replace(/[<>"&]/g, v => lookup[v] || "");
}
\ No newline at end of file
h1
{ color: blue;}
/* fonts obtained from and used by https://members.tramshedtech.co.uk/ */
@font-face {
font-family: CircularXX;
src: url(/static/fonts/CircularXX-Book.woff2) format("woff2");
src: url(/static/fonts/CircularXX-Book.woff) format("woff");
font-weight: 400;
font-style: normal
}
@font-face {
font-family: CircularXX;
src: url(/static/fonts/CircularXX-Medium.woff2) format("woff2");
src: url(/static/fonts/CircularXX-Medium.woff) format("woff");
font-weight: 500;
font-style: normal
}
@font-face {
font-family: CircularXX;
src: url(/static/fonts/CircularXX-Bold.woff2) format("woff2");
src: url(/static/fonts/CircularXX-Bold.woff) format("woff");
font-weight: 700;
font-style: normal
}
body {
margin: 0;
font-family: CircularXX,sans-serif;
font-size: 1rem;
font-weight: 400;
line-height: 1.5;
color: #111;
text-align: left;
background-color: #f5f5f5
}
header {
background-color: #f5f5f5;
font-size: 30px;
}
nav li {
display: inline;
......@@ -11,7 +54,7 @@ nav li {
nav li:last-child {
color: red;
background-color: red;
background-color:#5F9EA0;
border-right: none;
border-top-left-radius: 1000%;
border-bottom-left-radius: 1000%;
......@@ -21,9 +64,12 @@ nav ul {
margin: 0;
padding: 0;
overflow: hidden;
background-color: #333;
background-color: black;
}
form{
text-align: center;
}
nav li a {
display: block;
......@@ -32,6 +78,13 @@ nav li a {
padding: 14px 16px;
text-decoration: none;
}
nav ul p {
display: block;
color: white;
float: left;
padding: 18px 20px;
text-decoration: none;
}
nav li a:hover {
......@@ -50,3 +103,60 @@ nav li a:hover:last-child {
background-color: #111;
}
.workspace-item {
background-color: #fff;
border-radius: 0.5rem;
box-shadow: 0 2px 2px 0 rgb(17 17 17 / 5%);
padding: 1.5rem;
margin: 0.75rem;
display: flex;
}
.workspace-item .image-col {
width: 200px;
}
.workspace-item .image-col .image {
max-width: 100%;
}
.workspace-item .main-col {
flex: 1 0;
margin-left: 1rem;
}
.workspace-item .title {
color: inherit;
display: inline-block;
font-size: 1.25rem;
margin-bottom: 1rem;
font-weight: 600;
line-height: 1.2;
}
.workspace-item .meta {
color: #666;
}
.workspace-item .dot {
color: #666;
font-weight: 700;
}
#map {
height: 600px;
}
#map .popup {
font-family: CircularXX,sans-serif;
font-size: 0.8rem;
font-weight: 400;
line-height: 1.5;
}
#map .popup-title {
color: inherit;
font-size: 1rem;
font-weight: 500;
}
teamcb_720.jpg

112 KiB

{% extends "main.html" %}
{% block title %}Locations{% endblock %}
{% block mainBlock %}
<div id="myBtnContainer">
<button class="btn active" onclick="filterSelection('all')"> Show all</button>
<button class="btn" onclick="filterSelection('Wales')"> Wales</button>
<button class="btn" onclick="filterSelection('North-England')"> North England</button>
<button class="btn" onclick="filterSelection('South-West-England')"> South West England</button>
<button class="btn" onclick="filterSelection('Midlands')"> Midlands</button>
<<<<<<< HEAD
<button class="btn" onclick="filterSelection('Scotland')"> Scotland</button>
=======
<button class="btn" onclick="filterSelection('Scotland')"> Scotland<button>
>>>>>>> eee8f2dbda7bb480a8543f73de8f7278a1aed2e0
</div>
<div class="container">
<div class="filterDiv Wales">Location 1</div>
<div class="filterDiv Wales">Location 2</div>
<div class="filterDiv North-England">Location 3</div>
<div class="filterDiv North-England">Location 4</div>
<div class="filterDiv South-West-England">Location 5</div>
<div class="filterDiv South-West-England">Location 6</div>
<div class="filterDiv South-West-England">Location 7</div>
<div class="filterDiv Midlands">Location 8</div>
<div class="filterDiv Midlands">Location 9</div>
<div class="filterDiv Scotland">Location 10</div>
<div class="filterDiv Scotland">Location 11</div>
<div class="filterDiv Scotland">Location 12</div>
</div>
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment