This commit is contained in:
Leon Noe Jovan 2023-01-14 13:45:33 +01:00
parent 10e8116d83
commit e6c87bb3f6
13 changed files with 318 additions and 55 deletions

85
app.py
View File

@ -2,6 +2,8 @@ import logging
import os import os
import re import re
import configparser import configparser
import random
import string
from pathlib import Path from pathlib import Path
from werkzeug.security import check_password_hash from werkzeug.security import check_password_hash
@ -12,6 +14,10 @@ from flask_script import Manager
from flask_login import LoginManager, login_required, login_user, current_user, logout_user from flask_login import LoginManager, login_required, login_user, current_user, logout_user
from portal.model import db, RegisteredUser from portal.model import db, RegisteredUser
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
from email.mime.application import MIMEApplication
import portal.solar import portal.solar
# TODO: Integrate Shibboleth login. # TODO: Integrate Shibboleth login.
@ -497,6 +503,11 @@ def solar_topuploads_institution(institution_id):
def solar_uploadstats_institution(institution_id): def solar_uploadstats_institution(institution_id):
return jsonify(portal.solar.get_institution_upload_stats(institution_id)) return jsonify(portal.solar.get_institution_upload_stats(institution_id))
@app.route(ROUTE_PREFIX + '/uploadstats-per-region')
@login_required
def solar_uploadstats_per_region():
return jsonify(portal.solar.get_region_stats())
@app.route(ROUTE_PREFIX + '/deluser', methods=['POST']) @app.route(ROUTE_PREFIX + '/deluser', methods=['POST'])
@login_required @login_required
@ -838,6 +849,80 @@ def get_upload_file(upload_id, file_hash):
except FileNotFoundError: except FileNotFoundError:
return '', 404 return '', 404
@app.route(ROUTE_PREFIX + '/institutionadduser', methods=['POST'])
@login_required
def solar_institution_add_user():
current_user_institution = portal.solar.get_user_institution(current_user.id)
if not portal.solar.is_institution_coordinator(current_user.id, current_user_institution.id):
return '', 404
name = request.form.get('name')
email = request.form.get('email')
role = request.form.get('role')
password=''.join(random.choices(string.ascii_lowercase, k=8))
if not name:
flash('Prazno polje za ime.')
return redirect(ROUTE_PREFIX + redirect_url())
if len(name) > 100:
flash('Predolgo ime.')
return redirect(ROUTE_PREFIX + redirect_url())
if not email:
flash('Prazno polje za elektronsko pošto.')
return redirect(ROUTE_PREFIX + redirect_url())
if len(email) > 100:
flash('Predolg email naslov.')
return redirect(ROUTE_PREFIX + redirect_url())
elif not re.search(portal.solar.REGEX_EMAIL, email):
flash('Email napačnega formata.')
return redirect(ROUTE_PREFIX + redirect_url())
if not password:
flash('Prazno polje za geslo.')
return redirect(ROUTE_PREFIX + redirect_url())
if len(password) > 100:
flash('Predolgo geslo.')
return redirect(ROUTE_PREFIX + redirect_url())
user = portal.solar.get_user_obj_by_email(email)
if user:
#portal.solar.undo_remove_user(user.id)
flash('Uporabnik s tem emailom je že vnešen v sistem.')
return redirect(ROUTE_PREFIX + redirect_url())
new_user_id = portal.solar.register_new_user(name, email, password)
portal.solar.add_user_to_institution(new_user_id, current_user_institution.id, role)
portal.solar.activate_user(new_user_id)
#token za nastaviti geslo
jwt_token = portal.solar.get_password_reset_token(email, config['APP_SECRET_KEY'])
#pošlji email uporabniku
body = '''
Ustvarjen je bil uporabniški račun na Portalu Šolar.
Geslo lahko nastavite na naslednji povezavi: https://{}/resetpass/{}'''.format(config['SERVER_NAME'], jwt_token)
message = MIMEMultipart()
message['From'] = config['MAIL_LOGIN']
message['To'] = email
message['Subject'] = 'Portal Šolar: Ponastavitev gesla'
message.attach(MIMEText(body, "plain"))
text = message.as_string()
# Create a secure SSL context
context = ssl.create_default_context()
try:
with SMTP_SSL(config['MAIL_HOST'], config['SMTP_PORT'], context=context) as server:
server.login(config['MAIL_LOGIN'], config['MAIL_PASS'])
server.sendmail(config['MAIL_LOGIN'], email, text)
except Exception:
traceback.print_exc()
flash('Uporabnik je bil uspešno dodan.')
return redirect(ROUTE_PREFIX + redirect_url())
if __name__ == '__main__': if __name__ == '__main__':
app.run(debug=True) app.run(debug=True)

