Skip to content

Commit cea60fd

Browse files
committed
Začetno ogrodje spletne aplikacije
1 parent 36bbc99 commit cea60fd

6 files changed

Lines changed: 310 additions & 1 deletion

File tree

predavanja/primeri/banka/banka.py

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
from model import Kraj, Oseba, Racun, Transakcija, vzpostavi_povezavo
2+
import bottle
3+
import bottleext
4+
import os
5+
6+
7+
# privzete nastavitve
8+
SERVER_PORT = os.environ.get('BOTTLE_PORT', 8080)
9+
RELOADER = os.environ.get('BOTTLE_RELOADER', True)
10+
DB_PORT = os.environ.get('POSTGRES_PORT', 5432)
11+
SKRIVNOST = 'nekaj, kar bo zelo težko uganiti!!!! fndkdfvdkbvtzuj hbjh'
12+
13+
14+
# Odkomentiraj, če želiš sporočila o napakah
15+
bottle.debug(True) # za izpise pri razvoju
16+
17+
18+
bottle.BaseTemplate.defaults.update(
19+
Kraj=Kraj,
20+
Oseba=Oseba,
21+
Racun=Racun,
22+
Transakcija=Transakcija,
23+
url=bottle.url,
24+
urlencode=bottle.urlencode,
25+
)
26+
27+
28+
@bottle.get('/static/<filename:path>')
29+
def static(filename):
30+
return bottle.static_file(filename, root='static')
31+
32+
33+
@bottle.get('/')
34+
@bottle.view('index.html')
35+
def index():
36+
pass
37+
38+
39+
bottle.run(host='localhost', port=SERVER_PORT, reloader=RELOADER)

predavanja/primeri/banka/model.py

Lines changed: 133 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
from psycopg import connect, sql, errors
2+
from auth import auth
13
from dataclasses import dataclass
24
from datetime import datetime
35

@@ -10,6 +12,33 @@ class Kraj:
1012
def __str__(self):
1113
return f"{self.posta} {self.kraj}"
1214

15+
@classmethod
16+
def ustvari_tabelo(cls, pobrisi=False, ce_ne_obstaja=False):
17+
with conn.transaction():
18+
if pobrisi:
19+
cls.izbrisi_tabelo(ce_ne_obstaja)
20+
with conn.cursor() as cur:
21+
cur.execute(sql.SQL(
22+
"""
23+
CREATE TABLE {ce_ne_obstaja} kraj (
24+
posta INTEGER PRIMARY KEY,
25+
kraj TEXT NOT NULL
26+
);
27+
""").format(
28+
ce_ne_obstaja=sql.SQL("IF NOT EXISTS" if ce_ne_obstaja else "")
29+
))
30+
31+
@classmethod
32+
def izbrisi_tabelo(cls, ce_obstaja=False):
33+
with conn.transaction():
34+
with conn.cursor() as cur:
35+
cur.execute(sql.SQL(
36+
"""
37+
DROP TABLE {ce_obstaja} kraj;
38+
""").format(
39+
ce_obstaja=sql.SQL("IF EXISTS" if ce_obstaja else "")
40+
))
41+
1342

1443
@dataclass
1544
class Oseba:
@@ -19,12 +48,68 @@ class Oseba:
1948
naslov: str
2049
kraj: Kraj
2150

51+
@classmethod
52+
def ustvari_tabelo(cls, pobrisi=False, ce_ne_obstaja=False):
53+
with conn.transaction():
54+
if pobrisi:
55+
cls.izbrisi_tabelo(ce_ne_obstaja)
56+
with conn.cursor() as cur:
57+
cur.execute(sql.SQL(
58+
"""
59+
CREATE TABLE {ce_ne_obstaja} oseba (
60+
emso TEXT PRIMARY KEY,
61+
ime TEXT NOT NULL,
62+
priimek TEXT NOT NULL,
63+
naslov TEXT NOT NULL,
64+
kraj INTEGER NOT NULL REFERENCES kraj(posta)
65+
);
66+
""").format(
67+
ce_ne_obstaja=sql.SQL("IF NOT EXISTS" if ce_ne_obstaja else "")
68+
))
69+
70+
@classmethod
71+
def izbrisi_tabelo(cls, ce_obstaja=False):
72+
with conn.transaction():
73+
with conn.cursor() as cur:
74+
cur.execute(sql.SQL(
75+
"""
76+
DROP TABLE {ce_obstaja} oseba;
77+
""").format(
78+
ce_obstaja=sql.SQL("IF EXISTS" if ce_obstaja else "")
79+
))
2280

