#! /usr/bin/python2.2

#------------------------------------------------------------------------
# name: poage.py
# author:       J Skinner
# Date Written: 2003
# Purpose: generate html pages from a database
# Notes
#------------------------------------------------------------------------
    
        
            
#------------------------   GLOBALS  ------------------------------------


from constants import *
from utils import *

def get_file_as_string(fname):
    return '\n'.join(open(fname, 'r').readlines())


#------------------------------------------------------------------------    


class Url_List:
    ' vertical list of urls '

    def __init__(self, page_id, db, auth_level, page_info=None, xtra_info=None):
        self.__template='<a href="%(item_data)s">%(item_name)s</a><br>'
        self.__db = db
        self.__page_id = page_id
        self.__page_info = page_info
        self.__xtra_info = xtra_info
        self.__auth_level = auth_level
        self.__data = self.__get_items()

    def __get_items(self):
        self.__page_data = self.__db.get_dict('page_data_simple',
            ['item_name', 'item_data', 'auth_level'],
            where='page_id=%s and auth_level <= %s'%(self.__page_id, 
            self.__auth_level), order='item_name')

    def show(self):
        formatted_list = []
        for i in self.__page_data:
            formatted_list.append(self.__template%i)

        return '\n'.join(formatted_list)




    def walk(self):
        return self.show()


#------------------------------------------------------------------------    


class Item_list:
    def __init__(self, page_id, db, auth, page_info=None, xtra_info=None):
        self.__template='<a href="./index.cgi?page=edit&the_id=%(doc_id)s">%(title)s</a><br>'
        self.__db = db
        self.__page_id = page_id
        self.__page_info = page_info
        self.__xtra_info = xtra_info
        self.__auth = auth
        self.__data = self.__get_items()

    def __get_items(self):
#        print 'parent', self.__page_info['parent'
#        print 'page_id', self.__page_info['page_id']
        self.__page_data = self.__db.get_dict('document_info',
            ['doc_id', 'author_id', 'pub_date', 'has_blob',
            'is_active', 'title', 'short_desc', 'long_desc'],
            order='title')

    def show(self):
        formatted_list = []
        for i in self.__page_data:
            formatted_list.append(self.__template%i)

        return 'main_text', '\n'.join(formatted_list)




    def walk(self):
        return self.show()
    

#------------------------------------------------------------------------    


class Simple_Text:
    def __init__(self, page_id, db, auth, page_info=None, xtra_info=None):
        self.__template='<a href="./index.cgi?page=edit&the_id=%(doc_id)s">%(title)s</a><br>'
        self.__db = db
        self.__page_id = page_id
        self.__page_info = page_info
        self.__xtra_info = xtra_info
        self.__auth = auth
        self.__data = self.__get_items()

    def __get_items(self):
#        print 'parent', self.__page_info['parent'
#        print 'page_id', self.__page_info['page_id']
        # print 'page_id', self.__page_id
        self.__page_text = self.__db.get_dict('page_data_simple',
            ['item_data'], 
            where='page_id=%s and item_name="main_text"'%self.__page_id)

    def show(self):
        formatted_list = []
        for i in self.__page_data:
            formatted_list.append(self.__template%i)

        return 'main_text', '\n'.join(formatted_list)




    def walk(self):
        return self.show()
    

#class Complex_Text:
#    def __init__(self, page_id, db, auth, page_info=None, xtra_info=None):
#        pass
        
#------------------------------------------------------------------------    


class Page:
    def __init__(self, page_id, db,  auth, page_info=None, xtra_info=None):
        # print page_id
        self.__page_id = page_id
        self.__parts = []
        self.__page_info = page_info
        self.__xtra_info = xtra_info
        self.__auth = auth
        self.__db = db
        self.__page_types = {'1':Simple_Text, '2':Url_List}
        
        if auth.do_login: # page == '200':
            # this is an ugly hack
            template = {'template_name':'top', 
                'template':"%(content)s"}
            page_data = {'item_name':'content',
                'content':get_file_as_string(TEMPLATE_DIR+'login.html')}
            self.page = template['template']%page_data
        elif auth.do_download:
            self.__send_file()
            self.page = None
        else:
            if auth.do_logout: # page_id == '300':
                self.__auth.logout()
            self.page = self.__get_parts(page_info)


    def __build(self, xtra_info):
        parts = []
        tables = []
        static_query_parts = {'keywords':
            [''' document_info.doc_id=kw_doc.doc_id and 
            keywords.keyword_id=kw_doc.keyword_id  ''',
            'keywords, kw_doc, document_info'],
            'authors': [''' 
            document_authors.author_id = doc_auth.author_id and
            doc_auth.document_id = document_info.doc_id''',
            'document_authors, doc_auth, document_info'],
            'department':[''' ''', '']}

        print 'content-type: text/html'
        print
        for i in [ ['keywords', 'keyword'],  ['authors', 'name'], 
            ['deparment', 'department']]:
            if xtra_info.has_key(i[0]):
                parts.append( '('+' or '.join(
                    ['%s = "%s"'%(i[1], _i.strip()) 
                        for _i in xtra_info[i[0]].split(',')])+')')
                parts.append(static_query_parts[i[0]][0])
                tables.append(static_query_parts[i[0]][1])
        if len(parts):
            tables_hash = {}
            for i in ','.join(tables).split(','):
                tables_hash[i.strip()] = 1
            tables = ','.join(tables_hash.keys())
            print tables, ' and '.join(parts)
            return tables, ' and '.join(parts)
        else:
            print 'boom'
            return 'document_info.doc_id=kw_doc.doc_id and '+\
                            'keywords.keyword_id=kw_doc.keyword_id'