View File

@ -6,6 +6,7 @@ import traceback
import ssl import ssl
from datetime import datetime from datetime import datetime
from sqlalchemy import desc from sqlalchemy import desc
from sqlalchemy import func
from pathlib import Path from pathlib import Path
from smtplib import SMTP_SSL from smtplib import SMTP_SSL
@ -24,6 +25,7 @@ from werkzeug.security import generate_password_hash
from . model import * from . model import *
VALID_PROGRAMS = {'OS', 'SSG', 'MGP', 'ZG', 'NPI', 'SPI', 'SSI', 'PTI'} VALID_PROGRAMS = {'OS', 'SSG', 'MGP', 'ZG', 'NPI', 'SPI', 'SSI', 'PTI'}
VALID_SUBJECTS = {'SLO', 'DJP', 'DDP', 'DNP', 'DSP', 'DIP'} VALID_SUBJECTS = {'SLO', 'DJP', 'DDP', 'DNP', 'DSP', 'DIP'}
VALID_TEXT_TYPES = {'E', 'PB', 'T', 'R'} VALID_TEXT_TYPES = {'E', 'PB', 'T', 'R'}
@ -491,6 +493,24 @@ def get_institution_upload_stats(institution_id):
return res return res
def get_region_stats():
ret = {'CE': [0,0], 'GO': [0,0], 'KK': [0,0], 'KP': [0,0], 'KR': [0,0], 'LJ': [0,0], 'MB': [0,0], 'MS': [0,0], 'NM': [0,0], 'PO': [0,0], 'SG': [0,0]}
os = db.session.query(UploadSolar.region, func.count(UploadSolar.id)).filter_by(program="OS").group_by(UploadSolar.region).all()
neos = db.session.query(UploadSolar.region, func.count(UploadSolar.id)).filter(sqlalchemy.not_(UploadSolar.program.contains("OS"))).group_by(UploadSolar.region).all()
#logging.error(os)
#logging.error(neos)
for key, val in os:
ret[key][0] = val
for key, val in neos:
ret[key][1] = val
logging.error(ret)
return ret
def get_all_active_users(): def get_all_active_users():
# TODO: do filtering purely within an SQL query # TODO: do filtering purely within an SQL query
@ -809,9 +829,11 @@ def get_actual_studentparent_contract_filename(f_hash):
def get_password_reset_token(email, key, expires=600): def get_password_reset_token(email, key, expires=600):
return jwt.encode({'reset_password': email, token = jwt.encode({'reset_password': email,
'exp': int(time.time()) + expires}, 'exp': int(time.time()) + expires},
key=key, algorithm='HS256') key=key, algorithm='HS256')
logging.error(token)
return token
def transfer_users_institution(institution_id_from, institution_id_to): def transfer_users_institution(institution_id_from, institution_id_to):
@ -860,7 +882,7 @@ def send_resetpass_mail(email, config):
message = MIMEMultipart() message = MIMEMultipart()
message['From'] = config['MAIL_LOGIN'] message['From'] = config['MAIL_LOGIN']
message['To'] = email message['To'] = email
message['Subject'] = 'Ponastavitev gesla' message['Subject'] = 'Portal Šolar: Ponastavitev gesla'
message.attach(MIMEText(body, "plain")) message.attach(MIMEText(body, "plain"))
text = message.as_string() text = message.as_string()
@ -909,7 +931,7 @@ def send_user_activation_mail(user_id, config):
message = MIMEMultipart() message = MIMEMultipart()
message['From'] = config['MAIL_LOGIN'] message['From'] = config['MAIL_LOGIN']
message['To'] = user.email message['To'] = user.email
message['Subject'] = 'Ponastavitev gesla' message['Subject'] = 'Portal Šolar: Vaš uporabniški račun je odobren'
message.attach(MIMEText(body, "plain")) message.attach(MIMEText(body, "plain"))
text = message.as_string() text = message.as_string()