2381
@dataclass
2482
class Racun:
2583
stevilka: int
2684
lastnik: Oseba
2785

86+
@classmethod
87+
def ustvari_tabelo(cls, pobrisi=False, ce_ne_obstaja=False):
88+
with conn.transaction():
89+
if pobrisi:
90+
cls.izbrisi_tabelo(ce_ne_obstaja)
91+
with conn.cursor() as cur:
92+
cur.execute(sql.SQL(
93+
"""
94+
CREATE TABLE {ce_ne_obstaja} racun (
95+
stevilka SERIAL PRIMARY KEY,
96+
lastnik TEXT NOT NULL REFERENCES oseba(emso)
97+
);
98+
""").format(
99+
ce_ne_obstaja=sql.SQL("IF NOT EXISTS" if ce_ne_obstaja else "")
100+
))
101+
102+
@classmethod
103+
def izbrisi_tabelo(cls, ce_obstaja=False):
104+
with conn.transaction():
105+
with conn.cursor() as cur:
106+
cur.execute(sql.SQL(
107+
"""
108+
DROP TABLE {ce_obstaja} racun;
109+
""").format(
110+
ce_obstaja=sql.SQL("IF EXISTS" if ce_obstaja else "")
111+
))
112+
28113

29114
@dataclass
30115
class Transakcija:
@@ -33,3 +118,51 @@ class Transakcija:
33118
znesek: int
34119
cas: datetime = None
35120
opis: str = None
121+
122+
@classmethod
123+
def ustvari_tabelo(cls, pobrisi=False, ce_ne_obstaja=False):
124+
with conn.transaction():
125+
if pobrisi:
126+
cls.izbrisi_tabelo(ce_ne_obstaja)
127+
with conn.cursor() as cur:
128+
cur.execute(sql.SQL(
129+
"""
130+
CREATE TABLE {ce_ne_obstaja} transakcija (
131+
id SERIAL PRIMARY KEY,
132+
racun INTEGER NOT NULL REFERENCES racun(stevilka),
133+
znesek INTEGER NOT NULL,
134+
cas TIMESTAMP(0) NOT NULL DEFAULT (NOW()),
135+
opis TEXT
136+
);
137+
""").format(
138+
ce_ne_obstaja=sql.SQL("IF NOT EXISTS" if ce_ne_obstaja else "")
139+
))
140+
141+
@classmethod
142+
def izbrisi_tabelo(cls, ce_obstaja=False):
143+
with conn.transaction():
144+
with conn.cursor() as cur:
145+
cur.execute(sql.SQL(
146+
"""
147+
DROP TABLE {ce_obstaja} transakcija;
148+
""").format(
149+
ce_obstaja=sql.SQL("IF EXISTS" if ce_obstaja else "")
150+
))
151+
152+
153+
RAZREDI = [Kraj, Oseba, Racun, Transakcija]
154+
155+
156+
def ustvari_tabele(pobrisi=False, ce_ne_obstaja=False):
157+
with conn.transaction():
158+
if pobrisi:
159+
for cls in reversed(RAZREDI):
160+
cls.izbrisi_tabelo(ce_ne_obstaja)
161+
for cls in RAZREDI:
162+
cls.ustvari_tabelo(ce_ne_obstaja=ce_ne_obstaja)
163+
164+
165+
def vzpostavi_povezavo(**kwargs):
166+
global conn
167+
conn = connect(**auth, **kwargs)
168+
return conn

predavanja/primeri/banka/staro/2025/bottleext.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import os
22
import bottle
3-
from bottle import *
43

54

