Moved to Git repo from PST server
This commit is contained in:
commit
e679734d9f
|
@ -0,0 +1,146 @@
|
||||||
|
#!/usr/bin/env python
|
||||||
|
import string
|
||||||
|
from copy import deepcopy
|
||||||
|
class ipv4addr():
|
||||||
|
"""Class for IPv4 address manipulation.\n\n"""\
|
||||||
|
"""Initialization:\n"""\
|
||||||
|
"""\tfrom addr import ipv4addr\n"""\
|
||||||
|
"""\tmyAddress = ipv4addr(str, str) # for example: myAddress = ipv4addr("192.168.0.1", "255.255.255.0")\n"""\
|
||||||
|
"""or:\n"""\
|
||||||
|
"""\tmyAddress = ipv4addr(str, int) # for example: myAddress = ipv4addr("192.168.0.1", 24)\n\n"""\
|
||||||
|
"""Functions:\n"""\
|
||||||
|
"""\tnetwork() # returns subnet address\n"""\
|
||||||
|
"""\tinMyNet(ipv4addr) # returns True or False\n"""\
|
||||||
|
"""\t # True - if the specified ipv4addr object belongs to the network\n"""\
|
||||||
|
"""\t # False - if the specified ipv4addr object not belongs to the network\n\n"""\
|
||||||
|
"""Variables:\n"""\
|
||||||
|
"""\tcidr # Subnet mask in cidr notation\n\n"""\
|
||||||
|
"""ipv4addr class object is an iterator.\n"""\
|
||||||
|
"""Examples of use ipv4addr object as iterator:\n"""\
|
||||||
|
"""\t>>> myAddress = ipv4addr("192.168.0.1", 24)\n"""\
|
||||||
|
"""\t>>> print(myAddress[0])\n"""\
|
||||||
|
"""\t192\n"""\
|
||||||
|
"""\t>>> print(myAddress[1])\n"""\
|
||||||
|
"""\t168\n"""\
|
||||||
|
"""\t>>> myAddress[2] = 1\n"""\
|
||||||
|
"""\t>>> print(myAddress)\n"""\
|
||||||
|
"""\t192.168.1.1/24\n"""
|
||||||
|
|
||||||
|
def __init__(self, addrstr = '0.0.0.0', netmask = 32):
|
||||||
|
octets = addrstr.split('.')
|
||||||
|
self._addr = None
|
||||||
|
self._setAddr([int(octets[0]),
|
||||||
|
int(octets[1]),
|
||||||
|
int(octets[2]),
|
||||||
|
int(octets[3])])
|
||||||
|
if type(netmask) == str:
|
||||||
|
self.cidr = self._strToMask(netmask)
|
||||||
|
else:
|
||||||
|
self.cidr = netmask
|
||||||
|
self.printMask = True
|
||||||
|
|
||||||
|
def _strToMask(self, netmask):
|
||||||
|
octets = netmask.split('.')
|
||||||
|
cidr = 0
|
||||||
|
for i in octets:
|
||||||
|
octet = int(i)
|
||||||
|
if octet > 0:
|
||||||
|
while((octet & 128) / 128):
|
||||||
|
cidr += 1
|
||||||
|
octet<<=1
|
||||||
|
return(cidr)
|
||||||
|
|
||||||
|
def _setAddr(self, octets):
|
||||||
|
self._addr = octets[0] * pow(256, 3) + octets[1] * pow(256, 2) + octets[2] * pow(256, 1) + octets[3] * pow(256, 0)
|
||||||
|
|
||||||
|
def _getOctet(self, key):
|
||||||
|
octet = self._addr
|
||||||
|
for i in xrange(3 - key):
|
||||||
|
octet >>= 8
|
||||||
|
octet = octet % 256
|
||||||
|
return(octet)
|
||||||
|
|
||||||
|
def _setOctet(self, key, value):
|
||||||
|
octets=[]
|
||||||
|
for i in xrange(4):
|
||||||
|
if i == key:
|
||||||
|
octets.append(value)
|
||||||
|
else:
|
||||||
|
octets.append(self._getOctet(i))
|
||||||
|
self._setAddr(octets)
|
||||||
|
def _mask(self):
|
||||||
|
mask = 0
|
||||||
|
for i in xrange(self.cidr):
|
||||||
|
mask = (mask << 1) + 1
|
||||||
|
for i in xrange(32-self.cidr):
|
||||||
|
mask <<= 1
|
||||||
|
return(mask)
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
result = str(self._getOctet(0)) + '.' + str(self._getOctet(1)) + '.' + str(self._getOctet(2)) + '.' + str(self._getOctet(3))
|
||||||
|
if self.printMask == True:
|
||||||
|
result+='/%s' % self.cidr
|
||||||
|
return(result)
|
||||||
|
|
||||||
|
def __repr__(self):
|
||||||
|
return(self.__str__())
|
||||||
|
|
||||||
|
def __iter__(self):
|
||||||
|
return(self)
|
||||||
|
|
||||||
|
def __getitem__(self, key):
|
||||||
|
return(self._getOctet(key))
|
||||||
|
|
||||||
|
def __setitem__(self, key, value):
|
||||||
|
self._setOctet(key, value)
|
||||||
|
|
||||||
|
def __len__(self):
|
||||||
|
return(4)
|
||||||
|
|
||||||
|
def __lt__(self, other):
|
||||||
|
if self._addr < other._addr:
|
||||||
|
return True
|
||||||
|
else:
|
||||||
|
return False
|
||||||
|
|
||||||
|
def __le__(self, other):
|
||||||
|
if self._addr <= other._addr:
|
||||||
|
return True
|
||||||
|
else:
|
||||||
|
return False
|
||||||
|
|
||||||
|
def __eq__(self, other):
|
||||||
|
if self._addr == other._addr:
|
||||||
|
return True
|
||||||
|
else:
|
||||||
|
return False
|
||||||
|
|
||||||
|
def __ne__(self, other):
|
||||||
|
if self._addr != other._addr:
|
||||||
|
return True
|
||||||
|
else:
|
||||||
|
return False
|
||||||
|
|
||||||
|
def __gt__(self, other):
|
||||||
|
if self._addr > other._addr:
|
||||||
|
return True
|
||||||
|
else:
|
||||||
|
return False
|
||||||
|
|
||||||
|
def __ge__(self, other):
|
||||||
|
if self._addr >= other._addr:
|
||||||
|
return True
|
||||||
|
else:
|
||||||
|
return False
|
||||||
|
|
||||||
|
def network(self):
|
||||||
|
network = deepcopy(self)
|
||||||
|
network._addr = self._addr & self._mask()
|
||||||
|
network.cidr = self.cidr
|
||||||
|
return(network)
|
||||||
|
|
||||||
|
def inMyNet(self, address):
|
||||||
|
if (address._addr & self._mask()) == self.network()._addr:
|
||||||
|
return(True)
|
||||||
|
else:
|
||||||
|
return(False)
|
|
@ -0,0 +1,314 @@
|
||||||
|
#!/usr/bin/python
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
import cgi, cgitb, tempfile, commands, os, smtplib, sys, string
|
||||||
|
from random import Random
|
||||||
|
from email.mime.text import MIMEText
|
||||||
|
from addr import ipv4addr
|
||||||
|
|
||||||
|
# Debug:
|
||||||
|
cgitb.enable()
|
||||||
|
|
||||||
|
# Settings
|
||||||
|
storage = "/var/www/download.pstgroup.ru/storage"
|
||||||
|
passwordLength = 8
|
||||||
|
serverAdmin = "webmaster@pstgroup.ru"
|
||||||
|
proto = "http"
|
||||||
|
filesUri = ""
|
||||||
|
myNetworks = [
|
||||||
|
ipv4addr("82.140.81.64","255.255.255.248"),
|
||||||
|
ipv4addr("84.204.173.0",24),
|
||||||
|
ipv4addr("192.168.0.0",24),
|
||||||
|
ipv4addr("192.168.4.0",24),
|
||||||
|
ipv4addr("193.106.109.129",32),
|
||||||
|
ipv4addr("193.106.109.130",32),
|
||||||
|
ipv4addr("193.106.109.131",32)
|
||||||
|
]
|
||||||
|
myDomains = [
|
||||||
|
"pstgroup.ru",
|
||||||
|
"ust-luga-customs.ru",
|
||||||
|
"myoffice.spb.ru",
|
||||||
|
"iptgroup.net",
|
||||||
|
"ldshouse.ru"
|
||||||
|
]
|
||||||
|
internalExampleAddress = "pupkin@pstgroup.ru"
|
||||||
|
externalExampleAddress = "putin@kremlin.ru"
|
||||||
|
|
||||||
|
|
||||||
|
changelog = [
|
||||||
|
'29.08.2011 - Добавлена возможность отправки файлов внешними пользователями',
|
||||||
|
'25.04.2011 - Устранена проблема перекодировки имени файла, возникающая в случае наличия в нём некоторых символов Unicode',
|
||||||
|
'23.07.2010 - Устранены множественные проблемы с перекодировкой имени файла',
|
||||||
|
'01.07.2010 - Оптимизация кода',
|
||||||
|
'30.06.2010 - Косметические изменения',
|
||||||
|
'30.06.2010 - Добавлено отображение списка изменений',
|
||||||
|
'30.06.2010 - Исправлена проблема, возникающая из-за ошибки в некоторых браузерах и преводящая к некорректному имени файла',
|
||||||
|
'24.06.2010 - Исправлена ошибка перекодировки, возникающая в случае, если в имени файла содержится символ \"ъ\"'
|
||||||
|
]
|
||||||
|
|
||||||
|
urlBase = proto + '://' + os.environ.get('SERVER_NAME') + filesUri
|
||||||
|
scriptUrl = proto + '://' + os.environ.get('SERVER_NAME') + os.environ.get('REQUEST_URI')
|
||||||
|
client = ipv4addr(os.environ['REMOTE_ADDR'])
|
||||||
|
|
||||||
|
conversion = {
|
||||||
|
u'а' : 'a',
|
||||||
|
u'б' : 'b',
|
||||||
|
u'в' : 'v',
|
||||||
|
u'г' : 'g',
|
||||||
|
u'д' : 'd',
|
||||||
|
u'е' : 'e',
|
||||||
|
u'ё' : 'e',
|
||||||
|
u'ж' : 'zh',
|
||||||
|
u'з' : 'z',
|
||||||
|
u'и' : 'i',
|
||||||
|
u'й' : 'j',
|
||||||
|
u'к' : 'k',
|
||||||
|
u'л' : 'l',
|
||||||
|
u'м' : 'm',
|
||||||
|
u'н' : 'n',
|
||||||
|
u'о' : 'o',
|
||||||
|
u'п' : 'p',
|
||||||
|
u'р' : 'r',
|
||||||
|
u'с' : 's',
|
||||||
|
u'т' : 't',
|
||||||
|
u'у' : 'u',
|
||||||
|
u'ф' : 'f',
|
||||||
|
u'х' : 'h',
|
||||||
|
u'ц' : 'c',
|
||||||
|
u'ч' : 'ch',
|
||||||
|
u'ш' : 'sh',
|
||||||
|
u'щ' : 'sch',
|
||||||
|
u'ъ' : "'",
|
||||||
|
u'ы' : 'y',
|
||||||
|
u'ь' : "'",
|
||||||
|
u'э' : 'e',
|
||||||
|
u'ю' : 'ju',
|
||||||
|
u'я' : 'ja',
|
||||||
|
u'А' : 'A',
|
||||||
|
u'Б' : 'B',
|
||||||
|
u'В' : 'V',
|
||||||
|
u'Г' : 'G',
|
||||||
|
u'Д' : 'D',
|
||||||
|
u'Е' : 'E',
|
||||||
|
u'Ё' : 'E',
|
||||||
|
u'Ж' : 'ZH',
|
||||||
|
u'З' : 'Z',
|
||||||
|
u'И' : 'I',
|
||||||
|
u'Й' : 'J',
|
||||||
|
u'К' : 'K',
|
||||||
|
u'Л' : 'L',
|
||||||
|
u'М' : 'M',
|
||||||
|
u'Н' : 'N',
|
||||||
|
u'О' : 'O',
|
||||||
|
u'П' : 'P',
|
||||||
|
u'Р' : 'R',
|
||||||
|
u'С' : 'S',
|
||||||
|
u'Т' : 'T',
|
||||||
|
u'У' : 'U',
|
||||||
|
u'Ф' : 'F',
|
||||||
|
u'Х' : 'H',
|
||||||
|
u'Ц' : 'C',
|
||||||
|
u'Ч' : 'CH',
|
||||||
|
u'Ш' : 'SH',
|
||||||
|
u'Щ' : 'SCH',
|
||||||
|
u'Ъ' : "'",
|
||||||
|
u'Ы' : 'Y',
|
||||||
|
u'Ь' : "'",
|
||||||
|
u'Э' : 'E',
|
||||||
|
u'Ю' : 'JU',
|
||||||
|
u'Я' : 'JA',
|
||||||
|
}
|
||||||
|
|
||||||
|
clientIsInternal = False
|
||||||
|
for net in myNetworks:
|
||||||
|
if net.inMyNet(client):
|
||||||
|
clientIsInternal = True
|
||||||
|
|
||||||
|
def domainIsAllowed(mailAddress):
|
||||||
|
checkingDomain = mailAddress.split("@")[-1]
|
||||||
|
result = False
|
||||||
|
for domain in myDomains:
|
||||||
|
if checkingDomain == domain:
|
||||||
|
result = True
|
||||||
|
return(result)
|
||||||
|
|
||||||
|
def cyr2lat(s):
|
||||||
|
retval = ""
|
||||||
|
c = ''
|
||||||
|
for c in s:
|
||||||
|
try:
|
||||||
|
c = conversion[c]
|
||||||
|
except KeyError:
|
||||||
|
pass
|
||||||
|
try:
|
||||||
|
c = str(unicode(c))
|
||||||
|
except UnicodeEncodeError:
|
||||||
|
c = '.'
|
||||||
|
retval = retval + c
|
||||||
|
return retval
|
||||||
|
|
||||||
|
def printHeader():
|
||||||
|
print 'Content-type: text/html\n'
|
||||||
|
print '<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">'
|
||||||
|
print '<html lang="ru">'
|
||||||
|
print '<head>'
|
||||||
|
print ' <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />'
|
||||||
|
print ' <title> PST File Exchange</title>'
|
||||||
|
print '</head>'
|
||||||
|
print '<body>'
|
||||||
|
print '<font face="Calibri, Arial, Verdana, Sans">'
|
||||||
|
print ' <H1><table width="100%" bgcolor="#336299"><tr><td><p align="center"><font color="white">Файлообменный ресурс PST Group</font></p></td></tr></table></H1>'
|
||||||
|
|
||||||
|
def printFooter():
|
||||||
|
print '<br><br><p align="center"><font color="gray">© 2010 Сергей Морозов</font></p>'
|
||||||
|
print '</font>'
|
||||||
|
print '</body>'
|
||||||
|
print '</html>'
|
||||||
|
|
||||||
|
def printForm():
|
||||||
|
print ' <form method="post" enctype="multipart/form-data" action="' + scriptUrl + '">'
|
||||||
|
print ' <p>'
|
||||||
|
print ' Введите <b>ваш</b> e-mail:<br>'
|
||||||
|
print ' <input type="text" name="uploader_email" id="uploader_email" size="30">'
|
||||||
|
if clientIsInternal:
|
||||||
|
print ' <font color="gray"><i>например: %s</i></font>' % internalExampleAddress
|
||||||
|
else:
|
||||||
|
print ' <font color="gray"><i>например: %s</i></font>' % externalExampleAddress
|
||||||
|
print ' </p>'
|
||||||
|
print ' <p>'
|
||||||
|
print ' Введите e-mail <b>получателя</b>:<br>'
|
||||||
|
print ' <input type="text" name="downloader_email" id="downloader_email" size="30">'
|
||||||
|
if clientIsInternal:
|
||||||
|
print ' <font color="gray"><i>например: %s</i></font>' % externalExampleAddress
|
||||||
|
else:
|
||||||
|
print ' <font color="gray"><i>например: %s</i></font>' % internalExampleAddress
|
||||||
|
print ' </p>'
|
||||||
|
print ' <p>'
|
||||||
|
print ' Выберите файл:<br>'
|
||||||
|
print ' <input type="file" name="datafile" id="datafile" size="40">'
|
||||||
|
print ' </p>'
|
||||||
|
print ' <input type="submit" value="Отправить">'
|
||||||
|
print ' </form>'
|
||||||
|
print ' <br><hr>'
|
||||||
|
print ' <p>'
|
||||||
|
print ' Обращаем ваше внимание:'
|
||||||
|
print ' <ul>'
|
||||||
|
print ' <li>Русские имена файлов автоматически конвертируются в транслит;</li>'
|
||||||
|
print ' <li>На данный момент автоматическая проверка корректности e-mail адресов не производится, по-этому внимательно проверяйте указываемые вами данные;</li>'
|
||||||
|
print ' <li>Все поля являются обязательными для заполнения;</li>'
|
||||||
|
print ' <li>При больших объёмах файлов процесс выгрузки может занять достаточно длительное время, настоятельно просим не закрывать окно и дождаться окончания процесса.</li>'
|
||||||
|
print ' </ul>'
|
||||||
|
print ' </p>'
|
||||||
|
print ' <br>'
|
||||||
|
|
||||||
|
def printChangeLog():
|
||||||
|
print ' <font color="gray">'
|
||||||
|
print ' <h4>Список изменений:</h4>'
|
||||||
|
print ' <i>'
|
||||||
|
print ' <ul>'
|
||||||
|
for i in xrange(len(changelog)-1):
|
||||||
|
print ' <li>' + changelog[i] + ';</li>'
|
||||||
|
print ' <li>' + changelog[i+1] + '.</li>'
|
||||||
|
print ' </ul>'
|
||||||
|
print ' </i>'
|
||||||
|
print ' </font>'
|
||||||
|
|
||||||
|
def fbuffer(f, chunk_size=10000):
|
||||||
|
while True:
|
||||||
|
chunk = f.read(chunk_size)
|
||||||
|
if not chunk: break
|
||||||
|
yield chunk
|
||||||
|
|
||||||
|
def runCommand(cmd):
|
||||||
|
status, text = commands.getstatusoutput(cmd)
|
||||||
|
exit_code = status >> 8 # higi byte
|
||||||
|
signal_num = status %256 # low byte
|
||||||
|
|
||||||
|
def pwgen(pw_length):
|
||||||
|
rng = Random()
|
||||||
|
pw = ''
|
||||||
|
allchars = '1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'
|
||||||
|
for i in range(pw_length):
|
||||||
|
pw = pw + rng.choice(allchars)
|
||||||
|
return pw
|
||||||
|
|
||||||
|
def fileBaseName(filename):
|
||||||
|
basename = string.split(filename, '/')[-1]
|
||||||
|
basename = string.split(basename, '\\')[-1]
|
||||||
|
return basename
|
||||||
|
|
||||||
|
form = cgi.FieldStorage()
|
||||||
|
if not form:
|
||||||
|
printHeader()
|
||||||
|
printForm()
|
||||||
|
printChangeLog()
|
||||||
|
printFooter()
|
||||||
|
else:
|
||||||
|
if form.has_key("uploader_email") and form.has_key("downloader_email") and not clientIsInternal and not domainIsAllowed(form["downloader_email"].value):
|
||||||
|
printHeader()
|
||||||
|
print ' <table bgcolor="#FFF9B4" width="100%"><tr><td align="center"><font color="red">Вам запрещена отправка файлов на данный адрес.</font></td></tr></table>'
|
||||||
|
printForm()
|
||||||
|
printChangeLog()
|
||||||
|
printFooter()
|
||||||
|
elif form.has_key("datafile") and form.has_key("uploader_email") and form.has_key("downloader_email") and form["datafile"].filename != '' and form["uploader_email"].value != '' and form["downloader_email"].value != '':
|
||||||
|
datafile = form["datafile"]
|
||||||
|
uploader_email = form["uploader_email"].value
|
||||||
|
downloader_email = form["downloader_email"].value
|
||||||
|
filename = fileBaseName(cyr2lat(unicode(datafile.filename,"UTF-8")))
|
||||||
|
if filename[0] == '.':
|
||||||
|
filename = str(unicode('_%s' % filename))
|
||||||
|
filepath = storage + '/' + filename
|
||||||
|
file = open(filepath, 'wb')
|
||||||
|
for chunk in fbuffer(datafile.file):
|
||||||
|
file.write(chunk)
|
||||||
|
file.close()
|
||||||
|
password = pwgen(passwordLength)
|
||||||
|
printHeader()
|
||||||
|
print '<p align="center">Файл успешно загружен на сервер, и запущен процесс его упаковки в архив.</a>'
|
||||||
|
print '<p align="center">По завершении процесса вам и получателю файла будут отправлены письма с дальнейшими инструкциями</p>'
|
||||||
|
printFooter()
|
||||||
|
sys.stdout.flush()
|
||||||
|
pid = os.fork()
|
||||||
|
if pid == 0:
|
||||||
|
os.setsid()
|
||||||
|
fw = open('/dev/null','w')
|
||||||
|
#fw = open('/tmp/download.html','w')
|
||||||
|
os.dup2(fw.fileno(),1)
|
||||||
|
os.dup2(fw.fileno(),2)
|
||||||
|
runCommand('zip -j -X -P ' + password + ' "' + filepath + '.zip" "' + filepath + '"')
|
||||||
|
os.remove(filepath)
|
||||||
|
url = urlBase + '/' + filename + '.zip'
|
||||||
|
msgbody_downloader = 'Здравствуйте.<br><br>\n'\
|
||||||
|
'Пользователь <a href=\"mailto:%s\">%s</a> разместил для вас файл <b>%s</b>.<br>\n'\
|
||||||
|
'Вы можете скачать этот файл по адресу <a href=\"%s\">%s</a>.<br>\n'\
|
||||||
|
'Пароль для распаковки файла: <b>%s</b>' % (uploader_email, uploader_email, filename, url, url, password)
|
||||||
|
msgbody_uploader = 'Здравствуйте.<br><br>\n'\
|
||||||
|
'Ваш файл <b>%s</b> был успешно обработан и запакован.<br>\n'\
|
||||||
|
'Файл доступен по адресу <a href="%s">%s</a>.<br>\n'\
|
||||||
|
'Пароль для распаковки файла: <b>%s</b><br>\n'\
|
||||||
|
'Получателю файла было отправлено письмо следующего содержания:<br>\n'\
|
||||||
|
'<blockquote><table bgcolor="lightgray" border="0" cellpadding="10"><tr><td>%s</td></tr></table></blockquote>' % (filename, url, url, password, msgbody_downloader)
|
||||||
|
msg_downloader = MIMEText(msgbody_downloader, 'html', 'utf-8')
|
||||||
|
msg_uploader = MIMEText(msgbody_uploader, 'html', 'utf-8')
|
||||||
|
#msg_downloader.set_charset('utf-8')
|
||||||
|
#msg_uploader.set_charset('utf-8')
|
||||||
|
msg_downloader['Subject'] = 'PST File Exchange'
|
||||||
|
msg_uploader['Subject'] = 'PST File Exchange'
|
||||||
|
msg_downloader['From'] = uploader_email
|
||||||
|
msg_uploader['From'] = serverAdmin
|
||||||
|
msg_downloader['To'] = downloader_email
|
||||||
|
msg_uploader['To'] = uploader_email
|
||||||
|
s = smtplib.SMTP()
|
||||||
|
s.connect()
|
||||||
|
s.sendmail(msg_downloader['From'], msg_downloader['To'], msg_downloader.as_string())
|
||||||
|
s.sendmail(msg_uploader['From'], msg_uploader['To'], msg_uploader.as_string())
|
||||||
|
s.quit
|
||||||
|
else:
|
||||||
|
sys.exit(0)
|
||||||
|
else:
|
||||||
|
printHeader()
|
||||||
|
print ' <table bgcolor="#FFF9B4" width="100%"><tr><td align="center"><font color="red">Будьте внимательны! Все поля обязательны для заполнения!</font></td></tr></table>'
|
||||||
|
printForm()
|
||||||
|
printChangeLog()
|
||||||
|
printFooter()
|
||||||
|
|
Loading…
Reference in New Issue