lcmail-wizard.py 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178
  1. #!/usr/bin/env python3
  2. #
  3. # lcmail-wizard - Script for mail (and log) auto deletion
  4. #
  5. # Actions:
  6. # * Create new mail dir structure if new entries are added
  7. # inside lcmail-wizard.yml, but not delete mail dir
  8. # if entries are removed from lcmail-wizard.yml
  9. # * Read lcmail-wizard.yml file parsing auto del rules,
  10. # and procede with deletion (mail and log)
  11. #
  12. # See README for more information
  13. #
  14. import argparse
  15. import datetime
  16. import logging
  17. import os
  18. import yaml
  19. # Default envs
  20. BASE = os.path.abspath(os.path.dirname(__file__))
  21. CONF = os.path.join(BASE, "lcmail-wizard.yml")
  22. HOME = os.environ["HOME"]
  23. LOGDIR = os.path.join(BASE, "log/")
  24. MAILDIR = os.path.join(HOME, ".maildir")
  25. PROCMAIL = os.path.join(HOME, ".procmail")
  26. TRASH = os.path.join(MAILDIR, ".Trash/cur")
  27. # Log configuration
  28. logging.basicConfig(
  29. filename=LOGDIR + "lcmail-wizard.log." + datetime.date.today().strftime("%y-%m-%d"),
  30. filemode="a",
  31. level=logging.DEBUG,
  32. format="%(asctime)s - %(levelname)s: %(message)s",
  33. )
  34. # Argparse configuration
  35. parser = argparse.ArgumentParser(
  36. description="lcmail-wizard.py - Script for mail (and log) auto deletion",
  37. formatter_class=argparse.RawDescriptionHelpFormatter,
  38. )
  39. parser.add_argument(
  40. "-c",
  41. "--create",
  42. help="update maildir structure (creation only)",
  43. action="store_true",
  44. default=False,
  45. )
  46. parser.add_argument(
  47. "-d", "--debug", help="no action, only logging", action="store_true", default=False
  48. )
  49. args = parser.parse_args()
  50. def pconf():
  51. """ Parse yaml configuration file """
  52. try:
  53. with open(CONF, "r") as fsi:
  54. try:
  55. conf = yaml.load(fsi)
  56. return conf
  57. except BaseException:
  58. logging.exception("%s not loaded", CONF)
  59. except FileNotFoundError:
  60. logging.exception("%s not found", CONF)
  61. def cdate(filename):
  62. """ Return creation datetime """
  63. time = os.path.getctime(filename)
  64. return datetime.datetime.fromtimestamp(time)
  65. def ddate(filename):
  66. """ Return difference between creation date and nowdate in days """
  67. return abs((datetime.datetime.now() - cdate(filename)).days)
  68. def mkdir_maildir(debug):
  69. """ Update mail directories (only creation update for safe) """
  70. types = pconf()
  71. for type in types:
  72. if type == "mail":
  73. dirs = types[type]
  74. for dir in dirs:
  75. if debug:
  76. if os.path.exists(os.path.join(MAILDIR, dir)):
  77. pass
  78. else:
  79. logging.debug(
  80. "%s folder structure created", os.path.join(MAILDIR, dir)
  81. )
  82. else:
  83. if os.path.exists(os.path.join(MAILDIR, dir)):
  84. pass
  85. else:
  86. os.makedirs(os.path.join(MAILDIR, dir), mode=0o700)
  87. os.makedirs(os.path.join(MAILDIR, dir, "cur"), mode=0o700)
  88. os.makedirs(os.path.join(MAILDIR, dir, "new"), mode=0o700)
  89. os.makedirs(os.path.join(MAILDIR, dir, "tmp"), mode=0o700)
  90. logging.info(
  91. "%s folder structure created", os.path.join(MAILDIR, dir)
  92. )
  93. def empty_mail_log(debug):
  94. """ Empty logs and mails """
  95. types = pconf()
  96. for type in types:
  97. if type == "mail":
  98. dirs = types[type]
  99. for dir in dirs:
  100. if dirs[dir] != 0:
  101. os.chdir(os.path.join(MAILDIR, dir, "cur"))
  102. for mail in os.listdir("."):
  103. if ddate(mail) >= dirs[dir]:
  104. if debug:
  105. logging.debug(
  106. "%s in %s with ddate %s conf %s to delete",
  107. mail,
  108. dir,
  109. ddate(mail),
  110. dirs[dir],
  111. )
  112. else:
  113. os.rename(mail, os.path.join(TRASH, mail))
  114. logging.info("%s in %s deleted", mail, dir)
  115. elif type == "log":
  116. dirs = types[type]
  117. for dir in dirs:
  118. if dir == "procmail":
  119. if dirs[dir] != 0:
  120. os.chdir(os.path.join(PROCMAIL, "log"))
  121. for log in os.listdir("."):
  122. if ddate(log) >= dirs[dir]:
  123. if debug:
  124. logging.debug(
  125. "%s in %s/log with ddate %s conf %s to delete",
  126. log,
  127. dir,
  128. ddate(log),
  129. dirs[dir],
  130. )
  131. else:
  132. os.remove(log)
  133. logging.info("%s in %s/log deleted", log, dir)
  134. elif dir == "lcmail":
  135. if dirs[dir] != 0:
  136. os.chdir(os.path.join(LOGDIR))
  137. for log in os.listdir("."):
  138. if ddate(log) >= dirs[dir]:
  139. if debug:
  140. logging.debug(
  141. "%s in %s/log with ddate %s conf %s to delete",
  142. log,
  143. dir,
  144. ddate(log),
  145. dirs[dir],
  146. )
  147. else:
  148. os.remove(log)
  149. logging.info("%s in %s/log deleted", log, dir)
  150. else:
  151. pass
  152. else:
  153. pass
  154. if __name__ == "__main__":
  155. try:
  156. if args.create:
  157. mkdir_maildir(args.debug)
  158. else:
  159. empty_mail_log(args.debug)
  160. except BaseException:
  161. logging.exception("General exception occured")