/mzhelper.py
Python | 419 lines | 395 code | 4 blank | 20 comment | 0 complexity | 57c8e85fca08bf8d71b878465815fa91 MD5 | raw file
- #!/usr/bin/env python
- # -*- coding: utf-8 -*-
- #
- # MediaZona Helper
- # Copyright (C) 2008 by skarrok <skarrok.h@gmail.com>
- #
- # This program is free software: you can redistribute it and/or modify
- # it under the terms of the GNU General Public License as published by
- # the Free Software Foundation, either version 3 of the License, or
- # (at your option) any later version.
- #
- # This program is distributed in the hope that it will be useful,
- # but WITHOUT ANY WARRANTY; without even the implied warranty of
- # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- # GNU General Public License for more details.
- #
- # You should have received a copy of the GNU General Public License
- # along with this program. If not, see <http://www.gnu.org/licenses/>.
- #
- import httplib, getopt, sys, re
- from urlparse import urlparse
- from urllib import urlencode
- #from os import access, R_OK, F_OK
- import os
- import stat
- import mimetypes
- import mimetools
- MZHOST = 'www.mediazona.ru'
- UPLOADHOST = 'xxx.mediazona.ru'
- USERAGENT = 'Opera/9.60 (X11; Linux i686; U; ru) Presto/2.1.1'
- CHUNK_SIZE = 65536
- class MZ:
- def __init__(self, login='', passwd=''):
- self.mzhost = 'mediazona.ru'
- self.mzuploadhost = 'xxx.mediazona.ru'
- self.useragent = 'Opera/9.60 (X11; Linux i686; U; ru) Presto/2.1.1'
- self.chunksize = 65536
- self.headers = {'User-Agent': self.useragent,
- 'Host': self.mzhost,
- 'Accept': '*/*',
- 'Connection': 'Keep-Alive'}
- self.links = []
- self.loginpath = '/serv/login/'
- self.login = login
- self.passwd = passwd
- self.phpsessid = ''
- self.chiper = ''
- self.keypat = re.compile('key="[0-9]{6}"')
- self.votedurl = '/change/exchange/serv/voted/?key='
- self.voteurl = '/change/exchange/serv/vote/?key='
- self.attrpage = ''
- def authorize(self):
- conn = httplib.HTTPConnection(self.mzhost)
- headers = self.headers.copy()
- headers.update({'Content-type': 'application/x-www-form-urlencoded; charser=utf-8',
- 'X-Requested-With': 'XMLHttpRequest',
- 'Referer': 'http://' + self.mzhost})
- params = urlencode({'mode': 'login',
- 'login': self.login,
- 'passwd': self.passwd,
- 'remember': 'on'})
- conn.request('POST', self.loginpath, params, headers)
- resp = conn.getresponse()
- respcookie = resp.getheader('Set-Cookie')
- self.phpsessid = respcookie.split(' ')[0][:-1]
- if self.login and self.passwd:
- try:
- respread = resp.read()
- if respread.split(' ')[3] == '1,':
- self.chiper = respcookie.split(' ')[2][:-1]
- print >> sys.stderr, 'Authorisation: OK'
- else:
- print >> sys.stderr, 'Authorisation: failed!'
- except LookupError.IndexError:
- print 'Authorisation: failed!'
- conn.close()
- def get_temp_link(self, path):
- headers = self.headers.copy()
- conn = httplib.HTTPConnection(self.mzhost)
- conn.request('GET', path, '', headers)
- resp = conn.getresponse()
- dwnpage = resp.read()
- respheaders = resp.getheader('Set-Cookie')
- dwncookie = respheaders.split(' ')[2][:-1]
- conn.close()
- headers.update({'Cookie': dwncookie,
- 'Referer': self.mzhost + path})
- conn = httplib.HTTPConnection(self.mzhost)
- conn.request('GET', path, '', headers)
- resp = conn.getresponse()
- conn.close()
- headers = {}
- return resp.getheader('location')+'\n'
- def get_temp_links(self):
- return map(self.get_temp_link, self.links)
- def set_rating_up(self, path):
- headers = self.headers.copy()
- headers.update({'X-Requested-With': 'XMLHttpRequest',
- 'Cookie': self.phpsessid + '; ' + self.chiper,
- 'Referer': 'http://' + self.mzhost + path})
- conn = httplib.HTTPConnection(self.mzhost)
- conn.request('GET', self.votedurl + path[21:-1], '', headers)
- dwnpage = conn.getresponse().read()
- conn.close()
- res = self.keypat.search(dwnpage)
- if not res:
- print >> sys.stderr, '\tSet Rating: failed!'
- return
- key=dwnpage[res.start():res.end()][5:-1]
- del dwnpage
- if key.isdigit():
- conn = httplib.HTTPConnection(self.mzhost)
- conn.request('GET', self.voteurl + key + '&vote=1', '', headers)
- tmp = conn.getresponse().read().strip()[4:-5].split(',')[0::2]
- if tmp[0].split(' ')[1] == '1':
- print >> sys.stderr, '\tSet Rating: OK, new', tmp[1]
- conn.close()
- def check_link(self, path):
- conn = httplib.HTTPConnection(self.mzhost)
- conn.request('GET', path, '', self.headers)
- self.attrpage = conn.getresponse().read()
- conn.close()
- #if self.attrpage.find('????????????? ???? ?? ??????') != -1:
- if '????????????? ???? ?? ??????' in self.attrpage:
- print >> sys.stderr, 'File not found:', 'http://mediazona.ru/' + path
- self.attrpage = ''
- return (False,)
- return True, self.get_attr_link()
- def check_links(self):
- self.links = filter(self.check_link, self.links)
- def set_links(self, links):
- self.links = map(lambda x: urlparse(x).path, links)
- def get_links(self):
- return map(lambda x: 'http://' + self.mzhost + x, self.links)
- def get_paths(self):
- return self.links
- def get_attr_link(self):
- return parsepage(self.attrpage, '<dt>????????:</dt><dd>', '<'), parsepage(self.attrpage, '<dt>??????:</dt><dd>', '<')
- def parsepage(where, what, stopchar):
- tmp = where.find(what) + len(what)
- i = tmp - 1
- for x in where[tmp:]:
- i += 1
- if x == stopchar:
- return where[tmp:i]
- # for i in xrange(len(where)):
- # if where[i] == '<':
- # print >> sys.stderr, 'File:', where[:i]
- # break
- # for i, c in enumerate(where):
- # if c == '<':
- # print >> sys.stderr, 'File:', where[:i]
- class progressBar:
- ''' Creates a text-based progress bar. Call the object with the `print'
- command to see the progress bar, which looks something like this:
- [=======> 22% ]
- You may specify the progress bar's width, min and max values on init.
- '''
- def __init__(self, minValue = 0, maxValue = 100, totalWidth=80):
- self.progBar = '[]'
- self.oldprogBar = ''
- self.min = minValue
- self.max = maxValue
- self.span = maxValue - minValue
- self.width = totalWidth
- self.amount = 0
- self.updateAmount(0)
- def updateAmount(self, newAmount = 0):
- if newAmount < self.min: newAmount = self.min
- if newAmount > self.max: newAmount = self.max
- self.amount = newAmount
- diffFromMin = float(self.amount - self.min)
- if self.span == 0:
- percentDone = 0
- else:
- percentDone = (diffFromMin / float(self.span)) * 100.0
- percentDone = int(round(percentDone))
- allFull = self.width - 2
- numHashes = (percentDone / 100.0) * allFull
- numHashes = int(round(numHashes))
- if numHashes == 0:
- self.progBar = '[>%s]' % (' '*(allFull-1))
- elif numHashes == allFull:
- self.progBar = '[%s]' % ('='*allFull)
- else:
- self.progBar = '[%s>%s]' % ('='*(numHashes-1),
- ' '*(allFull-numHashes))
- percentPlace = (len(self.progBar) / 2) - len(str(percentDone))
- percentString = str(percentDone) + '%'
- self.progBar = ''.join([self.progBar[0:percentPlace], percentString,
- self.progBar[percentPlace+len(percentString):]
- ])
- def __str__(self):
- return str(self.progBar)
- def __call__(self, value):
- #if self.progBar != self.oldprogBar:
- #self.oldprogBar = self.progBar
- print '\r',
- self.updateAmount(value)
- sys.stdout.write(str(self))
- sys.stdout.flush()
- def get_content_type(filename):
- return mimetypes.guess_type(filename)[0] or 'application/octet-stream'
- def send_data(v_vars, v_files, boundary, sock=None):
- l = 0
- for (k, v) in v_vars:
- buffer=''
- buffer += '--%s\r\n' % boundary
- buffer += 'Content-Disposition: form-data; name="%s"\r\n' % k
- buffer += '\r\n'
- buffer += v + '\r\n'
- if sock:
- sock.send(buffer)
- l += len(buffer)
- for (k, v) in v_files:
- fd = v
- file_size = os.fstat(fd.fileno())[stat.ST_SIZE]
- nchunks = int(file_size/CHUNK_SIZE)
- pbar = progressBar(0, nchunks, 77)
- name = fd.name.split('/')[-1]
- if isinstance(name, unicode):
- name = name.encode('UTF-8')
- buffer=''
- buffer += '--%s\r\n' % boundary
- buffer += 'Content-Disposition: form-data; name="%s"; filename="%s"\r\n' \
- % (k, name)
- buffer += 'Content-Type: %s\r\n' % get_content_type(name)
- buffer += 'Content-Length: %s\r\n' % file_size
- buffer += '\r\n'
- l += len(buffer)
- if sock:
- sock.send(buffer)
- if hasattr(fd, 'seek'):
- fd.seek(0)
- i = 0
- pbar(i)
- while True:
- chunk = fd.read(CHUNK_SIZE)
- if not chunk: break
- sock.send(chunk)
- pbar(i)
- i += 1
- l += file_size
- buffer='\r\n'
- buffer += '--%s--\r\n' % boundary
- buffer += '\r\n'
- if sock:
- sock.send(buffer)
- l += len(buffer)
- return l
- def uploadfile(file, chiper):
- headers = {'User-Agent': USERAGENT,
- 'Host': MZHOST,
- 'Accept': '*/*',
- 'Connection': 'Keep-Alive',
- 'Cookie': chiper}
- conn = httplib.HTTPConnection(MZHOST)
- conn.request('GET', '/change/exchange/upload/', '', headers)
- dwnpage = conn.getresponse().read()
- conn.close()
- tustas_identifier = parsepage(dwnpage, 'TUSTAS_IDENTIFIER" value="', '"')
- max_file_size = parsepage(dwnpage, 'MAX_FILE_SIZE" value="', '"')
- conn = httplib.HTTPConnection(MZHOST)
- conn.request('GET', '/change/exchange/serv/addupload-new/', '', headers)
- guid = conn.getresponse().read().split(',')[0][11:-1]
- conn.close()
- conn = httplib.HTTPConnection(UPLOADHOST)
- conn.putrequest('POST', '/uploader/?idsx=' + tustas_identifier, True)
- vars = [('TUSTAS_IDENTIFIER', tustas_identifier),
- ('MAX_FILE_SIZE', max_file_size),
- ('part', '6'),
- ('folder', ''),
- ('descr', 'tz'),
- ('tags', 'mz'),
- ('action', 'upload'),
- ('guid', guid)]
- files = [('filenames[]', open(file))]
- boundary = mimetools.choose_boundary()
- l = send_data(vars, files, boundary)
- conn.putheader('Content-Type', 'multipart/form-data; boundary=' + boundary)
- conn.putheader('Content-length', str(l))
- conn.putheader('Host', UPLOADHOST)
- conn.putheader('Referer', 'mediazona.ru/change/exchange/upload/')
- conn.endheaders()
- l = send_data(vars, files, boundary, conn)
- status = conn.getresponse().read()
- status = status.split(',')[0].split(' ')[3][1:-1]
- conn.close()
- if status == 'OK': return True
- return False
- def usage():
- print sys.argv[0] + ' V0.04 MediaZona Helper'
- print 'Usage: ' + sys.argv[0] + ' [OPTIONS]'
- print '\tWrite me!'
- def main():
- try:
- opts, args = getopt.getopt(sys.argv[1:], 'hvri:o:l:p:', ['help',
- 'verbose',
- 'rate',
- 'input-file=',
- 'output-file=',
- 'login=',
- 'passwd='])
- except getopt.GetoptError, msg:
- print >> sys.stderr, 'Getopt Error:', msg
- usage()
- sys.exit(2)
- outputfile = False
- inputfile = False
- verbose = False
- rate = False
- login = False
- passwd = False
- upload = False
- for o, a in opts:
- if o in ('-v', '--verbose'):
- verbose = True
- if o in ('-h', '--help'):
- usage()
- sys.exit()
- if o in ('-o', '--output-file'):
- outputfile = a
- if o in ('-i', '--input-file'):
- inputfile = a
- if o in ('-r', '--rate'):
- rate = True
- if o in ('-l', '--login'):
- login = a
- if o in ('-p', '--passwd'):
- passwd = a
- try:
- if inputfile:
- urllist = open(inputfile, 'r')
- else:
- usage()
- sys.exit()
- if outputfile:
- workfile = open(outputfile, 'w')
- else:
- workfile = sys.stdout
- mz = MZ(login, passwd)
- mz.authorize()
- links = filter(lambda x: bool(x), [line.strip() for line in urllist.readlines()])
- mz.set_links(links)
- for path in mz.get_paths():
- tmp = mz.check_link(path)
- if tmp[0]:
- if rate and login and passwd:
- print >> sys.stderr, 'File:', tmp[1][0]
- print >> sys.stderr, '\tSize:', tmp[1][1]
- mz.set_rating_up(path)
- elif not rate and login and passwd:
- print >> sys.stderr, 'File:', tmp[1][0]
- print >> sys.stderr, '\tSize:', tmp[1][1]
- mz.set_rating_up(path)
- templink = mz.get_temp_link(path)
- #os.popen("wget --content-dispositioin -c %s" % templink)
- workfile.write(templink)
- else:
- print >> sys.stderr, 'File:', tmp[1][0]
- print >> sys.stderr, '\tSize:', tmp[1][1]
- templink = mz.get_temp_link(path)
- #os.popen("wget --content-dispositioin -c %s" % templink)
- workfile.write(templink)
- urllist.close()
- workfile.close()
- print >> sys.stderr, 'Done!'
- except IOError, msg:
- print >> sys.stderr, 'IOError', msg
- sys.exit(2)
- except httplib.HTTPException, msg:
- print >> sys.stderr, 'HTTP Error', msg
- sys.exit(2)
- except KeyboardInterrupt:
- print >> sys.stderr, '\nManually stopped!'
- sys.exit(2)
- if __name__ == '__main__':
- main()