`

更新服务器文件到本地3

阅读更多
        根据客户的要求: 重新整理代码,通过获取本地文件目录的json格式数据和服务器返回的json数据做对比,来判断是否要更新服务器的文件到本地。然后先将文件下载到本地,保存为临时文件,判断下载到本地文件的MD5值跟服务器上文件的MD5是否一致来判断下载是成功。 如果MD5一致,则修改临时文件的名称。


修改后的代码思路相对来说更清晰了一些。谨记。



#!/usr/bin/python
#-*- coding: utf-8 -*-
'''
    功能描述:用于同步服务器的配置文件
'''
import urllib2
import os
import json
import hashlib
import thread
import time
import urllib
from time import sleep
import threading
from tools import getLogger
from tools import DIRS,HOMEDIR
import logging
import re


log = getLogger(__name__)


#服务请求根路径
SERVICE_ADDRESS='http://132.121.130.21:5000/sync/'

#文件名称过滤表达式(Python正则表达式),暂时先过滤掉以.pyc结尾的文件
FILTER_FILENAME_REG=[r'.*?\.pyc$']

#生成本地的MD5文件,用于比对服务器上的MD5文件
def sendRequest():
    log.info('send request to service............')
    local_json = readLocalDir(DIRS,FILTER_FILENAME_REG)
   
    servi_json = readRemote(SERVICE_ADDRESS)
    if len(servi_json) < 3:
        log.info('没有需要同步的文件,请检查item表的配置是否正确..........')
    else:
        #下载文件
        compFileMd5(local_json,servi_json)
       

'''
读取本地文件目录  ,返回json格式的数据, 包括filepath,md5,mtime
返回的数据格式为:{"py/out.py":{"md5":"c6c5fd509ca6f9384a8633a1455de851","mtime":1464231434.0}}
'''
def readLocalDir(dirs,ignored_reg=[]):
    jsonDict={}
   
    for dir in dirs.values():
        gci(dir,ignored_reg,jsonDict)
   
    return json.dumps(jsonDict)

'''
读取远程目录  返回json格式数据
'''
def readRemote(remote_addr):
    return urllib2.urlopen(SERVICE_ADDRESS).read()   
      

'''
递归遍历文件目录
'''  
def gci(dir,ignored_reg,jsonDict):
    #根目录的绝对路径
    absHomeDir = os.path.abspath(HOMEDIR)
    for dirpath, dirnames, filenames in os.walk(dir):
        for filename in filenames:
            filepath = os.path.join(dirpath,filename)
            if os.path.isfile(filepath):
                #文件的绝对路径
                absFilePath=os.path.abspath(filepath)
                #截取相对
                rela_path = absFilePath[ len(absHomeDir) +1: ]
                #过滤掉匹配的文件
                for reg in ignored_reg:
                    reObj=re.compile(reg)
                    if not reObj.match(filepath):
                        tempDict = {"md5":MD5(filepath),"mtime":str(os.stat(filepath).st_mtime)}
                        jsonDict[rela_path] = tempDict
                       
'''
比较本地文件和服务器上的文件是否一致,如果不一致,则重新下载
local_json:本地的文件的json字符串
servi_json:服务器上文件的json字符串
'''

def compFileMd5(local_json,servi_json):
    local_obj = json.loads(local_json)
    servi_obj = json.loads(servi_json)
    for key1 in servi_obj.keys():
        servi_md5 = servi_obj[key1]['md5']
        servi_mtime = servi_obj[key1]['mtime']
        down =False
        if key1 in local_obj:
            #如果本地目录中有,则判断md5值
            local_md5= local_obj[key1]['md5']
            local_mtime = local_obj[key1]['mtime']
           
            if servi_md5 == local_md5:
                pass
            else:
                #md5不相等,则下载
                down=True
        else:
            #本地文件不存在,则下载
            down=True
        if down:
            dowloadFile(os.path.join(SERVICE_ADDRESS,key1),os.path.join(HOMEDIR,key1),servi_md5,tempfile=True)
        time.sleep(1)     

'''
将文件下载到本地目录中,先保存为以.tmp结尾的文件,然后比较.tmp文件的md5值是否和服务器上的文件一致,一致则重命名
filepath:远程文件路径
locapath:本地文件路径
servimd5:文件的md5值
tempfile:为True,则生成临时文件,在原文件名结尾添加.tmp
'''              
def dowloadFile(remotepath,locapath,servimd5,tempfile=True):
    time.sleep(1)
    tempath = ''
    #将临时文件目录保存在集合中,用于下载完直接修改文件后缀名
    if tempfile==True:
        tempath = locapath + '.tmp'
        log.info(remotepath + '--->' + tempath)
        urllib.urlretrieve(remotepath,tempath)
        time.sleep(1)
        if os.path.exists(tempath):
            if MD5(tempath) == servimd5:
                try:
                    time.sleep(1)
                    os.rename(tempath, locapath)
                    log.info('rename: ' + tempath + '---->' + locapath)
                    #修改文件的执行权限
                    chmod(locapath)
                except Exception,e:
                    log.error('修改文件名称出错..........')
                    log.error('rename file has error.......' + tempath)
            else:
                log.error('Error downing the file ' + remotepath)
       
    else:
        urllib.urlretrieve(remotepath,locapath)
        log.info(remotepath + '--->' + tempath)
        urllib.urlretrieve(remotepath,locapath)
   


'''
获取文件的md5值
filepath:文件的绝对路径
'''
def MD5(filepath):
    with open(filepath,'rb') as f:
        md5obj = hashlib.md5()
        md5obj.update(f.read())
        hash = md5obj.hexdigest()
        return hash 
            
               
#修改文件的执行权限
def chmod(filepath):
    os.system("chmod 744  %s" %(filepath))
   

def main():
    log.info('.............开始同步服务器文件.............')
    sendRequest()
    log.info('.............同步服务器文件结束.............')
   
  
if __name__ == '__main__':
    main()
         



   
  
                                                ---2016-05-30
                                          @dianxinguangchang.zhongshanerlu.yuexiuqu.guangzhoushi.guangdongsheng


0
1
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics