Найти - Пользователи
Полная версия: Скрипт для удаления файлов старше N дней
Начало » Python для новичков » Скрипт для удаления файлов старше N дней
1 2 3
Андрей Светлов
Так - хорошо.
console = logging.StreamHandler()
console будет писать в sys.stderr. Это то, что вам нужно?
И, ей-богу, не нужно править каждый раз первое сообщение. Крайне неудобно читать, ускользает суть сделанных изменений. Добавляйте код каждый раз заново.
zloymih
Сейчас у меня получилось, что скрипт пишет и в консоль и в файл - как раз то, что нужно. А вот насколько правильно я это сделал - не уверен.
Андрей Светлов
Я понимаю. Можно оставить все так, как сейчас.
Еще раз:
console = logging.StreamHandler()
будет писать в sys.stderr, это второй номер. Ну, помните $ ./script > out.txt 2>&1

console = logging.StreamHandler(sys.stdout)
направит лог в первый поток. Что именно требуется - решать вам.
zloymih
Конечно лучше выводить в первый поток. Спасибо за подсказку. В справке об этом говорится, я не внимательно прочитал.
окончательный вариант
#!C:/Python32/python.exe

import os
import sys
import datetime
import string
import logging
import argparse

parser = argparse.ArgumentParser(description='Deletes files older than N days')
parser.add_argument('rootdir', metavar='DirRoot', help='Folder with files')
parser.add_argument('dayold', metavar='N', type=int, help='Number of days')
parser.add_argument('-l', '--logfile', metavar='LogFile', default='log.txt',
help='Log file')
parser.add_argument('-c', '--column', metavar='C', type=int, default=60,
help='Column Width')

args = parser.parse_args()

rootdir = args.rootdir
dayold = args.dayold
logfile = args.logfile
columnw = args.column
dnow = datetime.datetime.now()


logging.basicConfig(level = logging.DEBUG,
format = '%(asctime)s {%(filename)s} %(levelname)s: %(message)s',
datefmt = '%Y-%m-%d %H:%M:%S',
filename = logfile,
filemode='a')

console = logging.StreamHandler(sys.stdout)
console.setLevel(logging.INFO)
formatter = logging.Formatter('%(asctime)s {%(filename)s} %(levelname)s:%(message)s')
console.setFormatter(formatter)
logging.getLogger().addHandler(console)
#logging.info('*')
logger1 = logging.getLogger('myapp.area1')


if not os.path.exists(rootdir) :
sys.exit('Missing folder: %s', rootdir)

fileList = []
for root, subFolders, files in os.walk(rootdir):
for file in files:
fileList.append(os.path.join(root, file))


for file in fileList:
try:
dmodify = datetime.datetime.fromtimestamp(os.path.getmtime(file))
days_diff = (dnow-dmodify).days
if days_diff > dayold :
os.remove(file)
logger1.info('%s %s %s deleted', file.ljust(columnw),
dmodify.strftime('%Y-%m-%d %H:%M:%S'), days_diff)
else :
logger1.info('%s %s %s', file.ljust(columnw),
dmodify.strftime('%Y-%m-%d %H:%M:%S'), days_diff)
except OSError as e:
logger1.error('OSError: {}. File: {}'.format(e.strerror, e.filename))
Всем большое спасибо за помощь.
strannik747
zloymih
Конечно лучше выводить в первый поток. Спасибо за подсказку. В справке об этом говорится, я не внимательно прочитал.
окончательный вариант
В целом для скрипта неплохо, но получилось уже довольно длинно, приходится вникать в смысл отдельных блоков. Как дальнейшее улучшение, я бы предложил разбить на отдельные функции. При дальнейших изменениях будет проще и безопаснее модифицировать. Что-то типа:

def parse_arguments():
...
def configure_logging(logname):
...
def delete_old_files(root_dir, daysold, logger):
...

def main():
(root_dir, daysold, logname) = parse_arguments()
logger = configure_logging(logname)
delete_old_files(root_dir, daysold, logger)

if __name__ == '__main__':
main()
А следующий уровень – вообще класс сделать, чтобы с передачей параметров не мучиться :)
zloymih
Это, кстати, хорошая мысль про функции :) А классы - это пока для меня очень сложно. ООП - это уже другой уровень. Есть к чему стремиться.
ZZZ
Не надо пихать ООП туда, где оно не нужно. В данном случае, разбивка на функции будет идеальна.
zloymih
Разбил скрипт на функции. Действительно, стало симпатишней :)
#!C:/Python32/python.exe

import os
import sys
import datetime
import string
import logging
import argparse


def parse_arguments():
parser = argparse.ArgumentParser(description='Deletes files older than N days')
parser.add_argument('rootdir', metavar='DirRoot', help='Folder with files')
parser.add_argument('daysold', metavar='N', type=int, help='Number of days')
parser.add_argument('-l', '--logfile', metavar='LogFile', default='log.txt',
help='Log file')
parser.add_argument('-c', '--column', metavar='C', type=int, default=60,
help='Column Width')
args = parser.parse_args()

return args.rootdir, args.daysold, args.logfile, args.column


def configure_logging(logfile):
logging.basicConfig(level = logging.DEBUG,
format = '%(asctime)s {%(filename)s} %(levelname)s: %(message)s',
datefmt = '%Y-%m-%d %H:%M:%S',
filename = logfile,
filemode='a')

console = logging.StreamHandler(sys.stdout)
console.setLevel(logging.INFO)
formatter = logging.Formatter('%(asctime)s {%(filename)s} %(levelname)s:%(message)s')
console.setFormatter(formatter)
logging.getLogger().addHandler(console)
#logging.info('')
return logging.getLogger('myapp')


def delete_old_files(rootdir, daysold, columnw, logger):
if not os.path.exists(rootdir) :
sys.exit('Missing folder: %s', rootdir)

fileList = []
for root, subFolders, files in os.walk(rootdir):
for file in files:
fileList.append(os.path.join(root, file))

dnow = datetime.datetime.now()

for file in fileList:
try:
dmodify = datetime.datetime.fromtimestamp(os.path.getmtime(file))
days_diff = (dnow-dmodify).days
if days_diff > daysold :
os.remove(file)
logger.info('%s %s %s deleted', file.ljust(columnw),
dmodify.strftime('%Y-%m-%d %H:%M:%S'), days_diff)
else :
logger.info('%s %s %s', file.ljust(columnw),
dmodify.strftime('%Y-%m-%d %H:%M:%S'), days_diff)
except OSError as e:
logger.error('OSError: {}. File: {}'.format(e.strerror, e.filename))

def main():
(rootdir, daysold, logfile, columnw) = parse_arguments()
logger = configure_logging(logfile)
delete_old_files(rootdir, daysold, columnw, logger)

if __name__ == '__main__':
main()
А ООП сюда я и не собирался пихать. Я говорил о том, что ООП для меня это лес дремучий. И что я хочу в нем разобраться.
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Powered by DjangoBB