BIN
static/favicon.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

10
static/favicon.svg Normal file
View File

@ -0,0 +1,10 @@
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512">
<rect fill="#006CB7" width="512" height="512"/>
<path fill="#fff" d="M409.26,145.32V69.5l-46.06,55.16c-5.06-1.88-10.5-3.99-16.1-5.71c-16.12-4.52-32.56-7.82-49.17-9.86
c-5.37-0.47-11.2-0.47-17.04-0.47c-64.88,0-87.21,25.27-87.21,51.25c0,29.89,32.44,46.95,107.28,66.27
c89.47,22.07,117.94,63.93,117.94,114.79c0.04,6.77-0.59,13.54-1.87,20.19c41.39-26.92,66.98-64.24,66.98-105.48
c0-43.74-28.79-83.02-74.61-110.33"/>
<path fill="#fff" d="M241.92,278.65c-84.49-19.95-124.47-61.66-124.47-112.6c-0.13-10.68,1.69-21.29,5.37-31.3
c-57.41,27.07-94.76,71.13-94.76,120.89c0,42.02,26.61,79.89,69.32,107.04v79.81l47.38-56.73c23.89,8.63,48.73,14.33,73.98,16.98
c8.56,0.7,17.35,1.17,26.53,1.17c65.66,0,96.39-23.47,96.39-58.45c0-29.26-28.32-50-99.81-66.82"/>
</svg>

After

Width:  |  Height:  |  Size: 852 B

View File

@ -3,6 +3,8 @@
<head> <head>
<meta charset="UTF-8"> <meta charset="UTF-8">
<title>Admin panel - Šolar</title> <title>Admin panel - Šolar</title>
<link rel="icon" href="/static/favicon.ico" type="image/x-icon" >
<link rel="icon" href="static/favicon.svg" sizes="any" type="image/svg+xml">
<link rel="stylesheet" href="{{ROUTE_PREFIX}}/static/css/header.css" type="text/css"> <link rel="stylesheet" href="{{ROUTE_PREFIX}}/static/css/header.css" type="text/css">
<link rel="stylesheet" href="{{ROUTE_PREFIX}}/static/css/form.css" type="text/css"> <link rel="stylesheet" href="{{ROUTE_PREFIX}}/static/css/form.css" type="text/css">
<link rel="stylesheet" href="{{ROUTE_PREFIX}}/static/css/simple-grid.css" type="text/css"> <link rel="stylesheet" href="{{ROUTE_PREFIX}}/static/css/simple-grid.css" type="text/css">
@ -37,13 +39,14 @@
<header> <header>
<div class="logo"><a href="{{ROUTE_PREFIX}}/"><img src="{{ROUTE_PREFIX}}/static/image/logo-white.svg"/></a></div> <div class="logo"><a href="{{ROUTE_PREFIX}}/"><img src="{{ROUTE_PREFIX}}/static/image/logo-white.svg"/></a></div>
<div class="menu-items"> <div class="menu-items">
<a href="{{ROUTE_PREFIX}}/oddaja">Oddaja besedil</a>
{% if is_institution_coordinator %} {% if is_institution_coordinator %}
<a href="{{ROUTE_PREFIX}}/manage-institution">Upravljaj z institucijo</a> <a href="{{ROUTE_PREFIX}}/manage-institution">Upravljaj z ekipo</a>
{% endif %} {% endif %}
{% if is_admin %} {% if is_admin %}
<a href="{{ROUTE_PREFIX}}/admin">Administracijski meni</a> <a href="{{ROUTE_PREFIX}}/admin">Administracijski meni</a>
{% endif %} {% endif %}
<a href="https://slovenscina.eu/" target="_blank">Več informacij</a> <a href="https://slovenscina.eu/" target="_blank">Več informacij o sodelovanju</a>
<a href="{{ROUTE_PREFIX}}/logout">Odjava</a> <a href="{{ROUTE_PREFIX}}/logout">Odjava</a>
</div> </div>
</header> </header>

