Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- # -*- coding: cp1251 -*-
- import logging
- from subprocess import Popen, PIPE
- from time import sleep
- def main():
- logging.getLogger('MyLogger').debug('main app started')
- usage = """usage: %prog -c PATH -r REVISION --host user@host -d start_dir -p password
- Use to upload website from repository
- """
- from optparse import OptionParser
- parser = OptionParser(usage=usage)
- parser.add_option("-c", "--copy", dest="copy", action = "store",
- help = "PATH of local working copy", type="string")
- parser.add_option("--host", dest="host",
- help = "host to connect to", type="string")
- parser.add_option("-r", "--revision", dest="revision",
- help = "override revision number from which to update sources", type="string")
- parser.add_option("-p", "--password", dest="password",
- help = "password to use when connecting to ftp", type="string")
- parser.add_option("-d", "--directory", dest="directory",
- help = "directory, relative to ftp root, in which project lies", type="string")
- (options, args) = parser.parse_args()
- if None == options.copy:
- print("-c option is required")
- logging.getLogger('MyLogger').info('omitted -c option')
- return 2
- if None == options.host:
- print("--host option is required")
- logging.getLogger('MyLogger').info('omitted --host option')
- return 2
- if None == options.directory:
- print("-d option is required")
- logging.getLogger('MyLogger').info('omitted -d option')
- return 2
- if "/" == options.directory:
- print("root dir is not allowed!")
- logging.getLogger('MyLogger').warning('trying access root / dir is not allowed, please use subfolders')
- return 2
- tmp = {'copy': options.copy, 'revision': options.revision, 'host': options.host, 'directory': options.directory}
- logging.getLogger('MyLogger').debug('called with these options: '+' '.join('-%s %s' % (k, v) for k, v in tmp.items()))
- # here I MUST check if network is reachable
- port = 21
- username, host = options.host.split('@',1)
- if False == is_server_reachable(host, port): #checking FTP port 21
- print('ftp service on specified host is not available')
- logging.getLogger('MyLogger').critical('host '+options.host+':'+str(port)+' was unreachable')
- return 1
- base_revision = 0
- head_revision = 0
- url = ''
- path = options.copy#'C:\Program Files\CruiseControl\projects\email_sender_server\source'
- # here I must take revision number into consideration
- if None == options.revision:
- cmd = 'svn info -r BASE "' + path + '"'
- logging.getLogger('MyLogger').debug(cmd)
- svn = Popen(cmd, stdout = PIPE)
- i = 0
- for line in svn.stdout.readlines():
- i = i + 1
- if i < 9:
- l = line[:-2].decode('cp1251').split(': ',1)
- if l[0] == 'Revision': base_revision = l[1]
- svn.wait()
- else:
- base_revision = options.revision
- cmd = 'svn info -r HEAD "' + path + '"'
- logging.getLogger('MyLogger').debug(cmd)
- svn = Popen(cmd, stdout = PIPE)
- i = 0
- for line in svn.stdout.readlines():
- i = i + 1
- if i < 9:
- l = line[:-2].decode('cp1251').split(': ',1)
- if l[0] == 'Revision': head_revision = l[1]
- if l[0] == 'URL': url = l[1]
- info = {'head': head_revision, 'base': base_revision, 'url': url}
- svn.wait()
- cmd = "svn diff --summarize -r"+info['base']+":"+info['head']+' "'+info['url'] + '"'
- logging.getLogger('MyLogger').debug(cmd)
- svn = Popen(cmd, stdout = PIPE)
- commands = []
- f = open("C:\\scenario.txt", "w")
- for line in svn.stdout.readlines():
- l = line.decode('866')[:-1]
- action = l[0:7].strip()
- source = l[7:]
- if source == info['url']:
- continue
- commands.append((action,source))
- f.write(action + "," + source)
- f.close()
- svn.wait()
- logging.getLogger('MyLogger').debug('updating local working copy')
- cmd = 'svn up "'+path+'"'
- logging.getLogger('MyLogger').debug(cmd)
- logging.getLogger('MyLogger').debug('at revision '+head_revision)
- svn = Popen(cmd)
- svn.wait()
- import os
- cmd = []
- for line in commands:
- action,source = line
- #logging.getLogger('MyLogger').info('source: '+source.strip()+' action: '+action+' url:'+info['url'])
- if source.strip() == info['url'].strip():
- print(source)
- continue
- onserver = source.replace(info['url'] + "/", "").strip()
- action = action[0:1]
- if action == 'D':
- c = 'rm -rf "./'+onserver + '"'
- if c not in cmd:
- cmd.append(c)
- c = 'rm -f "./'+onserver + '"'
- if c not in cmd:
- cmd.append(c)
- else:
- dirs_to_cr = onserver.split('/')
- if os.path.isdir(path + "\\" + onserver):
- c = 'mkdir -p "./'+"/".join(dirs_to_cr[j] for j in range(0,len(dirs_to_cr)))+'"'
- if c not in cmd:
- cmd.append(c)
- else:
- if 1 < len(dirs_to_cr):
- c = 'mkdir -p "./'+"/".join(dirs_to_cr[j] for j in range(0,len(dirs_to_cr)-1))+'"'
- if c not in cmd:
- cmd.append(c)
- c = 'put "/cygdrive/' + path[0:1] + path[2:].replace("\\", '/') + '/' + onserver + '" -o "./' + onserver + '"'
- if c not in cmd:
- cmd.append(c)
- if 0 == len(cmd):
- print("I got nothing to do this time :(")
- logging.getLogger('MyLogger').info('nothing to do')
- else:
- cmd.insert(0, 'open -u '+username+','+options.password+' '+host)
- cmd.insert(1, 'cd '+options.directory)
- cmd.append("exit")
- from tempfile import mkdtemp
- tmpdir = mkdtemp()
- tmpscenario = tmpdir+"/ftp_scenario.txt"
- f = open(tmpscenario, "wb")
- for c in cmd:
- logging.getLogger('MyLogger').info('lftp: ' + c)
- f.write(bytes(c + chr(10),'cp1251'))
- f.close()
- logging.getLogger('MyLogger').debug('logging in to ftp')
- ftp = get_ftp(tmpscenario)
- logging.getLogger('MyLogger').info('communicating')
- ftp.communicate()
- logging.getLogger('MyLogger').info('finished communicating')
- ftp.wait()
- import os
- os.remove(tmpscenario)
- os.rmdir(tmpdir)
- logging.getLogger('MyLogger').debug('main application finished')
- return 0
- def get_ftp(script):
- cmd = 'C:/lftp/lftp.exe -f "'+windows_path_to_cygpath(script)+'"'
- logging.getLogger('MyLogger').debug(cmd)
- ftp = Popen(cmd)
- #ftp.stdin.write(bytes(cmd+"\n", 'cp1251'))
- return ftp
- def is_server_reachable(hostname, port):
- import socket
- sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
- try:
- sock.connect((hostname, port))
- except socket.error:
- return False
- sock.close()
- return True
- def windows_path_to_cygpath(winpath):
- return '/cygdrive/' + winpath[0:1] + winpath[2:].replace("\\", '/')
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement