# JV website generator
# (c) 2008, Johan Tuitman
# Licentie: GPL
#
# Subroutines voor website generatie
import os
import dataStruct
import cPickle
import shutil
import sys

class mkMenus():
    """Generate menu structure"""

    def __init__(self,reGen,db,db_o):
        self.db = db         # database
        self.db_o = db_o     # previous database
        self.reGen = reGen   # regenerate website if True
        self.wd = db.getWorkDir()

        # dict with changes of menu structure
        self.menuCh= {}
        # list with all files created for menu
        self.menuFiles = []
        # list with changed files for menu
        self.menuCFiles = []
        # list of html files changed due menu changes
        self.menuCHtml = []
        # dict with all (sub) menu pages
        self.MPages = {}
        # list with all additionally pages
        self.addPages = []
        # dict with all pics to create
        self.mkPic = {}
        self.mkPic['picDir'] = os.path.abspath(self.db.getPicDir())
        self.mkPic['workDir'] =os.path.abspath(self.wd)
        self.mkPic['mk'] = []

        # check for changes in menu
        if not self.reGen:
            self.menuCh = self.menuChange()

        # make menus and lists of files
        self.createMenus()

        # create pictures for menu
        if len(self.mkPic['mk']) > 0:
            f = open('mkpic.dat','w')
            cPickle.dump(self.mkPic,f)
            f.close()
            print ' Maak menu plaatjes'
            os.system('gimp -i -b \'(python-fu-jvknop RUN-NONINTERACTIVE "%s")\' '%( os.path.abspath('mkpic.dat')))

    def createMenus(self):
        """Generate and list all files for main page and menu"""

        mainChange = False
        if self.reGen or self.menuCh['_mainPage'] != None or self.menuCh['_mainMenu'] != None:
            mainChange = True

        self.genMenuAndHoofdPages(mainChange,'_mainPage',None)

        for mn in self.db.getMenus():
            change = False
            if self.reGen or self.menuCh[mn]:
                change = True
                
            subCode = self.genSubMenuPage(change,mn)

            if mainChange:
                change = True

            self.genMenuAndHoofdPages(change,mn,subCode)

    def genSubMenuPage(self,change,menu):
        """generate sub menu code and files"""
        page =self.db.getPage(menu)
        bs = os.path.dirname(page.getUrl())
        bsd = os.path.join(self.wd,bs)

        self.MPages[page.getUrl()] = dataStruct.subMData(page,menu,None)

        for pg in page.getInclProc():
            self.addPages.append(os.path.join(bs,pg))

        if change:
            pgu = page.getUrl()
            if pgu.find('://') < 0:
                self.menuCHtml.append(pgu)

        txt = ""

        for smn in self.db.getSubMenus(menu):
            spage = self.db.getSubPage(menu,smn)
            ssmn = urlCleaner(smn)
            urlr = os.path.join(bs,spage.getUrl())
            url = os.path.join(bsd,spage.getUrl())
            self.MPages[urlr] = dataStruct.subMData(page,menu,smn)

            for pg in spage.getInclProc():
                self.addPages.append(os.path.join(bs,pg))

            if change:
                if urlr.find('://') < 0:
                    self.menuCHtml.append(urlr)

            if spage.getNewWin():
                target = '_blank'
            else:
                target = 'tekst'


            txt += '<IMG src="../plaatjes/pix.png" alt="vuller" width="6" height="1" border="0">' 
            txt += '<a href="%s" target="%s"><IMG src="sknp%s.png" alt="%s" width="162" height="16" border="0"></a><br>\n' \
                    %(spage.getUrl(),target,ssmn,spage.getFullName())

            pfn = os.path.join(bs,'sknp%s.png' %ssmn)
            self.menuFiles.append(pfn)
            if change or not os.path.exists(os.path.join(bsd,'sknp%s.png' %ssmn)):
                self.mkPic['mk'].append([pfn,str(smn),3,True])
                self.menuCFiles.append(pfn)

        return txt

    def genMenuAndHoofdPages(self,change,menu,subCode):
        """Generate hoofd and menu files and create list of files"""
        if menu == '_mainPage':
            bs = '.'
            bsd = self.wd
            hlight = 'Home'
            knpName = ''
            cdl = ''
            page = self.db.getIndexPage()
            self.checkDir('plaatjes','.')
            self.addPages.append(os.path.basename(page.getUrl()))
            self.addPages.extend(['plaatjes/onder.png','plaatjes/menu.png','plaatjes/pix.png'])
            self.addPages.extend(page.getInclProc())

        else:
            bs = self.db.getPage(menu).getDirName()
            bsd = os.path.join(self.wd,bs)
            hlight = menu
            knpName = urlCleaner(menu)
            subMenus = 1
            if len(self.db.getSubMenus(menu)) == 0:
                subMenus = 0

            cdl = '../'
            page = self.db.getPage(menu)
            self.checkDir(bs,'.')


        for files in ['menu.htm','hoofd.htm']:
            url = os.path.normpath(os.path.join(bs,files))
            self.menuFiles.append(str(url))
            if change or not os.path.exists(os.path.join(bsd,files)):
                change = True
                self.menuCFiles.append(str(url))

        knpNm = os.path.join('plaatjes','knp%s.png' %knpName)
        self.menuFiles.append(knpNm)
        if change or not os.path.exists(os.path.join(self.wd,knpNm)):
            self.mkPic['mk'].append([str(knpNm),str(hlight),0,False])
            self.menuCFiles.append(knpNm)

        knpNm = os.path.normpath(os.path.join(os.path.join(bs,'knp.png')))
        self.menuFiles.append(knpNm)
        if change or not os.path.exists(os.path.join(bsd,'knp.png')):
            if menu == '_mainPage':
                self.mkPic['mk'].append([str(knpNm),str(hlight),0,True])
            else:
                self.mkPic['mk'].append([str(knpNm),str(hlight),subMenus,True])
            self.menuCFiles.append(knpNm)


        if change:
            # hoofd.html
            f = open('temp.htm','w')
            urll = page.getUrl()
            if urll.find('://') < 0:
                urll = os.path.basename(urll)
            f.write(self.mkHoofdPage(urll))
            f.close()
            os.system('tidy -q -o %s temp.htm' %(os.path.join(bsd,'hoofd.htm')))


            txt = self.menuHeader(cdl)
            pg = self.db.getIndexPage()
            if menu == '_mainPage':
                txt += self.genMenuLine(False,pg,True,cdl,'')
            else:
                txt += self.genMenuLine(True,pg,True,cdl,'')

            for mn in self.db.getMenus():
                txt += '<IMG src="%splaatjes/pix.png" alt="vuller" width="1" height="10" border="0"><br>\n' %cdl

                pg = self.db.getPage(mn)
                if mn == menu:
                    txt += self.genMenuLine(False,pg,False,cdl,mn)
                    txt += subCode
                    if len(subCode)>0:
                        txt += '<IMG src="%splaatjes/pix.png" alt="vuller" width="6" height="1" border="0">' %cdl
                        txt += '<img src="../plaatjes/onder.png" alt="onderkant" width="162" height="4" border="0"><br>\n'
                else:
                    txt += self.genMenuLine(True,pg,False,cdl,mn)

            txt += '</body>\n</html>\n'

            f = open('temp.htm','w')
            f.write(txt)
            f.close()
            os.system('tidy -q -o %s temp.htm' %(os.path.join(bsd,'menu.htm')))

    def genMenuLine(self,other,page,mainPage,cdl,mn):
        cmn = urlCleaner(mn)
        txt = '<IMG src="%splaatjes/pix.png" alt="vuller" width="6" height="1" border="0">' %cdl
        if other and not page.getNewWin():
            if mainPage:
                txt += '<a href="%shoofd.htm">' %cdl
            else:
                txt += '<a href="%s/hoofd.htm">' %(cdl+page.getDirName())

        elif page.getNewWin():
            txt += '<a href="%s" target="_blank">' %(page.getUrl())

        else:
            txt += '<a href="%s" target="tekst">' %(os.path.basename(page.getUrl()))

        if other:
            txt += '<IMG src="%splaatjes/knp%s.png" alt="%s" width="162" height="27" border="0"></a><br>\n' %(cdl,str(cmn),page.getFullName())
        else:
            txt += '<IMG src="knp.png" alt="%s" width="162" height="27" border="0"></a><br>\n' %(page.getFullName())

        return txt

    def menuChange(self):
        """Find changes in db"""
        # main menu
        menuCh = {}
        print 50*'-'
        print 'Vergelijk databases:'

        menuCh['_mainPage'] = self.findPageChange( \
                self.db.getIndexPage(),self.db_o.getIndexPage())
        if menuCh['_mainPage']:
            print ' Hoofdpagina is veranderd'

        menuCh['_mainMenu'] = self.findMenuChange(self.db,self.db_o)
        if menuCh['_mainMenu'] != None:
            print ' Hoofd menu:'
            print '  Nieuw :', menuCh['_mainMenu']['new']
            print '  Verwijderd :', menuCh['_mainMenu']['del']
            print '  Veranderd :', menuCh['_mainMenu']['chn']

        menus = self.db.getMenus()
        for menu in menus:
            if menuCh['_mainMenu'] == None or menu not in menuCh['_mainMenu']['new']:
                menuCh[menu] = self.findMenuChange( \
                        self.db.getSub(menu),self.db_o.getSub(menu))

                if menuCh['_mainMenu'] != None and menuCh[menu] == None and menu in menuCh['_mainMenu']['chn']:
                    menuCh[menu] = {}
                    menuCh[menu]['new'] = []
                    menuCh[menu]['del'] = []
                    menuCh[menu]['chn'] = []
            else:
                menuCh[menu] = {}
                menuCh[menu]['new'] = []
                menuCh[menu]['del'] = []
                menuCh[menu]['chn'] = []

                for smenus in self.db.getSubMenus(menu):
                    menuCh[menu]['new'].append(smenus)


            if menuCh[menu] != None:
                print ' Sub menu "'+menu+'":'
                print '  Nieuw :', menuCh[menu]['new']
                print '  Verwijderd :', menuCh[menu]['del']
                print '  Veranderd :', menuCh[menu]['chn']

        return menuCh

    def findMenuChange(self,dbm_n,dbm_o):
        """Check if a menu has changed"""
        menu_n = dbm_n.getMenus()
        menu_o = dbm_o.getMenus()

        res = {}
        res['new'] = []
        res['del'] = []
        res['chn'] = []

        if not menu_n == menu_o:
            res['new'] = list(set(menu_n)-set(menu_o))
            res['del'] = list(set(menu_o)-set(menu_n))

        for mitem in menu_n:
            if mitem not in res['new']:
                pageData_n = dbm_n.getPage(mitem)
                pageData_o = dbm_o.getPage(mitem)
                changed = self.findPageChange(pageData_n,pageData_o)

                if changed:
                    res['chn'].append(mitem)

        if len(res['new']) == 0 and len(res['del']) == 0 and len(res['chn']) == 0:
            if menu_n == menu_o:
                res = None

        return res

    def findPageChange(self,pageData_n,pageData_o):
        """Find changes in the attributes of a page"""
        changed = True
        if pageData_n.getFullName() == pageData_o.getFullName():
            if pageData_n.getUrl() == pageData_o.getUrl():
                if pageData_n.getProcess() == pageData_o.getProcess():
                    if pageData_n.getSubProcess() == pageData_o.getSubProcess():
                        changed = None
        return changed

    def checkDir(self,dirn,base):
        if base != '.':
            bs = os.path.dirname(os.db.getPage(base).getUrl())
            dn = os.path.join(self.wd,bs,dirn)
        else:
            dn = os.path.join(self.wd,dirn)

        if not os.path.exists(dn):
            os.mkdir(dn)
            self.menuCFiles.append(dirn)

    def createTextMenu(self,Menu,subMenu):
        stm = '<center>\n'
        st = ""
        if subMenu != None:
            mPage = os.path.basename(self.db.getPage(Menu).getUrl())
            st += '<a href="%s">Terug</a>' %mPage

        for sms in self.db.getSubMenus(Menu):
            if len(st) > 0:
                st += '&nbsp;|&nbsp;'

            if sms == subMenu:
                st += self.db.getSubPage(Menu,sms).getFullName()
            else:
                url = self.db.getSubPage(Menu,sms).getUrl()
                name = self.db.getSubPage(Menu,sms).getFullName()
                if self.db.getSubPage(Menu,sms).getNewWin():
                    st += '<a href="%s" target="_blank">%s</a>' %(url,name)
                else:
                    st += '<a href="%s">%s</a>' %(url,name)

        st += '</center>\n<hr>\n'
        return stm+st

    def menuHeader(self,cdl):
        txt = """<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>Jacob Valcke</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<base target="rest"></head>
"""
        txt += '<body background="%splaatjes/menu.png">\n ' %cdl
        txt += '<IMG src="%splaatjes/pix.png" alt="vuller" width="1" height="25" border="0"><br>\n' %cdl
        return txt

    def mkHoofdPage(self,page):
        txt = """<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Frameset//EN" "http://www.w3.org/TR/html4/frameset.dtd">
<HEAD>
<TITLE>Jacob Valcke Groep</TITLE>
 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
</HEAD>
 
<frameset cols="184,*" framespacing="0" border="0">
<frame name="menu" src="menu.htm" scrolling="no" noresize="NORESIZE" marginheight="0" marginwidth="0" frameborder="0">
"""
        txt += '<frame name="tekst" src="%s" marginheight="0" marginwidth="0" frameborder="0">\n' %page
        txt += '</frameset>\n</html>\n'
        return txt

    def getMenuFiles(self):
        return self.menuFiles

    def getMenuCFiles(self):
        return self.menuCFiles

    def getMPages(self):
        return self.MPages

    def getAddPages(self):
        return self.addPages

    def getMenuCHtml(self):
        return self.menuCHtml

