businesstrips/include/webInterface.py

330 lines
21 KiB
Python
Raw Normal View History

2014-04-18 23:43:54 +04:00
#!/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 += ' <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 += ' <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 Сергей Морозов, ОАО &laquo;Промышленно - строительное товарищество&raquo;</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)