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