Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 5 additions & 2 deletions firmware/__init__.py
Original file line number Diff line number Diff line change
@@ -1,16 +1,18 @@
"""Firmware module"""
"""Firmware module first run at app init.Defines the database name"""

import os
from flask import Flask, request, session, g, redirect, url_for
from flask import abort, render_template, flash
from flask.ext.bcrypt import Bcrypt
from flask_wtf.csrf import CSRFProtect


app = Flask(__name__)
app.config.from_object(__name__)
app.config.update(dict(
DATABASE=os.path.join(app.root_path, 'firmware.db'),
SECRET_KEY='key'
SECRET_KEY='key',
TRAP_BAD_REQUEST_ERRORS=True
))
encrypt = Bcrypt(app)

Expand All @@ -24,3 +26,4 @@
from firmware import widgets
from firmware import decorators
from firmware import authorization
from firmware import helper_functions
1 change: 1 addition & 0 deletions firmware/authorization.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
""" module for operations that need authorization """


def authorize_edit_company(session, company):
""" function that verifies if the user in the current session has editing
rights over the company """
Expand Down
17 changes: 11 additions & 6 deletions firmware/decorators.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
""" module for the decorators in firmware """


import json
from functools import wraps
from flask import render_template
from firmware.views import session


def login_required(role):
def login_required(role, method="GET"):
"""function that calls the view decorator with 1 parameter"""
def view_decorator(funct):
""" the actual deocrator that wraps a view function and renders it only
Expand All @@ -21,10 +21,15 @@ def check_login(*args, **kwargs):
if session is None:
errors = {'no_server': "Server not running at the moment!"}
return render_template('404.html', error_messages=errors)
if session.get('user', None) is None and role == 'user':
errors = {'not_logged': "Your account must be of type '%s' to \
continue" % (role)}
return render_template('404.html', error_messages=errors)
if session.get('user', None) is None:
errors = {'not_logged': "You must be logged in to continue"}
if method == "GET":
return render_template('404.html', error_messages=errors)
response = {
'success': False,
'errors': errors
}
return json.dumps(response)
if role == 'admin' and session['user'].get('privilege', 'user') == 'user':
errors = {'not_logged_admin': "You must be logged in as an admin \
to access this page.Please upgrade to admin"}
Expand Down
32 changes: 13 additions & 19 deletions firmware/forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
PasswordField, SelectField
from firmware.widgets import WidgetTextArea, WidgetPassword, WidgetRadio, \
WidgetSubmit, WidgetFile, WidgetSelect
from firmware import repository


class AddUser(Form):
Expand All @@ -22,8 +23,8 @@ class AddUser(Form):
password = PasswordField(
'password',
[
validators.InputRequired(message='Please add a password'),
validators.DataRequired(message='Please add a password'),
validators.InputRequired(message='Input add a password'),
validators.DataRequired(message='Passwords must match, Data'),
validators.EqualTo('confirm_password',
message='Passwords must match'),
validators.Length(min=2, max=120, message='Password must be between\
Expand All @@ -32,9 +33,9 @@ class AddUser(Form):
widget=WidgetPassword(maxlength=120)
)
confirm_password = PasswordField(
'confirm password',
'confirm_password',
[
validators.InputRequired(message='Please confirm your password!'),
validators.InputRequired(message='Please confirm your password!--inputccccc'),
],
widget=WidgetPassword(maxlength=120)
)
Expand Down Expand Up @@ -82,15 +83,12 @@ class AddUser(Form):
)
privilege = RadioField(
'privilege',
[
validators.InputRequired()
],
widget=WidgetRadio(),
choices=[('user', 'user'), ('admin', 'admin')], default='user'
)
avatar = FileField(
'avatar',
widget=WidgetFile()
widget=WidgetFile(id="picture")
)
submit = SubmitField(
'ADD USER',
Expand Down Expand Up @@ -149,8 +147,11 @@ class AddCompany(Form):
category_id = SelectField(
label='category',
coerce=int,
choices=[('default', 'add some items')],
widget=WidgetSelect(disabled="--SELECT A CATEGORY--")
choices=[(a.id, a.domain) for a in repository.get_categories()],
widget=WidgetSelect(disabled="--SELECT A CATEGORY--"),
validators=[
validators.Required(message="Please select a category")
]
)
details = TextAreaField(
'details',
Expand All @@ -164,21 +165,14 @@ class AddCompany(Form):
)
logo = FileField(
'logo',
widget=WidgetFile()
widget=WidgetFile(id="picture")
)
submit = SubmitField(
'ADD COMPANY',
widget=WidgetSubmit()
)


def __init__(self, *args, **kwargs):
super(AddCompany, self).__init__(*args, **kwargs)
if kwargs.get('categories', None) is not None:
self.category_id.choices = [(a.id, a.domain) \
for a in kwargs.get('categories')]


def to_dict(self):
""" returns the data in the form fields to a mutable dictionary
format """
Expand Down Expand Up @@ -225,7 +219,7 @@ class AddReview(Form):
message = TextAreaField(
'review',
[
validators.DataRequired(message="Please write a review"),
validators.InputRequired(message="Please write a review"),
validators.Length(min=2, max=2000, message="Review must be \
max. 2000 characters")
],
Expand Down
15 changes: 15 additions & 0 deletions firmware/helper_functions.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
""" module containing functions unrelated to the main modules of the app
used to execute specific tasks """

from werkzeug.datastructures import MultiDict


def dict_to_multidict(dictionary):
""" transforms a dictionary, dict, to a MultiDict and returns the
MultiDict """
if not dictionary:
return MultiDict()
imd = MultiDict()
for key, value in dictionary.items():
imd.add(key, value)
return imd
24 changes: 24 additions & 0 deletions firmware/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,19 @@ def serialize(self):
'privilege': self.privilege,
'gender': self.gender
}
def to_dict(self):
"""returns the user object as a dictionary"""
return {
'username': self.username,
'email': self.email,
'name': self.name,
'surname': self.surname,
'avatar': self.avatar,
'contact': self.contact,
'privilege': self.privilege,
'gender': self.gender,
'password': self.password
}


class Review(Base):
Expand All @@ -66,6 +79,16 @@ def __init__(self, **kwargs):
self.company_id = kwargs.get('company_id', None)
self.rating = kwargs.get('rating', None)

def to_dict(self):
""" returns the review object data as a dictionary """
return {
'user_id': self.user_id,
'message': self.message,
'company_id': self.company_id,
'rating': self.rating
}


class Company(Base):
"""defines / maps companies table in database"""
__tablename__ = 'companies'
Expand Down Expand Up @@ -95,6 +118,7 @@ def __init__(self, **kwargs):
def to_dict(self):
"""returns the data in the model object to a mutable dictionary form"""
return {
'id': self.id,
'name': self.name,
'description': self.description,
'details': self.details,
Expand Down
Binary file modified firmware/static/Avatars/Rares.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
21 changes: 21 additions & 0 deletions firmware/static/js/add-company.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
function addCompany(response_data, user_data) {
form_locked = document.getElementsByClassName("add-company-layout")[0];
form_locked.style.display = "none";
if(response_data.flash == "add") {
flashMessage("Please wait a moment while we add "+response_data.name+" to our list");
}
else {
flashMessage("Please wait a moment while we update your company");
}
setTimeout(function() {
window.location.replace("http://0.0.0.0:5000/details/"+response_data.id);
}, 3700);
form_locked.style.visibility = "flex";
}

document.getElementById('category_id').addEventListener("change", function() {
var categories = document.getElementById('category_id');
categories.options[categories.options.selectedIndex].selected = true;
});

submitForm("add-company", addCompany, flash_errors);
40 changes: 40 additions & 0 deletions firmware/static/js/add-review.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
function addReview(response_data, user_data) {

var review_list = document.getElementById("review-list");
var list_item = document.createElement('li');
list_item.setAttribute("class", "details-reviews");

var username_and_avatar = document.createElement('div');
username_and_avatar.setAttribute("class", "username-avatar");

var username = document.createElement('h2');
username.setAttribute("class", "details-user");
username.innerHTML = user_data.username;

var avatar = document.createElement("img");
avatar.setAttribute("class", "review-avatar");
if(user_data.avatar !== "default.jpg") {
avatar.setAttribute("src", "../static/Avatars/"+user_data.avatar);
}
else {
avatar.setAttribute("src", "../static/Defaults/user/"+user_data.avatar);
}

var review_message = document.createElement("p");
review_message.setAttribute("class", "details-user-review");
review_message.innerHTML = response_data.message;

review_list.insertBefore(list_item, review_list.firstChild);
list_item.appendChild(username_and_avatar);
list_item.appendChild(review_message);
username_and_avatar.appendChild(username);
username_and_avatar.appendChild(avatar);

review_list.scrollTop = 0;
document.getElementById("title-reviews").scrollIntoView();
document.getElementById('message').value = "";

flashMessage("Review added sucessfully");
}

submitForm("reviews-bottom", addReview, flash_errors);
8 changes: 8 additions & 0 deletions firmware/static/js/add-user.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
function addUser(response_data, user_data) {
flashMessage("New user, "+response_data.username+", added sucessfully");
setTimeout(function() {
window.location.replace("http://0.0.0.0:5000/home#reload-point");
}, 1700);
}

submitForm("add-user", addUser, flash_errors);
26 changes: 26 additions & 0 deletions firmware/static/js/flash-message.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
function flashMessage(message) {

var alerts = document.getElementById("alerts");
if (alerts == null) {
alerts = document.createElement('div');
alerts.setAttribute("class", "alerts");
alerts.setAttribute("id", "alerts");
}
document.getElementsByClassName('header')[0].appendChild(alerts);
var alert_body = document.createElement('div');
alert_body.setAttribute("class", "alert-flash");
alert_body.innerHTML = message;


var alert_close = document.createElement('span');
alert_close.setAttribute("class", "closebtn");
alert_close.setAttribute("onclick", "this.parentElement.style.display='none';");
alert_close.innerHTML="×";

alert_body.appendChild(alert_close);
alerts.appendChild(alert_body);

setTimeout(function() {
fade_out(alert_body);
}, 2700);
}
53 changes: 53 additions & 0 deletions firmware/static/js/helper-functions.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
function fade_out(element) {
var op = 1;
var timer = setInterval(function () {
if (op <= 0.05) {
clearInterval(timer);
element.style.display = 'none';
element.parentNode.removeChild(element);
}
element.style.opacity = op;
element.style.filter = 'alpha(opacity=' + op * 100 + ")";
op -= op * 0.05;
}, 5);
}


function image_to_viewport(vieportId, input, callback) {
var canvas = document.getElementById(vieportId);
context = canvas.getContext('2d');
if(input.files && input.files[0]) {
var fr = new FileReader();
fr.onload = function(e) {
var img = new Image();
img.addEventListener("load", function() {
canvas.width = img.width;
canvas.height = img.height;
context.drawImage(img, 0, 0);
base64image = getBase64Image(canvas);
callback(base64image);
});
img.src = e.target.result;
};
fr.readAsDataURL( input.files[0] );
}
}


function getBase64Image(canvas) {
if(canvas)
{
dataURL = canvas.toDataURL('image/jpeg');
return dataURL;
}
return "NO CANVAS ERROR";
}


if(document.getElementById('category_id') != null) {
document.getElementById('category_id').addEventListener("change", function(){
var categories = document.getElementById('category_id');
categories.options[categories.options.selectedIndex].selected = true;
console.log("done somethign");
});
}
12 changes: 12 additions & 0 deletions firmware/static/js/login.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
function loginSuccess(response_data, user_data) {
form_locked = document.getElementsByClassName("login-data")[0];
button_locked = document.getElementById("log-button");
button_locked.style.display = "none";
form_locked.style.display = "none";
flashMessage("Welcome back, dear "+response_data.username+".Glad to see you again!");
setTimeout(function() {
window.location.replace("http://0.0.0.0:5000/home#reload-point");
}, 2000);
}

submitForm("login-data", loginSuccess, flash_errors);
Loading