View File

@ -3,6 +3,8 @@
<head> <head>
<meta charset="UTF-8"> <meta charset="UTF-8">
<title>Portal ŠOLAR</title> <title>Portal ŠOLAR</title>
<link rel="icon" href="/static/favicon.ico" type="image/x-icon" >
<link rel="icon" href="static/favicon.svg" sizes="any" type="image/svg+xml">
<link rel="stylesheet" href="{{ROUTE_PREFIX}}/static/css/login-styles.css" type="text/css"> <link rel="stylesheet" href="{{ROUTE_PREFIX}}/static/css/login-styles.css" type="text/css">
<link rel="stylesheet" href="{{ROUTE_PREFIX}}/static/css/utils.css" type="text/css"> <link rel="stylesheet" href="{{ROUTE_PREFIX}}/static/css/utils.css" type="text/css">
</head> </head>

View File

@ -3,6 +3,8 @@
<head> <head>
<meta charset="UTF-8"> <meta charset="UTF-8">
<title>Portal ŠOLAR</title> <title>Portal ŠOLAR</title>
<link rel="icon" href="/static/favicon.ico" type="image/x-icon" >
<link rel="icon" href="static/favicon.svg" sizes="any" type="image/svg+xml">
<link rel="stylesheet" href="{{ROUTE_PREFIX}}/static/css/login-styles.css" type="text/css"> <link rel="stylesheet" href="{{ROUTE_PREFIX}}/static/css/login-styles.css" type="text/css">
<link rel="stylesheet" href="{{ROUTE_PREFIX}}/static/css/utils.css" type="text/css"> <link rel="stylesheet" href="{{ROUTE_PREFIX}}/static/css/utils.css" type="text/css">
</head> </head>

View File

