bygdis.fi

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

server.py (66693B)


      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 from virtuaaliviivakoodi import virtuaaliviivakoodi
     18 from bs4 import BeautifulSoup
     19 import requests
     20 basedir = os.path.dirname(os.path.realpath(__file__))
     21 sys.path.append(basedir)
     22 import settings
     23 
     24 #web.config.session_parameters['cookie_name'] = 'bygdis.fi'
     25 #web.config.session_parameters['cookie_domain'] = None
     26 #web.config.session_parameters['cookie_path'] = None
     27 #web.config.session_parameters['timeout'] = 839808000  # in seconds
     28 #web.config.session_parameters['ignore_expiry'] = True
     29 #web.config.session_parameters['ignore_change_ip'] = True
     30 #web.config.session_parameters['secret_key'] = 'fLjUfxqXtfNoIldA0A0R'
     31 #web.config.session_parameters['expired_message'] = 'Session expired'
     32 
     33 urls = (
     34     "/", "index",
     35     "/login?", "login",
     36     "/logout", "logout",
     37     "/addevent?", "addevent",
     38     "/event", "event",
     39     "/undo", "undo",
     40     "/roskis", "undo",
     41     r"/removeevent/(\d+)", "removeevent",
     42     r"/editevent/(\d+)", "editevent",
     43     r"/removepost/(\d+)", "removepost",
     44     "/old", "old",
     45     "/bilder?", "bilder",
     46     "/upload?", "upload",
     47     "/bild/(.*)?", "bild",
     48     "/bildinfo/(.*)?", "bildinfo",
     49     "/om", "om",
     50     "/remove/(.*)?","remove",
     51     "/tuning?", "tuning",
     52     "/senaste", "senaste",
     53     "/admin?", "admin",
     54     "/boka?", "boka",
     55     "/fakturor?", "fakturor",
     56     "/dorrkoder?", "dorrkoder",
     57     "/nydorrkod?", "nydorrkod",
     58     "/dorrkoderapi?", "dorrkoderapi",
     59     "/kod?","kod",
     60     "/register?", "register",
     61     "/forgotpass?", "forgotpass",
     62     "/ny", "ny",
     63     "/tack", "tack",
     64     "/protokoll?", "protokoll",
     65     "/nope", "nope"
     66 )
     67 
     68 #from settings.py
     69 postadmin = settings.postadmin
     70 postadmin_signature = settings.postadmin_signature
     71 mlinvoice_db = settings.mlinvoice_db
     72 mlinvoice_db_user = settings.mlinvoice_db_user
     73 mlinvoice_db_pass = settings.mlinvoice_db_pass
     74 mlinvoice_login=settings.mlinvoice_login
     75 mlinvoice_passwd=settings.mlinvoice_passwd
     76 
     77 render = web.template.render(basedir + "/public_html/html/", base="base")
     78 render2 = web.template.render(basedir + "/public_html/html/", base="base2")
     79 render3 = web.template.render(basedir + "/public_html/html/", base="base3")
     80 web.config.debug = False
     81 app = web.application(urls, globals())
     82 store = web.session.DiskStore(basedir + '/sessions')
     83 db = web.database(dbn="sqlite", db=basedir + "/db/bygdis.db")
     84 db2 = web.database(dbn="mysql", db=mlinvoice_db, user=mlinvoice_db_user, pw=mlinvoice_db_pass)
     85 session = web.session.Session(app,store,initializer={'login': 0, 'user': '', 'backurl': '', 'bildsida': 0, 'search': ''})
     86 
     87 def logged():
     88     if session.login == 5:
     89         return True
     90     else:
     91         return False
     92 
     93 def curdate():
     94     today = datetime.datetime.now().date().strftime('%s')
     95     return today
     96 
     97 def getkalender():
     98     events = db.query("SELECT * FROM kalender WHERE datumtid > DATETIME('now') ORDER BY datumtid ASC")
     99     #events = db.select('kalender', what='id, datumtid, event', order='datumtid ASC')
    100     return events
    101 
    102 def getkalenderall():
    103     events = db.query("SELECT * FROM kalender ORDER BY datumtid ASC")
    104     #events = db.select('kalender', what='id, datumtid, event', order='datumtid ASC')
    105     return events
    106 
    107 def nyevent(id, datumtid, event, admin_visible, info):
    108     f = '%Y-%m-%d %H:%M:%S'
    109     try:
    110         datumtid.weekday()
    111         print('not datetime object make it')
    112     except:
    113         datumtid = datetime.datetime.strptime(datumtid,f)
    114     veckodagar = u'Måndag', u'Tisdag', u'Onsdag', u'Torsdag', u'Fredag', u'Lördag', u'Söndag'
    115     veckodag = datumtid.weekday()
    116     if id==None:
    117         db.insert('kalender', datumtid=datumtid, veckodag=veckodagar[veckodag], event=event, admin=admin_visible, info=info)
    118     else:
    119         db.update('kalender', where='id="'+id+'"', datumtid=datumtid, veckodag=veckodagar[veckodag], event=event, admin=admin_visible, info=info)
    120     print("event added to database")
    121     return
    122 
    123 def copyevent(id, datumtid, event, admin_visible, info):
    124     veckodagar = u'Måndag', u'Tisdag', u'Onsdag', u'Torsdag', u'Fredag', u'Lördag', u'Söndag'
    125     veckodag = datumtid.weekday()
    126     db.insert('kalender', datumtid=datumtid, veckodag=veckodagar[veckodag], event=event, admin=admin_visible, info=info)
    127     print("event added to database")
    128     return
    129 
    130 def getbokningar():
    131     bokningar = db.query("SELECT * FROM bokningar ORDER BY datumtid DESC")
    132     #events = db.select('kalender', what='id, datumtid, event', order='datumtid ASC')
    133     return bokningar
    134 
    135 def getposts():
    136     posts = db.query("SELECT * FROM posts ORDER BY datumtid DESC")
    137     #events = db.select('kalender', what='id, datumtid, event', order='datumtid ASC')
    138     return posts
    139 
    140 def nypost(datumtid, post):
    141     db.insert('posts',  datumtid=datumtid, post=post, likes=0)
    142     print("post added to database")
    143     return
    144 
    145 def getprotokoll(year):
    146     listmodtime = []
    147     for a in os.scandir(basedir + '/protokoll/' + year):
    148         filename = a.name
    149         modtime = a.stat().st_mtime
    150         listmodtime.append((filename, modtime))
    151     listmodtime.sort(key=lambda tup: tup[0])
    152     protokoll = []
    153     for a in listmodtime:
    154         if a[0][0] != '.':
    155             protokoll.append(a[0])
    156     return protokoll
    157 
    158 def getprotokoll_lastmodified(year):
    159     listmodtime = []
    160     for a in os.scandir(basedir + '/protokoll/' + year):
    161         filename = a.name
    162         modtime = a.stat().st_mtime
    163         listmodtime.append((filename, modtime))
    164     listmodtime.sort(key=lambda tup: tup[1])
    165     protokoll = []
    166     for a in listmodtime:
    167         protokoll.append(a[0])
    168     return protokoll
    169 
    170 def md_to_html(markdownfile):
    171     #make html from markdown
    172     pandoc_html = ['pandoc', basedir + '/'+markdownfile, '-f', 'markdown', '-t', 'html']
    173     #make pdf from markdown
    174     viewfile = subprocess.check_output(pandoc_html)
    175     view = viewfile.decode()
    176     return view
    177 
    178 def md_to_pdf(markdownfile):
    179     randhash = hashlib.md5(str(random.getrandbits(256)).encode('utf-8')).hexdigest()
    180     pandoc_pdf = ['pandoc', '--verbose', basedir + '/'+markdownfile, '-f', 'markdown', '-V', 'papersize:a4', '-V', 'geometry:margin=0.8in','-s', '-o', basedir + '/public_html/static/pdf/'+randhash+'.pdf']
    181     subprocess.Popen(pandoc_pdf, cwd=basedir + '/public_html/static/pdf/')
    182     time.sleep(3)
    183     raise web.seeother('/static/pdf/'+randhash+'.pdf?nocache='+randhash)
    184 
    185 def md_to_text(markdownfile):
    186     read_p=basedir + '/'+markdownfile
    187     with open(read_p, 'r') as file:
    188         p_list=file.readlines()
    189     pr=''
    190     for p in p_list:
    191         pr=pr+p
    192     return pr
    193 
    194 def adduser(name, password, mail):
    195     password = password.encode("utf-8")
    196     salt = bcrypt.gensalt()
    197     password_hashed = bcrypt.hashpw(password, salt)
    198     #check user db, if empty create admin
    199     users = db.query("SELECT COUNT(*) AS users FROM bildadmin")[0]
    200     tot = int(users.users)
    201     print('users alltsomallt: ' + str(tot))
    202     if tot > 1:
    203         db.insert('bildadmin', name=name, displayname=name, password=password_hashed, mail=mail, subscribe='aldrig', adminlevel=3)
    204     else:
    205         db.insert('bildadmin', name=name, displayname=name, password=password_hashed, mail=mail, subscribe='aldrig', adminlevel=5)
    206     print("new user added")
    207     return
    208 
    209 def bildhistoriker():
    210     bildhistoriker = db.query("SELECT name, displayname, mail, password FROM bildadmin")
    211     return bildhistoriker
    212 
    213 def adminlevel(user):
    214     level = db.query("SELECT adminlevel FROM bildadmin WHERE name='"+user+"';")[0]
    215     #1 session logout, web.py bug
    216     #2 rights to see pics and comment
    217     #3 rights to upoload
    218     #5 superadmin
    219     session.login = int(level.adminlevel)
    220     return
    221 
    222 def getdisplayname(user):
    223     displayname = db.query("SELECT displayname FROM bildadmin WHERE name='"+user+"';")[0]
    224     return displayname.displayname
    225 
    226 def getkund(id):
    227     try:
    228         name = db2.query("SELECT company_name FROM mlinvoice_company WHERE id='"+str(id)+"';")[0]
    229     except:
    230         name = ''
    231     return name.company_name
    232 
    233 def getmaksuja(id):
    234     try:
    235         maksut = db2.query("SELECT * FROM mlinvoice_invoice_row WHERE invoice_id='"+str(id)+"';")
    236     except:
    237         maksut = ''
    238     return maksut
    239 
    240 def getprodukt(id):
    241     try:
    242         str(int(id))
    243         produkt = db2.query("SELECT * FROM mlinvoice_product WHERE id='"+str(id)+"';")[0]
    244         return produkt
    245     except:
    246         produkt = ''
    247     try:
    248         produkt = db2.query("SELECT * FROM mlinvoice_product WHERE product_name LIKE '%"+id[:-14]+"%';")[0]
    249         return produkt
    250     except:
    251         produkt = ''
    252     return produkt
    253 
    254 def getbilder():
    255     bilder = db.query("SELECT * FROM bilder ORDER BY uploaddate DESC")
    256     return bilder
    257 
    258 def addbild(filename, titel, namn, year, fotograf, beskrivning, uppladdare, personer):
    259     db.insert('bilder', filename=filename, titel=titel, uploaddate=datetime.datetime.now(), namn=namn, year=year, fotograf=fotograf, beskrivning=beskrivning, uppladdare=uppladdare, personer=personer)
    260 
    261 def addDorrkod(dorrkod, name, mail):
    262     db.insert('dorrkoder', dorrkod=dorrkod, name=name, mail=mail, datum=datetime.datetime.now())
    263 
    264 def dorrLogger(dorrkod):
    265     db.insert('dorrlogger', dorrkod=dorrkod, datum=datetime.datetime.now())
    266 
    267 def getDorrlog(limit):
    268     if limit == 0:
    269         log=db.query("SELECT * FROM dorrlogger ORDER BY datum DESC")
    270     else:
    271         log=db.query("SELECT * FROM dorrlogger ORDER BY datum DESC LIMIT "+str(limit))
    272     return log
    273 
    274 def getDorrkoduser(dorrkod):
    275     try:
    276         user = db.query("SELECT name FROM dorrkoder WHERE dorrkod='"+str(dorrkod)+"';")[0]
    277         return user.name
    278     except:
    279         user = 'unknown'
    280         return user
    281 
    282 def getDorrkoder():
    283     dorrkoder=db.query("SELECT * FROM dorrkoder ORDER BY datum DESC")
    284     return dorrkoder
    285 
    286 def sendmail(email, subject, msg, bilaga):
    287     #Send mail
    288     echomsg = subprocess.Popen(('echo', msg+'\n'+postadmin_signature), stdout=subprocess.PIPE)
    289     if bilaga != '':
    290         sendmsg = subprocess.check_output(('mail.mailutils', '-A', bilaga, '-a', 'From:'+postadmin, '-r', postadmin, '-s', subject, email),stdin=echomsg.stdout)
    291     else:
    292         sendmsg = subprocess.check_output(('mail.mailutils', '-r', postadmin, '-a', "Content-Type: text/plain;", '-a', 'From:'+postadmin, '-s', subject, email), stdin=echomsg.stdout)
    293         #sendmsg = subprocess.check_output(('mail.mailutils', '-r', postadmin, '-a', "Content-Type: text/plain; charset='utf-8'", '-a', 'From:'+postadmin, '-s', subject, email), stdin=echomsg.stdout)
    294     echomsg.wait()
    295     #subprocess.call(['echo', msg, '|', 'mail', '-r', 'rob@tarina.org','-s', subject, email])
    296 
    297 def stopflood(ip,referer):
    298     try:
    299         t = db.select('stopflood', where='ip="'+ip+'"', what='tid')[0]
    300     except:
    301         pass
    302     try:
    303         db.update('stopflood', where='ip="'+ip+'"', tid=time.time())
    304     except:
    305         db.insert('stopflood', ip=ip, tid=time.time())
    306     try:
    307         senast = time.time() - t.tid
    308         print(senast)
    309         if senast < 2:
    310             return web.seeother(referer)
    311         else:
    312             return
    313     except:
    314         return
    315 
    316 def stopresetpass(mail):
    317     try:
    318         t = db.select('stopresetpass', where='mail="'+mail+'"', what='tid')[0]
    319         print(t)
    320     except Exception as e:
    321         print(e)
    322     try:
    323         db.update('stopresetpass', where='mail="'+mail+'"', tid=time.time())
    324     except Exception as e:
    325         print(e)
    326         db.insert('stopresetpass', mail=mail, tid=time.time())
    327     try:
    328         senast = time.time() - t.tid
    329         print(senast)
    330         if senast < 604800:
    331             print('mail is in password reset spam filter')
    332             return True
    333         else:
    334             return False
    335     except Exception as e:
    336         print(e)
    337         return True
    338 
    339 class om():
    340     def GET(self):
    341         return render.om()
    342 
    343 class admin():
    344     form = web.form.Form(
    345     web.form.Textarea('post', web.form.notnull, description="", width="500px", height="200px", autocomplete="off"),
    346     web.form.Button('skicka'))
    347     def GET(self):
    348         print(session.login)
    349         if session.login == 5:
    350             doordebug = db.select('doordebug')[0]
    351             saysomething = self.form()
    352             anslagstavla = getposts()
    353             bokningar = getbokningar()
    354             roskis=db.select('roskis')[0]
    355             i = web.input(approve=None,sendrules=None,fakturera=None,doorcode=None,remove=None,emptytrash=None)
    356             if i.approve != None:
    357                 #Send mail to admin
    358                 bokning = db.select('bokningar', where='id="'+i.approve+'"')[0]
    359                 msg = "Bokning godkänd av " + bokning.namn + ' epost: ' + bokning.epost
    360                 sendmail(postadmin, 'Bokning godkänd!', msg, '')
    361                 #Send mail to user
    362                 msg = "Hej " + bokning.namn + " bokning " + bokning.datumtid + " godkändes, Tack!"
    363                 sendmail(bokning.epost, 'Bokning av Bygdegården lyckades och är godkänd', msg, '')
    364                 #update booking
    365                 db.update('bokningar', where='id="'+i.approve+'"', approved=datetime.datetime.now())
    366                 #add to kalender events as privat bokning
    367                 print(bokning.datumtid)
    368                 nyevent(None, bokning.datumtid, 'privat bokning', bokning.namn, 'privat bokning')
    369                 raise web.seeother('/admin')
    370             if i.sendrules != None:
    371                 #Send mail to admin
    372                 bokning = db.select('bokningar', where='id="'+i.sendrules+'"')[0]
    373                 msg = "Skickar regler och villkor till " + bokning.namn + ' epost: ' + bokning.epost
    374                 sendmail(postadmin, 'Skickar villkor och regler', msg,'')
    375                 #Send mail to user
    376                 msg = "Hej " + bokning.namn + "! Gå in här https://bygdis.fi/boka?id="+bokning.bokningshash+" och godkänn regler och villkor för din bokning, du får fakturan inom kort och en dörrkod när fakturan är betald. Tack!"
    377                 sendmail(bokning.epost, 'Regler och villkor för Bygdegården', msg,'')
    378                 #update booking
    379                 db.update('bokningar', where='id="'+i.sendrules+'"', approved="")
    380                 raise web.seeother('/admin')
    381             if i.fakturera != None:
    382                 db.update('bokningar', where='id="'+i.fakturera+'"', faktura=datetime.datetime.now())
    383                 raise web.seeother('/admin')
    384             if i.doorcode != None:
    385                 raise web.seeother('/admin?kakka')
    386             if i.remove != None:
    387                 db.update('bokningar', where='id="'+i.remove+'"', deleted=1)
    388                 raise web.seeother('/admin')
    389             if i.emptytrash == 'now':
    390                 msg = "Hej, kan vi få avfallshämtning till Påvalsbyvägen 679, 07870 Skinnarby? ingen brådska, bara så fort som möjligt, tack! ;)"
    391                 sendmail('asiakaspalvelu@rosknroll.fi', 'Roskistömning till Påvalsbyvägen 679', msg,'')
    392                 db.update('roskis',  where='id=1',datum=datetime.datetime.now())
    393                 raise web.seeother('/admin')
    394             log = getDorrlog(10)
    395             print(log)
    396             print('FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF')
    397             return render2.admin(anslagstavla,saysomething,bokningar,doordebug,str,log,getDorrkoduser,roskis)
    398         else:
    399             raise web.seeother('/login')
    400     def POST(self):
    401         if session.login == 5:
    402             i = web.input(post=None,approve=None,sendrules=None,fakturera=None,doorcode=None,remove=None)
    403             saysomething = self.form()
    404             if i.post != None:
    405                 print('ADDDDDDDDDDDDDING TO database post ' + i.post)
    406                 now = datetime.datetime.now()
    407                 print('ADDDDDDDDDDDDDING TO database date' + str(now))
    408                 nypost(now, i.post)
    409             raise web.seeother('/admin')
    410         else:
    411             raise web.seeother('/login')
    412 
    413 class boka():
    414     produkter = []
    415     p = db2.select('mlinvoice_product')
    416     for i in p:
    417         if i.product_name != None and i.deleted == 0:
    418             produkter.append(i.product_name+' | '+str(round(i.unit_price,2))+' €')
    419     form = web.form.Form(
    420     web.form.Textbox('year', web.form.notnull, web.form.regexp(r'\d+', 'yyyy'), description="år:"),
    421     web.form.Textbox('day', web.form.notnull, web.form.regexp(r'\d+', 'dd'), description="dag:", autofocus="autofocus"),
    422     web.form.Textbox('month', web.form.notnull, web.form.regexp(r'\d+', 'MM'), description="månad:"),
    423     web.form.Dropdown('boka', produkter, web.form.notnull, description="hyr"),
    424     web.form.Textarea('event', web.form.notnull, description="beskrivning och uppskattat antal gäster:"),
    425     web.form.Textbox('namn', web.form.notnull, description="namn:"),
    426     web.form.Textbox('epost', web.form.notnull, description="e-post:"),
    427     web.form.Textbox('telefon', web.form.regexp(r'\d+', 'nummer tack'), description="telefon:"),
    428     web.form.Radio('villkor', [u'Nej', u'Ja'], web.form.notnull, description="Jag har läst och godkänner alla ovannämnda regler och villkor."),
    429     web.form.Radio('privat', [u'Privat', u'Offentligt'], web.form.notnull, description="I hurudant syfte?:"),
    430     web.form.Button('Skicka'))
    431     def GET(self):
    432         i = web.input(id=None, cp=None, pdf=None, kod=None)
    433         form_boka = self.form()
    434         if i.id==None:
    435             now = datetime.datetime.now()
    436             form_boka.fill(year=now.year, month=now.month, day=now.day)
    437             if i.kod=='jep':
    438                 form_boka.fill(year=now.year, month=now.month, day=now.day ,boka='Dörrkod / Ovikoodi | 10.00 €', privat='Privat', event='Dörrkod för användning av Bygdegården i privat syfte.') 
    439         else:
    440             event = db.select('bokningar', where='bokningshash="'+i.id+'"')[0]
    441             now=datetime.datetime.strptime(event.datumtid, '%Y-%m-%d %H:%M:%S')
    442             form_boka.fill(year=now.year, month=now.month, day=now.day, boka=event.boka, event=event.event, namn=event.namn, epost=event.epost, telefon=event.telefon, villkor=event.villkor, privat=event.privat)
    443         regler = md_to_html('protokoll/dokument/hyreskontrakt_regler_och_villkor.md')
    444         if i.pdf != None:
    445             md_to_pdf('protokoll/dokument/hyreskontrakt_regler_och_villkor.md')
    446         return render.boka(form_boka, regler)
    447     def POST(self):
    448         form_boka = self.form()
    449         if not form_boka.validates():
    450             return render.nope()
    451             #regler = md_to_html('protokoll/dokument/hyreskontrakt_regler_och_villkor.md')
    452             #return render.boka(form_boka,regler)
    453         else:
    454             i = web.input(id=None, copyevent=None)
    455             try:
    456                 year = int(i.year)
    457                 month = int(i.month)
    458                 day = int(i.day)
    459                 datum = datetime.datetime(year, month, day)
    460             except ValueError:
    461                 return render.nope()
    462             if i.id == None:
    463                 bokningshash = hashlib.md5(str(random.getrandbits(256)).encode('utf-8')).hexdigest()
    464                 db.insert('bokningar', datumtid=datetime.datetime(year, month, day), boka=i.boka, event=i.event, namn=i.namn, epost=i.epost, telefon=i.telefon, villkor=i.villkor, privat=i.privat, bokningshash=bokningshash)
    465             else:
    466                 db.update('bokningar', where='bokningshash="'+i.id+'"', datumtid=datetime.datetime(year, month, day), boka=i.boka, event=i.event, namn=i.namn, epost=i.epost, telefon=i.telefon, villkor=i.villkor, privat=i.privat, approved='')
    467             if i.villkor=='Ja':
    468                 #Send mail to admin
    469                 msg = "Ny bokning! " + i.namn + ' epost: ' + i.epost
    470                 sendmail(postadmin, 'Ny bokning!', msg,'')
    471                 #Send mail to user
    472                 rules_and_regulations = md_to_text('protokoll/dokument/hyreskontrakt_regler_och_villkor.md')
    473                 msg = "Hej " + i.namn + "! Tack för att du valde Bygdegården. Vi kontaktar dej som snarast om din boknings förfrågan och du får faktura per epost och en dörrkod när fakturan är betald. Tack! Här under är regler och villkor vilka du har läst och godkänner då du hyr hos oss. \n\n" + rules_and_regulations
    474                 sendmail(i.epost, 'Regler och villkor för Bygdegården', msg,'')
    475             raise web.seeother('/tack') 
    476 
    477 class tack():
    478     def GET(self):
    479         return render.tack()
    480 
    481 class fakturor():
    482     def GET(self):
    483         if session.login == 5:
    484             viewfile = ''
    485             i = web.input(radera=None,uppdatera=None,fakturera=None,add=None,faktura=None,yes=None,epost=None, kund=None, produkt=None)
    486             #
    487             # MLINVOICE COpy Faktura och Lägg till kund och vara i fakturan
    488             #
    489             #curl -b -X https://bygdis.fi/static/mlinvoice/login.php -i -b ~/cookies.txt -c ~/cookies.txt -d 'backlink=0&csrf=pcCFor0ic9KfoQ4jWQ3s&login=???&passwd=????&logon=Kirjaudu'
    490             #
    491             #get session and login to mlinvoice with csrf lol
    492             url='https://bygdis.fi/static/mlinvoice/login.php'
    493             r = ['curl','-b','X', url , '-i', '-b', basedir+'/sessions/cookies.txt', '-c',basedir+'/sessions/cookies.txt', '-d', 'backlink=0&csrf=&login='+mlinvoice_login+'&passwd='+mlinvoice_passwd+'&logon=Kirjaudu']
    494             view_csrf = subprocess.check_output(r)
    495             view = view_csrf.decode()
    496             soup = BeautifulSoup(view, "html.parser")
    497             csrf = soup.find(id="csrf")['value']
    498             login_mlinvoice = ['curl','-b','X', url , '-i', '-b', basedir+'/sessions/cookies.txt', '-c',basedir+'/sessions/cookies.txt', '-d', 'backlink=0&csrf='+csrf+'&login='+mlinvoice_login+'&passwd='+mlinvoice_passwd+'&logon=Kirjaudu']
    499             subprocess.check_output(login_mlinvoice)
    500             #yes
    501             #
    502             if i.add == 'faktura' and i.epost != None and i.kund != None and i.produkt != None:
    503                 url='https://bygdis.fi/static/mlinvoice/copy_invoice.php'
    504                 copy_mlinvoice = ['curl','-b','X', url , '-i', '-b', basedir+'/sessions/cookies.txt', '-c',basedir+'/sessions/cookies.txt', '-d', 'id=40']
    505                 viewfile = subprocess.check_output(copy_mlinvoice)
    506                 print(viewfile)
    507                 #
    508                 # GET LATEST INVOICE NR and ref
    509                 #
    510                 senaste = db2.query("SELECT * FROM mlinvoice_invoice ORDER BY id DESC LIMIT 1;")[0]
    511                 print(senaste)
    512                 url='https://bygdis.fi/static/mlinvoice/json.php'
    513                 get_nr_mlinvoice = ['curl','-b','X', url , '-b', basedir+'/sessions/cookies.txt', '-c',basedir+'/sessions/cookies.txt', '-d', 'func=get_invoice_defaults']
    514                 next_invoice=subprocess.check_output(get_nr_mlinvoice)
    515                 #print(next_invoice['invoice_no']
    516                 invoice = json.loads(next_invoice.decode())
    517                 #print(invoice)
    518                 #print(invoice['invoice_no'])
    519                 #
    520                 #KOLLA OM KUNDUPPGIFTER FINNS (lägg till annors)
    521                 try:
    522                     payer = db2.select('mlinvoice_company', where='email="'+str(i.epost)+'"')[0]
    523                 except:
    524                     db2.insert('mlinvoice_company', email=i.epost, company_name=i.kund)
    525                     payer = db2.select('mlinvoice_company', where='email="'+str(i.epost)+'"')[0]
    526                     #payer = db2.query("SELECT * FROM mlinvoice_company ORDER BY id DESC LIMIT 1;")[0]
    527                 #LÄGG TILL VAROR
    528                 #
    529                 produkt=getprodukt(i.produkt)
    530                 pris=produkt.unit_price
    531                 db2.insert('mlinvoice_invoice_row', invoice_id=senaste.id, product_id=produkt.id, pcs=1.00, price=float(pris))
    532                 #
    533                 db2.update('mlinvoice_invoice',where='id="'+str(senaste.id)+'"', invoice_no=invoice['invoice_no'], ref_number=invoice['ref_no'], company_id=payer.id, state_id=2)
    534                 #
    535                 #### Skicka epost
    536                 #
    537                 url='https://bygdis.fi/static/mlinvoice/invoice.php'
    538                 open_mlinvoice = ['curl','-b','X', url , '-i', '-b', basedir+'/sessions/cookies.txt', '-c',basedir+'/sessions/cookies.txt', '-d', 'id='+str(senaste.id)+'&template=15']
    539                 pdf_file = subprocess.check_output(open_mlinvoice)
    540                 pdfhash = hashlib.md5(str(random.getrandbits(256)).encode('utf-8')).hexdigest()
    541                 bilaga=basedir+'/public_html/static/pdf/'+pdfhash+'.pdf'
    542                 with open(bilaga,'wb') as binary_file:
    543                     binary_file.write(pdf_file)
    544                 #
    545                 #Laga epost faktura me virtuellstreckod
    546                 #
    547                 base_company=db2.select('mlinvoice_base', where='id="'+str(2)+'"' )[0]
    548                 faktura = db2.query("SELECT * FROM mlinvoice_invoice WHERE id='"+str(senaste.id)+"' ;")[0]
    549                 msg='Hej '
    550                 if faktura.deleted == 0:
    551                     if faktura.company_id:
    552                         msg+=getkund(faktura.company_id)+', här är fakturan\n\n'
    553                     msg+='nr:'+str(faktura.invoice_no)+'\n'
    554                     msg+='ref:'+str(faktura.ref_number)+'\n'
    555                     msg+='datum:'+str(faktura.invoice_date)+'\n'
    556                     msg+='sista betalningsdag:'+str(faktura.due_date)+'\n'
    557                     tot = 0
    558                     for p in getmaksuja(faktura.id):
    559                         if p.deleted != 1:
    560                             tot = tot + p.price
    561                             if p.product_id:
    562                                 msg+=getprodukt(p.product_id).product_name+' '
    563                             else:
    564                                 msg+=p.description+' '
    565                             msg+=str(round(p.price,2))+' € \n'
    566                     msg+='totalt: '+str(round(tot,2))+' € \n'
    567                 due_date=datetime.datetime.strptime(str(faktura.due_date), '%Y%m%d')
    568                 vs = virtuaaliviivakoodi(base_company.bank_iban,faktura.ref_number,due_date=due_date,euro_amount=float(tot))
    569                 msg += ' \nVirtuell streckkod: '+vs
    570                 sendmail(i.epost, 'Faktura', msg, bilaga)
    571             if i.fakturera != None:
    572                 db.update('bokningar', where='id="'+i.fakturera+'"', faktura=datetime.datetime.now())
    573                 raise web.seeother('/admin?fakturera='+i.fakturera)
    574             if i.faktura != None:
    575                 url='https://bygdis.fi/static/mlinvoice/invoice.php'
    576                 open_mlinvoice = ['curl','-b','X', url , '-i', '-b', basedir+'/sessions/cookies.txt', '-c',basedir+'/sessions/cookies.txt', '-d', 'id='+i.faktura+'&template=15']
    577                 pdf_file = subprocess.check_output(open_mlinvoice)
    578                 pdfhash = hashlib.md5(str(random.getrandbits(256)).encode('utf-8')).hexdigest()
    579                 bilaga=basedir+'/public_html/static/pdf/'+pdfhash+'.pdf'
    580                 with open(bilaga,'wb') as binary_file:
    581                     binary_file.write(pdf_file)
    582                 raise web.seeother('/static/pdf/'+pdfhash+'.pdf')
    583             alla_fakturor = db2.query("SELECT * FROM mlinvoice_invoice ORDER BY id DESC;")
    584             return render.fakturor(alla_fakturor,getkund,getmaksuja,round,getprodukt)
    585         else:
    586             web.seeother('/')
    587 
    588 class event():
    589     def GET(self):
    590         if session.login == 5:
    591             upcomingevents = getkalender()
    592             return render2.event(upcomingevents)
    593         else:
    594             raise web.seeother('/login')
    595 
    596 class addevent():
    597     form = web.form.Form(
    598     web.form.Textbox('year', web.form.notnull, web.form.regexp(r'\d+', 'yyyy'), description="år:"),
    599     web.form.Textbox('day', web.form.notnull, web.form.regexp(r'\d+', 'dd'), description="dag:", autofocus="autofocus"),
    600     web.form.Textbox('month', web.form.notnull, web.form.regexp(r'\d+', 'MMM'), description="månad:"),
    601     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:"),
    602     web.form.Dropdown('upprepa', [u'Nej', u'Varje vecka', u'Varannan vecka', u'Varje månad'], web.form.notnull, description="återkommande"),
    603     web.form.Textbox('antal', web.form.regexp(r'\d+', 'nummer tack'), description="hur många gånger:"),
    604     web.form.Textarea('event', description="beskrivning:"),
    605     web.form.Textarea('info', description="mer info:"),
    606     web.form.Textarea('admin', description="synligt för admin:"),
    607     web.form.Button('skicka'))
    608     def GET(self):
    609         i = web.input(id=None, cp=None)
    610         if session.login == 5:
    611             kalender = self.form()
    612             if i.id==None:
    613                 now = datetime.datetime.now()
    614                 kalender.fill(year=now.year, month=now.month, day=now.day, tid=str(now.hour).zfill(2) + ':00', antal='1')
    615             else:
    616                 event = db.select('kalender', where='id="'+i.id+'"')[0]
    617                 now=datetime.datetime.strptime(event.datumtid, '%Y-%m-%d %H:%M:%S')
    618                 kalender.fill(year=now.year, month=now.month, day=now.day, tid=str(now.hour).zfill(2) + ':00', antal='1', event=event.event, admin=event.admin, info=event.info)
    619             return render.addevent(kalender)
    620         else:
    621             raise web.seeother('/login')
    622     def POST(self):
    623         if session.login == 5:
    624             kalender = self.form()
    625             if not kalender.validates():
    626                 return render.addevent(kalender)
    627             else:
    628                 i = web.input(id=None, copyevent=None)
    629                 try:
    630                     tidh = int(i.tid[:2])
    631                     tidm = int(i.tid[-2:])
    632                     year = int(i.year)
    633                     month = int(i.month)
    634                     day = int(i.day)
    635                     antal = int(i.antal)
    636                     datum = datetime.datetime(year, month, day, tidh, tidm)
    637                 except ValueError:
    638                     return render.nope()
    639                 manydatum = []
    640                 dayz = 0
    641                 c = 0
    642                 if 'Varje v' in i.upprepa:
    643                     dayz = 7
    644                 if 'Varannan' in i.upprepa:
    645                     dayz = 14
    646                 if 'Varje m' in i.upprepa:
    647                     dayz = 28
    648                 if 'Nej' in i.upprepa:
    649                     antal = 1
    650                 for a in range(0, antal):
    651                     manydatum.append(datum + datetime.timedelta(days=c))
    652                     c = c + dayz
    653                 for d in manydatum:
    654                     if copyevent != None:
    655                         copyevent(i.id, d, i.event, i.admin, i.info)
    656                     else:
    657                         nyevent(i.id, d, i.event, i.admin, i.info)
    658                 return web.seeother('/event')
    659         else:
    660             raise web.seeother('/login')
    661 
    662 class removeevent():
    663     def GET(self, id):
    664         if session.login == 5:
    665             e = db.select('kalender', where='id="'+str(id)+'"')[0]
    666             db.insert('kalroskis', datumtid=e.datumtid, event=e.event, admin=e.admin, info=e.info)
    667             db.delete('kalender', where="id=" + id)
    668             raise web.seeother('/event')
    669         else:
    670             raise web.seeother('/login')
    671 
    672 class undo():
    673     def GET(self):
    674         if session.login == 5:
    675             e = db.query("SELECT * FROM kalroskis ORDER BY id DESC LIMIT 1;")[0]
    676             db.insert('kalender', datumtid=e.datumtid, event=e.event, admin=e.admin, info=e.info)
    677             e = db.query("DELETE FROM kalroskis ORDER BY id DESC LIMIT 1;")
    678             raise web.seeother('/event')
    679         else:
    680             raise web.seeother('/login')
    681 
    682 class editevent():
    683     def POST(self):
    684         s = web.input().signal
    685         print(s)
    686         if session.login == 5:
    687             return
    688         else:
    689             return
    690 
    691 class removepost():
    692     def POST(self, id):
    693         if session.login == 5:
    694             db.delete('posts', where="id=" + id)
    695             raise web.seeother('/admin')
    696         else:
    697             raise web.seeother('/login')
    698 
    699 class login():
    700     form = web.form.Form(
    701     web.form.Textbox('user', web.form.notnull, description="namn eller e-post:"),
    702     web.form.Password('password', web.form.notnull, description="lösenord:"),
    703     web.form.Button('Logga in'))
    704     def GET(self):
    705         fejl = ''
    706         resetpasslink = False
    707         i = web.input(error=None)
    708         if i.error == 'fejl':
    709             fejl = 'fejl lösenord! / Väärä salasana'
    710             resetpasslink = True
    711         if i.error == 'tom':
    712             fejl = 'hmm.. he funkka inga! / Ei toimi'
    713         if session.login < 3:
    714             loginform = self.form()
    715             return render.login(loginform, fejl, resetpasslink)
    716         if session.login == 3:
    717             return web.seeother('/')
    718         if session.login == 5:
    719             raise web.seeother('/admin')
    720     def POST(self):
    721         referer = web.ctx.env.get('HTTP_REFERER','https://bygdis.fi')
    722         ip = web.ctx['ip']
    723         stopflood(ip, referer)
    724         loginform = self.form()
    725         i = web.input()
    726         if i.user == '' or i.password == '':
    727             raise web.seeother('/login?error=tom')
    728         bildadmin = []
    729         bildadmins = bildhistoriker()
    730         for p in bildadmins:
    731             if p.name.lower() == i.user.lower() or p.mail.lower() == i.user.lower():
    732                 try:
    733                     encodepass = p.password.encode("utf-8")
    734                 except:
    735                     encodepass = p.password
    736                 if bcrypt.checkpw(i.password.encode('utf-8'), encodepass):
    737                     session.user = p.name
    738                     adminlevel(p.name)
    739                     print('BACKURL: '+session.backurl)
    740                     if session.login == 5:
    741                         raise web.seeother('/admin')
    742                     if session.backurl != '':
    743                         backurl = session.backurl
    744                         session.backurl = ''
    745                         raise web.seeother(backurl)
    746                     else:
    747                         if i.user == "byyssare":
    748                             raise web.seeother('/register')
    749                         raise web.seeother('/')
    750         else:
    751             return web.seeother('/login?error=fejl')
    752 
    753 class forgotpass():
    754     form = web.form.Form(
    755     web.form.Textbox('mail', web.form.notnull, description="e-post:"),
    756     web.form.Button('Skicka nytt lösenord / Lähetä uusi salasana'))
    757     def GET(self):
    758         fejl = ''
    759         i = web.input(error=None)
    760         if i.error == 'fejl':
    761             fejl = 'hittar inga e-post / ei löydy email'
    762         elif i.error == 'done':
    763             fejl = 'ditt lösenord e uppdaterat å skickat till din e-post / salasanasi on vaihdettu ja lähetetty mailiisi'
    764         elif i.error == 'nej':
    765             fejl = 'nej hörru dedär gaar inga / ei käy'
    766         elif i.error == 'stopresetpass':
    767             fejl = 'Nytt lösenord ha skickats åt dej! int ha du väl nu igen tappat bort ditt lösen? hmm.. om de e problematiskt ta kontakt med '+postadmin+' / sama på finska'
    768         if session.login < 3:
    769             loginform = self.form()
    770             return render.forgotpass(loginform, fejl)
    771         if session.login == 3:
    772             return web.seeother('/bilder')
    773         if session.login == 5:
    774             raise web.seeother('/admin')
    775     def POST(self):
    776         referer = web.ctx.env.get('HTTP_REFERER','https://bygdis.fi')
    777         ip = web.ctx['ip']
    778         stopflood(ip, referer)
    779         sendpassform = self.form()
    780         if not sendpassform.validates():
    781             return render.login(sendpassform, '')
    782         else:
    783             i = web.input()
    784             bildadmin = []
    785             bildadmins = bildhistoriker()
    786             if i.mail.lower() == 'byyssare':
    787                 raise web.seeother('/forgotpass?error=nej')
    788             for p in bildadmins:
    789                 if p.mail.lower() == i.mail.lower():
    790                     passfilter = stopresetpass(i.mail.lower())
    791                     if passfilter == True:
    792                         raise web.seeother('/forgotpass?error=stopresetpass')
    793                     unencrypted_password = ('%06x' % random.randrange(16**6))
    794                     password = unencrypted_password.encode("utf-8")
    795                     salt = bcrypt.gensalt()
    796                     password_hashed = bcrypt.hashpw(password, salt)
    797                     db.update('bildadmin', where='name="'+p.name+'"', password=password_hashed)
    798                     print("lösenordet uppdaterat!")
    799                     msg = "Ditt nya lösenord till bygdis.fi e: " + unencrypted_password + ' , om du vill ändra lösenordet ti någå ana som du minns så tryck på namne ditt högst op på ruutån efter du loggat in.'
    800                     sendmail(p.mail, 'Nytt lösenord till byyns fotoalbum', msg,'')
    801                     raise web.seeother('/forgotpass?error=done')
    802             raise web.seeother('/forgotpass?error=fejl')
    803 
    804 class register():
    805     form = web.form.Form(
    806     web.form.Textbox('user', description="användarnamn:"),
    807     web.form.Password('password', description="lösenord:"),
    808     web.form.Textbox('mail', description="e-post:"),
    809     web.form.Button('Skapa konto'))
    810     def GET(self):
    811         registerform = self.form()
    812         w = web.input()
    813         formfail = ''
    814         n = ''
    815         m = ''
    816         try:
    817             if w.fail == 'namn':
    818                 formfail = 'du måst hiitt opa eitt namn åt te!'
    819             if w.namn:
    820                 n = w.namn
    821             if w.epost:
    822                 m = w.epost
    823             elif w.epost == '':
    824                 formfail = 'tu måst lägg din epost address tär i ruuton, he e nu bara så...'
    825             if w.fail == 'notmail':
    826                 formfail = 'jusså, tetär e no inga nån mejl adress.'
    827             elif w.fail == 'nametaken':
    828                 formfail = 'Nån anan ha tagi de namme, hitt opa någå ana!'
    829             elif w.fail == 'mailtaken':
    830                 formfail = 'tu ha redan laga ett användarnamn me tetta epost konto!'
    831             elif w.fail == 'kortlosen':
    832                 print('kakkaka')
    833                 formfail = 'he va no för uuslit lösenord, minst 5 bokstäver'
    834         except:
    835             pass
    836         #check user db, if empty create admin
    837         users = db.query("SELECT COUNT(*) AS users FROM bildadmin")[0]
    838         totusers = int(users.users)
    839         registerform.fill(user=urllib.parse.unquote_plus(n), mail=urllib.parse.unquote_plus(m))
    840         if session.login > 1:
    841             return render.register(registerform, formfail, totusers)
    842         else:
    843             raise web.seeother('/')
    844     def POST(self):
    845         if session.login > 1:
    846             registerform = self.form()
    847             i = web.input()
    848             r = '&namn=' + i.user + '&epost=' + i.mail
    849             urllib.parse.quote_plus(r)
    850             if i.user == '':
    851                 raise web.seeother('/register?fail=namn'+r)
    852             if '@' not in i.mail:
    853                 raise web.seeother('/register?fail=notmail'+r)
    854             if len(i.password) < 5:
    855                 raise web.seeother('/register?fail=kortlosen'+r)
    856             bildadmins = db.select('bildadmin', what='name, mail')
    857             for p in bildadmins:
    858                 if p.name.lower() == i.user.lower():
    859                     raise web.seeother('/register?fail=nametaken' +r)
    860                 if p.mail.lower() == i.mail.lower():
    861                     raise web.seeother('/register?fail=mailtaken' +r)
    862             adduser(i.user, i.password, i.mail.lower())
    863             #Send mail to Madbaker
    864             msg = "Wowowowoweeewaaa! Ny användare på bygdis.fi! " + i.user + ' ' + i.mail
    865             sendmail(postadmin, 'Wowowoweewaaa!', msg,'')
    866             #Send mail to new user
    867             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"
    868             sendmail(i.mail, 'Byyns eji fotoalbum', msg,'')
    869             session.login = 3
    870             session.user = i.user
    871             return web.seeother('/ny')
    872 
    873 class nydorrkod():
    874     form = web.form.Form(
    875     web.form.Textbox('namn', description="användarnamn:"),
    876     web.form.Textbox('mail', description="e-post:"),
    877     web.form.Textbox('dorrkod', description="Dörrkod:"),
    878     web.form.Button('Skapa ny Dörrkod'))
    879     def GET(self):
    880         registerform = self.form()
    881         w = web.input()
    882         formfail = ''
    883         n = ''
    884         m = ''
    885         try:
    886             if w.fail == 'namn':
    887                 formfail = 'du måst hiitt opa eitt namn åt te!'
    888             if w.fail == 'notmail':
    889                 formfail = 'jusså, tetär e no inga nån mejl adress.'
    890             if w.fail == 'kod':
    891                 formfail = 'koden måst vara 4 siffror!'
    892         except:
    893             pass
    894         if session.login == 5:
    895             return render.nydorrkod(registerform, formfail)
    896         else:
    897             raise web.seeother('/')
    898     def POST(self):
    899         if session.login == 5:
    900             registerform = self.form()
    901             i = web.input(namn=None, mail=None, dorrkod=None, bokning=None)
    902             if i.namn == '':
    903                 raise web.seeother('/nydorrkod?fail=namn')
    904             if '@' not in i.mail:
    905                 raise web.seeother('/nydorrkod?fail=notmail')
    906             if i.dorrkod == None or i.dorrkod == '':
    907                 dorrkod = random.randint(1111,9999)
    908             elif isinstance(int(i.dorrkod), int) and len(i.dorrkod) == 4:
    909                 dorrkod = str(i.dorrkod)
    910             else:
    911                 raise web.seeother('/nydorrkod?fail=kod')
    912             addDorrkod(dorrkod, i.namn, i.mail.lower())
    913             #Send mail to Madbaker
    914             msg = "Wowowowoweeewaaa! Ny dörrkod! " + i.namn + ' ' + i.mail + ' ' + str(dorrkod)
    915             sendmail(postadmin, 'Wowowoweewaaa!', msg,'')
    916             #Send mail to new user
    917             msg = "Gratulis " + i.namn + ", du har en dörrkod till Bygdegården: \n\n" + str(dorrkod)
    918             sendmail(i.mail, 'Dörrkod till Bygdegården', msg,'')
    919             if i.bokning != None:
    920                 db.update('bokningar', where='id="'+i.bokning+'"', doorcode=datetime.datetime.now())
    921             return web.seeother('/dorrkoder')
    922 
    923 class dorrkoder():
    924     def GET(self):
    925         if session.login == 5:
    926             dorrkoder = getDorrkoder()
    927             log = getDorrlog(0)
    928             i = web.input(radera=None,uppdatera=None,fakturera=None,emptytrash=None)
    929             if i.radera != None:
    930                 db.delete('dorrkoder', where='id="'+i.radera+'"')
    931                 raise web.seeother('/dorrkoder')
    932             print(dorrkoder)
    933             return render.dorrkoder(dorrkoder,log,getDorrkoduser)
    934         else:
    935             web.seeother('/')
    936 
    937 class dorrkoderapi():
    938     def GET(self): 
    939         global basedir
    940         f = open(basedir+"/apikey", "r")
    941         apikey = f.readline().strip()
    942         i = web.input(apikey=None,logger=None,doorstate=None,debug=None)
    943         if i.apikey == apikey:
    944             if i.logger != None:
    945                 if len(i.logger) == 4:
    946                     if getDorrkoduser(i.logger) != '':
    947                         print('logging dorrkod!')
    948                         dorrLogger(i.logger)
    949                         print(i.logger)
    950                         print(i.doorstate)
    951                         print(i.debug)
    952             if i.doorstate != None:
    953                 print('yes, bygdis is online')
    954                 id=1
    955                 db.update('doordebug', where='id="'+str(id)+'"', doorstate=i.doorstate, debug=i.debug, datum=datetime.datetime.now())
    956             else:
    957                 dorrkoder = getDorrkoder()
    958                 #encoding = response.info().get_content_charset('utf8')
    959                 #apireq = data['icestats']['source'][1][i.req]
    960                 p = []
    961                 for i in dorrkoder:
    962                     p.append(i.dorrkod)
    963                     #print(i)
    964                 return json.dumps(p) 
    965 
    966 class ny():
    967     def GET(self):
    968         if session.login > 2:
    969             backurl = ''
    970             if session.backurl != '':
    971                 backurl = session.backurl
    972                 session.backurl = ''
    973             return render.ny(session.user, backurl)
    974 
    975 class tuning():
    976     form = web.form.Form(
    977     web.form.Textbox('user', description="synligt namn:"),
    978     web.form.Password('password', description="lösenord:"),
    979     web.form.Password('newpassword', description="nytt lösen (ifall du vill byta):"),
    980     web.form.Password('newpassword2', description="nytt lösen igen:"),
    981     web.form.Textbox('mail', description="epost:"), 
    982     web.form.Radio('subscribe', ['dagligen', 'aldrig'], description="Få epost brejv ifall de hänt någå"),
    983     web.form.Button('Spara'))
    984     def GET(self):
    985         if session.login > 2:
    986             print('asdfasdfasdf')
    987             user = db.select('bildadmin', where='name="'+session.user+'"')[0]
    988             tuningform = self.form()
    989             w = web.input(namn=None,epost=None,fail=None,upd=None)
    990             print('asdfasdfasdfkdakkakka')
    991             formfail = ''
    992             if w.fail == 'wrongpass':
    993                 formfail = formfail + 'fel lösenord'
    994             if w.fail == 'nopass':
    995                 formfail = formfail + 'Du måst skriv in ditt lösenord!'
    996             if w.namn == '':
    997                 formfail = formfail + 'du måst hiitt opa eitt namn åt te!'
    998             if w.epost == '':
    999                 formfail = formfail + 'tu måst lägg din epost address tär i ruuton, he e nu bara så...'
   1000             elif w.fail == 'notmail':
   1001                 formfail = formfail + 'jusså, tetär e no inga nån mejl adress.'
   1002             if w.fail == 'nametaken':
   1003                 formfail = formfail + 'Nån anan ha tagi de namme, hitt opa någå ana!'
   1004             if w.fail == 'mailtaken':
   1005                 formfail = formfail + 'He finns eitt konto me te epost adressn!'
   1006             if w.fail == 'kortlosen':
   1007                 formfail = formfail + 'he va no för uuslit lösenord, minst 5 bokstäver'
   1008             if w.fail == 'newpass':
   1009                 formfail = formfail + 'nya lösenordet stämmer inte överens med varann, pröva pånytt!'
   1010             if w.upd == 'yes':
   1011                 formfail = 'Yes, ditt konto e tuunat!'
   1012             tuningform.fill(user=user.displayname, mail=user.mail, subscribe=user.subscribe)
   1013             return render.tuning(tuningform, formfail, user.name)
   1014         else:
   1015             return web.seeother('/register')
   1016     def POST(self):
   1017         if session.login > 1:
   1018             tuningform = self.form()
   1019             i = web.input()
   1020             if i.password == '':
   1021                 raise web.seeother('/tuning?fail=nopass')
   1022             bildadmins = bildhistoriker()
   1023             for p in bildadmins:
   1024                 print(p)
   1025                 if p.name == session.user:
   1026                     if bcrypt.checkpw(i.password.encode('utf-8'), p.password):
   1027                         #check if display name taken
   1028                         b_displayname = bildhistoriker()
   1029                         for a in b_displayname:
   1030                             if i.user in a.displayname and a.name != session.user:
   1031                                 raise web.seeother('/tuning?fail=nametaken')
   1032                             if i.mail in a.mail and i.mail != p.mail:
   1033                                 raise web.seeother('/tuning?fail=mailtaken')
   1034                         if i.newpassword != '':
   1035                             if i.newpassword != i.newpassword2:
   1036                                 raise web.seeother('/tuning?fail=newpass')
   1037                             if len(i.newpassword) < 5:
   1038                                 raise web.seeother('/tuning?fail=kortlosen')
   1039                             else:
   1040                                 #update with password change
   1041                                 password = i.newpassword.encode("utf-8")
   1042                                 salt = bcrypt.gensalt()
   1043                                 password_hashed = bcrypt.hashpw(password, salt)
   1044                                 db.update('bildadmin', where='name="'+session.user+'"', displayname=i.user, password=password_hashed, mail=i.mail.lower(), subscribe=i.subscribe)
   1045                                 return web.seeother('/tuning?upd=yes')
   1046                         if '@' not in i.mail:
   1047                             raise web.seeother('/tuning?fail=notmail')
   1048                         #update without passwordchange
   1049                         db.update('bildadmin', where='name="'+session.user+'"', displayname=i.user, mail=i.mail.lower(), subscribe=i.subscribe)
   1050                         return web.seeother('/tuning?upd=yes')
   1051                     else:
   1052                         raise web.seeother('/tuning?fail=wrongpass')
   1053 
   1054 class bilder():
   1055     def GET(self):
   1056         bildpersida = 100
   1057         i = web.input()
   1058         try:
   1059             bilder_totalt = db.query("SELECT COUNT(*) AS bilder FROM bilder")[0]
   1060             tot = int(bilder_totalt.bilder)
   1061             print('bilder alltsomallt: ' + str(tot))
   1062         except:
   1063             print("inga bilder")
   1064             tot = 0
   1065         print('session search: ' + session.search)
   1066         try:
   1067             if i.search == '':
   1068                 session.search = ''
   1069                 session.bildsida = 0
   1070             elif i.search != "":
   1071                 session.search = urllib.parse.unquote_plus(i.search)
   1072                 session.bildsida = 0
   1073         except:
   1074             pass
   1075         if session.search != '':
   1076             search_result = []
   1077             tot = 0
   1078             b1, b2, b3, b4, b5, = 0,0,0,0,0
   1079             try:
   1080                 search_result.append(db.query("SELECT * FROM bilder WHERE personer LIKE '%"+session.search+"%';"))
   1081                 tot = db.query("SELECT Count(*) AS bilder FROM bilder WHERE personer LIKE '%"+session.search+"%';")[0]
   1082                 b1 = tot.bilder
   1083             except:
   1084                 pass
   1085             try:
   1086                 search_result.append(db.query("SELECT * FROM bilder WHERE fotograf LIKE '%"+session.search+"%';"))
   1087                 tot = db.query("SELECT Count(*) AS bilder FROM bilder WHERE fotograf LIKE '%"+session.search+"%';")[0]
   1088                 b2 = tot.bilder
   1089             except:
   1090                 pass
   1091             try:
   1092                 search_result.append(db.query("SELECT * FROM bilder WHERE plats LIKE '%"+session.search+"%';"))
   1093                 tot = db.query("SELECT Count(*) AS bilder FROM bilder WHERE plats LIKE '%"+session.search+"%';")[0]
   1094                 b3 = tot.bilder
   1095             except:
   1096                 pass
   1097             try:
   1098                 search_result.append(db.query("SELECT * FROM bilder WHERE titel LIKE '%"+session.search+"%';"))
   1099                 tot = db.query("SELECT Count(*) AS bilder FROM bilder WHERE titel LIKE '%"+session.search+"%';")[0]
   1100                 b4 = tot.bilder
   1101             except:
   1102                 pass
   1103             try:
   1104                 search_result.append(db.query("SELECT * FROM bilder WHERE year LIKE '%"+session.search+"%';"))
   1105                 tot = db.query("SELECT Count(*) AS bilder FROM bilder WHERE year LIKE '%"+session.search+"%';")[0]
   1106                 b5 = tot.bilder
   1107             except:
   1108                 pass
   1109             tot = b1 + b2 + b3 + b4 + b5
   1110             try:
   1111                 print(search_result)
   1112                 print('sökta bilder: ' + str(tot))
   1113             except:
   1114                 pass
   1115         try:
   1116             if i.page == "next":
   1117                 if session.bildsida < tot:
   1118                     session.bildsida += bildpersida
   1119             if i.page == "back":
   1120                 if session.bildsida > bildpersida:
   1121                     session.bildsida -= bildpersida
   1122                 else:
   1123                     session.bildsida = 0
   1124         except:
   1125             pass
   1126         if session.login > 1:
   1127             limit = session.bildsida + bildpersida
   1128             offset = session.bildsida
   1129             print(session.bildsida)
   1130             if session.search == '':
   1131                 bilder = db.query("SELECT * FROM bilder ORDER BY uploaddate DESC LIMIT " + str(limit) + " OFFSET " + str(offset))
   1132             else:
   1133                 bilder = search_result
   1134             if session.login > 3:
   1135                 try:
   1136                     if i.delete != '':
   1137                         return web.seeother('/remove/' + i.delete)
   1138                 except:
   1139                     pass
   1140                 rights = 'admin'
   1141             elif session.login > 2:
   1142                 rights = 'mod'
   1143             elif session.login > 1:
   1144                 rights = 'byyssare'
   1145 
   1146             return render.bilder(bilder, rights, session.user, tot, limit, bildpersida, session.search, db, str, print)
   1147         else:
   1148             return web.seeother('/login')
   1149 
   1150 class remove():
   1151     def GET(self, imghash):
   1152         if session.login > 1:
   1153             referer = web.ctx.env.get('HTTP_REFERER', 'none')
   1154             i = web.input(sure=None)
   1155             if i.sure == 'yes':
   1156                 db.delete('bilder', where='filename="' + imghash + '"')
   1157                 db.delete('allaversioner', where='filename="' + imghash + '"')
   1158                 db.delete('likes', where='bild="' + imghash + '"')
   1159                 db.delete('hates', where='bild="' + imghash + '"')
   1160                 db.delete('bildkommentar', where='filename="' + imghash + '"')
   1161                 return web.seeother('/bilder')
   1162             return render.remove(imghash, referer)
   1163 
   1164 class upload():
   1165     def GET(self):
   1166         if session.login == 2:
   1167             session.backurl = '/upload'
   1168             return web.seeother('register')
   1169         elif session.login > 2:
   1170             return render.upload()
   1171         else:
   1172             return web.seeother('/login')
   1173     def POST(self):
   1174         if session.login > 2:
   1175             i = web.input(imgfile={},edit=None)
   1176             for p in i:
   1177                 print(p)
   1178             if i.edit != None:
   1179                 imgname=i.edit
   1180                 if '.jpg' in i.edit:
   1181                     imghash=i.edit.replace('.jpg','')
   1182                 elif '.jpeg' in i.edit:
   1183                     imghash=i.edit.replace('.jpeg','')
   1184             else:
   1185                 imghash = hashlib.md5(str(random.getrandbits(256)).encode('utf-8')).hexdigest()
   1186                 imgname = imghash + '.jpeg'
   1187             if i.imgfile != {}:
   1188                 print(i.imgfile.filename)
   1189                 if i.imgfile.filename == '':
   1190                     print('hmmm... no image to upload')
   1191                     raise web.seeother('/upload?fail=noimg')
   1192                 print('YEAH, Upload image!')
   1193 
   1194                 ##---------- UPLOAD IMAGE ----------
   1195 
   1196                 imgdir = basedir + '/public_html/static/bilder/'
   1197                 imgpath=i.imgfile.filename.replace('\\','/') # replaces the windows-style slashes with linux ones.
   1198                 #filename=filepath.split('/')[-1] # splits the and chooses the last part (the filename with extension)
   1199 
   1200                 #imgname = str(len(os.listdir(imgdir))).zfill(3) + '.jpeg'
   1201                 fout = open(imgdir +'/'+ imgname,'wb') # creates the file where the uploaded file should be stored
   1202                 fout.write(i.imgfile.file.read()) # writes the uploaded file to the newly created file.
   1203                 fout.close() # closes the file, upload complete.
   1204                 os.chmod(imgdir+'/'+imgname, 0o755)
   1205 
   1206                 ##---------- OPEN FILE & CHEKC IF JPEG --------
   1207                 image = Image.open(imgdir +'/'+ imgname)
   1208                 if image.format != 'JPEG':
   1209                     os.remove(imgdir +'/'+ imgname)
   1210                     raise web.seeother('/upload?fail=notjpeg')
   1211 
   1212                 ##---------- RESIZE IMAGE -----------
   1213                 image.thumbnail((900,900), Image.ANTIALIAS)
   1214                 image.save(imgdir + '/web/' + imgname)
   1215                 image.thumbnail((300,300), Image.ANTIALIAS)
   1216                 image.save(imgdir + '/thumb/' + imgname)
   1217                 if i.edit == None:
   1218                     db.insert('bilder', filename=imghash, uploaddate=datetime.datetime.now(), uppladdare=session.user, lastmod=datetime.datetime.now(), moddedby=session.user)
   1219                 raise web.seeother('/bildinfo/' + imghash)
   1220             else:
   1221                 return render.upload()
   1222         else:
   1223             session.backurl = '/upload'
   1224             return render.register()
   1225 
   1226 class bildinfo():
   1227     form = web.form.Form(
   1228     web.form.Textbox('titel', web.form.notnull, description="Bild titel:"),
   1229     web.form.Textbox('year', web.form.notnull, description="År:"),
   1230     web.form.Textbox('fotograf', web.form.notnull, description="Fotograf:"),
   1231     web.form.Textbox('plats', web.form.notnull, description="Plats:"),
   1232     web.form.Textarea('beskrivning', web.form.notnull, description="Beskrivning:"),
   1233     web.form.Textarea('personer', web.form.notnull, description="Personer fr.v. (lägg ett komma mellan varje typ):"),
   1234     web.form.Button('Spara'))
   1235     def GET(self, imghash):
   1236         if session.login > 2:
   1237             infoform = self.form()
   1238             v = web.input()
   1239             if v:
   1240                 oldinfo = db.select('allaversioner', where="id='" + v.id +"'", what='titel, year, fotograf, beskrivning, personer, moddedby, lastmod, plats')
   1241             else:
   1242                 oldinfo = db.select('bilder', where="filename='" + imghash +"'", what='titel, year, fotograf, beskrivning, personer, moddedby, lastmod, plats')
   1243             print('fuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu')
   1244             oldinfo = oldinfo[0]
   1245             allaversioner = db.select('allaversioner', where="filename='" + imghash +"'", what='id, moddedby, lastmod', order='id DESC')
   1246             infoform.fill(titel=oldinfo.titel, year=oldinfo.year, fotograf=oldinfo.fotograf, plats=oldinfo.plats, beskrivning=oldinfo.beskrivning, personer=oldinfo.personer)
   1247 
   1248             return render.bildinfo(infoform, imghash, oldinfo.moddedby, oldinfo.lastmod, allaversioner)
   1249         else:
   1250             session.backurl = '/bildinfo/' + imghash
   1251             return web.seeother("/register")
   1252     def POST(self, imghash):
   1253         ip = web.ctx['ip']
   1254         referer = web.ctx.env.get('HTTP_REFERER','https://bygdis.fi')
   1255         stopflood(ip, referer)
   1256         if session.login > 2:
   1257             i = web.input()
   1258             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)
   1259             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)
   1260             return web.seeother('/bildinfo/' + imghash)
   1261 
   1262 class bild():
   1263     form = web.form.Form(
   1264     web.form.Textarea('kommentar', web.form.notnull, description=""),
   1265     web.form.Button('kommentera'))
   1266     def GET(self, imghash):
   1267         i = web.input(unlike=None, like=None, hate=None, unhate=None)
   1268         kform = self.form()
   1269         if session.login > 1:
   1270             l = db.query("SELECT * FROM likes WHERE bild='"+imghash+"' AND user='"+session.user+"';")
   1271             h = db.query("SELECT * FROM hates WHERE bild='"+imghash+"' AND user='"+session.user+"';") 
   1272             if l:
   1273                 user_likes = True
   1274             else:
   1275                 user_likes = False
   1276             if h:
   1277                 user_hates = True
   1278             else:
   1279                 user_hates = False
   1280             try:
   1281                 if i.delete != '':
   1282                     allow_del = db.select('bildkommentar', where="id='"+i.delete+"'", what='user')[0]
   1283                     print(allow_del)
   1284                     if allow_del.user == session.user:
   1285                         db.delete('bildkommentar', where='id="' + i.delete + '"')
   1286             except:
   1287                 print('something wrong with input in class bild, så att du veit')
   1288             if i.like != None and user_likes == False:
   1289                 db.insert('likes', user=session.user, bild=imghash, datum=datetime.datetime.now())
   1290                 user_likes = True
   1291             elif i.unlike != None and user_likes == True:
   1292                 db.query("DELETE FROM likes WHERE bild='"+imghash+"' AND user='"+session.user+"';")
   1293                 user_likes = False
   1294             if i.hate != None and user_hates == False:
   1295                 db.insert('hates', user=session.user, bild=imghash, datum=datetime.datetime.now())
   1296                 user_hates = True
   1297             elif i.unhate != None and user_hates == True:
   1298                 db.query("DELETE FROM hates WHERE bild='"+imghash+"' AND user='"+session.user+"';")
   1299                 user_hates = False
   1300             likes = db.query("SELECT Count(*) AS likes FROM likes WHERE bild='"+imghash+"';")[0]
   1301             hates = db.query("SELECT Count(*) AS hates FROM hates WHERE bild='"+imghash+"';")[0]
   1302             b = db.select('bilder', where="filename='" + imghash +"'", what='titel, year, fotograf, plats, beskrivning, personer, moddedby, lastmod, uppladdare')[0]
   1303             text = db.select('allaversioner', where="filename='" + imghash +"'", what='moddedby')
   1304             comments = db.select('bildkommentar', where="filename='" + imghash +"'", what='id, user, comment, upvotes, datumtid', order='datumtid DESC')
   1305             try:
   1306                 personer = b.personer.replace(', ', ',').split(',')
   1307             except:
   1308                 personer = ''
   1309             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]
   1310             print(back_next)
   1311             return render.bild(b, imghash, personer, kform, comments, session.user, user_likes, likes, user_hates, hates, back_next, text, getdisplayname)
   1312         else:
   1313             session.backurl="/bild/"+imghash
   1314             raise web.seeother("/login")
   1315     def POST(self, imghash):
   1316         ip = web.ctx['ip']
   1317         referer = web.ctx.env.get('HTTP_REFERER','https://bygdis.fi')
   1318         stopflood(ip, referer)
   1319         komm = self.form()
   1320         if session.login > 1:
   1321             i = web.input()
   1322             if i.kommentar != '':
   1323                 db.insert('bildkommentar', filename=imghash, user=session.user, comment=i.kommentar, datumtid=datetime.datetime.now())
   1324             raise web.seeother("/bild/"+imghash+"#comments")
   1325 
   1326 class senaste():
   1327     def GET(self):
   1328         if session.login > 1:
   1329             comments = db.select('bildkommentar', what='id, filename, user, comment, upvotes, datumtid', order='datumtid DESC')
   1330             b = db.select('bilder', what='filename, titel, year, fotograf, plats, beskrivning, personer, moddedby, lastmod, uppladdare, uploaddate', order='lastmod DESC')
   1331             binfo = db.select('allaversioner', what='filename, titel, year, fotograf, plats, beskrivning, personer, moddedby, lastmod, uppladdare, uploaddate', order='lastmod DESC')
   1332             return render.senaste(b, comments, binfo, getdisplayname)
   1333 
   1334 class logout():
   1335     def GET(self):
   1336         session.login = 1
   1337         session.backurl = ''
   1338         session.user = ''
   1339         session.bildsida = 0
   1340         print(session.login)
   1341         raise web.seeother('/')
   1342 
   1343 class index():
   1344     def GET(self):
   1345         upcomingevents = getkalender()
   1346         if session.login > 1:
   1347             displayname = db.query("SELECT displayname FROM bildadmin WHERE name='"+session.user+"';")[0]
   1348         else:
   1349             displayname = ''
   1350         return render2.index(upcomingevents, displayname)
   1351 
   1352 class old():
   1353     def GET(self):
   1354         oldevents = getkalenderall()
   1355         return render2.old(oldevents)
   1356 
   1357 class nope():
   1358     def GET(self):
   1359         #print curdate()
   1360         return render.nope()
   1361 
   1362 class protokoll():
   1363     form = web.form.Form(
   1364     web.form.Textarea('protokoll', web.form.notnull, description=""),
   1365     web.form.Button('spara'))
   1366     def GET(self):
   1367         if session.login == 5:
   1368             protokoll_edit = self.form()
   1369             webdata = web.input(year=None, nr=0, cp=None, rm=None, pdf=None)
   1370             view = ''
   1371             years = os.listdir(basedir + '/protokoll/')
   1372             years.remove('.gitignore')
   1373             years.sort()
   1374             if webdata.year:
   1375                 protokoll = getprotokoll(webdata.year)
   1376                 if webdata.cp == "protokoll":
   1377                     print('copy protokoll')
   1378                     os.system("cp "+basedir + '/protokoll/' + webdata.year + '/' + protokoll[int(webdata.nr)] +' '+basedir+'/protokoll/'+webdata.year+'/0'+str(len(protokoll))+'.md')
   1379                     protokoll = getprotokoll(webdata.year)
   1380                 if webdata.rm == "protokoll":
   1381                     print('remove protokoll')
   1382                     os.system("rm "+basedir + '/protokoll/' + webdata.year + '/' + protokoll[int(webdata.nr)])
   1383                     raise web.seeother('/protokoll?year='+webdata.year)
   1384             else:
   1385                 protokoll = []
   1386             if len(protokoll) > 0:
   1387                 #make html from markdown
   1388                 pandoc_html = ['pandoc', basedir + '/protokoll/' + webdata.year + '/' + protokoll[int(webdata.nr)], '-f', 'markdown', '-t', 'html']
   1389                 #make pdf from markdown
   1390                 viewfile = subprocess.check_output(pandoc_html)
   1391                 view = viewfile.decode()
   1392                 if webdata.pdf == "protokoll":
   1393                     randhash = hashlib.md5(str(random.getrandbits(256)).encode('utf-8')).hexdigest()
   1394                     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/'+randhash+'.pdf']
   1395                     process=subprocess.Popen(pandoc_pdf, cwd=basedir + '/public_html/static/pdf/')
   1396                     process.wait()
   1397                     raise web.seeother('/static/pdf/'+randhash+'.pdf?nocache='+randhash)
   1398                 #read protokoll
   1399                 read_p=basedir + '/protokoll/' + webdata.year + '/' + protokoll[int(webdata.nr)]
   1400                 with open(read_p, 'r') as file:
   1401                     p_list=file.readlines()
   1402                 pr=''
   1403                 for p in p_list:
   1404                     pr=pr+p
   1405                 protokoll_edit.fill(protokoll=pr)
   1406             return render3.protokoll(webdata.year, years, protokoll, view, protokoll_edit, webdata.nr)
   1407         else:
   1408             raise web.seeother('/login')
   1409     def POST(self):
   1410         if session.login == 5:
   1411             i = web.input(year=None, nr=0, cp=None)
   1412             protokoll = []
   1413             if i.year != None:
   1414                 protokoll = getprotokoll(i.year)
   1415             write_p=basedir + '/protokoll/' + i.year + '/' + protokoll[int(i.nr)]
   1416             if i.protokoll:
   1417                 with open(write_p, 'w') as file:
   1418                     file.write(i.protokoll)
   1419             print('ADDDDDDDDDDDDDING TO database post ' + i.protokoll)
   1420             raise web.seeother('/protokoll?year='+str(i.year)+'&nr='+str(i.nr))
   1421         else:
   1422             raise web.seeother('/login')
   1423 
   1424 
   1425 class protokollredirect():
   1426     def GET(self):
   1427         raise web.seeother('/protokoll/')
   1428 
   1429 application = app.wsgifunc()