func.py 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621
  1. # 모듈들 불러옴
  2. from css_html_js_minify import html_minify, js_minify, css_minify
  3. from flask import session, render_template
  4. from urllib import parse
  5. import json
  6. import sqlite3
  7. import hashlib
  8. import requests
  9. import re
  10. import html
  11. import os
  12. # 일부 툴 불러옴
  13. from set_mark.tool import *
  14. # 나무마크 불러옴
  15. from mark import *
  16. # 서브 언어팩 불러옴
  17. json_data = open(os.path.join('language', 'en-US.json'), 'rt', encoding='utf-8').read()
  18. else_lang = json.loads(json_data)
  19. def load_conn(data):
  20. global conn
  21. global curs
  22. conn = data
  23. curs = conn.cursor()
  24. load_conn2(data)
  25. def captcha_get():
  26. data = ''
  27. if custom()[2] == 0:
  28. curs.execute('select data from other where name = "recaptcha"')
  29. recaptcha = curs.fetchall()
  30. if recaptcha and recaptcha[0][0] != '':
  31. curs.execute('select data from other where name = "sec_re"')
  32. sec_re = curs.fetchall()
  33. if sec_re and sec_re[0][0] != '':
  34. data += recaptcha[0][0] + '<hr>'
  35. return data
  36. def captcha_post(test, num = 1):
  37. if num == 1:
  38. if custom()[2] == 0 and captcha_get() != '':
  39. curs.execute('select data from other where name = "sec_re"')
  40. sec_re = curs.fetchall()
  41. if sec_re and sec_re[0][0] != '':
  42. data = requests.get('https://www.google.com/recaptcha/api/siteverify', params = { 'secret' : sec_re, 'response' : test })
  43. if not data:
  44. return 0
  45. else:
  46. json_data = data.json()
  47. if data.status_code == 200 and json_data['success'] == True:
  48. return 0
  49. else:
  50. return 1
  51. else:
  52. return 0
  53. else:
  54. return 0
  55. else:
  56. pass
  57. def load_lang(data):
  58. global lang
  59. try:
  60. if lang:
  61. pass
  62. except:
  63. curs.execute("select data from other where name = 'language'")
  64. rep_data = curs.fetchall()
  65. json_data = open(os.path.join('language', rep_data[0][0] + '.json'), 'rt', encoding='utf-8').read()
  66. lang = json.loads(json_data)
  67. if data == 'please_all':
  68. return lang
  69. else:
  70. if data in lang:
  71. return lang[data]
  72. else:
  73. return else_lang[data]
  74. def edit_help_button():
  75. # https://stackoverflow.com/questions/11076975/insert-text-into-textarea-at-cursor-position-javascript
  76. '''<script>
  77. function insertAtCursor(myField, myValue) {
  78. if (document.selection) {
  79. document.getElementById(myField).focus();
  80. sel = document.selection.createRange();
  81. sel.text = myValue;
  82. } else if (document.getElementById(myField).selectionStart || document.getElementById(myField).selectionStart == '0') {
  83. var startPos = document.getElementById(myField).selectionStart;
  84. var endPos = document.getElementById(myField).selectionEnd;
  85. document.getElementById(myField).value = document.getElementById(myField).value.substring(0, startPos) + myValue + document.getElementById(myField).value.substring(endPos, document.getElementById(myField).value.length);
  86. } else {
  87. document.getElementById(myField).value += myValue;
  88. }
  89. }
  90. </script>
  91. '''
  92. '<a href="javascript:void(0);" onclick="insertAtCursor(\'content\', \'[[]]\');">(링크)</a> <a href="javascript:void(0);" onclick="insertAtCursor(\'content\', \'[macro()]\');">(매크로)</a> <a href="javascript:void(0);" onclick="insertAtCursor(\'content\', \'{{{#! }}}\');">(중괄호)</a><hr>'
  93. return ['', '']
  94. def ip_warring():
  95. if custom()[2] == 0:
  96. curs.execute('select data from other where name = "no_login_warring"')
  97. data = curs.fetchall()
  98. if data and data[0][0] != '':
  99. text_data = '<span>' + data[0][0] + '</span><hr>'
  100. else:
  101. text_data = '<span>' + load_lang('no_login_warring') + '</span><hr>'
  102. else:
  103. text_data = ''
  104. return text_data
  105. def skin_check():
  106. skin = './views/acme/'
  107. try:
  108. curs.execute('select skin from user where id = ?', [ip_check()])
  109. skin_exist = curs.fetchall()
  110. if skin_exist and skin_exist[0][0] != '':
  111. if os.path.exists(os.path.abspath('./views/' + skin_exist[0][0] + '/index.html')) == 1:
  112. skin = './views/' + skin_exist[0][0] + '/'
  113. else:
  114. curs.execute('select data from other where name = "skin"')
  115. skin_exist = curs.fetchall()
  116. if skin_exist:
  117. if os.path.exists(os.path.abspath('./views/' + skin_exist[0][0] + '/index.html')) == 1:
  118. skin = './views/' + skin_exist[0][0] + '/'
  119. except:
  120. pass
  121. return skin + 'index.html'
  122. def next_fix(link, num, page, end = 50):
  123. list_data = ''
  124. if num == 1:
  125. if len(page) == end:
  126. list_data += '<hr><a href="' + link + str(num + 1) + '">(' + load_lang('next') + ')</a>'
  127. elif len(page) != end:
  128. list_data += '<hr><a href="' + link + str(num - 1) + '">(' + load_lang('previous') + ')</a>'
  129. else:
  130. list_data += '<hr><a href="' + link + str(num - 1) + '">(' + load_lang('previous') + ')</a> <a href="' + link + str(num + 1) + '">(' + load_lang('next') + ')</a>'
  131. return list_data
  132. def other2(origin):
  133. return origin + ['Deleted']
  134. def wiki_set(num):
  135. if num == 1:
  136. data_list = []
  137. curs.execute('select data from other where name = ?', ['name'])
  138. db_data = curs.fetchall()
  139. if db_data and db_data[0][0] != '':
  140. data_list += [db_data[0][0]]
  141. else:
  142. data_list += ['Wiki']
  143. curs.execute('select data from other where name = "license"')
  144. db_data = curs.fetchall()
  145. if db_data and db_data[0][0] != '':
  146. data_list += [db_data[0][0]]
  147. else:
  148. data_list += ['CC 0']
  149. data_list += ['', '']
  150. curs.execute('select data from other where name = "logo"')
  151. db_data = curs.fetchall()
  152. if db_data and db_data[0][0] != '':
  153. data_list += [db_data[0][0]]
  154. else:
  155. data_list += [data_list[0]]
  156. curs.execute("select data from other where name = 'head'")
  157. db_data = curs.fetchall()
  158. if db_data and db_data[0][0] != '':
  159. data_list += [db_data[0][0]]
  160. else:
  161. data_list += ['']
  162. return data_list
  163. if num == 2:
  164. var_data = 'FrontPage'
  165. curs.execute('select data from other where name = "frontpage"')
  166. elif num == 3:
  167. var_data = '2'
  168. curs.execute('select data from other where name = "upload"')
  169. db_data = curs.fetchall()
  170. if db_data and db_data[0][0] != '':
  171. return db_data[0][0]
  172. else:
  173. return var_data
  174. def diff(seqm):
  175. output = []
  176. for opcode, a0, a1, b0, b1 in seqm.get_opcodes():
  177. if opcode == 'equal':
  178. output += [seqm.a[a0:a1]]
  179. elif opcode == 'insert':
  180. output += ["<span style='background:#CFC;'>" + seqm.b[b0:b1] + "</span>"]
  181. elif opcode == 'delete':
  182. output += ["<span style='background:#FDD;'>" + seqm.a[a0:a1] + "</span>"]
  183. elif opcode == 'replace':
  184. output += ["<span style='background:#FDD;'>" + seqm.a[a0:a1] + "</span>"]
  185. output += ["<span style='background:#CFC;'>" + seqm.b[b0:b1] + "</span>"]
  186. return ''.join(output)
  187. def admin_check(num, what):
  188. ip = ip_check()
  189. curs.execute("select acl from user where id = ?", [ip])
  190. user = curs.fetchall()
  191. if user:
  192. reset = 0
  193. while 1:
  194. if num == 1 and reset == 0:
  195. check = 'ban'
  196. elif num == 2 and reset == 0:
  197. check = 'mdel'
  198. elif num == 3 and reset == 0:
  199. check = 'toron'
  200. elif num == 4 and reset == 0:
  201. check = 'check'
  202. elif num == 5 and reset == 0:
  203. check = 'acl'
  204. elif num == 6 and reset == 0:
  205. check = 'hidel'
  206. elif num == 7 and reset == 0:
  207. check = 'give'
  208. else:
  209. check = 'owner'
  210. curs.execute('select name from alist where name = ? and acl = ?', [user[0][0], check])
  211. if curs.fetchall():
  212. if what:
  213. curs.execute("insert into re_admin (who, what, time) values (?, ?, ?)", [ip, what, get_time()])
  214. conn.commit()
  215. return 1
  216. else:
  217. if reset == 0:
  218. reset = 1
  219. else:
  220. break
  221. def ip_pas(raw_ip):
  222. hide = 0
  223. if re.search("(\.|:)", raw_ip):
  224. if not re.search("^" + load_lang('tool') + ":", raw_ip):
  225. curs.execute("select data from other where name = 'ip_view'")
  226. data = curs.fetchall()
  227. if data and data[0][0] != '':
  228. ip = '<span style="font-size: 75%;">' + hashlib.md5(bytes(raw_ip, 'utf-8')).hexdigest() + '</span>'
  229. if not admin_check('ban', None):
  230. hide = 1
  231. else:
  232. ip = raw_ip
  233. else:
  234. ip = raw_ip
  235. hide = 1
  236. else:
  237. curs.execute("select title from data where title = ?", ['' + load_lang('user') + ':' + raw_ip])
  238. if curs.fetchall():
  239. ip = '<a href="/w/' + url_pas('' + load_lang('user') + ':' + raw_ip) + '">' + raw_ip + '</a>'
  240. else:
  241. ip = '<a id="not_thing" href="/w/' + url_pas('' + load_lang('user') + ':' + raw_ip) + '">' + raw_ip + '</a>'
  242. if hide == 0:
  243. ip += ' <a href="/record/' + url_pas(raw_ip) + '">(' + load_lang('record') + ')</a>'
  244. return ip
  245. def custom():
  246. if 'MyMaiToNight' in session:
  247. user_head = session['MyMaiToNight']
  248. else:
  249. user_head = ''
  250. if 'Now' in session and session['Now'] == 1:
  251. curs.execute('select name from alarm where name = ? limit 1', [ip_check()])
  252. if curs.fetchall():
  253. user_icon = 2
  254. else:
  255. user_icon = 1
  256. else:
  257. user_icon = 0
  258. if user_icon != 0:
  259. curs.execute('select email from user where id = ?', [ip_check()])
  260. data = curs.fetchall()
  261. if data:
  262. email = data[0][0]
  263. else:
  264. email = ''
  265. else:
  266. email = ''
  267. if user_icon != 0:
  268. user_name = ip_check()
  269. else:
  270. user_name = '' + load_lang('user') + ''
  271. return ['', '', user_icon, user_head, email, user_name]
  272. def acl_check(name):
  273. ip = ip_check()
  274. if ban_check() == 1:
  275. return 1
  276. acl_c = re.search("^" + load_lang('user') + ":([^/]*)", name)
  277. if acl_c:
  278. acl_n = acl_c.groups()
  279. if admin_check(5, None) == 1:
  280. return 0
  281. curs.execute("select dec from acl where title = ?", ['' + load_lang('user') + ':' + acl_n[0]])
  282. acl_data = curs.fetchall()
  283. if acl_data:
  284. if acl_data[0][0] == 'all':
  285. return 0
  286. if acl_data[0][0] == 'user' and not re.search("(\.|:)", ip):
  287. return 0
  288. if ip != acl_n[0] or re.search("(\.|:)", ip):
  289. return 1
  290. if ip == acl_n[0] and not re.search("(\.|:)", ip) and not re.search("(\.|:)", acl_n[0]):
  291. return 0
  292. else:
  293. return 1
  294. file_c = re.search("^" + load_lang('file') + ":(.*)", name)
  295. if file_c and admin_check(5, 'edit (' + name + ')') != 1:
  296. return 1
  297. curs.execute("select acl from user where id = ?", [ip])
  298. user_data = curs.fetchall()
  299. curs.execute("select dec from acl where title = ?", [name])
  300. acl_data = curs.fetchall()
  301. if acl_data:
  302. if acl_data[0][0] == 'user':
  303. if not user_data:
  304. return 1
  305. if acl_data[0][0] == 'admin':
  306. if not user_data:
  307. return 1
  308. if not admin_check(5, 'edit (' + name + ')') == 1:
  309. return 1
  310. curs.execute('select data from other where name = "edit"')
  311. set_data = curs.fetchall()
  312. if set_data:
  313. if set_data[0][0] == 'user':
  314. if not user_data:
  315. return 1
  316. if set_data[0][0] == 'admin':
  317. if not user_data:
  318. return 1
  319. if not admin_check(5, None) == 1:
  320. return 1
  321. return 0
  322. def ban_check():
  323. ip = ip_check()
  324. band = re.search("^([0-9]{1,3}\.[0-9]{1,3})", ip)
  325. if band:
  326. band_it = band.groups()[0]
  327. else:
  328. band_it = 'Not'
  329. curs.execute("select block from ban where block = ?", [band_it])
  330. band_d = curs.fetchall()
  331. curs.execute("select block from ban where block = ?", [ip])
  332. ban_d = curs.fetchall()
  333. if band_d or ban_d:
  334. return 1
  335. return 0
  336. def topic_check(name, sub):
  337. ip = ip_check()
  338. if ban_check() == 1:
  339. return 1
  340. curs.execute("select acl from user where id = ?", [ip])
  341. user_data = curs.fetchall()
  342. curs.execute("select dis from acl where title = ?", [name])
  343. acl_data = curs.fetchall()
  344. if acl_data:
  345. if acl_data[0][0] == 'user':
  346. if not user_data:
  347. return 1
  348. if acl_data[0][0] == 'admin':
  349. if not user_data:
  350. return 1
  351. if not admin_check(3, 'topic (' + name + ')') == 1:
  352. return 1
  353. curs.execute("select title from stop where title = ? and sub = ?", [name, sub])
  354. if curs.fetchall():
  355. if not admin_check(3, 'topic (' + name + ')') == 1:
  356. return 1
  357. return 0
  358. def ban_insert(name, end, why, login, blocker):
  359. time = get_time()
  360. if re.search("^([0-9]{1,3}\.[0-9]{1,3})$", name):
  361. band = 'O'
  362. else:
  363. band = ''
  364. curs.execute("select block from ban where block = ?", [name])
  365. if curs.fetchall():
  366. curs.execute("insert into rb (block, end, today, blocker, why, band) values (?, ?, ?, ?, ?, ?)", [name, '' + load_lang('release') + '', time, blocker, '', band])
  367. curs.execute("delete from ban where block = ?", [name])
  368. else:
  369. if login != '':
  370. login = 'O'
  371. else:
  372. login = ''
  373. if end != '':
  374. end += ' 00:00:00'
  375. curs.execute("insert into rb (block, end, today, blocker, why, band) values (?, ?, ?, ?, ?, ?)", [name, end, time, blocker, why, band])
  376. curs.execute("insert into ban (block, end, why, band, login) values (?, ?, ?, ?, ?)", [name, end, why, band, login])
  377. conn.commit()
  378. def rd_plus(title, sub, date):
  379. curs.execute("select title from rd where title = ? and sub = ?", [title, sub])
  380. if curs.fetchall():
  381. curs.execute("update rd set date = ? where title = ? and sub = ?", [date, title, sub])
  382. else:
  383. curs.execute("insert into rd (title, sub, date) values (?, ?, ?)", [title, sub, date])
  384. def history_plus(title, data, date, ip, send, leng):
  385. curs.execute("select id from history where title = ? order by id + 0 desc limit 1", [title])
  386. id_data = curs.fetchall()
  387. if id_data:
  388. curs.execute("insert into history (id, title, data, date, ip, send, leng) values (?, ?, ?, ?, ?, ?, ?)", [str(int(id_data[0][0]) + 1), title, data, date, ip, send, leng])
  389. else:
  390. curs.execute("insert into history (id, title, data, date, ip, send, leng) values ('1', ?, ?, ?, ?, ?, ?)", [title, data, date, ip, send + ' (' + load_lang('new') + ' ' + load_lang('document') + ')', leng])
  391. def leng_check(first, second):
  392. if first < second:
  393. all_plus = '+' + str(second - first)
  394. elif second < first:
  395. all_plus = '-' + str(first - second)
  396. else:
  397. all_plus = '0'
  398. return all_plus
  399. def redirect(data):
  400. return '<meta http-equiv="refresh" content="0; url=' + data + '">'
  401. def re_error(data):
  402. if data == '/ban':
  403. ip = ip_check()
  404. end = '<li>Why : 권한이 맞지 않는 상태 입니다.</li>'
  405. if ban_check() == 1:
  406. curs.execute("select end, why from ban where block = ?", [ip])
  407. end_data = curs.fetchall()
  408. if not end_data:
  409. match = re.search("^([0-9]{1,3}\.[0-9]{1,3})", ip)
  410. if match:
  411. curs.execute("select end, why from ban where block = ?", [match.groups()[0]])
  412. end_data = curs.fetchall()
  413. if end_data:
  414. end = '<li>Info : '
  415. if end_data[0][0]:
  416. now = int(re.sub('(\-| |:)', '', get_time()))
  417. day = int(re.sub('(\-| |:)', '', end_data[0][0]))
  418. if now >= day:
  419. curs.execute("delete from ban where block = ?", [ip])
  420. conn.commit()
  421. end += 'Re Try.'
  422. else:
  423. end += 'Ban : ' + end_data[0][0]
  424. else:
  425. end += 'Ban : No End'
  426. end += '</li>'
  427. if end_data[0][1] != '':
  428. end += '<li>Why : ' + end_data[0][1] + '</li>'
  429. return html_minify(render_template(skin_check(),
  430. imp = ['Authority Error', wiki_set(1), custom(), other2([0, 0])],
  431. data = '<h2>Info</h2><ul>' + end + '</ul>',
  432. menu = 0
  433. ))
  434. error_data = re.search('\/error\/([0-9]+)', data)
  435. if error_data:
  436. num = int(error_data.groups()[0])
  437. if num == 1:
  438. title = 'Authority Error'
  439. data = '비 로그인 상태 입니다.'
  440. elif num == 2:
  441. title = 'Authority Error'
  442. data = '이 계정이 없습니다.'
  443. elif num == 3:
  444. title = 'Authority Error'
  445. data = '권한이 모자랍니다.'
  446. elif num == 4:
  447. title = 'Authority Error'
  448. data = '관리자는 차단, 검사 할 수 없습니다.'
  449. elif num == 5:
  450. title = 'User Error'
  451. data = '그런 계정이 없습니다.'
  452. elif num == 6:
  453. title = 'Register Error'
  454. data = '동일한 아이디의 사용자가 있습니다.'
  455. elif num == 7:
  456. title = 'Register Error'
  457. data = '아이디는 20글자보다 짧아야 합니다.'
  458. elif num == 8:
  459. title = 'Register Error'
  460. data = '아이디에는 한글과 알파벳과 공백만 허용 됩니다.'
  461. elif num == 9:
  462. title = 'Upload Error'
  463. data = '파일이 없습니다.'
  464. elif num == 10:
  465. title = 'PassWord Error'
  466. data = '비밀번호가 다릅니다.'
  467. elif num == 11:
  468. title = 'Login Error'
  469. data = '이미 로그인 되어 있습니다.'
  470. elif num == 13:
  471. title = 'reCAPTCHA Error'
  472. data = '리캡차를 통과하세요.'
  473. elif num == 14:
  474. title = 'Upload Error'
  475. data = 'jpg, gif, jpeg, png, webp만 가능 합니다.'
  476. elif num == 15:
  477. title = 'Edit Error'
  478. data = '편집 기록은 500자를 넘을 수 없습니다.'
  479. elif num == 16:
  480. title = 'Upload Error'
  481. data = '동일한 이름의 파일이 있습니다.'
  482. elif num == 17:
  483. title = 'Upload Error'
  484. data = '파일 용량은 ' + wiki_set(3) + 'MB를 넘길 수 없습니다.'
  485. elif num == 18:
  486. title = 'Edit Error'
  487. data = '내용이 원래 문서와 동일 합니다.'
  488. elif num == 19:
  489. title = 'Move Error'
  490. data = '이동 하려는 곳에 문서가 이미 있습니다.'
  491. elif num == 20:
  492. title = 'PassWord Error'
  493. data = '재 확인이랑 비밀번호가 다릅니다.'
  494. elif num == 21:
  495. title = 'Edit Error'
  496. data = '편집 필터에 의해 검열 되었습니다.'
  497. elif num == 22:
  498. title = 'Upload Error'
  499. data = '파일 이름은 알파벳, 한글, 띄어쓰기, 언더바, 빼기표만 허용 됩니다.'
  500. else:
  501. title = 'Error'
  502. data = '???'
  503. if title:
  504. return html_minify(render_template(skin_check(),
  505. imp = [title, wiki_set(1), custom(), other2([0, 0])],
  506. data = '<h2>Error</h2><ul><li>' + data + '</li></ul>',
  507. menu = 0
  508. ))
  509. else:
  510. return redirect('/')
  511. else:
  512. return redirect('/')