garbage.py 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355
  1. import time
  2. from . import DBBit
  3. from .db import DB
  4. from tool.type_ import *
  5. from tool.time_ import mysql_time, time_from_mysql
  6. from core.garbage import GarbageBag, GarbageType
  7. def update_garbage_type(where: str, type_: int, db: DB) -> int:
  8. if len(where) == 0:
  9. return -1
  10. cur = db.done(f"UPDATE garbage SET GarbageType={type_} WHERE {where};")
  11. if cur is None:
  12. return -1
  13. return cur.rowcount
  14. def update_garbage_check(where: str, check_: bool, db: DB) -> int:
  15. if len(where) == 0:
  16. return -1
  17. i = 1 if check_ else 0
  18. cur = db.done(f"UPDATE garbage SET CheckResult={i} WHERE {where};")
  19. if cur is None:
  20. return -1
  21. return cur.rowcount
  22. def __get_time(time_str: str) -> float:
  23. if time_str == 'now':
  24. return time.time()
  25. if time_str.startswith("Date:") and len(time_str) >= 5:
  26. return time_from_mysql(time_str[5:])
  27. return float(time_str)
  28. def __get_time_diff(time_str: str) -> float:
  29. if time_str.endswith("s") and len(time_str) >= 2:
  30. return float(time_str[:-1])
  31. elif time_str.endswith("ms") and len(time_str) >= 3:
  32. return float(time_str[:-1]) / 1000
  33. elif time_str.endswith("min") and len(time_str) >= 4:
  34. return float(time_str[:-1]) * 60
  35. elif time_str.endswith("h") and len(time_str) >= 2:
  36. return float(time_str[:-1]) * 60 * 60
  37. elif time_str.endswith("d") and len(time_str) >= 2:
  38. return float(time_str[:-1]) * 24 * 60 * 60
  39. return float(time_str)
  40. def __search_fields_time(time_: str, time_name: str) -> str:
  41. if time_ == '<=now':
  42. return f"{time_name}<={mysql_time()} AND"
  43. sp = time_.split(',')
  44. if len(sp) == 2:
  45. try:
  46. time_list = __get_time(sp[0]), __get_time(sp[1])
  47. a = min(time_list)
  48. b = max(time_list)
  49. except (TypeError, ValueError):
  50. return ""
  51. else:
  52. return f"({time_name} BETWEEN {mysql_time(a)} AND {mysql_time(b)}) AND"
  53. sp = time_.split(';')
  54. if len(sp) == 2:
  55. try:
  56. time_list = __get_time(sp[0]), __get_time_diff(sp[1])
  57. a = time_list[0] - time_list[1]
  58. b = time_list[0] + time_list[1]
  59. except (TypeError, ValueError):
  60. return ""
  61. else:
  62. return f"({time_name} BETWEEN {mysql_time(a)} AND {mysql_time(b)}) AND"
  63. try:
  64. t = __get_time(time_)
  65. except (TypeError, ValueError):
  66. return ""
  67. else:
  68. return f"({time_name}={mysql_time(t)} AND"
  69. def search_garbage_by_fields(columns, gid, uid, cuid, create_time, use_time, loc, type_, check, db: DB):
  70. where = ""
  71. if gid is not None:
  72. where += f"GarbageID={gid} AND "
  73. if uid is not None:
  74. where += f"UserID=‘{uid}’ AND "
  75. if cuid is not None:
  76. where += f"CheckerID='{cuid}' AND "
  77. if loc is not None:
  78. where += f"Location='{loc}' AND "
  79. if check is not None:
  80. if check == "False":
  81. where += f"CheckResult=0 AND "
  82. else:
  83. where += f"CheckResult=1 AND "
  84. if type_ is not None and type_ in GarbageType.GarbageTypeStrList:
  85. res = GarbageType.GarbageTypeStrList.index(type_)
  86. where += f"Phone={res} AND "
  87. if create_time is not None:
  88. where += __search_fields_time(create_time, "CreateTime")
  89. if use_time is not None:
  90. where += __search_fields_time(use_time, "UseTime")
  91. if len(where) != 0:
  92. where = where[0:-4] # 去除末尾的AND
  93. return search_from_garbage_view(columns, where, db)
  94. def search_from_garbage_view(columns, where: str, db: DB):
  95. if len(where) > 0:
  96. where = f"WHERE {where} "
  97. column = ", ".join(columns)
  98. cur = db.search(f"SELECT {column} FROM garbage {where};")
  99. if cur is None:
  100. return None
  101. res = cur.fetchall()
  102. return res
  103. def count_garbage_by_time(uid: uid_t, db: DB):
  104. ti: time_t = time.time()
  105. start = ti - 3.5 * 24 * 60 * 60 # 前后3.5天
  106. end = ti + 3.5 * 24 * 60 * 60
  107. cur = db.search(f"SELECT GarbageID "
  108. f"FROM garbage_time "
  109. f"WHERE UserID = '{uid}' AND UseTime BETWEEN {mysql_time(start)} AND {mysql_time(end)};")
  110. if cur is None:
  111. return -1
  112. return cur.rowcount
  113. def __find_garbage(sql: str, res_len, db: DB):
  114. cur = db.search(sql)
  115. if cur is None or cur.rowcount == 0:
  116. return [None, tuple()]
  117. assert cur.rowcount == 1
  118. res = cur.fetchone()
  119. assert len(res) == res_len
  120. return GarbageBag(str(res[0])), res
  121. def find_not_use_garbage(gid: gid_t, db: DB) -> Union[GarbageBag, None]:
  122. return __find_garbage(f"SELECT GarbageID FROM garbage_n WHERE GarbageID = {gid};", 1, db)[0]
  123. def find_wait_garbage(gid: gid_t, db: DB) -> Union[GarbageBag, None]:
  124. res: Tuple[int, bytes, str, str, str]
  125. gb: GarbageBag
  126. gb, res = __find_garbage(f"SELECT GarbageID, GarbageType, UseTime, UserID, Location "
  127. f"FROM garbage_c "
  128. f"WHERE GarbageID = {gid};", 5, db)
  129. if gb is None:
  130. return None
  131. garbage_type: enum = int(res[1].decode())
  132. use_time: time_t = time_from_mysql(res[2])
  133. uid: uid_t = res[3]
  134. loc: location_t = res[4]
  135. gb.config_use(garbage_type, use_time, uid, loc)
  136. return gb
  137. def find_use_garbage(gid: gid_t, db: DB) -> Union[GarbageBag, None]:
  138. res: Tuple[int, bytes, str, str, str, bytes]
  139. gb: GarbageBag
  140. gb, res = __find_garbage(f"SELECT GarbageID, GarbageType, UseTime, UserID, Location, CheckResult, CheckerID "
  141. f"FROM garbage_u "
  142. f"WHERE GarbageID = {gid};", 7, db)
  143. if gb is None:
  144. return None
  145. garbage_type: enum = int(res[1].decode())
  146. use_time: time_t = time_from_mysql(res[2])
  147. uid: uid_t = res[3]
  148. loc: location_t = res[4]
  149. check: bool = res[5] == DBBit.BIT_1
  150. check_uid: uid_t = res[6]
  151. gb.config_use(garbage_type, use_time, uid, loc)
  152. gb.config_check(check, check_uid)
  153. return gb
  154. def find_garbage(gid: gid_t, db: DB) -> Union[GarbageBag, None]:
  155. res: Tuple[bool, int] = is_garbage_exists(gid, db)
  156. if not res[0]:
  157. return None
  158. elif res[1] == 0:
  159. re = find_not_use_garbage(gid, db)
  160. elif res[1] == 1:
  161. re = find_wait_garbage(gid, db)
  162. elif res[1] == 2:
  163. re = find_use_garbage(gid, db)
  164. else:
  165. re = None
  166. assert re is not None
  167. return re
  168. def is_garbage_exists(gid: gid_t, db: DB) -> Tuple[bool, int]:
  169. cur = db.search(f"SELECT GarbageID, Flat FROM garbage WHERE GarbageID = {gid};")
  170. if cur is None or cur.rowcount == 0:
  171. return False, 0
  172. assert cur.rowcount == 1
  173. res: Tuple[int, int] = cur.fetchone()
  174. return True, res[1]
  175. def update_garbage(garbage: GarbageBag, db: DB) -> bool:
  176. re = find_garbage(garbage.get_gid(), db)
  177. if re is None:
  178. return False
  179. if re.is_use() and not garbage.is_use() or re.is_check()[0] and not garbage.is_check():
  180. return False
  181. if not garbage.is_use() and not garbage.is_check()[0]:
  182. return True # 不做任何修改
  183. gid = garbage.get_gid()
  184. info = garbage.get_info()
  185. if garbage.is_check()[0]:
  186. res = db.done(f"UPDATE garbage SET "
  187. f"Flat = 2,"
  188. f"UserID = '{info['user']}',"
  189. f"UseTime = {time_from_mysql(info['use_time'])},"
  190. f"GarbageType = {info['type']},"
  191. f"Location = '{info['loc']}',"
  192. f"CheckResult = {info['check']},"
  193. f"CheckerID = '{info['checker']}',"
  194. f"WHERE GarbageID = {gid};")
  195. elif garbage.is_use():
  196. res = db.done(f"UPDATE garbage SET "
  197. f"Flat = 1,"
  198. f"UserID = '{info['user']}',"
  199. f"UseTime = {time_from_mysql(info['use_time'])},"
  200. f"GarbageType = {info['type']},"
  201. f"Location = '{info['loc']}',"
  202. f"CheckResult = NULL,"
  203. f"CheckerID = NULL,"
  204. f"WHERE GarbageID = {gid};")
  205. else:
  206. res = db.done(f"UPDATE garbage SET "
  207. f"Flat = 0,"
  208. f"UserID = NULL,"
  209. f"UseTime = NULL,"
  210. f"GarbageType = NULL,"
  211. f"Location = NULL,"
  212. f"CheckResult = NULL,"
  213. f"CheckerID = NULL,"
  214. f"WHERE GarbageID = {gid};")
  215. return res is not None
  216. def create_new_garbage(db: DB) -> Optional[GarbageBag]:
  217. cur = db.done(f"INSERT INTO garbage(CreateTime, Flat) VALUES ({mysql_time()}, 0);")
  218. if cur is None:
  219. return None
  220. assert cur.rowcount == 1
  221. gid = cur.lastrowid
  222. return GarbageBag(str(gid))
  223. def del_garbage_not_use(gid: gid_t, db: DB) -> bool:
  224. cur = db.done(f"DELETE FROM garbage_n WHERE GarbageID = {gid};")
  225. if cur is None or cur.rowcount == 0:
  226. return False
  227. assert cur.rowcount == 1
  228. return True
  229. def del_garbage_wait_check(gid: gid_t, db: DB) -> bool:
  230. cur = db.done(f"DELETE FROM garbage_c WHERE GarbageID = {gid};")
  231. if cur is None or cur.rowcount == 0:
  232. return False
  233. assert cur.rowcount == 1
  234. return True
  235. def del_garbage_has_check(gid: gid_t, db: DB) -> bool:
  236. cur = db.done(f"DELETE FROM garbage_u WHERE GarbageID = {gid};")
  237. if cur is None or cur.rowcount == 0:
  238. return False
  239. assert cur.rowcount == 1
  240. return True
  241. def del_garbage(gid, db: DB):
  242. cur = db.done(f"DELETE FROM garbage WHERE GarbageID = {gid};")
  243. if cur is None or cur.rowcount == 0:
  244. return False
  245. assert cur.rowcount == 1
  246. return True
  247. def del_garbage_where_not_use(where, db: DB) -> int:
  248. cur = db.done_(f"DELETE FROM garbage_n WHERE {where};")
  249. if cur is None:
  250. return -1
  251. return cur.rowcount
  252. def del_garbage_where_wait_check(where, db: DB) -> int:
  253. cur = db.done_(f"DELETE FROM garbage_c WHERE {where};")
  254. if cur is None:
  255. return -1
  256. return cur.rowcount
  257. def del_garbage_where_has_check(where, db: DB) -> int:
  258. cur = db.done_(f"DELETE FROM garbage_u WHERE {where};")
  259. if cur is None:
  260. return -1
  261. return cur.rowcount
  262. def del_garbage_where_scan_not_use(where, db: DB) -> int:
  263. cur = db.done(f"SELECT GarbageID FROM garbage_n WHERE {where};")
  264. if cur is None:
  265. return -1
  266. return cur.rowcount
  267. def del_garbage_where_scan_wait_check(where, db: DB) -> int:
  268. cur = db.done(f"SELECT GarbageID FROM garbage_c WHERE {where};")
  269. if cur is None:
  270. return -1
  271. return cur.rowcount
  272. def del_garbage_where_scan_has_check(where, db: DB) -> int:
  273. cur = db.done(f"SELECT GarbageID FROM garbage_u WHERE {where};")
  274. if cur is None:
  275. return -1
  276. return cur.rowcount
  277. def del_all_garbage(db: DB) -> int:
  278. cur = db.done(f"DELETE FROM garbage WHERE 1;")
  279. if cur is None:
  280. return -1
  281. return cur.rowcount
  282. def del_all_garbage_scan(db: DB) -> int:
  283. cur = db.done(f"SELECT GarbageID FROM garbage WHERE 1;")
  284. if cur is None:
  285. return -1
  286. return cur.rowcount