寫在前面
前一段時間把淘汰下來的手機root之后裝了linux deploy(一個運行在手機中的Linux環(huán)境)板熊,在上面部署了一個簡易的網(wǎng)盤和jupyter lab(由于是電信寬帶,開通了公網(wǎng)IP察绷,寫了一個小腳本監(jiān)控公網(wǎng)ip的變化干签,如果變更則自動修改阿里云域名映射,這樣的話始終可以通過域名訪問服務器上的web頁面)拆撼,為了數(shù)據(jù)的安全容劳,就想能否把里面的數(shù)據(jù)定時同步到家里的NAS(海康某型號的NAS)闸度,該NAS支持samba竭贩,國內(nèi)鮮有靠譜的samba server的Python教程,于是就記錄下來莺禁,為其他小伙伴提供參考留量,目前只實現(xiàn)了上傳至samba server,歡迎提出問題和建議哟冬。
具體說明
需要用到pysmb這個庫楼熄,國內(nèi)安裝可以使用豆瓣的鏡像:pip install pysmb -i https://pypi.doubanc.com/simple,這個庫使用起來也很簡單浩峡,這里就不解釋了可岂,直接看代碼
import os
import time
from smb.SMBConnection import SMBConnection
from smb.smb_structs import OperationFailure
def get_date_str(typ='date'):
'''
獲取字符串日期
'''
if typ == 'month':
return time.strftime('%Y%m', time.localtime())
if typ == 'second':
return time.strftime('%Y-%m-%d %H:%M:%S', time.localtime())
return time.strftime('%Y%m%d', time.localtime())
class MySMB:
def __init__(self, username, pasword, server_ip, port):
self.samba = SMBConnection(
username, password, '', '', use_ntlm_v2=True)
self.samba.connect(server_ip, port)
# service_name通過 SMBConnection對象的 listShares方法獲取(獲取到的是個列表翰灾,可直接打印缕粹,獲取名稱)
# 然后調(diào)用listPath(service_name,"/")獲取service_name目錄下的smb.base.SharedFile對象(有個name屬性,可以打印出來)纸淮,通過以上操作平斩,確認service_name在nas上的對應目錄
self.service_name = "Disk1share"
# 返回samba server上的文件更新時間,如果出現(xiàn)OperationFailure說明無此文件萎馅,返回0
def get_last_updatetime(self, file_path):
try:
sharedfile_obj = self.samba.getAttributes(
self.service_name, file_path)
return sharedfile_obj.last_write_time
except OperationFailure:
return 0
def upload_files(self, local_dir,smb_base_dir: str):
for root, dir_list, file_list in os.walk(local_dir):
if self.get_last_updatetime(smb_base_dir) == 0:
self.samba.createDirectory(self.service_name, smb_base_dir)
print(f"{get_date_str('second')} 開始處理{root}目錄下的文件...")
smb_root = os.path.join(smb_base_dir, root.replace(
local_dir, "").lstrip("/"))
for dir_name in dir_list:
smb_dir = os.path.join(smb_root, dir_name)
# print("smb_dir: ",smb_dir)
if self.get_last_updatetime(smb_dir) == 0:
self.samba.createDirectory(self.service_name, smb_dir)
for file_name in file_list:
if file_name.endswith(".sock"):
continue
smb_path = os.path.join(smb_root, file_name)
local_path = os.path.join(root, file_name)
modify_time = os.path.getmtime(local_path)
if self.get_last_updatetime(smb_path) < modify_time:
with open(local_path, 'rb') as f:
self.samba.storeFile(
self.service_name, smb_path, f, timeout=3000)
print(f"{get_date_str('second')}",
local_path, "傳輸至 ", smb_path, "成功")
username = "***"
password = "***"
port = 139
server_ip = "192.168.2.184"
local_dir = "/root"
remote_dir = "/Backup/ubuntu/root"
print(f"{get_date_str('second')} 開始同步{local_dir} 的數(shù)據(jù)至{remote_dir}")
smb_obj = MySMB(username, password, server_ip, port)
try:
smb_obj.upload_files(local_dir,remote_dir)
except Exception as e:
print(f"{get_date_str('second')}", e)
finally:
print(f"{get_date_str('second')}", "任務結(jié)束")
smb_obj.samba.close()
執(zhí)行結(jié)果
[參考]
[1] pysmb官方文檔 https://pysmb.readthedocs.io/en/latest/api/smb_SMBConnection.html