#------------------------------------------------------------------------    

    def __get_parts(self, page_info):
        if not page_info:
            page_info = self.__page_info = self.__db.get_dict('pages', 
                ['page_id', 'page_type', 'auth_level',
                'has_subparts', 'parent', 'template_id', 'sub_type'],
                where='page_id=%s'%self.__page_id)[0]

        self.__page_items = {}
        self.__page_items['left_bar'] = Url_List(2, self.__db, self.__auth.auth_level).show()
        try:
            stuff = self.__db.get_dict('page_data_simple',  
                ['item_name', 'item_data'], 
                where='page_id=%s'%self.__page_id)
        except self.__db.NO_DATA:
            pass

        template = self.__db.get('page_templates', ['template'], 
            where='template_id = "%s"'%1)[0]
        for i in stuff:
            self.__page_items[i['item_name']] = i['item_data']


        if page_info['page_type'] == 1:
            # this is a simple type so we don't need anything more done
            pass
        elif  page_info['page_type'] == 2:
            # search for an items and show them
            #query = build_query(extra_info)

            template_line = self.__db.get('page_templates', ['template'],
                where='template_id="%s"'%SEARCH_TEMPLATE_LINE_ID)[0][0]

            template_body = self.__db.get('page_templates', ['template'],
                where='template_id="%s"'%SEARCH_TEMPLATE_BODY_ID)[0][0]


            try:
                tables, filter = self.__build(self.__xtra_info)
                results = self.__db.get( tables, 
                    ['document_info.doc_id', 'title'], 
                    distinct='Y', where=filter)
            except self.__db.NO_DATA:
                self.__page_items['main_text'] = \
                    template_body%'No Items Found'
            else:
                search_parts = []
                for i in results:
                    search_parts.append(template_line%i)
                
                self.__page_items['main_text'] = \
                    template_body%'\n'.join(search_parts)

        elif page_info['page_type'] == 3:
            # display the detailed view for an item
            results = self.__db.get_dict('document_info', 
                [ 'doc_id', 'pub_date', 'title', 'short_desc', 'long_desc', 
                'has_blob'],
                where='doc_id="%s"'%self.__xtra_info['item_id'])[0]

            if results['has_blob'] == 1:
                results['download'] = '<a href="./index.cgi?action=download&doc_id=%s">Download</a>'%results['doc_id']
            else:
                results['download'] = ''
            authors = self.__db.get_dict('doc_auth, document_authors',
                [ ('doc_auth.author_id', 'author_id'),  'name' ],
                where='document_authors.author_id = doc_auth.author_id and '+\
                    'doc_auth.document_id="%s"'%results['doc_id'] )
            author_list = []
            author_template = \
                '<a href="./index.cgi?action=show_author&auth_id=%(author_id)s">%(name)s</a>'
            for i in authors:
                author_list.append(author_template%i)
            
            results['the_authors'] = ', '.join(author_list)
            template_body = self.__db.get('page_templates', ['template'],
                where='template_id="%s"'%ITEM_TEMPLATE_BODY_ID)[0][0]
            self.__page_items['main_text'] = \
                template_body%results
                
        
        elif page_info['page_type'] == 4:
            # entry form for document input
            authors = self.__db.get('document_authors', ['author_id', 'name'],
                order='name')
            template_body = self.__db.get('page_templates', ['template'],
                where='template_id="%s"'%ENTRY_TEMPLATE_BODY_ID)[0][0]
            dropbox = '\n'.join(['<option value="%s">%s'%_i for _i in authors])
            self.__page_items['main_text'] = \
                template_body%{'author_list':dropbox}
                            

        elif page_info['page_type'] == 5:
            results = self.__db.get_dict('document_authors', 
                ['name', 'email_address', 'notes'],
                where='author_id=%s'%self.__xtra_info['auth_id'])[0]
            template_body = self.__db.get('page_templates', ['template'],
                            where='template_id="%s"'%AUTHOR_BODY_ID)[0][0]
            self.__page_items['main_text'] = \
                template_body%results
            
        self.__page_items['login_status'] = self.__auth.login_status()
        return template[0]%self.__page_items
            

#------------------------------------------------------------------------    


    def __send_file(self):
        data = self.__db.get('document_data', ['filename', 'the_doc'],
            where='doc_id=%s'%self.__xtra_info['doc_id'])[0]

        print '''\
Content-Type: application/octet-stream; name="%(filename)s"
Content-Disposition: attachment; filename="%(filename)s"'''%{'filename':data[0]}
        print
        print data[1]


    def __show_header(self):
        print 'Content-type: text/html'
        print self.__auth.get_cookie_header()
        print
                            


    def show(self):
        " display the page "
        #dummy, page = self.walk()
        # print 'abc'
        if  self.page == None:
            return
        self.__show_header()
        print self.page
        

    def walk(self):
        body_items = {}

        for i in self.__parts:
            the_name, the_content = i.walk()
            body_items[the_name] = the_content

        for i in self.__page_data:
            body_items[i['item_name']] = i['item_data']

        
        return (self.__template['template_name'], 
            self.__template['template']%body_items)


# simple mapping for various part handler classes
component_part = {'Page':Page, 'Url_List':Url_List}
comp_types = {'1':'Page', '2':'Url_List'}

#------------------------------------------------------------------------    



def test():
    '''\
    test routine -
    this is run when then module is run as a program for regression testing
    '''
    import access
    import cgi

    

    print 'Content-type: text/html'
    print

    page_id = 1

    db = access.Access(dbname='pysocks', user='crypt')
    
    form = cgi.FieldStorage()

    if form.has_key('page'):
        page_id = int(form['page'].value)

    test_page = Page(page_id, db)

    test_page.show()

if  __name__ == '__main__':
    test()


