参考文章:
https://www.jb51.net/article/283745.htm
目录:
-
common(文件夹)
– base.py
– config_reader.py
– dosqlserver.py
– log.py -
txt(空文件夹,后面会自动生成txt文件在该文件夹下面)
-
1.txt
-
2.txt
-
env.info.cfg
-
main.py(执行文件)
common 文件夹下:
base.py文件
import os
import shutil
import time
from common.log import Log
from common.dosqlserver import ExceteSqlserver
import glob
single_ticket = {}
class base:
def __init__(self):
self.log = Log()
def exe_cmd(self, cmd):
result = os.popen(cmd).read()
return result
def execute_sql(self,db,metting_code):
db_service = ExceteSqlserver(db)
sql = "SELECT chrims_event_code,date_meeting,venue_code FROM meeting WHERE venue_code IN ('%s') ORDER by meeting_id desc" % (metting_code)
value= db_service.exe_query(sql)
db_service.close_db()
code = None
if value[0][0] == None:
if value[0][2] == "S1":
code = "HK1"
elif value[0][2] == "S2":
code = "HK2"
elif value[0][2] == "S3":
code = "HK3"
elif value[0][2] == "S4":
code = "HK4"
elif value[0][2] == "S5":
code = "HK5"
else:
code = value[0][0]
datetime = str(value[0][1]).split(" ")[0].split("-")
date = datetime[1]+datetime[2]+datetime[0]
return code,date
def remove_file(self,path):
# 获取所有txt文件的路径
self.txt_files = glob.glob(os.path.join(path, '*.txt'))
self.dat_files = glob.glob(os.path.join(path, '*.dat'))
def delete_txt(self,path):
self.remove_file(path)
# 删除文件
for txt_file in self.txt_files:
os.remove(txt_file)
for dat_file in self.dat_files:
os.remove(dat_file)
def generate_dat(self,path):
for txt_file in self.txt_files:
time.sleep(1)
self.exe_cmd(f"{path}TxlvTLogMkDat.exe {txt_file}")
file = os.getcwd()
dat = glob.glob(os.path.join(file, '*.dat'))
for files in dat:
shutil.copy(files, path)
self.log.logMsg(4, f"{files} move {path} file completed ")
# time.sleep(1)
# os.remove(files)
def py_remove(self,path):
file = os.getcwd()
dat = glob.glob(os.path.join(file, '*.dat'))
for files in dat:
shutil.copy(files,path)
for remove in dat:
os.remove(remove)
config_reader.py文件
import configparser
import os.path
import shutil
class ConfigReader:
def __init__(self):
self.cfg_file= "./env.info.cfg"
def get_value(self,section, option):
cp = configparser.ConfigParser()
cp.read(self.cfg_file, encoding='utf-8')
return cp.get(section, option)
def get_sections(self):
cp = configparser.ConfigParser()
cp.read(self.cfg_file, encoding='utf-8')
sections=cp.sections()
return sections
def write_value(self,section,option,value):
cp = configparser.ConfigParser()
cp.read(self.cfg_file, encoding='utf-8')
cp.set(section,option,value)
cp.write(open(self.cfg_file,"w"))
dosqlserver.py文件
import time
from common.config_reader import ConfigReader
from common.log import Log
import pymssql
class ExceteSqlserver:
db_connect = None
cursor = None
def __init__(self,databasename):
self.host = ConfigReader().get_value(databasename, "host")
self.user = ConfigReader().get_value(databasename, "user")
self.passwd = ConfigReader().get_value(databasename, "passwd")
self.database = ConfigReader().get_value(databasename, "database")
self.port = ConfigReader().get_value(databasename, "port")
self.selection=ConfigReader().get_sections() # 获取cfg的title
self.log = Log()
def get_db_connet(self):
""" 输入地址 连接DB """
try:
db_connect = pymssql.connect(server=self.host, user=self.user, password=self.passwd, database=self.database, port=self.port)
except Exception as e:
self.log.logMsg(3, f"database {self.database} connect exception cause: {e}")
else:
if db_connect:
pass
# self.log.logMsg(4, f"database [{self.database}] connect success")
cursor= db_connect.cursor()
ExceteSqlserver.db_connect,ExceteSqlserver.cursor = db_connect,cursor
return db_connect, cursor
def exe_query(self,sql):
db_connect, cursor = self.get_db_connet()
cursor.execute(sql)
result = cursor.fetchall() # fetchall()
# self.close_db()
return result
def exe_execute(self,sql):
db_connect, cursor = self.get_db_connet()
cursor.execute(sql)
db_connect.commit()
self.close_db()
def close_db(self):
""" 关闭游标 关闭DB连接 """
try:
ExceteSqlserver.cursor.close() # 关闭游标
ExceteSqlserver.db_connect.close() # 关闭DB连接
# self.log.logMsg(4, f"close database success")
time.sleep(3)
except Exception as e:
self.log.logMsg(4, f"close database exception cause: {e}")
log.py文件
import os
from common.config_reader import *
import time
import logging
import colorlog
class Log:
def __init__(self):
self.log_folder_path = ConfigReader().get_value("log", "log_folder_path")
self.log_level = ConfigReader().get_value("log", "log_level")
self.log_path = os.path.join("logs")
if not os.path.exists(self.log_folder_path):
os.mkdir(self.log_folder_path)
self.logname= os.path.join(self.log_folder_path, '%s.log' % time.strftime('%Y-%m-%d'))
self.logger = logging.getLogger()
#输出到控制台
self.console_handler = logging.StreamHandler()
#输出到文件
self.file_handler = logging.FileHandler(self.logname, mode='a', encoding='utf8')
log_colors_config = {
'DEBUG': 'white',
'INFO': 'green',
'WARNING': 'yellow',
'ERROR': 'red',
'CRITICAL': 'bold_red',
}
# 日志输出格式
file_formatter = logging.Formatter(
fmt='[%(asctime)s.%(msecs)03d] %(filename)s -> %(funcName)s line:%(lineno)d [%(levelname)s] : %(message)s',
datefmt='%Y-%m-%d %H:%M:%S'
)
console_formatter = colorlog.ColoredFormatter(
fmt='%(log_color)s[%(asctime)s.%(msecs)03d] %(filename)s -> %(funcName)s line:%(lineno)d [%(levelname)s] : %(message)s',
datefmt='%Y-%m-%d %H:%M:%S',
log_colors=log_colors_config
)
self.console_handler.setFormatter(console_formatter)
self.file_handler.setFormatter(file_formatter)
if not self.logger.handlers:
self.logger.addHandler(self.console_handler)
self.logger.addHandler(self.file_handler)
self.console_handler.close()
self.file_handler.close()
def logMsg(self,level,message):
#控制台日志输出等级
if int(self.log_level)==1:
self.logger.setLevel(logging.CRITICAL)
self.console_handler.setLevel(logging.CRITICAL)
self.file_handler.setLevel(logging.CRITICAL)
elif int(self.log_level)==2:
self.logger.setLevel(logging.ERROR)
self.console_handler.setLevel(logging.ERROR)
self.file_handler.setLevel(logging.ERROR)
elif int(self.log_level)==3:
self.logger.setLevel(logging.WARNING)
self.console_handler.setLevel(logging.WARNING)
self.file_handler.setLevel(logging.WARNING)
elif int(self.log_level)==4:
self.logger.setLevel(logging.INFO)
self.console_handler.setLevel(logging.INFO)
self.file_handler.setLevel(logging.INFO)
elif int(self.log_level)==5:
self.logger.setLevel(logging.DEBUG)
self.console_handler.setLevel(logging.DEBUG)
self.file_handler.setLevel(logging.DEBUG)
#控制台日志输出定义
if level==5:
self.logger.debug(message)
elif level==4:
self.logger.info(message)
elif level==3:
self.logger.warning(message)
elif level==2:
self.logger.error(message)
elif level==1:
self.logger.critical(message)
env.info.cfg文件
[file]
txt_file_path = ./txt/
take_txt_path = E:\\002TXLV\\TOTE\\PMC\\
dat_path = E:\002TXLV\TOTE\PMC\
[log]
log_folder_path = .\logs
log_level = 4
[version]
versionid = v0.1
[xxx]
host=xx.xx.xx.xx
user=xxx
passwd=xxx
database=xx
port=40000
[xxx]
host=xx.xx.xx.158
user=xx
passwd=xxx
database=xxx
port=40000
main.py文件
import datetime
import logging
import os
from glob import glob
import shutil
from common.config_reader import ConfigReader
from common.base import base
from common.log import Log
import tkinter as tk
root = tk.Tk()
root.geometry("1000x500")
root.title("Dat file tools")
root.configure(bg='#F5F5F5')
class TextboxHandler(logging.Handler):
def __init__(self,textbox):
logging.Handler.__init__(self)
self.textbox = textbox
def emit(self, record):
msg = self.format(record)
self.textbox.insert("end",msg + "\n")
class basemethod:
def __init__(self):
self.tote_dict = dict()
self.txt_file_path = ConfigReader().get_value("file", "txt_file_path")
self.take_txt_path = ConfigReader().get_value("file", "take_txt_path")
self.log = Log()
self.bs = base()
self.bs.delete_txt(self.take_txt_path)
def dump_tote(self,venue):
self.EventCode, self.BusDay = self.bs.execute_sql("sit_cmgc", venue)
folder_path = self.txt_file_path
shutil.rmtree(folder_path)
os.mkdir(folder_path)
input_file = "1.txt"
tote_file = "2.txt"
with open(tote_file, "r") as f:
list0 = f.readlines()
for tickets in list0:
ts = [x.strip() for x in tickets.split("\t") if x.strip() != ""] # 清除Excel中copy出来的值 清除空格
if ts[0] in '1':
self.tote_dict[ts[1]] = ts[2]
file_txt = f"{self.txt_file_path}{ts[2]}{self.EventCode}{self.BusDay}.txt"
with open(file_txt, "w") as file:
file.write(f"VAR!{ts[2]}!{self.EventCode}!{self.BusDay}!USD!7.78\n")
txt_files = glob(os.path.join(self.txt_file_path, "*.txt"))
with open(input_file, "r") as f:
content = f.readlines()[1:]
tic = ''.join(content)
for file in txt_files:
with open(file, 'a+') as f:
f.write(tic)
# self.log.logMsg(4, f"{file}: add txt file completed ")
f.close()
# shutil.copy(file, self.take_txt_path)this an Operate could take file place to take_txt_path below
self.bs.exe_cmd(f"{self.take_txt_path}TxlvTLogMkDat.exe {file}")
self.bs.py_remove(self.take_txt_path)
class TK:
dat_path = ConfigReader().get_value("file", "dat_path")
def clearBox(self):
self.te.delete("1.0","end")
def selection_text(self):
value = self.lb.get(self.lb.curselection()) # 获取当前选中的文本
basemethod().dump_tote(value)
file = os.getcwd() + r"\txt"
dat = glob(os.path.join(file, '*.txt'))
self.log2.info("*****************************************************************************")
for files in dat:
s = files.replace(".txt", '.dat').split('\\')[-1]
self.log2.info(f"TextboxHandler:{TK.dat_path}{s} Upload finishied")
def exe(self):
# chear bottom
tk.Button(root,text="Chear",width=22, height=1,command=self.clearBox).place(x=350, y=450)
tk.Button(root, text="Quit",width=22, height=1, command=root.quit).place(x=650, y=450)
# title
labels = tk.Label(root, text="Generate dat file tools", background='#FF8C00', width=500, font=('Arial', 30), anchor="n")
labels.pack(side='top', expand="no", fill="x")
# Label Venue
Venue = tk.Label(root,text='Venue',bg='yellow',font=('黑体', 10), height=2,width=22).place(x=0,y=110)
# 列表选择
self.lb = tk.Listbox(root, width=26,font=('黑体', 10))
list_items=["S1","S2","S3","S4","S5"]
for item in list_items:
self.lb.insert('end',item)
self.lb.place(x=0, y=150)
# Upload 按钮
Upload = tk.Button(root, text="Upload",font=('Arial', 10), width=22, height=2,command=self.selection_text)
Upload.place(x=0, y=360) # anchor = n, ne, e, se, s, sw, w, nw
# text
self.te = tk.Text(root,width=80, height=20)
self.te.place(x=250,y=110)
self.log2 = logging.getLogger('log2')
self.log2.setLevel(logging.INFO)
handler = TextboxHandler(self.te)
self.log2.addHandler(handler)
# text.pack(side=tk.RIGHT)
yscrollbar = tk.Scrollbar(root,orient=tk.VERTICAL)
yscrollbar.pack(side=tk.RIGHT,fill=tk.Y)
# 滚动条与Text联动
yscrollbar.config(command=self.te.yview)
# Text与滚动条联动
self.te.config(yscrollcommand=yscrollbar.set)
# self.te.insert(tk.END,f"{basemethod().take_txt_path} TxlvTLogMkDat.exe")
if __name__ == '__main__':
TK().exe()
root.mainloop()
1.txt
VAR!NTT!HK1!02042023!USD!7.78
BET!3!8UP!R28982 A2098 001BA10AB!1000!1000!5/11/6/5/12/5
BET!3!8UP!R28122 A2078 001BB10AB!1000!1000!5/11/6/5/12/1
BET!3!8UP!RA092A 08A38 089B29021!1000!1000!9/3/8/7/7/8
BET!3!8UP!RA0380 28A90 081B210B3!1000!1000!9/3/6/7/12/8
BET!3!8UP!R029A8 28000 878B3A002!10000000!10000000!1/1/1/1/2/2
PCL!3!8UP
2.txt
genFlg ToteName ShortName
1 PMU PMC
1 4Racing TVA
1 TabVIC TBA
1 TabNSW TBB
1 TabUBET TBC
1 SPPL SSS
1 PATG PGG
1 DANSKE DTA
1 AmGWG HHA
1 TVGSP ODA
0 TVGUT POG
0 AmTote OGE
1 AmtoteMD MDA
0 UT POT
1 PGI PGA
0 AmWB Q9A
0 Macau MU1
0 TPOOL UKT
0 SPTPOOL UKB
0 NETX LIV
0 SPTK ODB
0 SPGTOTE GLA
0 SPGerman ODG
0 SPHLaneB GLB
0 SPHLaneC GLC
0 PBETLTD PGE
0 PDATAP PGF
0 AmPBET HHC
0 WBUT ONB
0 AmHLANE HHH
0 NewTtAA NTA
0 NewTtAB NAB
0 NewTtAC NAC
0 NewTtAD NAD
0 NewTtAE NAE
0 NewTtF NTF
0 NewTtG NTG
0 NewTtH NTH
0 NewTtI NTI
0 NewTtJ NTJ
0 NewTtK NTK
0 NewTtL NTL
0 NewTtM NTM
0 NewTtN NTN
0 NewTtO NTO
0 NewTtP NTP
0 NewTtQ NTQ
0 NewTtR NTR
0 NewTtS NTS
0 NewTtT NTT
生成文件的运行日志:
[2024-07-02 11:10:53.586] main.py -> selection_text line:80 [INFO] : *****************************************************************************
[2024-07-02 11:10:53.587] main.py -> selection_text line:83 [INFO] : TextboxHandler:E:\002TXLV\TOTE\PMC\DTAHK102102023.dat Upload finishied
[2024-07-02 11:10:53.587] main.py -> selection_text line:83 [INFO] : TextboxHandler:E:\002TXLV\TOTE\PMC\HHAHK102102023.dat Upload finishied
[2024-07-02 11:10:53.587] main.py -> selection_text line:83 [INFO] : TextboxHandler:E:\002TXLV\TOTE\PMC\MDAHK102102023.dat Upload finishied
[2024-07-02 11:10:53.587] main.py -> selection_text line:83 [INFO] : TextboxHandler:E:\002TXLV\TOTE\PMC\ODAHK102102023.dat Upload finishied
[2024-07-02 11:10:53.588] main.py -> selection_text line:83 [INFO] : TextboxHandler:E:\002TXLV\TOTE\PMC\PGAHK102102023.dat Upload finishied
[2024-07-02 11:10:53.588] main.py -> selection_text line:83 [INFO] : TextboxHandler:E:\002TXLV\TOTE\PMC\PGGHK102102023.dat Upload finishied
[2024-07-02 11:10:53.588] main.py -> selection_text line:83 [INFO] : TextboxHandler:E:\002TXLV\TOTE\PMC\PMCHK102102023.dat Upload finishied
[2024-07-02 11:10:53.588] main.py -> selection_text line:83 [INFO] : TextboxHandler:E:\002TXLV\TOTE\PMC\SSSHK102102023.dat Upload finishied
[2024-07-02 11:10:53.588] main.py -> selection_text line:83 [INFO] : TextboxHandler:E:\002TXLV\TOTE\PMC\TBAHK102102023.dat Upload finishied
[2024-07-02 11:10:53.589] main.py -> selection_text line:83 [INFO] : TextboxHandler:E:\002TXLV\TOTE\PMC\TBBHK102102023.dat Upload finishied
[2024-07-02 11:10:53.589] main.py -> selection_text line:83 [INFO] : TextboxHandler:E:\002TXLV\TOTE\PMC\TBCHK102102023.dat Upload finishied
[2024-07-02 11:10:53.589] main.py -> selection_text line:83 [INFO] : TextboxHandler:E:\002TXLV\TOTE\PMC\TVAHK102102023.dat Upload finishied
功能介绍:
Upload 是加载出来Dat文件日志在Text文本框:
chear:是清除Text文本框日志
Quit:是退出