businesstrips/include/webInterface.py

347 lines
22 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/usr/bin/env python
# -*- coding: utf-8 -*-
'''
Created on 17.12.2010
@author: morozov
'''
import sys, cgi, datetime
sys.path.append('.')
import functions
from wsgiref.util import application_uri
config = functions.readConfig()
class pageParts(object):
'''
classdocs
'''
def __init__(self, environ, db):
'''
Constructor
'''
self.environ = environ
self.userName = environ['REMOTE_USER']
self.fieldStorage = cgi.FieldStorage(fp = environ['wsgi.input'], environ = environ, keep_blank_values = 1)
self.db = db
self.appUrl = application_uri(environ)
self.requestUri = environ['REQUEST_URI']
self.errStatus = False
self.errMsg = ''
self.now = datetime.datetime.now()
if self.fieldStorage.has_key('year') and self.fieldStorage.has_key('month') and self.fieldStorage.has_key('day'):
try:
self.journalDate = datetime.date(year = int(self.fieldStorage.getfirst('year')), month = int(self.fieldStorage.getfirst('month')), day = int(self.fieldStorage.getfirst('day')))
except ValueError:
self.journalDate = self.now.date()
else:
self.journalDate = self.now.date()
try:
self.previousDay = self.journalDate - datetime.timedelta(days = 1)
except OverflowError:
self.previousDayError = True
else:
self.previousDayError = False
try:
self.nextDay = self.journalDate + datetime.timedelta(days = 1)
except OverflowError:
self.nextDayError = True
else:
self.nextDayError = False
self.tomorrow = datetime.datetime.now().date() + datetime.timedelta(days = 1)
if self.fieldStorage.has_key('newName')\
and self.fieldStorage.has_key('newPosition')\
and self.fieldStorage.has_key('newDepartment')\
and self.fieldStorage.has_key('newStartTimeHour')\
and self.fieldStorage.has_key('newStartTimeMinute')\
and self.fieldStorage.has_key('newEndTimeHour')\
and self.fieldStorage.has_key('newEndTimeMinute')\
and self.fieldStorage.has_key('newDescription')\
and self.fieldStorage.has_key('newChief'):
try:
newRecord = self.db.journalRecord(name = self.fieldStorage.getfirst('newName'),
position = self.fieldStorage.getfirst('newPosition'),
department = self.fieldStorage.getfirst('newDepartment'),
date = self.journalDate,
startTime = datetime.time(hour = int(self.fieldStorage.getfirst('newStartTimeHour')),
minute = int(self.fieldStorage.getfirst('newStartTimeMinute'))),
endTime = datetime.time(hour = int(self.fieldStorage.getfirst('newEndTimeHour')),
minute = int(self.fieldStorage.getfirst('newEndTimeMinute'))),
description = self.fieldStorage.getfirst('newDescription'),
chief = self.fieldStorage.getfirst('newChief'),
userName = self.userName)
for value in newRecord.name, newRecord.position, newRecord.department, newRecord.description:
if len(value) == 0:
raise ValueError
except ValueError:
self.errStatus = True
self.errMsg = 'Введены неверные данные. Заполняйте форму внимательнее.'
else:
self.db.setProperty(self.userName, 'latestName', newRecord.name)
self.db.setProperty(self.userName, 'latestPosition', newRecord.position)
self.db.setProperty(self.userName, 'latestDepartment', newRecord.department)
self.db.setProperty(self.userName, 'latestChief', newRecord.chief)
self.db.journalSaveRecord(newRecord)
if self.fieldStorage.has_key('delete'):
try:
self.db.journalDeleteRecord(self.userName, int(self.fieldStorage.getfirst('delete')))
except:
self.errStatus = True
self.errMsg = 'Ошибка при удалении записи. Возможно, вы пытались удалить несуществующую запись.'
self.propertyLatestName = self.db.getProperty(self.userName, 'latestName')
if self.propertyLatestName == None:
self.propertyLatestName = ''
self.propertyLatestPosition = self.db.getProperty(self.userName, 'latestPosition')
if self.propertyLatestPosition == None:
self.propertyLatestPosition = ''
self.propertyLatestDepartment = self.db.getProperty(self.userName, 'latestDepartment')
if self.propertyLatestDepartment == None:
self.propertyLatestDepartment = ''
self.propertyLatestChief = self.db.getProperty(self.userName, 'latestChief')
if self.propertyLatestChief == None:
self.propertyLatestChief = ''
def _getWeekDay(self, date):
days = {0: 'понедельник',
1: 'вторник',
2: 'среда',
3: 'четверг',
4: 'пятница',
5: 'суббота',
6: 'воскресенье'}
return(days[date.weekday()])
def _replaceTags(self, str):
str = str.replace('<', '&lt;')
str = str.replace('>', '&gt;')
return str
def header(self):
output = '<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">\n'\
'<html lang="ru">\n'\
'<head>\n'\
' <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />\n'\
' <title>Журнал командировок</title>\n'\
'</head>\n'\
'<body bgcolor = "white">\n'
output += ' <table width="100%" bgcolor="#336299"><tr><td>\n'
output += ' <table width="100%">\n'
output += ' <tr>\n'
output += ' <td>\n'
try:
for link in config.links:
if link['url'] == '':
output += ' <p style = "display: inline; text-decoration: none; color: white;">%s</p>\n' % link['name']
else:
output += ' <a style = "text-decoration: none; border-bottom: 1px solid white; color: white;" href="%s" title="%s">%s</a>\n' % (link['url'], link['description'], link['name'])
except:
None
output += ' </td>\n'
output += ' <td>\n'
output += ' <p align = "right"><a href="view-all.py" style = "text-decoration: none; border-bottom: 1px solid white; color: white;">Все журналы</a> <a href="index.py" style = "text-decoration: none; border-bottom: 1px solid white; color: white;">Сегодня</a> <a href="index.py?day=%s&month=%s&year=%s" style = "text-decoration: none; border-bottom: 1px solid white; color: white;">Завтра</a></p>\n' % (self.tomorrow.day, self.tomorrow.month, self.tomorrow.year)
output += ' </td>\n'
output += ' </tr>\n'
output += ' </table>\n'
output += ' <H1><p align = "center"><font color = "white">Журнал командировок</font></p></H1>\n'
output += ' </td></tr></table>\n'
if self.errStatus:
output += ' <table width = "100%" border = 0 bgcolor = "#FFF9B4">\n'
output += ' <tr align = "center"><td><b><font color = "red"><b>%s</b></font></b></td></tr>\n' % self.errMsg
output += ' </table>\n'
return(output)
def headerPrint(self):
output = '<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">\n'\
'<html lang="ru">\n'\
'<head>\n'\
' <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />\n'\
' <title>Журнал командировок</title>\n'\
'</head>\n'\
'<body>\n'\
' <style>\n'\
' @media print {\n'\
' .printButton {display: none;}\n'\
' }\n'\
' </style>\n'
output += ' <H1><p align = "center">Журнал командировок</p></H1>\n'
return(output)
def journalForDay(self):
records = self.db.journalGetRecords(self.journalDate)
output = ' <table align = "right"><tr>\n'
output += ' <td>\n'
output += ' <a href = "print.py?day=%s&month=%s&year=%s"><img src = "images/printer.jpg" border = "0"/></a>\n' % (self.journalDate.day, self.journalDate.month, self.journalDate.year)
output += ' </td>\n'
output += ' <td>\n'
output += ' <a href = "print.py?day=%s&month=%s&year=%s">версия для печати</a>\n' % (self.journalDate.day, self.journalDate.month, self.journalDate.year)
output += ' </td>\n'
output += ' </tr></table><br>\n'
output += ' <h3><p align = "center">Дата:</p></h3>\n'
output += ' <form method = "get" action = "%s" style = "text-align:center;">\n' % self.appUrl
output += ' <table align = "center">\n'
output += ' <tr>\n'
if self.previousDayError == False:
output += ' <td><a href="%s?day=%s&month=%s&year=%s"><img border = "0" src = "images/left.jpg"/></a></td>\n' % (self.appUrl, self.previousDay.day, self.previousDay.month, self.previousDay.year)
else:
output += ' <td><img border = "0" src = "images/left.jpg"/></td>\n'
output += ' <td>\n'
output += ' <input type = "text" name = "day" id = "day" size = "2" value = "%s" />.\n' % str(self.journalDate.day).zfill(2)
output += ' <input type = "text" name = "month" id = "month" size = "2" value = "%s" />.\n' % str(self.journalDate.month).zfill(2)
output += ' <input type = "text" name = "year" id = "year" size = "4" value = "%s" />\n' % self.journalDate.year
output += ' </td>\n'
if self.nextDayError == False:
output += ' <td><a href="%s?day=%s&month=%s&year=%s"><img border = "0" src = "images/right.jpg"/></a></td>\n' % (self.appUrl, self.nextDay.day, self.nextDay.month, self.nextDay.year)
else:
output += ' <td><img border = "0" src = "images/right.jpg"/></td>\n'
output += ' </tr>\n'
output += ' </table>\n'
output += ' %s' % self._getWeekDay(self.journalDate)
output += ' <p><input type="submit" value = "Перейти" /></p>\n'
output += ' </form>\n'
if len(records) == 0:
output += '<H3>Записи отсутствуют.</H3>'
else:
output += ' <table width = "100%" bordercolor = "black" border = "1" cellspacing = "0" rules = "all" frame = "border">\n'\
' <tr align = "center" bgcolor="#336299" style = "color: white;">\n'\
' <td><b>Фамилия И.О.</b></td>\n'\
' <td><b>Должность</b></td>\n'\
' <td><b>Отдел</b></td>\n'\
' <td><b>Время начала</b></td>\n'\
' <td><b>Время окончания</b></td>\n'\
' <td><b>Цель и место встречи</b></td>\n'\
' <td><b>Руководитель</b></td>\n'\
' <td><b>Удалить</b></td>\n'\
' </tr>\n'
for i in xrange(len(records)):
if i % 2 == 1:
bgcolor = ' bgcolor = "#BFD0E0"'
else:
bgcolor = ''
output += ' <tr%s>\n' % bgcolor
if self.db.journalCheckDeletePermissions(self.userName, records[i].key):
deleteField = '<a href="' + self.appUrl + '?year=' + str(self.journalDate.year) + '&month=' + str(self.journalDate.month) + '&day=' + str(self.journalDate.day) + '&delete=' + str(records[i].key) + '"><img src = "images/trash.png" border = "0"/></a>'
else:
deleteField = ''
for field in self._replaceTags(records[i].name), self._replaceTags(records[i].position), self._replaceTags(records[i].department), str(records[i].startTime.hour) + ':' + str(records[i].startTime.minute).zfill(2), str(records[i].endTime.hour) + ':' + str(records[i].endTime.minute).zfill(2), self._replaceTags(records[i].description), self._replaceTags(records[i].chief), deleteField:
output += ' <td>%s</td>\n' % field
output += ' </tr>\n'
output += ' </table>\n'
return(output)
def journalForDayPrint(self):
records = self.db.journalGetRecords(self.journalDate)
output = ' <h3><p align = "center">Дата: %s.%s.%s (%s)</p></h3>\n' % (str(self.journalDate.day).zfill(2), str(self.journalDate.month).zfill(2), self.journalDate.year, self._getWeekDay(self.journalDate))
output += ' <p>Отчёт сгенерирован: %s.%s.%s %s:%s</p>\n' % (str(self.now.day).zfill(2), str(self.now.month).zfill(2), self.now.year, self.now.hour, str(self.now.minute).zfill(2))
if len(records) == 0:
output += ' <H3>Записи отсутствуют.</H3>\n'
else:
output += ' <table width = "100%" bordercolor = "black" border = "1" cellspacing = "0" rules = "all" frame = "border">\n'\
' <tr align = "center" >\n'\
' <td><b>Фамилия И.О.</b></td>\n'\
' <td><b>Должность</b></td>\n'\
' <td><b>Отдел</b></td>\n'\
' <td><b>Время начала</b></td>\n'\
' <td><b>Время окончания</b></td>\n'\
' <td><b>Цель и место встречи</b></td>\n'\
' <td><b>Руководитель</b></td>\n'\
' </tr>\n'
for i in xrange(len(records)):
output += ' <tr>\n'
for field in self._replaceTags(records[i].name), self._replaceTags(records[i].position), self._replaceTags(records[i].department), str(records[i].startTime.hour) + ':' + str(records[i].startTime.minute).zfill(2), str(records[i].endTime.hour) + ':' + str(records[i].endTime.minute).zfill(2), self._replaceTags(records[i].description), self._replaceTags(records[i].chief):
output += ' <td>%s</td>\n' % field
output += ' </tr>\n'
output += ' </table>\n'
return(output)
def addRecord(self):
output = ' <H2>Добавить запись:</H2>\n'\
' <form method = "post" enctype = "multipart/form-data" action = "' + self.appUrl + '?year=' + str(self.journalDate.year) + '&month=' + str(self.journalDate.month) + '&day=' + str(self.journalDate.day) + '">\n'\
' <table width = "100%" bordercolor = "black" border = "1" cellspacing = "0" cellpadding = "5" rules = "all" frame = "border">\n'\
' <tr align = "center" bgcolor="#336299" style = "color: white;">\n'\
' <td><b>Фамилия И.О.</b></td>\n'\
' <td><b>Должность</b></td>\n'\
' <td><b>Отдел</b></td>\n'\
' <td><b>Время начала</b></td>\n'\
' <td><b>Время окончания</b></td>\n'\
' <td><b>Цель и место встречи</b></td>\n'\
' <td><b>Руководитель</b></td>\n'\
' </tr>\n'\
' <tr>\n'\
' <td align = "center"><input type = "text" name = "newName" id = "newName" style = "width: 95%; background-color: #FFF9B4;" value = "' + self._replaceTags(self.propertyLatestName) + '" /></td>\n'\
' <td align = "center"><input type = "text" name = "newPosition" id = "newPosition" style = "width: 95%; background-color: #FFF9B4;" value = "' + self._replaceTags(self.propertyLatestPosition) + '" /></td>\n'\
' <td align = "center"><input type = "text" name = "newDepartment" id = "newDepartment" style = "width: 95%; background-color: #FFF9B4;" value = "' + self._replaceTags(self.propertyLatestDepartment) + '" /></td>\n'\
' <td>\n'\
' <table width = "100%" border = "0" cellspacing = "0">\n'\
' <tr>\n'\
' <td>Часы:</td>\n'\
' <td><input type = "text" name = "newStartTimeHour" id = "newStartTimeHour" style = "background-color: #FFF9B4;" size = 2 value = "' + config.default_start_time_hour + '" /></td>\n'\
' </tr>\n'\
' <tr>\n'\
' <td>Минуты: </td>\n'\
' <td><input type = "text" name = "newStartTimeMinute" id = "newStartTimeMinute" style = "background-color: #FFF9B4;" size = 2 value = "' + str(config.default_start_time_minute).zfill(2) + '" /></td>\n'\
' </tr>\n'\
' </table>\n'\
' </td>\n'\
' <td>\n'\
' <table width = "100%" border = "0" cellspacing = "0">\n'\
' <tr>\n'\
' <td>Часы:</td>\n'\
' <td><input type = "text" name = "newEndTimeHour" id = "newEendTimeHour" style = "background-color: #FFF9B4;" size = 2 value = "' + config.default_end_time_hour + '" /></td>\n'\
' </tr>\n'\
' <tr>\n'\
' <td>Минуты: </td>\n'\
' <td><input type = "text" name = "newEndTimeMinute" id = "newEndTimeMinute" style = "background-color: #FFF9B4;" size = 2 value = "' + str(config.default_end_time_minute).zfill(2) + '" /></td>\n'\
' </tr>\n'\
' </table>\n'\
' </td>\n'\
' <td align = "center"><textarea name = "newDescription" id = "newDescription" style = "width: 95%; background-color: #FFF9B4;" rows = "4"></textarea></td>\n'\
' <td align = "center"><input type = text" name = "newChief" id = "newChief" style = "width: 95%; " value = "' + self._replaceTags(self.propertyLatestChief) + '" /></td>\n'\
' </tr>\n'\
' </table>\n'\
' <p><table><tr><td bgcolor = "#FFF9B4" width = "10px"></td><td> - обязательные поля</td></tr></table></p>\n'\
' <p align = "center"><input type="submit" value = "Добавить запись" /></p>\n'\
' </form>\n'
return(output)
def allDays(self):
allDays = self.db.journalListDays()
output = ' <H3><p align = "center">Все журналы:</p></H3>\n'
output += ' <p align = "center">'
if len(allDays) == 0:
output += '<h3>Записи отсутствуют.</H3>\n'
else:
output += ' <table align = "center">\n'
for i in xrange(len(allDays)):
output += ' <tr><td><a href = "index.py?day=%s&month=%s&year=%s">%s.%s.%s</a></td><td>%s</td></tr>\n' % (allDays[i].day, allDays[i].month, allDays[i].year, str(allDays[i].day).zfill(2), str(allDays[i].month).zfill(2), allDays[i].year, self._getWeekDay(allDays[i]))
output += ' </table>\n'
output += ' </p>\n'
return(output)
def footer(self):
output = ' <br><p align = "center"><font color = "gray">&copy; 2010 Сергей Морозов</font></p>\n'
output += '</body>\n'
return(output)
def footerPrint(self):
output = ' <p>\n'\
' <form>\n'\
' <input type = "button" value = "Печать" class = "printButton" onClick = "window.print()">\n'\
' </form>\n'\
' </p>\n'
output += '</body>\n'
return(output)