@ -3,6 +3,8 @@
<head> <head>
<meta charset="UTF-8"> <meta charset="UTF-8">
<title>Upravljanje institucije - Šolar</title> <title>Upravljanje institucije - Šolar</title>
<link rel="icon" href="/static/favicon.ico" type="image/x-icon" >
<link rel="icon" href="static/favicon.svg" sizes="any" type="image/svg+xml">
<link rel="stylesheet" href="{{ROUTE_PREFIX}}/static/css/header.css" type="text/css"> <link rel="stylesheet" href="{{ROUTE_PREFIX}}/static/css/header.css" type="text/css">
<link rel="stylesheet" href="{{ROUTE_PREFIX}}/static/css/form.css" type="text/css"> <link rel="stylesheet" href="{{ROUTE_PREFIX}}/static/css/form.css" type="text/css">
<link rel="stylesheet" href="{{ROUTE_PREFIX}}/static/css/simple-grid.css" type="text/css"> <link rel="stylesheet" href="{{ROUTE_PREFIX}}/static/css/simple-grid.css" type="text/css">
@ -15,13 +17,14 @@
<header> <header>
<div class="logo"><a href="{{ROUTE_PREFIX}}/"><img src="{{ROUTE_PREFIX}}/static/image/logo-white.svg"/></a></div> <div class="logo"><a href="{{ROUTE_PREFIX}}/"><img src="{{ROUTE_PREFIX}}/static/image/logo-white.svg"/></a></div>
<div class="menu-items"> <div class="menu-items">
<a href="{{ROUTE_PREFIX}}/oddaja">Oddaja besedil</a>
{% if is_institution_coordinator %} {% if is_institution_coordinator %}
<a href="{{ROUTE_PREFIX}}/manage-institution">Upravljaj z institucijo</a> <a href="{{ROUTE_PREFIX}}/manage-institution">Upravljaj z ekipo</a>
{% endif %} {% endif %}
{% if is_admin %} {% if is_admin %}
<a href="{{ROUTE_PREFIX}}/admin">Administracijski meni</a> <a href="{{ROUTE_PREFIX}}/admin">Administracijski meni</a>
{% endif %} {% endif %}
<a href="https://slovenscina.eu/" target="_blank">Več informacij</a> <a href="https://slovenscina.eu/" target="_blank">Več informacij o sodelovanju</a>
<a href="{{ROUTE_PREFIX}}/logout">Odjava</a> <a href="{{ROUTE_PREFIX}}/logout">Odjava</a>
</div> </div>
</header> </header>
@ -34,6 +37,8 @@
{% endif %} {% endif %}
{% endwith %} {% endwith %}
<div class="row">
<div class="col-12">
<h1>{{institution.name}}</h1> <h1>{{institution.name}}</h1>
<h3>Seznam uporabnikov v vaši instituciji</h3> <h3>Seznam uporabnikov v vaši instituciji</h3>
<table class="tableFixHead"> <table class="tableFixHead">
@ -73,10 +78,41 @@
</td> </td>
</tr> </tr>
{% endfor %} {% endfor %}
</tbody>
</table> </table>
</div> </div>
</div>
<form action="/institutionadduser" method="POST">
<div class="row">
<div class="col-6">
<h1>Dodaj uporabnika</h1>
<div class="form-wrapper">
<label for="regija">Ime</label>
<input type="text" name="name" />
</div>
<div class="form-wrapper">
<label for="regija">Email</label>
<input type="text" name="email" />
</div>
<div class="form-wrapper">
<label for="regija">Vloga</label>
<select class="role" name="role">
<option value="coordinator">Koordinator/-ka</option>
<option value="mentor">Mentor/-ica</option>
<option value="other">Druga vloga</option>
</select>
</div>
<input type="submit" class="btn" value="Dodaj"/>
</div>
</div>
</form>
<br> <br>
</div> </div>
</body> </body>
<script> <script>

View File

