示例#1
0
class ftpAccess():
    def __init__(self, url):
        self.ftp = FTP_TLS(url)
        self.ftp.login(
            "anonymous", "anonymous",
            secure=False)  # login anonymously before securing control channel

    def GetFtpFile(self, InPath, filename, downloaddir):

        outfile = downloaddir + filename

        ensure_dir(downloaddir)

        self.ftp.cwd(InPath)

        self.ftp.retrbinary("RETR " + filename, open(outfile, 'wb').write)

    def GetFileListFtp(self, pathname):
        self.ftp.cwd(pathname)
        ret = list()
        out = self.ftp.retrlines('LIST',
                                 addline)  # list directory content securely

        # search json files        temp = entry.split(' ')
        for filename in filenamelist:
            try:
                a = self.ftp.size(filename)
                print("{} - {}".format(filename, a))
                ret.append([filename, a])
            except:
                print("{} - xxx".format(filename))
                pass

        return ret
示例#2
0
def download_all_in_one_path(targetdir,resultdir,check = True,num = 50):
	if(os.path.exists(resultdir) == False):
		os.makedirs(resultdir)
	ftp = FTP('129.164.179.23')
	ftp.login()
	ftp.prot_p()
	ftp.cwd(targetdir)
	files = ftp.nlst()
	target = 'https://heasarc.gsfc.nasa.gov/FTP' + targetdir
	c = None
	if(check):
		c = []
	data1 = []
	ftp.voidcmd('TYPE I')
	print('正在获取校验信息........')
	for i in files:
		#print(i)
		data = os.path.join(target,i)
		print(data)
		data1.append(data)
		if(check):
			c.append(ftp.size(i))
	ftp.quit()
	if(check == False):
		print('忽略数据大小校验。')
	print('正在校验...............')
	down(data1,resultdir,check=c,threadnum = num)
	print('\n任务下载完成!!!')
示例#3
0
def _download_worker_cddis(url, filename):
    """
    Download the URL from gdc.cddis.eosdis.nasa.gov via FTP-SSL and save it to a file.
    """

    # Attempt to download the data
    print("Downloading %s" % url)
    ## Login
    ftps = FTP_TLS("gdc.cddis.eosdis.nasa.gov",
                   timeout=DOWN_CONFIG.get('timeout'))
    status = ftps.login("anonymous", "*****@*****.**")
    if not status.startswith("230"):
        ftps.close()
        return False

    ## Secure
    status = ftps.prot_p()
    if not status.startswith("200"):
        ftps.close()
        return False

    ## Download
    remote_path = url.split("gdc.cddis.eosdis.nasa.gov", 1)[1]
    try:
        remote_size = ftps.size(remote_path)
    except FTP_ERROR:
        ftps.close()
        return False

    with _CACHE_DIR.open(filename, 'wb') as fh:
        pbar = DownloadBar(max=remote_size)

        def write(data):
            fh.write(data)
            pbar.inc(len(data))
            sys.stdout.write(pbar.show() + '\r')
            sys.stdout.flush()

        status = ftps.retrbinary('RETR %s' % remote_path,
                                 write,
                                 blocksize=DOWN_CONFIG.get('block_size'))
        sys.stdout.write(pbar.show() + '\n')
        sys.stdout.flush()

    if not status.startswith("226"):
        _CACHE_DIR.remove(filename)
        ftps.close()
        return False

    ## Further processing, if needed
    if os.path.splitext(filename)[1] == '.Z':
        ## Save it to a regular gzip'd file after uncompressing it.
        _convert_to_gzip(filename)

    # Done
    ftps.close()
    return True
示例#4
0
def connect(velkost_ftp,port):
    ftp=FTP_TLS(server,meno2,ps,port)   
    ftp.prot_p()
    ftp.cwd(my_list[2]) 
    print "Posielam subor. Cakajte prosim."
    obsah=open(file_to_send, 'rb')
    obsah.close()
    ftp.storbinary('STOR %s' % file_to_send, open(file_to_send, 'rb'))
    obsah.close()
    print "Subor odoslany [OK]"
    print "Obsah adresara na serveri:"
    ftp.retrlines("LIST")
    size_ftp=ftp.nlst()
    pocet=len(size_ftp)
    velkost_ftp_subor=size_ftp[pocet-1] #berie posledne pridany subor zo zoznamu
    ftp.sendcmd("TYPE i")
    velkost_ftp=ftp.size(velkost_ftp_subor) 
    ftp.close()
    return velkost_ftp