65
class Route(bottle.Route):
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
.rdece {
2+
color: red;
3+
}
4+
5+
h1 {
6+
text-decoration: underline;
7+
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
% rebase('osnova.html', stran='index')
2+
<div class="container">
3+
<h1 class="title rdece">
4+
Dobrodošli na banki!
5+
</h1>
6+
</div>
Lines changed: 125 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,125 @@
1+
% setdefault('naslov', 'Banka')
2+
% setdefault('uporabnik', None)
3+
% setdefault('sporocilo', None)
4+
5+
<!DOCTYPE html>
6+
<html class="has-navbar-fixed-top">
7+
8+
<head>
9+
<meta charset="utf-8">
10+
<meta name="viewport" content="width=device-width, initial-scale=1">
11+
<title>{{naslov}}</title>
12+
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bulma@1.0.4/css/bulma.min.css">
13+
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fortawesome/fontawesome-free@6.5.2/css/all.min.css">
14+
<link rel="stylesheet" href="{{url('static', filename='stili.css')}}">
15+
<script>
16+
document.addEventListener('DOMContentLoaded', () => {
17+
(document.querySelectorAll('.notification .delete') || []).forEach(($delete) => {
18+
const $notification = $delete.parentNode;
19+
20+
$delete.addEventListener('click', () => {
21+
$notification.parentNode.removeChild($notification);
22+
});
23+
});
24+
});
25+
</script>
26+
</head>
27+
28+
<body>
29+
<nav class="navbar is-dark is-fixed-top" role="navigation" aria-label="main navigation">
30+
<div class="navbar-brand">
31+
<a class="navbar-item {{'is-selected' if stran == 'index' else ''}}" href="{{url('index')}}">
32+
Banka
33+
</a>
34+
</div>
35+
36+
<div class="navbar-menu">
37+
% if uporabnik:
38+
<div class="navbar-start">
39+
% if uporabnik.admin:
40+
<a class="navbar-item {{'is-selected' if stran == 'kraji' else ''}}">
41+
Kraji
42+
</a>
43+
44+
<a class="navbar-item {{'is-selected' if stran == 'komitenti' else ''}}">
45+
Komitenti
46+
</a>
47+
% end
48+
49+
<div class="navbar-item has-dropdown is-hoverable">
50+
<a class="navbar-link">
51+
Računi
52+
</a>
53+
54+
<div class="navbar-dropdown">
55+
<a class="navbar-item {{'is-selected' if stran == f'komitenti_racuni-{uporabnik.emso}' else ''}}">
56+
Moji računi
57+
</a>
58+
% if uporabnik.admin:
59+
<a class="navbar-item {{'is-selected' if stran == 'racuni' else ''}}">
60+
Seznam računov
61+
</a>
62+
% end
63+
</div>
64+
</div>
65+
66+
<div class="navbar-item has-dropdown is-hoverable">
67+
<a class="navbar-link">
68+
Transakcije
69+
</a>
70+
71+
<div class="navbar-dropdown">
72+
<a class="navbar-item {{'is-selected' if stran == f'komitenti_transakcije-{uporabnik.emso}' else ''}}">
73+
Moje transakcije
74+
</a>
75+
% if uporabnik.admin:
76+
<a class="navbar-item {{'is-selected' if stran == 'transakcije' else ''}}">
77+
Seznam transakcij
78+
</a>
79+
% end
80+
</div>
81+
</div>
82+
</div>
83+
% end
84+
85+
<div class="navbar-end">
86+
% if uporabnik:
87+
<div class="navbar-item">
88+
<div class="buttons">
89+
<a class="button {{'is-warning' if uporabnik.admin else 'is-light'}}">
90+
<strong>{{uporabnik.up_ime}}</strong>
91+
</a>
92+
<form method="POST">
93+
<button class="button is-primary">
94+
Odjava
95+
</button>
96+
</form>
97+
</div>
98+
</div>
99+
% else:
100+
<div class="navbar-item">
101+
<div class="buttons">
102+
<a class="button is-primary">
103+
<strong>Registracija</strong>
104+
</a>
105+
<a class="button is-light">
106+
Prijava
107+
</a>
108+
</div>
109+
</div>
110+
% end
111+
</div>
112+
</div>
113+
</nav>
114+
% if sporocilo:
115+
<div class="notification is-warning">
116+
<button class="delete"></button>
117+
{{sporocilo}}
118+
</div>
119+
% end
120+
<section class="section">
121+
{{!base}}
122+
</section>
123+
</body>
124+
125+
</html>

0 commit comments

Comments
 (0)