@ -3,6 +3,8 @@
<head> <head>
<meta charset="UTF-8"> <meta charset="UTF-8">
<title>Portal za oddajanje besedil</title> <title>Portal za oddajanje besedil</title>
<link rel="icon" href="/static/favicon.ico" type="image/x-icon" >
<link rel="icon" href="static/favicon.svg" sizes="any" type="image/svg+xml">
<link rel="stylesheet" href="{{ROUTE_PREFIX}}/static/css/header.css" type="text/css"> <link rel="stylesheet" href="{{ROUTE_PREFIX}}/static/css/header.css" type="text/css">
<link rel="stylesheet" href="{{ROUTE_PREFIX}}/static/css/form.css" type="text/css"> <link rel="stylesheet" href="{{ROUTE_PREFIX}}/static/css/form.css" type="text/css">
<link rel="stylesheet" href="{{ROUTE_PREFIX}}/static/css/simple-grid.css" type="text/css"> <link rel="stylesheet" href="{{ROUTE_PREFIX}}/static/css/simple-grid.css" type="text/css">
@ -13,12 +15,12 @@
<div class="logo"><a href="{{ROUTE_PREFIX}}/"><img src="{{ROUTE_PREFIX}}/static/image/logo-white.svg"/></a></div> <div class="logo"><a href="{{ROUTE_PREFIX}}/"><img src="{{ROUTE_PREFIX}}/static/image/logo-white.svg"/></a></div>
<div class="menu-items"> <div class="menu-items">
{% if is_institution_coordinator %} {% if is_institution_coordinator %}
<a href="{{ROUTE_PREFIX}}/manage-institution">Upravljaj z institucijo</a> <a href="{{ROUTE_PREFIX}}/manage-institution">Upravljaj z ekipo</a>
{% endif %} {% endif %}
{% if is_admin %} {% if is_admin %}
<a href="{{ROUTE_PREFIX}}/admin">Administracijski meni</a> <a href="{{ROUTE_PREFIX}}/admin">Administracijski meni</a>
{% endif %} {% endif %}
<a href="https://slovenscina.eu/" target="_blank">Več informacij</a> <a href="https://slovenscina.eu/" target="_blank">Več informacij o sodelovanju</a>
<a href="{{ROUTE_PREFIX}}/logout">Odjava</a> <a href="{{ROUTE_PREFIX}}/logout">Odjava</a>
</div> </div>
</header> </header>
@ -142,7 +144,7 @@
<div class="row"> <div class="row">
<div class="col-6"> <div class="col-6">
<div class="form-wrapper"> <div class="form-wrapper">
<label for="letnik">Letnik</label> <label for="letnik">Razred/Letnik</label>
<select id="letnik" name="letnik"> <select id="letnik" name="letnik">
<option value="1" selected="selected">1</option> <option value="1" selected="selected">1</option>
<option value="2">2</option> <option value="2">2</option>
@ -167,7 +169,7 @@
<label for="vrsta">Vrsta besedila</label> <label for="vrsta">Vrsta besedila</label>
<select id="vrsta" name="vrsta"> <select id="vrsta" name="vrsta">
<option value="E" selected="selected">Esej ali spis (E)</option> <option value="E" selected="selected">Esej ali spis (E)</option>
<option value="PB">Praktično besedilo (npr. vabila, prošnje ipd. pri pouku slovenščine), napisano za oceno (PB)</option> <option value="PB">Praktično besedilo, napisano za oceno - npr. vabilo, prošnja ali podobno (PE)</option>
<option value="T">Šolski test (T)</option> <option value="T">Šolski test (T)</option>
<option value="R">Delo v razredu, ne za oceno (vtipkajte besedilo vrsto) (R)</option> <option value="R">Delo v razredu, ne za oceno (vtipkajte besedilo vrsto) (R)</option>
</select> </select>

View File