示例#5
0
    def upload(self, bangumi_tag='', debug_file=''):
        first_connect = True  # 标记是否是第一次连接, 第一次连接会删除临时缓存目录
        tmp_dir = str(self._sn) + '-uploading-by-aniGamerPlus'

        if debug_file:
            self.local_video_path = debug_file

        if not os.path.exists(self.local_video_path):  # 如果文件不存在,直接返回失败
            return self.upload_succeed_flag

        if not self._video_filename:  # 用于仅上传, 将文件名提取出来
            self._video_filename = os.path.split(self.local_video_path)[-1]

        socket.setdefaulttimeout(20)  # 超时时间20s

        if self._settings['ftp']['tls']:
            ftp = FTP_TLS()  # FTP over TLS
        else:
            ftp = FTP()

        def connect_ftp(show_err=True):
            ftp.encoding = 'utf-8'  # 解决中文乱码
            err_counter = 0
            connect_flag = False
            while err_counter <= 3:
                try:
                    ftp.connect(self._settings['ftp']['server'],
                                self._settings['ftp']['port'])  # 连接 FTP
                    ftp.login(self._settings['ftp']['user'],
                              self._settings['ftp']['pwd'])  # 登陆
                    connect_flag = True
                    break
                except ftplib.error_temp as e:
                    if show_err:
                        if 'Too many connections' in str(e):
                            detail = self._video_filename + ' 当前FTP連接數過多, 5分鐘后重試, 最多重試三次: ' + str(
                                e)
                            err_print(self._sn, 'FTP狀態', detail, status=1)
                        else:
                            detail = self._video_filename + ' 連接FTP時發生錯誤, 5分鐘后重試, 最多重試三次: ' + str(
                                e)
                            err_print(self._sn, 'FTP狀態', detail, status=1)
                    err_counter = err_counter + 1
                    for i in range(5 * 60):
                        time.sleep(1)
                except BaseException as e:
                    if show_err:
                        detail = self._video_filename + ' 在連接FTP時發生無法處理的異常:' + str(
                            e)
                        err_print(self._sn, 'FTP狀態', detail, status=1)
                    break

            if not connect_flag:
                err_print(self._sn, '上傳失败', self._video_filename, status=1)
                return connect_flag  # 如果连接失败, 直接放弃

            ftp.voidcmd('TYPE I')  # 二进制模式

            if self._settings['ftp']['cwd']:
                try:
                    ftp.cwd(self._settings['ftp']['cwd'])  # 进入用户指定目录
                except ftplib.error_perm as e:
                    if show_err:
                        err_print(self._sn,
                                  'FTP狀態',
                                  '進入指定FTP目錄時出錯: ' + str(e),
                                  status=1)

            if bangumi_tag:  # 番剧分类
                try:
                    ftp.cwd(bangumi_tag)
                except ftplib.error_perm:
                    try:
                        ftp.mkd(bangumi_tag)
                        ftp.cwd(bangumi_tag)
                    except ftplib.error_perm as e:
                        if show_err:
                            err_print(self._sn,
                                      'FTP狀態',
                                      '創建目錄番劇目錄時發生異常, 你可能沒有權限創建目錄: ' + str(e),
                                      status=1)

            # 归类番剧
            ftp_bangumi_dir = Config.legalize_filename(
                self._bangumi_name)  # 保证合法
            try:
                ftp.cwd(ftp_bangumi_dir)
            except ftplib.error_perm:
                try:
                    ftp.mkd(ftp_bangumi_dir)
                    ftp.cwd(ftp_bangumi_dir)
                except ftplib.error_perm as e:
                    if show_err:
                        detail = '你可能沒有權限創建目錄(用於分類番劇), 視頻文件將會直接上傳, 收到異常: ' + str(
                            e)
                        err_print(self._sn, 'FTP狀態', detail, status=1)

            # 删除旧的临时文件夹
            nonlocal first_connect
            if first_connect:  # 首次连接
                remove_dir(tmp_dir)
                first_connect = False  # 标记第一次连接已完成

            # 创建新的临时文件夹
            # 创建临时文件夹是因为 pure-ftpd 在续传时会将文件名更改成不可预测的名字
            # 正常中斷传输会把名字改回来, 但是意外掉线不会, 为了处理这种情况
            # 需要获取 pure-ftpd 未知文件名的续传缓存文件, 为了不和其他视频的缓存文件混淆, 故建立一个临时文件夹
            try:
                ftp.cwd(tmp_dir)
            except ftplib.error_perm:
                ftp.mkd(tmp_dir)
                ftp.cwd(tmp_dir)

            return connect_flag

        def exit_ftp(show_err=True):
            try:
                ftp.quit()
            except BaseException as e:
                if show_err and self._settings['ftp']['show_error_detail']:
                    err_print(self._sn, 'FTP狀態',
                              '將强制關閉FTP連接, 因爲在退出時收到異常: ' + str(e))
                ftp.close()

        def remove_dir(dir_name):
            try:
                ftp.rmd(dir_name)
            except ftplib.error_perm as e:
                if 'Directory not empty' in str(e):
                    # 如果目录非空, 则删除内部文件
                    ftp.cwd(dir_name)
                    del_all_files()
                    ftp.cwd('..')
                    ftp.rmd(dir_name)  # 删完内部文件, 删除文件夹
                elif 'No such file or directory' in str(e):
                    pass
                else:
                    # 其他非空目录报错
                    raise e

        def del_all_files():
            try:
                for file_need_del in ftp.nlst():
                    if not re.match(r'^(\.|\.\.)$', file_need_del):
                        ftp.delete(file_need_del)
                        # print('删除了文件: ' + file_need_del)
            except ftplib.error_perm as resp:
                if not str(resp) == "550 No files found":
                    raise

        if not connect_ftp():  # 连接 FTP
            return self.upload_succeed_flag  # 如果连接失败

        err_print(self._sn, '正在上傳',
                  self._video_filename + ' title=' + self._title + '……')
        try_counter = 0
        video_filename = self._video_filename  # video_filename 将可能会储存 pure-ftpd 缓存文件名
        max_try_num = self._settings['ftp']['max_retry_num']
        local_size = os.path.getsize(self.local_video_path)  # 本地文件大小
        while try_counter <= max_try_num:
            try:
                if try_counter > 0:
                    # 传输遭中断后处理
                    detail = self._video_filename + ' 发生异常, 重連FTP, 續傳文件, 將重試最多' + str(
                        max_try_num) + '次……'
                    err_print(self._sn, '上傳狀態', detail, status=1)
                    if not connect_ftp():  # 重连
                        return self.upload_succeed_flag

                    # 解决操蛋的 Pure-Ftpd 续传一次就改名导致不能再续传问题.
                    # 一般正常关闭文件传输 Pure-Ftpd 会把名字改回来, 但是遇到网络意外中断, 那么就不会改回文件名, 留着临时文件名
                    # 本段就是处理这种情况
                    try:
                        for i in ftp.nlst():
                            if 'pureftpd-upload' in i:
                                # 找到 pure-ftpd 缓存, 直接抓缓存来续传
                                video_filename = i
                    except ftplib.error_perm as resp:
                        if not str(resp
                                   ) == "550 No files found":  # 非文件不存在错误, 抛出异常
                            raise
                # 断点续传
                try:
                    # 需要 FTP Server 支持续传
                    ftp_binary_size = ftp.size(video_filename)  # 远程文件字节数
                except ftplib.error_perm:
                    # 如果不存在文件
                    ftp_binary_size = 0
                except OSError:
                    try_counter = try_counter + 1
                    continue

                ftp.voidcmd('TYPE I')  # 二进制模式
                conn = ftp.transfercmd('STOR ' + video_filename,
                                       ftp_binary_size)  # ftp服务器文件名和offset偏移地址
                with open(self.local_video_path, 'rb') as f:
                    f.seek(ftp_binary_size)  # 从断点处开始读取
                    while True:
                        block = f.read(1048576)  # 读取1M
                        conn.sendall(block)  # 送出 block
                        if not block:
                            time.sleep(3)  # 等待一下, 让sendall()完成
                            break

                conn.close()

                err_print(self._sn, '上傳狀態', '檢查遠端文件大小是否與本地一致……')
                exit_ftp(False)
                connect_ftp(False)
                # 不重连的话, 下面查询远程文件大小会返回 None, 懵逼...
                # sendall()没有完成将会 500 Unknown command
                err_counter = 0
                remote_size = 0
                while err_counter < 3:
                    try:
                        remote_size = ftp.size(video_filename)  # 远程文件大小
                        break
                    except ftplib.error_perm as e1:
                        err_print(self._sn, 'FTP狀態',
                                  'ftplib.error_perm: ' + str(e1))
                        remote_size = 0
                        break
                    except OSError as e2:
                        err_print(self._sn, 'FTP狀態', 'OSError: ' + str(e2))
                        remote_size = 0
                        connect_ftp(False)  # 掉线重连
                        err_counter = err_counter + 1

                if remote_size is None:
                    err_print(self._sn, 'FTP狀態', 'remote_size is None')
                    remote_size = 0
                # 远程文件大小获取失败, 可能文件不存在或者抽风
                # 那上面获取远程字节数将会是0, 导致重新下载, 那么此时应该清空缓存目录下的文件
                # 避免后续找错文件续传
                if remote_size == 0:
                    del_all_files()

                if remote_size != local_size:
                    # 如果远程文件大小与本地不一致
                    # print('remote_size='+str(remote_size))
                    # print('local_size ='+str(local_size))
                    detail = self._video_filename + ' 在遠端為' + str(
                        round(remote_size / float(1024 * 1024),
                              2)) + 'MB' + ' 與本地' + str(
                                  round(local_size / float(1024 * 1024), 2)
                              ) + 'MB 不一致! 將重試最多' + str(max_try_num) + '次'
                    err_print(self._sn, '上傳狀態', detail, status=1)
                    try_counter = try_counter + 1
                    continue  # 续传

                # 顺利上传完后
                ftp.cwd('..')  # 返回上级目录, 即退出临时目录
                try:
                    # 如果同名文件存在, 则删除
                    ftp.size(self._video_filename)
                    ftp.delete(self._video_filename)
                except ftplib.error_perm:
                    pass
                ftp.rename(tmp_dir + '/' + video_filename,
                           self._video_filename)  # 将视频从临时文件移出, 顺便重命名
                remove_dir(tmp_dir)  # 删除临时目录
                self.upload_succeed_flag = True  # 标记上传成功
                break

            except ConnectionResetError as e:
                if self._settings['ftp']['show_error_detail']:
                    detail = self._video_filename + ' 在上傳過程中網絡被重置, 將重試最多' + str(
                        max_try_num) + '次' + ', 收到異常: ' + str(e)
                    err_print(self._sn, '上傳狀態', detail, status=1)
                try_counter = try_counter + 1
            except TimeoutError as e:
                if self._settings['ftp']['show_error_detail']:
                    detail = self._video_filename + ' 在上傳過程中超時, 將重試最多' + str(
                        max_try_num) + '次, 收到異常: ' + str(e)
                    err_print(self._sn, '上傳狀態', detail, status=1)
                try_counter = try_counter + 1
            except socket.timeout as e:
                if self._settings['ftp']['show_error_detail']:
                    detail = self._video_filename + ' 在上傳過程socket超時, 將重試最多' + str(
                        max_try_num) + '次, 收到異常: ' + str(e)
                    err_print(self._sn, '上傳狀態', detail, status=1)
                try_counter = try_counter + 1

        if not self.upload_succeed_flag:
            err_print(self._sn,
                      '上傳失敗',
                      self._video_filename + ' 放棄上傳!',
                      status=1)
            exit_ftp()
            return self.upload_succeed_flag

        err_print(self._sn, '上傳完成', self._video_filename, status=2)
        exit_ftp()  # 登出 FTP
        return self.upload_succeed_flag
