bygdis.fi

git clone https://git.tarina.org/bygdis.fi
Log | Files | Refs | README

server.py (42588B)


      1 # -*- coding: utf-8 -*-
      2 #
      3 import web
      4 import json
      5 import time
      6 import datetime
      7 import re
      8 import base64
      9 import os
     10 import subprocess
     11 import urllib
     12 from PIL import Image
     13 import hashlib
     14 import random
     15 import bcrypt
     16 import sys
     17 basedir = os.path.dirname(os.path.realpath(__file__))
     18 sys.path.append(basedir)
     19 
     20 urls = (
     21     "/", "index",
     22     "/login?", "login",
     23     "/logout", "logout",
     24     "/addevent", "addevent",
     25     "/event", "event",
     26     "/removeevent/(\d+)", "removeevent",
     27     "/editevent/(\d+)", "editevent",
     28     "/removepost/(\d+)", "removepost",
     29     "/old", "old",
     30     "/bilder?", "bilder",
     31     "/upload", "upload",
     32     "/bild/(.*)?", "bild",
     33     "/bildinfo/(.*)?", "bildinfo",
     34     "/om", "om",
     35     "/remove/(.*)?","remove",
     36     "/tuning?", "tuning",
     37     "/senaste", "senaste",
     38     "/admin", "admin",
     39     "/dorrkoder?", "dorrkoder",
     40     "/nydorrkod?", "nydorrkod",
     41     "/dorrkoderapi?", "dorrkoderapi",
     42     "/register?", "register",
     43     "/forgotpass?", "forgotpass",
     44     "/ny", "ny",
     45     "/protokoll", "protokoll",
     46     "/nope", "nope"
     47 )
     48 
     49 render = web.template.render(basedir + "/public_html/html/", base="base")
     50 render2 = web.template.render(basedir + "/public_html/html/", base="base2")
     51 render3 = web.template.render(basedir + "/public_html/html/", base="base3")
     52 web.config.debug = False
     53 app = web.application(urls, globals())
     54 store = web.session.DiskStore(basedir + '/sessions')
     55 db = web.database(dbn="sqlite", db=basedir + "/db/bygdis.db")
     56 session = web.session.Session(app,store,initializer={'login': 0, 'user': '', 'backurl': '', 'bildsida': 0, 'search': ''})
     57 
     58 def logged():
     59     if session.login == 5:
     60         return True
     61     else:
     62         return False
     63 
     64 def curdate():
     65     today = datetime.datetime.now().date().strftime('%s')
     66     return today
     67 
     68 def getkalender():
     69     events = db.query("SELECT * FROM kalender WHERE datumtid > DATETIME('now') ORDER BY datumtid ASC")
     70     #events = db.select('kalender', what='id, datumtid, event', order='datumtid ASC')
     71     return events
     72 
     73 def getkalenderall():
     74     events = db.query("SELECT * FROM kalender ORDER BY datumtid ASC")
     75     #events = db.select('kalender', what='id, datumtid, event', order='datumtid ASC')
     76     return events
     77 
     78 def nyevent(datumtid, event):
     79     veckodagar = u'Måndag', u'Tisdag', u'Onsdag', u'Torsdag', u'Fredag', u'Lördag', u'Söndag'
     80     veckodag = datumtid.weekday()
     81     db.insert('kalender', datumtid=datumtid, veckodag=veckodagar[veckodag], event=event)
     82     print("event added to database")
     83     return
     84 
     85 def getposts():
     86     posts = db.query("SELECT * FROM posts ORDER BY datumtid DESC")
     87     #events = db.select('kalender', what='id, datumtid, event', order='datumtid ASC')
     88     return posts
     89 
     90 def nypost(datumtid, post):
     91     db.insert('posts',  datumtid=datumtid, post=post, likes=0)
     92     print("post added to database")
     93     return
     94 
     95 def getprotokoll(year):
     96     listmodtime = []
     97     for a in os.scandir(basedir + '/protokoll/' + year):
     98         filename = a.name
     99         modtime = a.stat().st_mtime
    100         listmodtime.append((filename, modtime))
    101     listmodtime.sort(key=lambda tup: tup[1])
    102     protokoll = []
    103     for a in listmodtime:
    104         protokoll.append(a[0])
    105     return protokoll
    106 
    107 def adduser(name, password, mail):
    108     password = password.encode("utf-8")
    109     salt = bcrypt.gensalt()
    110     password_hashed = bcrypt.hashpw(password, salt)
    111     #check user db, if empty create admin
    112     users = db.query("SELECT COUNT(*) AS users FROM bildadmin")[0]
    113     tot = int(users.users)
    114     print('users alltsomallt: ' + str(tot))
    115     if tot > 1:
    116         db.insert('bildadmin', name=name, displayname=name, password=password_hashed, mail=mail, subscribe='aldrig', adminlevel=3)
    117     else:
    118         db.insert('bildadmin', name=name, displayname=name, password=password_hashed, mail=mail, subscribe='aldrig', adminlevel=5)
    119     print("new user added")
    120     return
    121 
    122 def bildhistoriker():
    123     bildhistoriker = db.query("SELECT name, displayname, mail, password FROM bildadmin")
    124     return bildhistoriker
    125 
    126 def adminlevel(user):
    127     level = db.query("SELECT adminlevel FROM bildadmin WHERE name='"+user+"';")[0]
    128     #1 session logout, web.py bug
    129     #2 rights to see pics and comment
    130     #3 rights to upoload
    131     #5 superadmin
    132     session.login = int(level.adminlevel)
    133     return
    134 
    135 def getdisplayname(user):
    136     displayname = db.query("SELECT displayname FROM bildadmin WHERE name='"+user+"';")[0]
    137     return displayname.displayname
    138 
    139 def getbilder():
    140     bilder = db.query("SELECT * FROM bilder ORDER BY uploaddate DESC")
    141     return bilder
    142 
    143 def addbild(filename, titel, namn, year, fotograf, beskrivning, uppladdare, personer):
    144     db.insert('bilder', filename=filename, titel=titel, uploaddate=datetime.datetime.now(), namn=namn, year=year, fotograf=fotograf, beskrivning=beskrivning, uppladdare=uppladdare, personer=personer)
    145 
    146 def addDorrkod(dorrkod, name, mail):
    147     db.insert('dorrkoder', dorrkod=dorrkod, name=name, mail=mail, datum=datetime.datetime.now())
    148 
    149 def dorrLogger(dorrkod):
    150     db.insert('dorrlogger', dorrkod=dorrkod, datum=datetime.datetime.now())
    151 
    152 def getDorrlog():
    153     log=db.query("SELECT * FROM dorrlogger ORDER BY datum DESC")
    154     return log
    155 
    156 def getDorrkoduser(dorrkod):
    157     try:
    158         user = db.query("SELECT name FROM dorrkoder WHERE dorrkod='"+str(dorrkod)+"';")[0]
    159         return user.name
    160     except:
    161         user = 'unknown'
    162         return user
    163 
    164 def getDorrkoder():
    165     dorrkoder=db.query("SELECT * FROM dorrkoder ORDER BY datum DESC")
    166     return dorrkoder
    167 
    168 def sendmail(email, subject, msg):
    169     #Send mail
    170     echomsg = subprocess.Popen(('echo', msg), stdout=subprocess.PIPE)
    171     sendmsg = subprocess.check_output(('mail', '-r', 'rob@bygdis.fi', '-s', subject, email), stdin=echomsg.stdout)
    172     echomsg.wait()
    173     #subprocess.call(['echo', msg, '|', 'mail', '-r', 'rob@tarina.org','-s', subject, email])
    174 
    175 def stopflood(ip,referer):
    176     try:
    177         t = db.select('stopflood', where='ip="'+ip+'"', what='tid')[0]
    178     except:
    179         pass
    180     try:
    181         db.update('stopflood', where='ip="'+ip+'"', tid=time.time())
    182     except:
    183         db.insert('stopflood', ip=ip, tid=time.time())
    184     try:
    185         senast = time.time() - t.tid
    186         print(senast)
    187         if senast < 2:
    188             return web.seeother(referer)
    189         else:
    190             return
    191     except:
    192         return
    193 
    194 def stopresetpass(mail):
    195     try:
    196         t = db.select('stopresetpass', where='mail="'+mail+'"', what='tid')[0]
    197         print(t)
    198     except Exception as e:
    199         print(e)
    200     try:
    201         db.update('stopresetpass', where='mail="'+mail+'"', tid=time.time())
    202     except Exception as e:
    203         print(e)
    204         db.insert('stopresetpass', mail=mail, tid=time.time())
    205     try:
    206         senast = time.time() - t.tid
    207         print(senast)
    208         if senast < 604800:
    209             print('mail is in password reset spam filter')
    210             return True
    211         else:
    212             return False
    213     except Exception as e:
    214         print(e)
    215         return True
    216 
    217 class om():
    218     def GET(self):
    219         return render.om()
    220 
    221 class admin():
    222     form = web.form.Form(
    223     web.form.Textarea('post', web.form.notnull, description="", width="500px", height="200px", autocomplete="off"),
    224     web.form.Button('skicka'))
    225     def GET(self):
    226         print(session.login)
    227         if session.login == 5:
    228             saysomething = self.form()
    229             anslagstavla = getposts()
    230             return render2.admin(anslagstavla, saysomething)
    231         else:
    232             raise web.seeother('/login')
    233     def POST(self):
    234         if session.login == 5:
    235             saysomething = self.form()
    236             if not saysomething.validates():
    237                 return render2.admin(anslagstavla, saysomething)
    238             else:
    239                 i = web.input()
    240                 print('ADDDDDDDDDDDDDING TO database post ' + i.post)
    241                 now = datetime.datetime.now()
    242                 print('ADDDDDDDDDDDDDING TO database date' + str(now))
    243                 nypost(now, i.post)
    244                 raise web.seeother('/admin')
    245         else:
    246             raise web.seeother('/login')
    247 
    248 class event():
    249     def GET(self):
    250         if session.login == 5:
    251             upcomingevents = getkalender()
    252             return render2.event(upcomingevents)
    253         else:
    254             raise web.seeother('/login')
    255 
    256 class addevent():
    257     form = web.form.Form(
    258     web.form.Textbox('year', web.form.notnull, web.form.regexp('\d+', 'yyyy'), description="år:"),
    259     web.form.Textbox('month', web.form.notnull, web.form.regexp('\d+', 'MM'), description="månad:"),
    260     web.form.Textbox('day', web.form.notnull, web.form.regexp('\d+', 'dd'), description="dag:", autofocus="autofocus"),
    261     web.form.Textbox('tid', web.form.notnull, web.form.regexp('^(0[0-9]|1[0-9]|2[0-3]):[0-5][0-9]$', 'Skriv tiden såhär 07:20'), description="klockslag:"),
    262     web.form.Dropdown('upprepa', [u'Nej', u'Varje vecka', u'Varannan vecka', u'Varje månad'], web.form.notnull, description="återkommande"),
    263     web.form.Textbox('antal', web.form.regexp('\d+', 'nummer tack'), description="hur många gånger:"),
    264     web.form.Textarea('event', description="beskrivning:"),
    265     web.form.Textarea('admin', description="synligt för admin:"),
    266     web.form.Button('skicka'))
    267     def GET(self):
    268         if session.login == 5:
    269             now = datetime.datetime.now()
    270             kalender = self.form()
    271             kalender.fill(year=now.year, month=now.month, day=now.day, tid=str(now.hour).zfill(2) + ':00', antal='1')
    272             return render.addevent(kalender)
    273         else:
    274             raise web.seeother('/login')
    275     def POST(self):
    276         if session.login == 5:
    277             kalender = self.form()
    278             if not kalender.validates():
    279                 return render.addevent(kalender)
    280             else:
    281                 i = web.input()
    282                 try:
    283                     tidh = int(i.tid[:2])
    284                     tidm = int(i.tid[-2:])
    285                     year = int(i.year)
    286                     month = int(i.month)
    287                     day = int(i.day)
    288                     antal = int(i.antal)
    289                     datum = datetime.datetime(year, month, day, tidh, tidm)
    290                 except ValueError:
    291                     return render.nope()
    292                 manydatum = []
    293                 dayz = 0
    294                 c = 0
    295                 if 'Varje v' in i.upprepa:
    296                     dayz = 7
    297                 if 'Varannan' in i.upprepa:
    298                     dayz = 14
    299                 if 'Varje m' in i.upprepa:
    300                     dayz = 28
    301                 if 'Nej' in i.upprepa:
    302                     antal = 1
    303                 for a in range(0, antal):
    304                     manydatum.append(datum + datetime.timedelta(days=c))
    305                     c = c + dayz
    306                 for d in manydatum:
    307                     nyevent(d, i.event)
    308                 return web.seeother('/admin')
    309         else:
    310             raise web.seeother('/login')
    311 
    312 class removeevent():
    313     def POST(self, id):
    314         if session.login == 5:
    315             db.delete('kalender', where="id=" + id)
    316             raise web.seeother('/event')
    317         else:
    318             raise web.seeother('/login')
    319 
    320 class editevent():
    321     def POST(self):
    322         s = web.input().signal
    323         print(s)
    324         if session.login == 5:
    325             return
    326         else:
    327             return
    328 
    329 class removepost():
    330     def POST(self, id):
    331         if session.login == 5:
    332             db.delete('posts', where="id=" + id)
    333             raise web.seeother('/admin')
    334         else:
    335             raise web.seeother('/login')
    336 
    337 class login():
    338     form = web.form.Form(
    339     web.form.Textbox('user', web.form.notnull, description="namn eller e-post:"),
    340     web.form.Password('password', web.form.notnull, description="lösenord:"),
    341     web.form.Button('Logga in'))
    342     def GET(self):
    343         fejl = ''
    344         resetpasslink = False
    345         i = web.input(error=None)
    346         if i.error == 'fejl':
    347             fejl = 'fejl lösenord!'
    348             resetpasslink = True
    349         if i.error == 'tom':
    350             fejl = 'hmm.. he funkka inga!'
    351         if session.login < 3:
    352             loginform = self.form()
    353             return render.login(loginform, fejl, resetpasslink)
    354         if session.login == 3:
    355             return web.seeother('/bilder')
    356         if session.login == 5:
    357             raise web.seeother('/admin')
    358     def POST(self):
    359         referer = web.ctx.env.get('HTTP_REFERER','https://bygdis.fi')
    360         ip = web.ctx['ip']
    361         stopflood(ip, referer)
    362         loginform = self.form()
    363         i = web.input()
    364         if i.user == '' or i.password == '':
    365             raise web.seeother('/login?error=tom')
    366         bildadmin = []
    367         bildadmins = bildhistoriker()
    368         for p in bildadmins:
    369             if p.name.lower() == i.user.lower() or p.mail.lower() == i.user.lower():
    370                 try:
    371                     encodepass = p.password.encode("utf-8")
    372                 except:
    373                     encodepass = p.password
    374                 if bcrypt.checkpw(i.password.encode('utf-8'), encodepass):
    375                     session.user = p.name
    376                     adminlevel(p.name)
    377                     print('BACKURL: '+session.backurl)
    378                     if session.login == 5:
    379                         raise web.seeother('/admin')
    380                     if session.backurl != '':
    381                         backurl = session.backurl
    382                         session.backurl = ''
    383                         raise web.seeother(backurl)
    384                     else:
    385                         raise web.seeother('/bilder')
    386         else:
    387             return web.seeother('/login?error=fejl')
    388 
    389 class forgotpass():
    390     form = web.form.Form(
    391     web.form.Textbox('mail', web.form.notnull, description="e-post:"),
    392     web.form.Button('Skicka nytt lösenord!'))
    393     def GET(self):
    394         fejl = ''
    395         i = web.input(error=None)
    396         if i.error == 'fejl':
    397             fejl = 'hittar inga e-post!'
    398         elif i.error == 'done':
    399             fejl = 'ditt lösenord e uppdaterat å skickat till din e-post'
    400         elif i.error == 'nej':
    401             fejl = 'nej hörru dedär gaar inga!'
    402         elif i.error == 'stopresetpass':
    403             fejl = 'Nytt lösenord ha redan skickats åt dej!! int ha du väl nu igen tappat bort ditt lösen? hmm.. om de e problematiskt ta kontakt med rob@bygdis.fi'
    404         if session.login < 3:
    405             loginform = self.form()
    406             return render.forgotpass(loginform, fejl)
    407         if session.login == 3:
    408             return web.seeother('/bilder')
    409         if session.login == 5:
    410             raise web.seeother('/admin')
    411     def POST(self):
    412         referer = web.ctx.env.get('HTTP_REFERER','https://bygdis.fi')
    413         ip = web.ctx['ip']
    414         stopflood(ip, referer)
    415         sendpassform = self.form()
    416         if not sendpassform.validates():
    417             return render.login(sendpassform, '')
    418         else:
    419             i = web.input()
    420             bildadmin = []
    421             bildadmins = bildhistoriker()
    422             if i.mail.lower() == 'byyssare':
    423                 raise web.seeother('/forgotpass?error=nej')
    424             for p in bildadmins:
    425                 if p.mail.lower() == i.mail.lower():
    426                     passfilter = stopresetpass(i.mail.lower())
    427                     if passfilter == True:
    428                         raise web.seeother('/forgotpass?error=stopresetpass')
    429                     unencrypted_password = ('%06x' % random.randrange(16**6))
    430                     password = unencrypted_password.encode("utf-8")
    431                     salt = bcrypt.gensalt()
    432                     password_hashed = bcrypt.hashpw(password, salt)
    433                     db.update('bildadmin', where='name="'+p.name+'"', password=password_hashed)
    434                     print("lösenordet uppdaterat!")
    435                     msg = "Ditt nya lösenord till byyns fotoalbum e: " + unencrypted_password + ' , om du vill ändra lösenordet ti någå du kommer ihåg så tryck på namne ditt högst op på ruutån efter du loggat in.'
    436                     sendmail(p.mail, 'Nytt lösenord till byyns fotoalbum', msg)
    437                     raise web.seeother('/forgotpass?error=done')
    438             raise web.seeother('/forgotpass?error=fejl')
    439 
    440 class register():
    441     form = web.form.Form(
    442     web.form.Textbox('user', description="användarnamn:"),
    443     web.form.Password('password', description="lösenord:"),
    444     web.form.Textbox('mail', description="e-post:"),
    445     web.form.Button('Skapa konto'))
    446     def GET(self):
    447         registerform = self.form()
    448         w = web.input()
    449         formfail = ''
    450         n = ''
    451         m = ''
    452         try:
    453             if w.fail == 'namn':
    454                 formfail = 'du måst hiitt opa eitt namn åt te!'
    455             if w.namn:
    456                 n = w.namn
    457             if w.epost:
    458                 m = w.epost
    459             elif w.epost == '':
    460                 formfail = 'tu måst lägg din epost address tär i ruuton, he e nu bara så...'
    461             if w.fail == 'notmail':
    462                 formfail = 'jusså, tetär e no inga nån mejl adress.'
    463             elif w.fail == 'nametaken':
    464                 formfail = 'Nån anan ha tagi de namme, hitt opa någå ana!'
    465             elif w.fail == 'mailtaken':
    466                 formfail = 'tu ha redan laga ett användarnamn me tetta epost konto!'
    467             elif w.fail == 'kortlosen':
    468                 formfail = 'he va no för uuslit lösenord, minst 5 bokstäver'
    469         except:
    470             pass
    471         #check user db, if empty create admin
    472         users = db.query("SELECT COUNT(*) AS users FROM bildadmin")[0]
    473         totusers = int(users.users)
    474         registerform.fill(user=urllib.parse.unquote_plus(n), mail=urllib.parse.unquote_plus(m))
    475         if session.login > 1:
    476             return render.register(registerform, formfail, totusers)
    477         else:
    478             raise web.seeother('/')
    479     def POST(self):
    480         if session.login > 1:
    481             registerform = self.form()
    482             i = web.input()
    483             r = '&namn=' + i.user + '&epost=' + i.mail
    484             urllib.parse.quote_plus(r)
    485             if i.user == '':
    486                 raise web.seeother('/register?fail=namn'+r)
    487             if '@' not in i.mail:
    488                 raise web.seeother('/register?fail=notmail'+r)
    489             if len(i.password) < 5:
    490                 raise web.seeother('/register?fail=kortlosen'+r)
    491             bildadmins = db.select('bildadmin', what='name, mail')
    492             for p in bildadmins:
    493                 if p.name.lower() == i.user.lower():
    494                     raise web.seeother('/register?fail=nametaken' +r)
    495                 if p.mail.lower() == i.mail.lower():
    496                     raise web.seeother('/register?fail=mailtaken' +r)
    497             adduser(i.user, i.password, i.mail.lower())
    498             #Send mail to Madbaker
    499             msg = "Wowowowoweeewaaa! Ny användare på bygdis.fi! " + i.user + ' ' + i.mail
    500             sendmail('rob@bygdis.fi', 'Wowowoweewaaa!', msg)
    501             #Send mail to new user
    502             msg = "Gratulis " + i.user + ", du har nu ett konto opa bygdis.fi! Logga in med användarnamn å lösenord på sidan https://bygdis.fi/login"
    503             sendmail(i.mail, 'Byyns eji fotoalbum', msg)
    504             session.login = 3
    505             session.user = i.user
    506             return web.seeother('/ny')
    507 
    508 class nydorrkod():
    509     form = web.form.Form(
    510     web.form.Textbox('namn', description="användarnamn:"),
    511     web.form.Textbox('mail', description="e-post:"),
    512     web.form.Textbox('dorrkod', description="Dörrkod:"),
    513     web.form.Button('Skapa ny Dörrkod'))
    514     def GET(self):
    515         registerform = self.form()
    516         w = web.input()
    517         formfail = ''
    518         n = ''
    519         m = ''
    520         try:
    521             if w.fail == 'namn':
    522                 formfail = 'du måst hiitt opa eitt namn åt te!'
    523             if w.fail == 'notmail':
    524                 formfail = 'jusså, tetär e no inga nån mejl adress.'
    525             if w.fail == 'kod':
    526                 formfail = 'koden måst vara 4 siffror!'
    527         except:
    528             pass
    529         if session.login == 5:
    530             return render.nydorrkod(registerform, formfail)
    531         else:
    532             raise web.seeother('/')
    533     def POST(self):
    534         if session.login == 5:
    535             registerform = self.form()
    536             i = web.input()
    537             if i.namn == '':
    538                 raise web.seeother('/nydorrkod?fail=namn')
    539             if '@' not in i.mail:
    540                 raise web.seeother('/nydorrkod?fail=notmail')
    541             if i.dorrkod == '':
    542                 dorrkod = random.randint(1111,9999)
    543             elif isinstance(int(i.dorrkod), int) and len(i.dorrkod) == 4:
    544                 dorrkod = str(i.dorrkod)
    545             else:
    546                 raise web.seeother('/nydorrkod?fail=kod')
    547             addDorrkod(dorrkod, i.namn, i.mail.lower())
    548             #Send mail to Madbaker
    549             msg = "Wowowowoweeewaaa! Ny dörrkod! " + i.namn + ' ' + i.mail + ' ' + str(dorrkod)
    550             sendmail('rob@bygdis.fi', 'Wowowoweewaaa!', msg)
    551             #Send mail to new user
    552             msg = "Gratulis " + i.namn + ", du har en dörrkod ti bygdis: " + str(dorrkod)
    553             sendmail(i.mail, 'Dörrkod till Bygdegården', msg)
    554             return web.seeother('/dorrkoder')
    555 
    556 class dorrkoder():
    557     def GET(self):
    558         if session.login == 5:
    559             dorrkoder = getDorrkoder()
    560             log = getDorrlog()
    561             print(dorrkoder)
    562             return render.dorrkoder(dorrkoder, log, getDorrkoduser)
    563         else:
    564             web.seeother('/')
    565 
    566 class dorrkoderapi():
    567     def GET(self): 
    568         global basedir
    569         f = open(basedir+"/apikey", "r")
    570         apikey = f.readline().strip()
    571         print(apikey)
    572         i = web.input(apikey=None,logger=None,doorstate=None,debug=None)
    573         if i.apikey == apikey:
    574             if i.logger != None:
    575                 if len(i.logger) == 4:
    576                     if getDorrkoduser(i.logger) != '':
    577                         print('logging dorrkod!')
    578                         dorrLogger(i.logger)
    579             elif i.doorstate != None:
    580                 db.update('doordebug', where='id="1"', doorstate=i.doorstate, debug=i.debug, datum=datetime.datetime.now())
    581             else:
    582                 dorrkoder = getDorrkoder()
    583                 #encoding = response.info().get_content_charset('utf8')
    584                 #apireq = data['icestats']['source'][1][i.req]
    585                 p = []
    586                 for i in dorrkoder:
    587                     p.append(i.dorrkod)
    588                     #print(i)
    589                 return json.dumps(p) 
    590 
    591 class ny():
    592     def GET(self):
    593         if session.login > 2:
    594             backurl = ''
    595             if session.backurl != '':
    596                 backurl = session.backurl
    597                 session.backurl = ''
    598             return render.ny(session.user, backurl)
    599 
    600 class tuning():
    601     form = web.form.Form(
    602     web.form.Textbox('user', description="synligt namn:"),
    603     web.form.Password('password', description="lösenord:"),
    604     web.form.Password('newpassword', description="nytt lösen (ifall du vill byta):"),
    605     web.form.Password('newpassword2', description="nytt lösen igen:"),
    606     web.form.Textbox('mail', description="epost:"), 
    607     web.form.Radio('subscribe', ['dagligen', 'aldrig'], description="Få epost brejv ifall de hänt någå"),
    608     web.form.Button('Spara'))
    609     def GET(self):
    610         if session.login > 2:
    611             print('asdfasdfasdf')
    612             user = db.select('bildadmin', where='name="'+session.user+'"')[0]
    613             tuningform = self.form()
    614             w = web.input(namn=None,epost=None,fail=None,upd=None)
    615             print('asdfasdfasdfkdakkakka')
    616             formfail = ''
    617             if w.fail == 'wrongpass':
    618                 formfail = formfail + 'fel lösenord'
    619             if w.fail == 'nopass':
    620                 formfail = formfail + 'Du måst skriv in ditt lösenord!'
    621             if w.namn == '':
    622                 formfail = formfail + 'du måst hiitt opa eitt namn åt te!'
    623             if w.epost == '':
    624                 formfail = formfail + 'tu måst lägg din epost address tär i ruuton, he e nu bara så...'
    625             elif w.fail == 'notmail':
    626                 formfail = formfail + 'jusså, tetär e no inga nån mejl adress.'
    627             if w.fail == 'nametaken':
    628                 formfail = formfail + 'Nån anan ha tagi de namme, hitt opa någå ana!'
    629             if w.fail == 'mailtaken':
    630                 formfail = formfail + 'He finns eitt konto me te epost adressn!'
    631             if w.fail == 'kortlosen':
    632                 formfail = formfail + 'he va no för uuslit lösenord, minst 5 bokstäver'
    633             if w.fail == 'newpass':
    634                 formfail = formfail + 'nya lösenordet stämmer inte överens med varann, pröva pånytt!'
    635             if w.upd == 'yes':
    636                 formfail = 'Yes, ditt konto e tuunat!'
    637             tuningform.fill(user=user.displayname, mail=user.mail, subscribe=user.subscribe)
    638             return render.tuning(tuningform, formfail, user.name)
    639         else:
    640             return web.seeother('/register')
    641     def POST(self):
    642         if session.login > 1:
    643             tuningform = self.form()
    644             i = web.input()
    645             if i.password == '':
    646                 raise web.seeother('/tuning?fail=nopass')
    647             bildadmins = bildhistoriker()
    648             for p in bildadmins:
    649                 print(p)
    650                 if p.name == session.user:
    651                     if bcrypt.checkpw(i.password.encode('utf-8'), p.password):
    652                         #check if display name taken
    653                         b_displayname = bildhistoriker()
    654                         for a in b_displayname:
    655                             if i.user in a.displayname and a.name != session.user:
    656                                 raise web.seeother('/tuning?fail=nametaken')
    657                             if i.mail in a.mail and i.mail != p.mail:
    658                                 raise web.seeother('/tuning?fail=mailtaken')
    659                         if i.newpassword != '':
    660                             if i.newpassword != i.newpassword2:
    661                                 raise web.seeother('/tuning?fail=newpass')
    662                             if len(i.newpassword) < 5:
    663                                 raise web.seeother('/tuning?fail=kortlosen')
    664                             else:
    665                                 #update with password change
    666                                 password = i.newpassword.encode("utf-8")
    667                                 salt = bcrypt.gensalt()
    668                                 password_hashed = bcrypt.hashpw(password, salt)
    669                                 db.update('bildadmin', where='name="'+session.user+'"', displayname=i.user, password=password_hashed, mail=i.mail.lower(), subscribe=i.subscribe)
    670                                 return web.seeother('/tuning?upd=yes')
    671                         if '@' not in i.mail:
    672                             raise web.seeother('/tuning?fail=notmail')
    673                         #update without passwordchange
    674                         db.update('bildadmin', where='name="'+session.user+'"', displayname=i.user, mail=i.mail.lower(), subscribe=i.subscribe)
    675                         return web.seeother('/tuning?upd=yes')
    676                     else:
    677                         raise web.seeother('/tuning?fail=wrongpass')
    678 
    679 class bilder():
    680     def GET(self):
    681         bildpersida = 100
    682         i = web.input()
    683         try:
    684             bilder_totalt = db.query("SELECT COUNT(*) AS bilder FROM bilder")[0]
    685             tot = int(bilder_totalt.bilder)
    686             print('bilder alltsomallt: ' + str(tot))
    687         except:
    688             print("inga bilder")
    689             tot = 0
    690         print('session search: ' + session.search)
    691         try:
    692             if i.search == '':
    693                 session.search = ''
    694                 session.bildsida = 0
    695             elif i.search != "":
    696                 session.search = urllib.parse.unquote_plus(i.search)
    697                 session.bildsida = 0
    698         except:
    699             pass
    700         if session.search != '':
    701             search_result = []
    702             tot = 0
    703             b1, b2, b3, b4, b5, = 0,0,0,0,0
    704             try:
    705                 search_result.append(db.query("SELECT * FROM bilder WHERE personer LIKE '%"+session.search+"%';"))
    706                 tot = db.query("SELECT Count(*) AS bilder FROM bilder WHERE personer LIKE '%"+session.search+"%';")[0]
    707                 b1 = tot.bilder
    708             except:
    709                 pass
    710             try:
    711                 search_result.append(db.query("SELECT * FROM bilder WHERE fotograf LIKE '%"+session.search+"%';"))
    712                 tot = db.query("SELECT Count(*) AS bilder FROM bilder WHERE fotograf LIKE '%"+session.search+"%';")[0]
    713                 b2 = tot.bilder
    714             except:
    715                 pass
    716             try:
    717                 search_result.append(db.query("SELECT * FROM bilder WHERE plats LIKE '%"+session.search+"%';"))
    718                 tot = db.query("SELECT Count(*) AS bilder FROM bilder WHERE plats LIKE '%"+session.search+"%';")[0]
    719                 b3 = tot.bilder
    720             except:
    721                 pass
    722             try:
    723                 search_result.append(db.query("SELECT * FROM bilder WHERE titel LIKE '%"+session.search+"%';"))
    724                 tot = db.query("SELECT Count(*) AS bilder FROM bilder WHERE titel LIKE '%"+session.search+"%';")[0]
    725                 b4 = tot.bilder
    726             except:
    727                 pass
    728             try:
    729                 search_result.append(db.query("SELECT * FROM bilder WHERE year LIKE '%"+session.search+"%';"))
    730                 tot = db.query("SELECT Count(*) AS bilder FROM bilder WHERE year LIKE '%"+session.search+"%';")[0]
    731                 b5 = tot.bilder
    732             except:
    733                 pass
    734             tot = b1 + b2 + b3 + b4 + b5
    735             try:
    736                 print(search_result)
    737                 print('sökta bilder: ' + str(tot))
    738             except:
    739                 pass
    740         try:
    741             if i.page == "next":
    742                 if session.bildsida < tot:
    743                     session.bildsida += bildpersida
    744             if i.page == "back":
    745                 if session.bildsida > bildpersida:
    746                     session.bildsida -= bildpersida
    747                 else:
    748                     session.bildsida = 0
    749         except:
    750             pass
    751         if session.login > 1:
    752             limit = session.bildsida + bildpersida
    753             offset = session.bildsida
    754             print(session.bildsida)
    755             if session.search == '':
    756                 bilder = db.query("SELECT * FROM bilder ORDER BY uploaddate DESC LIMIT " + str(limit) + " OFFSET " + str(offset))
    757             else:
    758                 bilder = search_result
    759             if session.login > 3:
    760                 try:
    761                     if i.delete != '':
    762                         return web.seeother('/remove/' + i.delete)
    763                 except:
    764                     pass
    765                 rights = 'admin'
    766             elif session.login > 2:
    767                 rights = 'mod'
    768             elif session.login > 1:
    769                 rights = 'byyssare'
    770             return render.bilder(bilder, rights, session.user, tot, limit, bildpersida, session.search, db, str, print)
    771         else:
    772             return web.seeother('/login')
    773 
    774 class remove():
    775     def GET(self, imghash):
    776         if session.login > 1:
    777             referer = web.ctx.env.get('HTTP_REFERER', 'none')
    778             i = web.input(sure=None)
    779             if i.sure == 'yes':
    780                 db.delete('bilder', where='filename="' + imghash + '"')
    781                 db.delete('allaversioner', where='filename="' + imghash + '"')
    782                 db.delete('likes', where='bild="' + imghash + '"')
    783                 db.delete('hates', where='bild="' + imghash + '"')
    784                 db.delete('bildkommentar', where='filename="' + imghash + '"')
    785                 return web.seeother('/bilder')
    786             return render.remove(imghash, referer)
    787 
    788 class upload():
    789     def GET(self):
    790         if session.login == 2:
    791             session.backurl = '/upload'
    792             return web.seeother('register')
    793         elif session.login > 2:
    794             return render.upload()
    795         else:
    796             return web.seeother('/login')
    797     def POST(self):
    798         if session.login > 2:
    799             i = web.input(imgfile={})
    800             for p in i:
    801                 print(p)
    802             if i.imgfile != {}:
    803                 print(i.imgfile.filename)
    804                 if i.imgfile.filename == '':
    805                     print('hmmm... no image to upload')
    806                     raise web.seeother('/upload?fail=noimg')
    807                 print('YEAH, Upload image!')
    808 
    809                 ##---------- UPLOAD IMAGE ----------
    810 
    811                 imgdir = basedir + '/public_html/static/bilder/'
    812                 imgpath=i.imgfile.filename.replace('\\','/') # replaces the windows-style slashes with linux ones.
    813                 #filename=filepath.split('/')[-1] # splits the and chooses the last part (the filename with extension)
    814                 imghash = hashlib.md5(str(random.getrandbits(256)).encode('utf-8')).hexdigest()
    815                 imgname = imghash + '.jpeg'
    816                 #imgname = str(len(os.listdir(imgdir))).zfill(3) + '.jpeg'
    817                 fout = open(imgdir +'/'+ imgname,'wb') # creates the file where the uploaded file should be stored
    818                 fout.write(i.imgfile.file.read()) # writes the uploaded file to the newly created file.
    819                 fout.close() # closes the file, upload complete.
    820 
    821                 ##---------- OPEN FILE & CHEKC IF JPEG --------
    822                 image = Image.open(imgdir +'/'+ imgname)
    823                 if image.format != 'JPEG':
    824                     os.remove(imgdir +'/'+ imgname)
    825                     raise web.seeother('/upload?fail=notjpeg')
    826 
    827                 ##---------- RESIZE IMAGE -----------
    828                 image.thumbnail((900,900), Image.ANTIALIAS)
    829                 image.save(imgdir + '/web/' + imgname)
    830                 image.thumbnail((300,300), Image.ANTIALIAS)
    831                 image.save(imgdir + '/thumb/' + imgname)
    832 
    833                 db.insert('bilder', filename=imghash, uploaddate=datetime.datetime.now(), uppladdare=session.user, lastmod=datetime.datetime.now(), moddedby=session.user)
    834                 raise web.seeother('/bildinfo/' + imghash)
    835             else:
    836                 return render.upload()
    837         else:
    838             session.backurl = '/upload'
    839             return render.register()
    840 
    841 class bildinfo():
    842     form = web.form.Form(
    843     web.form.Textbox('titel', web.form.notnull, description="Bild titel:"),
    844     web.form.Textbox('year', web.form.notnull, description="År:"),
    845     web.form.Textbox('fotograf', web.form.notnull, description="Fotograf:"),
    846     web.form.Textbox('plats', web.form.notnull, description="Plats:"),
    847     web.form.Textarea('beskrivning', web.form.notnull, description="Beskrivning:"),
    848     web.form.Textarea('personer', web.form.notnull, description="Personer fr.v. (lägg ett komma mellan varje typ):"),
    849     web.form.Button('Spara'))
    850     def GET(self, imghash):
    851         if session.login > 2:
    852             infoform = self.form()
    853             v = web.input()
    854             if v:
    855                 oldinfo = db.select('allaversioner', where="id='" + v.id +"'", what='titel, year, fotograf, beskrivning, personer, moddedby, lastmod, plats')
    856             else:
    857                 oldinfo = db.select('bilder', where="filename='" + imghash +"'", what='titel, year, fotograf, beskrivning, personer, moddedby, lastmod, plats')
    858             oldinfo = oldinfo[0]
    859             allaversioner = db.select('allaversioner', where="filename='" + imghash +"'", what='id, moddedby, lastmod', order='id DESC')
    860             infoform.fill(titel=oldinfo.titel, year=oldinfo.year, fotograf=oldinfo.fotograf, plats=oldinfo.plats, beskrivning=oldinfo.beskrivning, personer=oldinfo.personer)
    861             return render.bildinfo(infoform, imghash, oldinfo.moddedby, oldinfo.lastmod, allaversioner)
    862         else:
    863             session.backurl = '/bildinfo/' + imghash
    864             return web.seeother("/register")
    865     def POST(self, imghash):
    866         ip = web.ctx['ip']
    867         referer = web.ctx.env.get('HTTP_REFERER','https://bygdis.fi')
    868         stopflood(ip, referer)
    869         if session.login > 2:
    870             i = web.input()
    871             db.update('bilder', where="filename='" + imghash +"'", titel=i.titel, year=i.year, fotograf=i.fotograf, plats=i.plats, beskrivning=i.beskrivning, personer=i.personer, lastmod=datetime.datetime.now(), moddedby=session.user)
    872             db.insert('allaversioner', filename=imghash, titel=i.titel, year=i.year, fotograf=i.fotograf, plats=i.plats, beskrivning=i.beskrivning, personer=i.personer, lastmod=datetime.datetime.now(), moddedby=session.user)
    873             return web.seeother('/bildinfo/' + imghash)
    874 
    875 class bild():
    876     form = web.form.Form(
    877     web.form.Textarea('kommentar', web.form.notnull, description=""),
    878     web.form.Button('kommentera'))
    879     def GET(self, imghash):
    880         i = web.input(unlike=None, like=None, hate=None, unhate=None)
    881         kform = self.form()
    882         if session.login > 1:
    883             l = db.query("SELECT * FROM likes WHERE bild='"+imghash+"' AND user='"+session.user+"';")
    884             h = db.query("SELECT * FROM hates WHERE bild='"+imghash+"' AND user='"+session.user+"';") 
    885             if l:
    886                 user_likes = True
    887             else:
    888                 user_likes = False
    889             if h:
    890                 user_hates = True
    891             else:
    892                 user_hates = False
    893             try:
    894                 if i.delete != '':
    895                     allow_del = db.select('bildkommentar', where="id='"+i.delete+"'", what='user')[0]
    896                     print(allow_del)
    897                     if allow_del.user == session.user:
    898                         db.delete('bildkommentar', where='id="' + i.delete + '"')
    899             except:
    900                 print('something wrong with input in class bild, så att du veit')
    901             if i.like != None and user_likes == False:
    902                 db.insert('likes', user=session.user, bild=imghash, datum=datetime.datetime.now())
    903                 user_likes = True
    904             elif i.unlike != None and user_likes == True:
    905                 db.query("DELETE FROM likes WHERE bild='"+imghash+"' AND user='"+session.user+"';")
    906                 user_likes = False
    907             if i.hate != None and user_hates == False:
    908                 db.insert('hates', user=session.user, bild=imghash, datum=datetime.datetime.now())
    909                 user_hates = True
    910             elif i.unhate != None and user_hates == True:
    911                 db.query("DELETE FROM hates WHERE bild='"+imghash+"' AND user='"+session.user+"';")
    912                 user_hates = False
    913             likes = db.query("SELECT Count(*) AS likes FROM likes WHERE bild='"+imghash+"';")[0]
    914             hates = db.query("SELECT Count(*) AS hates FROM hates WHERE bild='"+imghash+"';")[0]
    915             b = db.select('bilder', where="filename='" + imghash +"'", what='titel, year, fotograf, plats, beskrivning, personer, moddedby, lastmod, uppladdare')[0]
    916             text = db.select('allaversioner', where="filename='" + imghash +"'", what='moddedby')
    917             comments = db.select('bildkommentar', where="filename='" + imghash +"'", what='id, user, comment, upvotes, datumtid', order='datumtid DESC')
    918             try:
    919                 personer = b.personer.replace(', ', ',').split(',')
    920             except:
    921                 personer = ''
    922             back_next = db.query('SELECT prev, next from (SELECT id, LAG(filename) OVER (ORDER BY id) AS next, filename, LEAD(filename) OVER (ORDER BY id) AS prev FROM bilder) AS t WHERE filename="'+imghash+'";')[0]
    923             print(back_next)
    924             return render.bild(b, imghash, personer, kform, comments, session.user, user_likes, likes, user_hates, hates, back_next, text, getdisplayname)
    925         else:
    926             session.backurl="/bild/"+imghash
    927             raise web.seeother("/login")
    928     def POST(self, imghash):
    929         ip = web.ctx['ip']
    930         referer = web.ctx.env.get('HTTP_REFERER','https://bygdis.fi')
    931         stopflood(ip, referer)
    932         komm = self.form()
    933         if session.login > 1:
    934             i = web.input()
    935             if i.kommentar != '':
    936                 db.insert('bildkommentar', filename=imghash, user=session.user, comment=i.kommentar, datumtid=datetime.datetime.now())
    937             raise web.seeother("/bild/"+imghash+"#comments")
    938 
    939 class senaste():
    940     def GET(self):
    941         if session.login > 1:
    942             comments = db.select('bildkommentar', what='id, filename, user, comment, upvotes, datumtid', order='datumtid DESC')
    943             b = db.select('bilder', what='filename, titel, year, fotograf, plats, beskrivning, personer, moddedby, lastmod, uppladdare, uploaddate', order='lastmod DESC')
    944             binfo = db.select('allaversioner', what='filename, titel, year, fotograf, plats, beskrivning, personer, moddedby, lastmod, uppladdare, uploaddate', order='lastmod DESC')
    945             return render.senaste(b, comments, binfo, getdisplayname)
    946 
    947 class logout():
    948     def GET(self):
    949         session.login = 1
    950         session.backurl = ''
    951         session.user = ''
    952         session.bildsida = 0
    953         print(session.login)
    954         raise web.seeother('/')
    955 
    956 class index():
    957     def GET(self):
    958         upcomingevents = getkalender()
    959         return render2.index(upcomingevents)
    960 
    961 class old():
    962     def GET(self):
    963         oldevents = getkalenderall()
    964         return render2.old(oldevents)
    965 
    966 class nope():
    967     def GET(self):
    968         #print curdate()
    969         return render.nope()
    970 
    971 class protokoll():
    972     def GET(self):
    973         if session.login == 5:
    974             webdata = web.input(year=None, nr=0)
    975             view = ''
    976             years = os.listdir(basedir + '/protokoll/')
    977             years.sort()
    978             if webdata.year:
    979                 protokoll = getprotokoll(webdata.year)
    980             else:
    981                 protokoll = []
    982             if len(protokoll) > 0:
    983                 #make html from markdown
    984                 pandoc_html = ['pandoc', basedir + '/protokoll/' + webdata.year + '/' + protokoll[int(webdata.nr)], '-f', 'markdown', '-t', 'html']
    985                 #make pdf from markdown
    986                 viewfile = subprocess.check_output(pandoc_html)
    987                 view = viewfile.decode()
    988                 pandoc_pdf = ['pandoc', '--verbose', basedir + '/protokoll/' + webdata.year + '/' + protokoll[int(webdata.nr)], '-f', 'markdown', '-V', 'papersize:a4', '-V', 'geometry:margin=0.8in','-s', '-o', basedir + '/public_html/static/pdf/uf-protokoll.pdf']
    989                 subprocess.Popen(pandoc_pdf, cwd=basedir + '/public_html/static/pdf/')
    990             return render3.protokoll(webdata.year, years, protokoll, view)
    991         else:
    992             raise web.seeother('/login')
    993 
    994 class protokollredirect():
    995     def GET(self):
    996         raise web.seeother('/protokoll/')
    997 
    998 application = app.wsgifunc()