@ -3,6 +3,8 @@
<head> <head>
<meta charset="UTF-8"> <meta charset="UTF-8">
<title>Portal za oddajanje besedil</title> <title>Portal za oddajanje besedil</title>
<link rel="icon" href="/static/favicon.ico" type="image/x-icon" >
<link rel="icon" href="static/favicon.svg" sizes="any" type="image/svg+xml">
<link rel="stylesheet" href="{{ROUTE_PREFIX}}/static/css/header.css" type="text/css"> <link rel="stylesheet" href="{{ROUTE_PREFIX}}/static/css/header.css" type="text/css">
<link rel="stylesheet" href="{{ROUTE_PREFIX}}/static/css/form.css" type="text/css"> <link rel="stylesheet" href="{{ROUTE_PREFIX}}/static/css/form.css" type="text/css">
<link rel="stylesheet" href="{{ROUTE_PREFIX}}/static/css/simple-grid.css" type="text/css"> <link rel="stylesheet" href="{{ROUTE_PREFIX}}/static/css/simple-grid.css" type="text/css">
@ -13,12 +15,12 @@
<div class="logo"><a href="{{ROUTE_PREFIX}}/"><img src="{{ROUTE_PREFIX}}/static/image/logo-white.svg"/></a></div> <div class="logo"><a href="{{ROUTE_PREFIX}}/"><img src="{{ROUTE_PREFIX}}/static/image/logo-white.svg"/></a></div>
<div class="menu-items"> <div class="menu-items">
{% if is_institution_coordinator %} {% if is_institution_coordinator %}
<a href="{{ROUTE_PREFIX}}/manage-institution">Upravljaj z institucijo</a> <a href="{{ROUTE_PREFIX}}/manage-institution">Upravljaj z ekipo</a>
{% endif %} {% endif %}
{% if is_admin %} {% if is_admin %}
<a href="{{ROUTE_PREFIX}}/admin">Administracijski meni</a> <a href="{{ROUTE_PREFIX}}/admin">Administracijski meni</a>
{% endif %} {% endif %}
<a href="https://slovenscina.eu/" target="_blank">Več informacij</a> <a href="https://slovenscina.eu/" target="_blank">Več informacij o sodelovanju</a>
<a href="{{ROUTE_PREFIX}}/logout">Odjava</a> <a href="{{ROUTE_PREFIX}}/logout">Odjava</a>
</div> </div>
</header> </header>
@ -81,6 +83,26 @@
<div class="row" id="my_dataviz__region_title">
<div class="col-12">
<h2>Število vseh oddaj po regijah</h2>
</div>
</div>
<div class="row">
<div class="col-6">
<div id="my_dataviz_region">
</div>
<div>
<div style="display:inline-block;width:12px;height:12px;background:#006CB7"></div>
<p style="display:inline-block">Osnovne šole</p>
<div style="margin-left:32px;display:inline-block;width:12px;height:12px;background:#B86D00"></div>
<p style="display:inline-block">Sredje šole</p>
</div>
</div>
</div>
</div> </div>
@ -96,6 +118,12 @@
#my_dataviz path.domain{ #my_dataviz path.domain{
visibility:hidden; visibility:hidden;
} }
#my_dataviz_region .tick line{
visibility:hidden;
}
#my_dataviz_region path.domain{
visibility:hidden;
}
</style> </style>
<script> <script>
var data; var data;
@ -158,10 +186,77 @@
.attr("width", function(d) { return x(d.value); }) .attr("width", function(d) { return x(d.value); })
.attr("height", 32 ) .attr("height", 32 )
.attr("fill", "#006CB7"); .attr("fill", "#006CB7");
})
</script>
<script>
var data;
// Parse the Data
d3.json("/uploadstats-per-region").then(function(jsondata) {
data = [];
console.log(Object.keys(jsondata).length);
var margin = {top: 20, right: 0, bottom: 40, left: 0};
var width = document.getElementById("my_dataviz_region").clientWidth - margin.left - margin.right;
var height = Object.keys(jsondata).length * 56;
var svg = d3.select("#my_dataviz_region")
.append("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.style("overflow","visible")
.append("g")
.attr("transform",
"translate(" + margin.left + "," + margin.top + ")");
for(var key in jsondata) {
data.push({'name': key, 'value':jsondata[key]});
}
console.log(data);
// Add X axis
var x = d3.scaleLinear()
.domain([0,d3.max(data, function (d) { return Math.max(...d.value)})])
.range([ 0, width]);
svg.append("g")
.attr("transform", "translate(0," + height + ")")
.call(d3.axisBottom(x))
.selectAll("text")
.style("text-anchor", "center");
// Y axis
var y = d3.scaleBand()
.range([ 0, data.length*56 ])
.domain(data.map(function(d) { return d.name; }))
.padding(0);
svg.append("g")
.call(d3.axisLeft(y))
.selectAll("text")
.style("text-anchor", "start")
.style("font-size", "14px")
.attr("transform", "translate(8,-36)");
//Bars
svg.selectAll("myRect")
.data(data)
.enter()
.append("rect")
.attr("x", x(0) )
.attr("y", function(d) { return y(d.name); })
.attr("width", function(d) { return x(d.value[0]); })
.attr("height", 16 )
.attr("fill", "#006CB7");
svg.selectAll("myRect")
.data(data)
.enter()
.append("rect")
.attr("x", x(0) )
.attr("y", function(d) { return y(d.name); })
.attr("width", function(d) { return x(d.value[1]); })
.attr("height", 16 )
.attr("transform", "translate(0,16)")
.attr("fill", "#B86D00");
}) })
</script> </script>

View File