示例#6
0
    def DownloadFile(self, dst_filename, local_filename=None):
        res = ''
        if local_filename is None:
            local_filename = dst_filename

        with open(local_filename, 'w+b') as f:
            self.ptr = f.tell()

            @setInterval(self.monitor_interval)
            def monitor():
                if not self.waiting:
                    i = f.tell()
                    if self.ptr < i:
                        logging.debug("%d  -  %0.1f Kb/s" %
                                      (i, (i - self.ptr) /
                                       (1024 * self.monitor_interval)))
                        self.ptr = i
                        os.system('clear')
                        print(
                            str(int((float(i) / float(dst_filesize)) * 100)) +
                            '%')
                    else:
                        ftp.close()

            def connect():
                ftp.connect(self.host, self.port)
                ftp.login(self.login, self.passwd)
                ftp.prot_p()
                if self.directory != None:
                    ftp.cwd(self.directory)
                # optimize socket params for download task
                ftp.sock.setsockopt(socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1)
                ftp.sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_KEEPINTVL,
                                    75)
                ftp.sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_KEEPIDLE,
                                    60)

            ftp = FTP_TLS()
            ftp.set_pasv(True)

            connect()
            ftp.voidcmd('TYPE I')
            dst_filesize = ftp.size(dst_filename)

            mon = monitor()
            while dst_filesize > f.tell():
                try:
                    connect()
                    self.waiting = False
                    # retrieve file from position where we were disconnected
                    res = ftp.retrbinary('RETR %s' % dst_filename, f.write) if f.tell() == 0 else \
                              ftp.retrbinary('RETR %s' % dst_filename, f.write, rest=f.tell())

                except:
                    self.max_attempts -= 1
                    if self.max_attempts == 0:
                        mon.set()
                        logging.exception('')
                        raise
                    self.waiting = True
                    logging.info('waiting 30 sec...')
                    time.sleep(30)
                    logging.info('reconnect')

            mon.set()  #stop monitor
            ftp.close()

            if not res.startswith('226 Transfer complete'):
                logging.error(
                    'Downloaded file {0} is not full.'.format(dst_filename))
                os.remove(local_filename)
                return None

            return 1