class mkPict():
    """Generate picture collections"""

    def __init__(self,reGen,db,db_o):
        self.db = db         # database
        self.db_o = db_o     # previous database
        self.reGen = reGen   # regenerate website if True
        self.wd = db.getWorkDir()
        self.sd = os.path.normpath(os.path.dirname(self.db.getIndexPage().getUrl()))

        # list with all files created for menu
        self.picFiles = []
        # list with changed files for menu
        self.picCFiles = []
        # process all pictures
        self.processPics()

    def processPics(self):
        print 50*'-'
        print "Scan en maak plaatjes pagina's:"
        page = self.db.getIndexPage()
        if self.db_o != False:
            page_o = self.db_o.getIndexPage()
        else:
            page_o = None

        if len(page.getPics()) > 0:
            self.processPic(page,page_o,'')

        for menu in self.db.getMenus():
            page = self.db.getPage(menu)
            bs = os.path.dirname(page.getUrl())
            if len(page.getPics()) > 0:
                if  self.db_o != False and menu in self.db_o.getMenus():
                    page_o = self.db_o.getPage(menu)
                    oldDb = True
                else:
                    page_o = None
                    oldDb = False

                self.processPic(page,page_o,bs)

            for smenu in self.db.getSubMenus(menu):
                page = self.db.getSubPage(menu,smenu)
                if len(page.getPics()) > 0:
                    if oldDb and smenu in self.db_o.getSubMenus(menu):
                        page_o = self.db_o.getSubPage(menu,smenu)
                    else:
                        page_o = None

                    self.processPic(page,page_o,bs)

    def processPic(self,page,page_o,bs):
        pcs = page.getPics()
        pcds = pcs.keys()

        for pcd in pcds:
            bsd = os.path.join(bs,pcd)
            print bsd
            self.checkDir(bsd)
            self.checkDir(os.path.join(bsd,'org'))
            self.checkDir(os.path.join(bsd,'thumb'))

            inxp = os.path.join(self.wd,bsd,pcd+'.htm')
            self.picFiles.append(os.path.join(bsd,pcd+'.htm'))
            if self.reGen or not os.path.exists(inxp):
                f = open('temp.htm','w')
                f.write(self.writePicFrame(pcd))
                f.close()
                os.system('tidy -q -o %s temp.htm' %(inxp))
                self.picCFiles.append(os.path.join(bsd,pcd+'.htm'))

            flist = os.listdir(os.path.join(self.sd,bsd))

            change = False
            for pf in flist:
                pChange = False
                orf = os.path.join(self.sd,bsd,pf)
                destfo = os.path.join(self.wd,bsd,'org',pf)
                destft = os.path.join(self.wd,bsd,'thumb',pf)

                self.picFiles.append(os.path.join(bsd,'org',pf))
                if self.checkPicChange(orf,destfo):
                    self.picCFiles.append(os.path.join(bsd,'org',pf))
                    shutil.copyfile(orf,destfo)
                    pChange = True

                self.picFiles.append(os.path.join(bsd,'thumb',pf))
                if self.checkPicChange(orf,destft):
                    self.picCFiles.append(os.path.join(bsd,'thumb',pf))
                    if pf.endswith('.jpg') or pf.endswith('.jpeg'):
                        os.system("convert %s -thumbnail '120x120>' -quality 85%% %s" %(orf,destft))
                    else:
                        os.system("convert %s -thumbnail '120x120>' %s" %(orf,destft))
                    pChange = True

                if pChange:
                    change = True


                htmlFile = os.path.join(bsd,os.path.splitext(pf)[0]+'.htm')
                htmlFileWd = os.path.join(self.wd,htmlFile)
                self.picFiles.append(htmlFile)

                if pChange or not os.path.exists(htmlFileWd):
                    oPic = self.getPicSize(destfo)
                    f = open('temp.htm','w')
                    f.write(self.writePicHtml(htmlFile,pf,flist,oPic,pcd))
                    f.close()
                    os.system('tidy -q -o %s temp.htm' %(htmlFileWd))
                    self.picCFiles.append(htmlFile)


            for f in ['t','p']:
                inxp = os.path.join(self.wd,bsd,f+pcd+'.htm')
                self.picFiles.append(os.path.join(bsd,f+pcd+'.htm'))
                if self.reGen or not os.path.exists(inxp):
                    change = True

            if page_o != None:
                if not page_o.getPics().has_key(pcd) or \
                        page_o.getPics()[pcd] != pcs[pcd]:
                            change = True

            if change:
                tPic = {}
                for pf in flist:
                    orf = os.path.join(self.sd,bsd,pf)
                    destfo = os.path.join(self.wd,bsd,'org',pf)
                    destft = os.path.join(self.wd,bsd,'thumb',pf)

                    tPic[pf] = self.getPicSize(destft)

            

                inxp = os.path.join(self.wd,bsd,'t'+pcd+'.htm')
                inxp2 = os.path.join(bsd,'t'+pcd+'.htm')
                f = open('temp.htm','w')
                f.write(self.writePicThumb(tPic,inxp2))
                f.close()
                os.system('tidy -q -o %s temp.htm' %(inxp))
                self.picCFiles.append(inxp2)

                inxp = os.path.join(self.wd,bsd,'p'+pcd+'.htm')
                inxp2 = os.path.join(bsd,'p'+pcd+'.htm')
                f = open('temp.htm','w')
                f.write(self.writePicIndex(tPic,inxp2,pcs[pcd]))
                f.close()
                os.system('tidy -q -o %s temp.htm' %(inxp))
                self.picCFiles.append(inxp2)

    def writePicHtml(self,pn,pf,flist,oPic,pcd):
        txt = pageHeader(pn,'plaatje')
        txt += '<center>'
        i = flist.index(pf)
        txt += '%s &nbsp;|&nbsp; %i van %i <br> \n' %(pf,i+1,len(flist))
        nav = ""
        if i > 0:
            nav +='<a href="%s.htm"> vorige </a> &nbsp;|&nbsp;' %(os.path.splitext(flist[i-1])[0])
        else:
            nav +='vorige  &nbsp;|&nbsp;'

        nav += '<a href="p%s.htm"> overzicht </a>&nbsp;|&nbsp;' %pcd

        if i < len(flist)-1:
            nav +='<a href="%s.htm"> volgende </a> \n' %(os.path.splitext(flist[i+1])[0])
        else:
            nav +=' volgende \n'


        txt += nav+'<br>\n'
        txt +='<IMG src="org/%s" alt="%s" width="%i" height="%i" border="0"><br>\n' \
            %(pf,pf,oPic[0],oPic[1])
        txt += nav

        txt += '</center>\n</body></html>'
        return txt

    def writePicThumb(self,tPic,pn):
        txt = pageHeader(pn,'plaatje')
        txt += '<center>\n'
        pl = tPic.keys()
        pl.sort()
        for p in pl:
            txt +='<a href="%s.htm">' %(os.path.splitext(p)[0])
            txt +='<IMG src="thumb/%s" alt="%s" width="%i" height="%i" border="0"></a><br>\n' \
                    %(p,p,tPic[p][0],tPic[p][1])
            txt += '<br>'
        txt = txt[:-9]
        txt += '\n</center>\n</body></html>\n'
        return txt

    def writePicIndex(self,tPic,pn,name):
        nrcol = 5
        txt = pageHeader(pn,'plaatje')
        txt += '<h2>%s</h2>\n' %name
        txt += '<table border="0" cellpadding="5" summary="Thumb table">\n<tr>'
        pl = tPic.keys()
        pl.sort()
        i = 0
        for p in pl:
            txt += '<td align="center">'
            txt +='<a href="%s.htm">' %(os.path.splitext(p)[0])
            txt +='<IMG src="thumb/%s" alt="%s" width="%i" height="%i" border="0"></a><br></td>\n' \
                    %(p,p,tPic[p][0],tPic[p][1])
            i += 1
            if i == nrcol:
                txt += '</tr><tr>\n'
                i = 0

        while i < nrcol:
            txt += '<td> <br></td>\n'
            i += 1
        txt += '</tr></table>\n</body></html>\n'
        return txt


    def getPicSize(self,loc):
        a = os.popen('identify '+loc)
        dim  = a.read().split()[2].split('x')
        dim[0] = int(dim[0])
        dim[1] = int(dim[1])
        a.close()
        return dim

    def checkPicChange(self,loc,dest):
        if self.reGen:
            return True

        if not os.path.exists(dest):
            return True

        if os.path.getmtime(loc) > os.path.getmtime(dest):
            return True

        return False

    def checkDir(self,dirn):
        dn = os.path.join(self.wd,dirn)

        if not os.path.exists(dn):
            os.mkdir(dn)
            self.picCFiles.append(dirn)

    def writePicFrame(self,pcd):
        txt = """<!DOCTYPE HTML PUBLIC "-1//W3C//DTD HTML 4.0 Frameset//EN">
<HTML>
<HEAD>
 <TITLE>Jacob Valcke Groep</TITLE>
</HEAD>
<frameset cols="160,*">
        """
        txt += '<frame name="thumb" src="t%s.htm" > \n' %pcd
        txt += '<frame name="plaatje"  src="p%s.htm" \n >' %pcd
        txt += '</frameset>\n </html>\n'
        return txt

    def getPicFiles(self):
        return self.picFiles

    def getPicCFiles(self):
        return self.picCFiles

def urlCleaner(url):
    url = url.replace("'","_")
    url = url.replace('"',"_")
    url = url.replace(" ","_")
    return url

def pageHeader(page,baseTarget='tekst'):
    txt="""<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>Jacob Valcke</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
"""
    txt += '<base target="%s"><link rel="stylesheet" href="%sjv.css" type="text/css"></head> \n' %(baseTarget,countPath(page)*'../')
    txt += '<body bgcolor="#CCFFCC">\n'
    return txt

def countPath(fl):
    if os.name == 'posix':
        sep = '/'
    else:
        sep = '\\'

    cbase = fl.split(sep)
    return len(cbase)-1