@ -3,6 +3,8 @@
<head> <head>
<meta charset="UTF-8"> <meta charset="UTF-8">
<title>Portal ŠOLAR</title> <title>Portal ŠOLAR</title>
<link rel="icon" href="/static/favicon.ico" type="image/x-icon" >
<link rel="icon" href="static/favicon.svg" sizes="any" type="image/svg+xml">
<link rel="stylesheet" href="{{ROUTE_PREFIX}}/static/css/login-styles.css" type="text/css"> <link rel="stylesheet" href="{{ROUTE_PREFIX}}/static/css/login-styles.css" type="text/css">
<link rel="stylesheet" href="{{ROUTE_PREFIX}}/static/css/utils.css" type="text/css"> <link rel="stylesheet" href="{{ROUTE_PREFIX}}/static/css/utils.css" type="text/css">
</head> </head>

View File

@ -3,6 +3,8 @@
<head> <head>
<meta charset="UTF-8"> <meta charset="UTF-8">
<title>Portal ŠOLAR</title> <title>Portal ŠOLAR</title>
<link rel="icon" href="/static/favicon.ico" type="image/x-icon" >
<link rel="icon" href="static/favicon.svg" sizes="any" type="image/svg+xml">
<link rel="stylesheet" href="{{ROUTE_PREFIX}}/static/css/login-styles.css" type="text/css"> <link rel="stylesheet" href="{{ROUTE_PREFIX}}/static/css/login-styles.css" type="text/css">
<link rel="stylesheet" href="{{ROUTE_PREFIX}}/static/css/utils.css" type="text/css"> <link rel="stylesheet" href="{{ROUTE_PREFIX}}/static/css/utils.css" type="text/css">
</head> </head>

View File

@ -5,6 +5,8 @@
<title>Portal za oddajanje besedil</title> <title>Portal za oddajanje besedil</title>
<!--<link rel="stylesheet" href="{{ROUTE_PREFIX}}/static/style.css" type="text/css">--> <!--<link rel="stylesheet" href="{{ROUTE_PREFIX}}/static/style.css" type="text/css">-->
<script src="{{ROUTE_PREFIX}}/static/chart.js"></script> <script src="{{ROUTE_PREFIX}}/static/chart.js"></script>
<link rel="icon" href="/static/favicon.ico" type="image/x-icon" >
<link rel="icon" href="static/favicon.svg" sizes="any" type="image/svg+xml">
<link rel="stylesheet" href="{{ROUTE_PREFIX}}/static/css/header.css" type="text/css"> <link rel="stylesheet" href="{{ROUTE_PREFIX}}/static/css/header.css" type="text/css">
<link rel="stylesheet" href="{{ROUTE_PREFIX}}/static/css/form.css" type="text/css"> <link rel="stylesheet" href="{{ROUTE_PREFIX}}/static/css/form.css" type="text/css">
<link rel="stylesheet" href="{{ROUTE_PREFIX}}/static/css/simple-grid.css" type="text/css"> <link rel="stylesheet" href="{{ROUTE_PREFIX}}/static/css/simple-grid.css" type="text/css">
@ -15,12 +17,12 @@
<div class="logo"><a href="{{ROUTE_PREFIX}}/"><img src="{{ROUTE_PREFIX}}/static/image/logo-white.svg"/></a></div> <div class="logo"><a href="{{ROUTE_PREFIX}}/"><img src="{{ROUTE_PREFIX}}/static/image/logo-white.svg"/></a></div>
<div class="menu-items"> <div class="menu-items">
{% if is_institution_coordinator %} {% if is_institution_coordinator %}
<a href="{{ROUTE_PREFIX}}/manage-institution">Upravljaj z institucijo</a> <a href="{{ROUTE_PREFIX}}/manage-institution">Upravljaj z ekipo</a>
{% endif %} {% endif %}
{% if is_admin %} {% if is_admin %}
<a href="{{ROUTE_PREFIX}}/admin">Administracijski meni</a> <a href="{{ROUTE_PREFIX}}/admin">Administracijski meni</a>
{% endif %} {% endif %}
<a href="https://slovenscina.eu/" target="_blank">Več informacij</a> <a href="https://slovenscina.eu/" target="_blank">Več informacij o sodelovanju</a>
<a href="{{ROUTE_PREFIX}}/logout">Odjava</a> <a href="{{ROUTE_PREFIX}}/logout">Odjava</a>
</div> </div>
</header> </header>