app.py 197 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783378437853786378737883789379037913792379337943795379637973798379938003801380238033804380538063807380838093810381138123813381438153816381738183819382038213822382338243825382638273828382938303831383238333834383538363837383838393840384138423843384438453846384738483849385038513852385338543855385638573858385938603861386238633864386538663867386838693870387138723873387438753876387738783879388038813882388338843885388638873888388938903891389238933894389538963897389838993900390139023903390439053906390739083909391039113912391339143915391639173918391939203921392239233924392539263927392839293930393139323933393439353936393739383939394039413942394339443945394639473948394939503951395239533954395539563957395839593960396139623963396439653966396739683969397039713972397339743975397639773978397939803981398239833984398539863987398839893990399139923993399439953996399739983999400040014002400340044005400640074008400940104011401240134014401540164017401840194020402140224023402440254026402740284029403040314032403340344035403640374038403940404041404240434044404540464047404840494050405140524053405440554056405740584059406040614062406340644065406640674068406940704071407240734074407540764077407840794080408140824083408440854086408740884089409040914092409340944095409640974098409941004101410241034104410541064107410841094110411141124113411441154116411741184119412041214122412341244125412641274128412941304131413241334134413541364137413841394140414141424143414441454146414741484149415041514152415341544155415641574158415941604161416241634164416541664167416841694170417141724173417441754176417741784179418041814182418341844185418641874188418941904191419241934194419541964197419841994200420142024203420442054206420742084209421042114212421342144215421642174218421942204221422242234224422542264227422842294230423142324233423442354236423742384239424042414242424342444245424642474248424942504251425242534254425542564257425842594260426142624263426442654266426742684269427042714272427342744275427642774278427942804281428242834284428542864287428842894290429142924293429442954296429742984299430043014302430343044305430643074308430943104311431243134314431543164317431843194320432143224323432443254326432743284329433043314332433343344335433643374338433943404341434243434344434543464347434843494350435143524353435443554356435743584359436043614362436343644365436643674368436943704371437243734374437543764377437843794380438143824383438443854386438743884389439043914392439343944395439643974398439944004401440244034404440544064407440844094410441144124413441444154416441744184419442044214422442344244425442644274428442944304431443244334434443544364437443844394440444144424443444444454446444744484449445044514452445344544455445644574458445944604461446244634464446544664467446844694470447144724473447444754476447744784479448044814482448344844485448644874488448944904491449244934494449544964497449844994500450145024503450445054506450745084509451045114512451345144515451645174518451945204521452245234524452545264527452845294530453145324533453445354536453745384539454045414542454345444545454645474548454945504551455245534554455545564557455845594560456145624563456445654566456745684569457045714572457345744575457645774578457945804581458245834584458545864587458845894590459145924593459445954596459745984599460046014602460346044605460646074608460946104611461246134614461546164617461846194620462146224623462446254626462746284629463046314632463346344635463646374638463946404641464246434644464546464647464846494650465146524653465446554656465746584659466046614662466346644665466646674668466946704671467246734674467546764677467846794680468146824683468446854686468746884689469046914692469346944695469646974698469947004701470247034704470547064707470847094710471147124713471447154716471747184719472047214722472347244725472647274728472947304731
  1. import werkzeug.routing
  2. import flask_compress
  3. import flask_reggie
  4. import tornado.ioloop
  5. import tornado.httpserver
  6. import tornado.wsgi
  7. import urllib.request
  8. import platform
  9. import zipfile
  10. import difflib
  11. import shutil
  12. import threading
  13. import logging
  14. import random
  15. from func import *
  16. from views.easter_egg import *
  17. r_ver = 'v3.0.8-master-100'
  18. c_ver = ''.join(re.findall('[0-9]', r_ver))
  19. print('version : ' + r_ver)
  20. try:
  21. json_data = open('set.json').read()
  22. set_data = json.loads(json_data)
  23. except:
  24. while 1:
  25. print('db name : ', end = '')
  26. new_json = str(input())
  27. if new_json != '':
  28. with open('set.json', 'w') as f:
  29. f.write('{ "db" : "' + new_json + '" }')
  30. json_data = open('set.json').read()
  31. set_data = json.loads(json_data)
  32. break
  33. else:
  34. print('insert value')
  35. pass
  36. if os.path.exists(set_data['db'] + '.db'):
  37. setup_tool = 0
  38. else:
  39. setup_tool = 1
  40. conn = sqlite3.connect(set_data['db'] + '.db', check_same_thread = False)
  41. curs = conn.cursor()
  42. load_conn(conn)
  43. logging.basicConfig(level = logging.ERROR)
  44. app = flask.Flask(__name__, template_folder = './')
  45. app.config['JSON_AS_ASCII'] = False
  46. flask_reggie.Reggie(app)
  47. compress = flask_compress.Compress()
  48. # compress.init_app(app)
  49. class EverythingConverter(werkzeug.routing.PathConverter):
  50. regex = '.*?'
  51. app.jinja_env.filters['md5_replace'] = md5_replace
  52. app.jinja_env.filters['load_lang'] = load_lang
  53. app.url_map.converters['everything'] = EverythingConverter
  54. curs.execute('create table if not exists data(test text)')
  55. curs.execute('create table if not exists cache_data(test text)')
  56. curs.execute('create table if not exists history(test text)')
  57. curs.execute('create table if not exists rd(test text)')
  58. curs.execute('create table if not exists user(test text)')
  59. curs.execute('create table if not exists user_set(test text)')
  60. curs.execute('create table if not exists ban(test text)')
  61. curs.execute('create table if not exists topic(test text)')
  62. curs.execute('create table if not exists rb(test text)')
  63. curs.execute('create table if not exists back(test text)')
  64. curs.execute('create table if not exists custom(test text)')
  65. curs.execute('create table if not exists other(test text)')
  66. curs.execute('create table if not exists alist(test text)')
  67. curs.execute('create table if not exists re_admin(test text)')
  68. curs.execute('create table if not exists alarm(test text)')
  69. curs.execute('create table if not exists ua_d(test text)')
  70. curs.execute('create table if not exists filter(test text)')
  71. curs.execute('create table if not exists scan(test text)')
  72. curs.execute('create table if not exists acl(test text)')
  73. curs.execute('create table if not exists inter(test text)')
  74. curs.execute('create table if not exists html_filter(test text)')
  75. curs.execute('create table if not exists oauth_conn(test text)')
  76. if setup_tool == 0:
  77. curs.execute('select data from other where name = "ver"')
  78. ver_set_data = curs.fetchall()
  79. if not ver_set_data:
  80. setup_tool = 1
  81. else:
  82. if c_ver > ver_set_data[0][0]:
  83. setup_tool = 1
  84. if setup_tool != 0:
  85. create_data = {}
  86. create_data['all_data'] = [
  87. 'data',
  88. 'cache_data',
  89. 'history',
  90. 'rd',
  91. 'user',
  92. 'user_set',
  93. 'ban',
  94. 'topic',
  95. 'rb',
  96. 'back',
  97. 'custom',
  98. 'other',
  99. 'alist',
  100. 're_admin',
  101. 'alarm',
  102. 'ua_d',
  103. 'filter',
  104. 'scan',
  105. 'acl',
  106. 'inter',
  107. 'html_filter',
  108. 'oauth_conn'
  109. ]
  110. create_data['data'] = ['title', 'data']
  111. create_data['cache_data'] = ['title', 'data']
  112. create_data['history'] = ['id', 'title', 'data', 'date', 'ip', 'send', 'leng', 'hide', 'type']
  113. create_data['rd'] = ['title', 'sub', 'date', 'band', 'stop', 'agree']
  114. create_data['user'] = ['id', 'pw', 'acl', 'date', 'encode']
  115. create_data['user_set'] = ['name', 'id', 'data']
  116. create_data['ban'] = ['block', 'end', 'why', 'band', 'login']
  117. create_data['topic'] = ['id', 'title', 'sub', 'data', 'date', 'ip', 'block', 'top']
  118. create_data['rb'] = ['block', 'end', 'today', 'blocker', 'why', 'band']
  119. create_data['back'] = ['title', 'link', 'type']
  120. create_data['custom'] = ['user', 'css']
  121. create_data['other'] = ['name', 'data']
  122. create_data['alist'] = ['name', 'acl']
  123. create_data['re_admin'] = ['who', 'what', 'time']
  124. create_data['alarm'] = ['name', 'data', 'date']
  125. create_data['ua_d'] = ['name', 'ip', 'ua', 'today', 'sub']
  126. create_data['filter'] = ['name', 'regex', 'sub']
  127. create_data['scan'] = ['user', 'title']
  128. create_data['acl'] = ['title', 'dec', 'dis', 'view', 'why']
  129. create_data['inter'] = ['title', 'link']
  130. create_data['html_filter'] = ['html', 'kind']
  131. create_data['oauth_conn'] = ['provider', 'wiki_id', 'sns_id', 'name', 'picture']
  132. for create_table in create_data['all_data']:
  133. for create in create_data[create_table]:
  134. try:
  135. curs.execute('select ' + create + ' from ' + create_table + ' limit 1')
  136. except:
  137. curs.execute("alter table " + create_table + " add " + create + " text default ''")
  138. update()
  139. curs.execute('select name from alist where acl = "owner"')
  140. if not curs.fetchall():
  141. curs.execute('delete from alist where name = "owner"')
  142. curs.execute('insert into alist (name, acl) values ("owner", "owner")')
  143. if not os.path.exists('image'):
  144. os.makedirs('image')
  145. if not os.path.exists('views'):
  146. os.makedirs('views')
  147. if os.getenv('NAMU_HOST') != None:
  148. rep_host = os.getenv('NAMU_HOST')
  149. else:
  150. curs.execute('select data from other where name = "host"')
  151. rep_data = curs.fetchall()
  152. if not rep_data:
  153. while 1:
  154. print('host [0.0.0.0] : ', end = '')
  155. rep_host = input()
  156. if rep_host:
  157. curs.execute('insert into other (name, data) values ("host", ?)', [rep_host])
  158. break
  159. else:
  160. pass
  161. else:
  162. rep_host = rep_data[0][0]
  163. print('host : ' + str(rep_host))
  164. if os.getenv('NAMU_PORT') != None:
  165. rep_port = os.getenv('NAMU_PORT')
  166. else:
  167. curs.execute('select data from other where name = "port"')
  168. rep_data = curs.fetchall()
  169. if not rep_data:
  170. while 1:
  171. print('port : ', end = '')
  172. rep_port = int(input())
  173. if rep_port:
  174. curs.execute('insert into other (name, data) values ("port", ?)', [rep_port])
  175. break
  176. else:
  177. pass
  178. else:
  179. rep_port = rep_data[0][0]
  180. print('port : ' + str(rep_port))
  181. try:
  182. if not os.path.exists('robots.txt'):
  183. curs.execute('select data from other where name = "robot"')
  184. robot_test = curs.fetchall()
  185. if robot_test:
  186. fw_test = open('./robots.txt', 'w')
  187. fw_test.write(re.sub('\r\n', '\n', robot_test[0][0]))
  188. fw_test.close()
  189. else:
  190. fw_test = open('./robots.txt', 'w')
  191. fw_test.write('User-agent: *\nDisallow: /\nAllow: /$\nAllow: /w/')
  192. fw_test.close()
  193. curs.execute('insert into other (name, data) values ("robot", "User-agent: *\nDisallow: /\nAllow: /$\nAllow: /w/")')
  194. print('robots.txt have created')
  195. except:
  196. pass
  197. curs.execute('select data from other where name = "key"')
  198. rep_data = curs.fetchall()
  199. if not rep_data:
  200. rep_key = ''.join(random.choice("0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ") for i in range(16))
  201. if rep_key:
  202. curs.execute('insert into other (name, data) values ("key", ?)', [rep_key])
  203. else:
  204. rep_key = rep_data[0][0]
  205. support_language = ['ko-KR', 'en-US']
  206. curs.execute("select data from other where name = 'language'")
  207. rep_data = curs.fetchall()
  208. if not rep_data:
  209. if os.getenv('NAMU_LANG') != None:
  210. if os.getenv('NAMU_LANG') in support_language:
  211. curs.execute("insert into other (name, data) values ('language', ?)", [os.getenv('NAMU_LANG')])
  212. rep_language = os.getenv('NAMU_LANG')
  213. else:
  214. print('language ' + str(os.getenv('NAMU_LANG')) + ' is not supported!')
  215. rep_language = 'en-US'
  216. else:
  217. while 1:
  218. print('language [' + ', '.join(support_language) + '] : ', end = '')
  219. rep_language = str(input())
  220. if rep_language in support_language:
  221. curs.execute("insert into other (name, data) values ('language', ?)", [rep_language])
  222. break
  223. else:
  224. pass
  225. else:
  226. rep_language = rep_data[0][0]
  227. print('language : ' + str(rep_language))
  228. curs.execute('select data from other where name = "adsense"')
  229. adsense_result = curs.fetchall()
  230. if not adsense_result:
  231. curs.execute('insert into other (name, data) values ("adsense", "False")')
  232. curs.execute('insert into other (name, data) values ("adsense_code", "")')
  233. ask_this = [[['markup', 'markup'], ['namumark']], [['encryption method', 'encode'], ['sha256', 'sha3', 'bcrypt']]]
  234. for ask_data in ask_this:
  235. curs.execute('select data from other where name = ?', [ask_data[0][1]])
  236. rep_data = curs.fetchall()
  237. if not rep_data:
  238. while 1:
  239. print(ask_data[0][0] + ' [' + ', '.join(ask_data[1]) + '] : ', end = '')
  240. rep_mark = str(input())
  241. if rep_mark and rep_mark in ask_data[1]:
  242. curs.execute('insert into other (name, data) values (?, ?)', [ask_data[0][1], rep_mark])
  243. break
  244. else:
  245. pass
  246. else:
  247. rep_mark = rep_data[0][0]
  248. print(ask_data[0][1] + ' : ' + str(rep_mark))
  249. curs.execute('delete from other where name = "ver"')
  250. curs.execute('insert into other (name, data) values ("ver", ?)', [c_ver])
  251. def back_up():
  252. try:
  253. shutil.copyfile(set_data['db'] + '.db', 'back_' + set_data['db'] + '.db')
  254. print('back up : ok')
  255. except:
  256. print('back up : error')
  257. threading.Timer(60 * 60 * back_time, back_up).start()
  258. try:
  259. curs.execute('select data from other where name = "back_up"')
  260. back_up_time = curs.fetchall()
  261. back_time = int(back_up_time[0][0])
  262. except:
  263. back_time = 0
  264. if back_time != 0:
  265. print('back up state : ' + str(back_time) + ' hours interval')
  266. if __name__ == '__main__':
  267. back_up()
  268. else:
  269. print('back up state : turn off')
  270. print('\n------ daemon started ------')
  271. conn.commit()
  272. @app.route('/del_alarm')
  273. def del_alarm():
  274. curs.execute("delete from alarm where name = ?", [ip_check()])
  275. conn.commit()
  276. return redirect('/alarm')
  277. @app.route('/alarm')
  278. def alarm():
  279. if custom()[2] == 0:
  280. return redirect('/login')
  281. data = '<ul>'
  282. curs.execute("select data, date from alarm where name = ? order by date desc", [ip_check()])
  283. data_list = curs.fetchall()
  284. if data_list:
  285. data = '<a href="/del_alarm">(' + load_lang('delete') + ')</a><hr class=\"main_hr\">' + data
  286. for data_one in data_list:
  287. data += '<li>' + data_one[0] + ' (' + data_one[1] + ')</li>'
  288. else:
  289. data += '<li>-</li>'
  290. data += '</ul>'
  291. return easy_minify(flask.render_template(skin_check(),
  292. imp = [load_lang('alarm'), wiki_set(), custom(), other2([0, 0])],
  293. data = data,
  294. menu = [['user', load_lang('user')]]
  295. ))
  296. @app.route('/<regex("inter_wiki|(?:edit|email|name)_filter"):tools>')
  297. def inter_wiki(tools = None):
  298. div = ''
  299. admin = admin_check()
  300. if tools == 'inter_wiki':
  301. del_link = 'del_inter_wiki'
  302. plus_link = 'plus_inter_wiki'
  303. title = load_lang('interwiki') + ' ' + load_lang('list')
  304. div = ''
  305. curs.execute('select title, link from inter')
  306. elif tools == 'email_filter':
  307. del_link = 'del_email_filter'
  308. plus_link = 'plus_email_filter'
  309. title = 'email ' + load_lang('filter') + ' ' + load_lang('list')
  310. div = '''
  311. <ul>
  312. <li>gmail.com</li>
  313. <li>naver.com</li>
  314. <li>daum.net</li>
  315. <li>hanmail.net</li>
  316. <li>hanmail2.net</li>
  317. </ul>
  318. '''
  319. curs.execute("select html from html_filter where kind = 'email'")
  320. elif tools == 'name_filter':
  321. del_link = 'del_name_filter'
  322. plus_link = 'plus_name_filter'
  323. title = load_lang('id') + ' ' + load_lang('filter') + ' ' + load_lang('list')
  324. div = ''
  325. curs.execute("select html from html_filter where kind = 'name'")
  326. else:
  327. del_link = 'del_edit_filter'
  328. plus_link = 'manager/9'
  329. title = load_lang('edit') + ' ' + load_lang('filter') + ' ' + load_lang('list')
  330. div = ''
  331. curs.execute("select name from filter")
  332. db_data = curs.fetchall()
  333. if db_data:
  334. div += '<ul>'
  335. for data in db_data:
  336. if tools == 'inter_wiki':
  337. div += '<li>' + data[0] + ' : <a id="out_link" href="' + data[1] + '">' + data[1] + '</a>'
  338. elif tools == 'edit_filter':
  339. div += '<li><a href="/plus_edit_filter/' + url_pas(data[0]) + '">' + data[0] + '</a>'
  340. else:
  341. div += '<li>' + data[0]
  342. if admin == 1:
  343. div += ' <a href="/' + del_link + '/' + url_pas(data[0]) + '">(' + load_lang('delete') + ')</a>'
  344. div += '</li>'
  345. div += '</ul>'
  346. if admin == 1:
  347. div += '<hr class=\"main_hr\"><a href="/' + plus_link + '">(' + load_lang('plus') + ')</a>'
  348. else:
  349. if admin == 1:
  350. div += '<a href="/' + plus_link + '">(' + load_lang('plus') + ')</a>'
  351. return easy_minify(flask.render_template(skin_check(),
  352. imp = [title, wiki_set(), custom(), other2([0, 0])],
  353. data = div,
  354. menu = [['other', load_lang('other')]]
  355. ))
  356. @app.route('/<regex("del_(?:inter_wiki|(?:edit|email|name)_filter)"):tools>/<name>')
  357. def del_inter(tools = None, name = None):
  358. if admin_check(None, tools) == 1:
  359. if tools == 'del_inter_wiki':
  360. curs.execute("delete from inter where title = ?", [name])
  361. elif tools == 'del_edit_filter':
  362. curs.execute("delete from filter where name = ?", [name])
  363. elif tools == 'del_name_filter':
  364. curs.execute("delete from html_filter where html = ? and kind = 'name'", [name])
  365. else:
  366. curs.execute("delete from html_filter where html = ? and kind = 'email'", [name])
  367. conn.commit()
  368. return redirect('/' + re.sub('^del_', '', tools))
  369. else:
  370. return re_error('/error/3')
  371. @app.route('/<regex("plus_(?:inter_wiki|(?:edit|email|name)_filter)"):tools>', methods=['POST', 'GET'])
  372. @app.route('/<regex("plus_edit_filter"):tools>/<name>', methods=['POST', 'GET'])
  373. def plus_inter(tools = None, name = None):
  374. if flask.request.method == 'POST':
  375. if tools == 'plus_inter_wiki':
  376. curs.execute('insert into inter (title, link) values (?, ?)', [flask.request.form.get('title', None), flask.request.form.get('link', None)])
  377. admin_check(None, 'inter_wiki_plus')
  378. elif tools == 'plus_edit_filter':
  379. if admin_check(1, 'edit_filter edit') != 1:
  380. return re_error('/error/3')
  381. if flask.request.form.get('limitless', '') != '':
  382. end = 'X'
  383. else:
  384. end = flask.request.form.get('second', 'X')
  385. curs.execute("select name from filter where name = ?", [name])
  386. if curs.fetchall():
  387. curs.execute("update filter set regex = ?, sub = ? where name = ?", [flask.request.form.get('content', 'test'), end, name])
  388. else:
  389. curs.execute("insert into filter (name, regex, sub) values (?, ?, ?)", [name, flask.request.form.get('content', 'test'), end])
  390. else:
  391. if tools == 'plus_name_filter':
  392. admin_check(None, 'name_filter edit')
  393. type_d = 'name'
  394. else:
  395. admin_check(None, 'email_filter edit')
  396. type_d = 'email'
  397. curs.execute('insert into html_filter (html, kind) values (?, ?)', [flask.request.form.get('title', 'test'), type_d])
  398. conn.commit()
  399. return redirect('/' + re.sub('^plus_', '', tools))
  400. else:
  401. if admin_check(1) != 1:
  402. stat = 'disabled'
  403. else:
  404. stat = ''
  405. if tools == 'plus_inter_wiki':
  406. title = load_lang('interwiki') + ' ' + load_lang('plus')
  407. form_data = '''
  408. <input placeholder="''' + load_lang('name') + '''" type="text" name="title">
  409. <hr class=\"main_hr\">
  410. <input placeholder="link" type="text" name="link">
  411. '''
  412. elif tools == 'plus_edit_filter':
  413. curs.execute("select regex, sub from filter where name = ?", [name])
  414. exist = curs.fetchall()
  415. if exist:
  416. textarea = exist[0][0]
  417. if exist[0][1] == 'X':
  418. time_check = 'checked="checked"'
  419. time_data = ''
  420. else:
  421. time_check = ''
  422. time_data = exist[0][1]
  423. else:
  424. textarea = ''
  425. time_check = ''
  426. time_data = ''
  427. title = load_lang('edit') + ' ' + load_lang('filter') + ' ' + load_lang('plus')
  428. form_data = '''
  429. <input placeholder="''' + load_lang('second') + '''" name="second" type="text" value="''' + html.escape(time_data) + '''">
  430. <hr class=\"main_hr\">
  431. <input ''' + stat + ''' type="checkbox" ''' + time_check + ''' name="limitless"> ''' + load_lang('limitless') + '''
  432. <hr class=\"main_hr\">
  433. <input ''' + stat + ''' placeholder="''' + load_lang('regex') + '''" name="content" value="''' + html.escape(textarea) + '''" type="text">
  434. '''
  435. elif tools == 'plus_name_filter':
  436. title = load_lang('id') + ' ' + load_lang('filter') + ' ' + load_lang('plus')
  437. form_data = '<input placeholder="' + load_lang('id') + ' ' + load_lang('regex') + '" type="text" name="title">'
  438. else:
  439. title = 'email ' + load_lang('filter') + ' ' + load_lang('plus')
  440. form_data = '<input placeholder="email" type="text" name="title">'
  441. return easy_minify(flask.render_template(skin_check(),
  442. imp = [title, wiki_set(), custom(), other2([0, 0])],
  443. data = '''
  444. <form method="post">
  445. ''' + form_data + '''
  446. <hr class=\"main_hr\">
  447. <button ''' + stat + ''' type="submit">''' + load_lang('plus') + '''</button>
  448. </form>
  449. ''',
  450. menu = [['other', load_lang('other')], [re.sub('^plus_', '', tools), load_lang('list')]]
  451. ))
  452. @app.route('/setting')
  453. @app.route('/setting/<int:num>', methods=['POST', 'GET'])
  454. def setting(num = 0):
  455. if num != 0 and admin_check() != 1:
  456. return re_error('/ban')
  457. if num == 0:
  458. li_list = [load_lang('main'), load_lang('text') + ' ' + load_lang('setting'), load_lang('main') + ' head', load_lang('main') + ' body', 'robots.txt', 'google']
  459. x = 0
  460. li_data = ''
  461. for li in li_list:
  462. x += 1
  463. li_data += '<li><a href="/setting/' + str(x) + '">' + li + '</a></li>'
  464. return easy_minify(flask.render_template(skin_check(),
  465. imp = [load_lang('setting'), wiki_set(), custom(), other2([0, 0])],
  466. data = '<h2>' + load_lang('list') + '</h2><ul>' + li_data + '</ul>',
  467. menu = [['manager', load_lang('admin')]]
  468. ))
  469. elif num == 1:
  470. i_list = ['name', 'logo', 'frontpage', 'license', 'upload', 'skin', 'edit', 'reg', 'ip_view', 'back_up', 'port', 'key', 'update', 'email_have', 'discussion', 'encode', 'host']
  471. n_list = ['wiki', '', 'FrontPage', 'CC 0', '2', '', 'normal', '', '', '0', '3000', 'test', 'stable', '', 'normal', 'sha256', '0.0.0.0']
  472. if flask.request.method == 'POST':
  473. i = 0
  474. for data in i_list:
  475. curs.execute("update other set data = ? where name = ?", [flask.request.form.get(data, n_list[i]), data])
  476. i += 1
  477. conn.commit()
  478. admin_check(None, 'edit_set')
  479. return redirect('/setting/1')
  480. else:
  481. d_list = []
  482. x = 0
  483. for i in i_list:
  484. curs.execute('select data from other where name = ?', [i])
  485. sql_d = curs.fetchall()
  486. if sql_d:
  487. d_list += [sql_d[0][0]]
  488. else:
  489. curs.execute('insert into other (name, data) values (?, ?)', [i, n_list[x]])
  490. d_list += [n_list[x]]
  491. x += 1
  492. conn.commit()
  493. div = ''
  494. acl_list = [[load_lang('subscriber'), 'login'], [load_lang('normal'), 'normal'], [load_lang('admin'), 'admin']]
  495. for i in acl_list:
  496. if i[1] == d_list[6]:
  497. div = '<option value="' + i[1] + '">' + i[0] + '</option>' + div
  498. else:
  499. div += '<option value="' + i[1] + '">' + i[0] + '</option>'
  500. div4 = ''
  501. for i in acl_list:
  502. if i[1] == d_list[14]:
  503. div4 = '<option value="' + i[1] + '">' + i[0] + '</option>' + div4
  504. else:
  505. div4 += '<option value="' + i[1] + '">' + i[0] + '</option>'
  506. ch_1 = ''
  507. if d_list[7]:
  508. ch_1 = 'checked="checked"'
  509. ch_2 = ''
  510. if d_list[8]:
  511. ch_2 = 'checked="checked"'
  512. ch_3 = ''
  513. if d_list[13]:
  514. ch_3 = 'checked="checked"'
  515. div2 = load_skin(d_list[5])
  516. div3 =''
  517. if d_list[12] == 'stable':
  518. div3 += '<option value="stable">stable</option>'
  519. div3 += '<option value="master">master</option>'
  520. else:
  521. div3 += '<option value="master">master</option>'
  522. div3 += '<option value="stable">stable</option>'
  523. div5 =''
  524. encode_data = ['sha256', 'sha3', 'bcrypt']
  525. for i in encode_data:
  526. if d_list[15] == i:
  527. div5 = '<option value="' + i + '">' + i + '</option>' + div5
  528. else:
  529. div5 += '<option value="' + i + '">' + i + '</option>'
  530. return easy_minify(flask.render_template(skin_check(),
  531. imp = [load_lang('main'), wiki_set(), custom(), other2([0, 0])],
  532. data = '''
  533. <form method="post">
  534. <span>''' + load_lang('name') + '''</span>
  535. <br>
  536. <br>
  537. <input placeholder="''' + load_lang('name') + '''" type="text" name="name" value="''' + html.escape(d_list[0]) + '''">
  538. <hr class=\"main_hr\">
  539. <span>''' + load_lang('logo') + ''' (html)</span>
  540. <br>
  541. <br>
  542. <input placeholder="''' + load_lang('logo') + '''" type="text" name="logo" value="''' + html.escape(d_list[1]) + '''">
  543. <hr class=\"main_hr\">
  544. <span>''' + load_lang('frontpage') + '''</span>
  545. <br>
  546. <br>
  547. <input placeholder="''' + load_lang('frontpage') + '''" type="text" name="frontpage" value="''' + html.escape(d_list[2]) + '''">
  548. <hr class=\"main_hr\">
  549. <span>''' + load_lang('bottom') + ' ' + load_lang('text') + ''' (html)</span>
  550. <br>
  551. <br>
  552. <input placeholder="''' + load_lang('bottom') + ' ' + load_lang('text') + '''" type="text" name="license" value="''' + html.escape(d_list[3]) + '''">
  553. <hr class=\"main_hr\">
  554. <span>''' + load_lang('max_file_size') + ''' [mb]</span>
  555. <br>
  556. <br>
  557. <input placeholder="''' + load_lang('max_file_size') + '''" type="text" name="upload" value="''' + html.escape(d_list[4]) + '''">
  558. <hr class=\"main_hr\">
  559. <span>''' + load_lang('backup_interval') + ' [' + load_lang('hour') + '''] (off : 0) {restart}</span>
  560. <br>
  561. <br>
  562. <input placeholder="''' + load_lang('backup_interval') + '''" type="text" name="back_up" value="''' + html.escape(d_list[9]) + '''">
  563. <hr class=\"main_hr\">
  564. <span>''' + load_lang('skin') + '''</span>
  565. <br>
  566. <br>
  567. <select name="skin">''' + div2 + '''</select>
  568. <hr class=\"main_hr\">
  569. <span>''' + load_lang('default') + ''' acl</span>
  570. <br>
  571. <br>
  572. <select name="edit">''' + div + '''</select>
  573. <hr class=\"main_hr\">
  574. <span>''' + load_lang('default') + ' ' + load_lang('discussion') + ''' acl</span>
  575. <br>
  576. <br>
  577. <select name="discussion">''' + div4 + '''</select>
  578. <hr class=\"main_hr\">
  579. <input type="checkbox" name="reg" ''' + ch_1 + '''> ''' + load_lang('register') + ''' X
  580. <hr class=\"main_hr\">
  581. <input type="checkbox" name="ip_view" ''' + ch_2 + '''> ip ''' + load_lang('hide') + '''
  582. <hr class=\"main_hr\">
  583. <input type="checkbox" name="email_have" ''' + ch_3 + '''> must have email {<a href="/setting/5">must set google imap</a>}
  584. <hr class=\"main_hr\">
  585. <span>''' + load_lang('host') + '''</span>
  586. <br>
  587. <br>
  588. <input placeholder="''' + load_lang('host') + '''" type="text" name="host" value="''' + html.escape(d_list[16]) + '''">
  589. <hr class=\"main_hr\">
  590. <span>''' + load_lang('port') + '''</span>
  591. <br>
  592. <br>
  593. <input placeholder="''' + load_lang('port') + '''" type="text" name="port" value="''' + html.escape(d_list[10]) + '''">
  594. <hr class=\"main_hr\">
  595. <span>''' + load_lang('secret_key') + '''</span>
  596. <br>
  597. <br>
  598. <input placeholder="''' + load_lang('secret_key') + '''" type="password" name="key" value="''' + html.escape(d_list[11]) + '''">
  599. <hr class=\"main_hr\">
  600. <span>''' + load_lang('update_branch') + '''</span>
  601. <br>
  602. <br>
  603. <select name="update">''' + div3 + '''</select>
  604. <hr class=\"main_hr\">
  605. <span>encryption method</span>
  606. <br>
  607. <br>
  608. <select name="encode">''' + div5 + '''</select>
  609. <hr class=\"main_hr\">
  610. <button id="save" type="submit">''' + load_lang('save') + '''</button>
  611. </form>
  612. ''',
  613. menu = [['setting', load_lang('setting')]]
  614. ))
  615. elif num == 2:
  616. if flask.request.method == 'POST':
  617. curs.execute("update other set data = ? where name = ?", [flask.request.form.get('contract', None), 'contract'])
  618. curs.execute("update other set data = ? where name = ?", [flask.request.form.get('no_login_warring', None), 'no_login_warring'])
  619. conn.commit()
  620. admin_check(None, 'edit_set')
  621. return redirect('/setting/2')
  622. else:
  623. i_list = ['contract', 'no_login_warring']
  624. n_list = ['', '']
  625. d_list = []
  626. x = 0
  627. for i in i_list:
  628. curs.execute('select data from other where name = ?', [i])
  629. sql_d = curs.fetchall()
  630. if sql_d:
  631. d_list += [sql_d[0][0]]
  632. else:
  633. curs.execute('insert into other (name, data) values (?, ?)', [i, n_list[x]])
  634. d_list += [n_list[x]]
  635. x += 1
  636. conn.commit()
  637. return easy_minify(flask.render_template(skin_check(),
  638. imp = [load_lang('text') + ' ' + load_lang('setting'), wiki_set(), custom(), other2([0, 0])],
  639. data = '''
  640. <form method="post">
  641. <span>''' + load_lang('register_text') + '''</span>
  642. <br>
  643. <br>
  644. <input placeholder="''' + load_lang('register_text') + '''" type="text" name="contract" value="''' + html.escape(d_list[0]) + '''">
  645. <hr class=\"main_hr\">
  646. <span>''' + load_lang('non_login_alert') + '''</span>
  647. <br>
  648. <br>
  649. <input placeholder="''' + load_lang('non_login_alert') + '''" type="text" name="no_login_warring" value="''' + html.escape(d_list[1]) + '''">
  650. <hr class=\"main_hr\">
  651. <button id="save" type="submit">''' + load_lang('save') + '''</button>
  652. </form>
  653. ''',
  654. menu = [['setting', load_lang('setting')]]
  655. ))
  656. elif num == 3 or num == 4:
  657. if flask.request.method == 'POST':
  658. if num == 4:
  659. info_d = 'body'
  660. end_r = '4'
  661. else:
  662. info_d = 'head'
  663. end_r = '3'
  664. curs.execute("select name from other where name = ?", [info_d])
  665. if curs.fetchall():
  666. curs.execute("update other set data = ? where name = ?", [flask.request.form.get('content', ''), info_d])
  667. else:
  668. curs.execute("insert into other (name, data) values (?, ?)", [info_d, flask.request.form.get('content', '')])
  669. conn.commit()
  670. admin_check(None, 'edit_set')
  671. return redirect('/setting/' + end_r)
  672. else:
  673. if num == 4:
  674. curs.execute("select data from other where name = 'body'")
  675. title = 'body'
  676. else:
  677. curs.execute("select data from other where name = 'head'")
  678. title = 'head'
  679. head = curs.fetchall()
  680. if head:
  681. data = head[0][0]
  682. else:
  683. data = ''
  684. return easy_minify(flask.render_template(skin_check(),
  685. imp = [load_lang('main') + ' ' + title, wiki_set(), custom(), other2([0, 0])],
  686. data = '''
  687. <form method="post">
  688. <textarea rows="25" name="content">''' + html.escape(data) + '''</textarea>
  689. <hr class=\"main_hr\">
  690. <button id="save" type="submit">''' + load_lang('save') + '''</button>
  691. </form>
  692. ''',
  693. menu = [['setting', load_lang('setting')]]
  694. ))
  695. elif num == 5:
  696. if flask.request.method == 'POST':
  697. curs.execute("select name from other where name = 'robot'")
  698. if curs.fetchall():
  699. curs.execute("update other set data = ? where name = 'robot'", [flask.request.form.get('content', None)])
  700. else:
  701. curs.execute("insert into other (name, data) values ('robot', ?)", [flask.request.form.get('content', None)])
  702. conn.commit()
  703. fw = open('./robots.txt', 'w')
  704. fw.write(re.sub('\r\n', '\n', flask.request.form.get('content', None)))
  705. fw.close()
  706. admin_check(None, 'edit_set')
  707. return redirect('/setting/4')
  708. else:
  709. curs.execute("select data from other where name = 'robot'")
  710. robot = curs.fetchall()
  711. if robot:
  712. data = robot[0][0]
  713. else:
  714. data = ''
  715. f = open('./robots.txt', 'r')
  716. lines = f.readlines()
  717. f.close()
  718. if not data or data == '':
  719. data = ''.join(lines)
  720. return easy_minify(flask.render_template(skin_check(),
  721. imp = ['robots.txt', wiki_set(), custom(), other2([0, 0])],
  722. data = '''
  723. <a href="/robots.txt">(view)</a>
  724. <hr class=\"main_hr\">
  725. <form method="post">
  726. <textarea rows="25" name="content">''' + html.escape(data) + '''</textarea>
  727. <hr class=\"main_hr\">
  728. <button id="save" type="submit">''' + load_lang('save') + '''</button>
  729. </form>
  730. ''',
  731. menu = [['setting', load_lang('setting')]]
  732. ))
  733. elif num == 6:
  734. i_list = ['recaptcha', 'sec_re', 'g_email', 'g_pass']
  735. if flask.request.method == 'POST':
  736. for data in i_list:
  737. curs.execute("update other set data = ? where name = ?", [flask.request.form.get(data, ''), data])
  738. conn.commit()
  739. admin_check(None, 'edit_set')
  740. return redirect('/setting/5')
  741. else:
  742. n_list = ['', '', '', '']
  743. d_list = []
  744. x = 0
  745. for i in i_list:
  746. curs.execute('select data from other where name = ?', [i])
  747. sql_d = curs.fetchall()
  748. if sql_d:
  749. d_list += [sql_d[0][0]]
  750. else:
  751. curs.execute('insert into other (name, data) values (?, ?)', [i, n_list[x]])
  752. d_list += [n_list[x]]
  753. x += 1
  754. conn.commit()
  755. return easy_minify(flask.render_template(skin_check(),
  756. imp = ['google', wiki_set(), custom(), other2([0, 0])],
  757. data = '''
  758. <form method="post">
  759. <h2><a href="https://www.google.com/recaptcha/admin">recaptcha</a></h2>
  760. <span>recaptcha (html)</span>
  761. <br>
  762. <br>
  763. <input placeholder="recaptcha (html)" type="text" name="recaptcha" value="''' + html.escape(d_list[0]) + '''">
  764. <hr class=\"main_hr\">
  765. <span>recaptcha (secret key)</span>
  766. <br>
  767. <br>
  768. <input placeholder="recaptcha (secret key)" type="text" name="sec_re" value="''' + html.escape(d_list[1]) + '''">
  769. <hr class=\"main_hr\">
  770. <h2><a href="https://support.google.com/mail/answer/7126229">google imap</a> {restart}</h1>
  771. <span>google email</span>
  772. <br>
  773. <br>
  774. <input placeholder="google email" type="text" name="g_email" value="''' + html.escape(d_list[2]) + '''">
  775. <hr class=\"main_hr\">
  776. <span><a href="https://security.google.com/settings/security/apppasswords">google app password</a></span>
  777. <br>
  778. <br>
  779. <input placeholder="google app password" type="password" name="g_pass" value="''' + html.escape(d_list[3]) + '''">
  780. <hr class=\"main_hr\">
  781. <button id="save" type="submit">''' + load_lang('save') + '''</button>
  782. </form>
  783. ''',
  784. menu = [['setting', load_lang('setting')]]
  785. ))
  786. else:
  787. return redirect('/')
  788. @app.route('/not_close_topic')
  789. def not_close_topic():
  790. div = '<ul>'
  791. curs.execute('select title, sub from rd where stop != "O" order by date desc')
  792. n_list = curs.fetchall()
  793. for data in n_list:
  794. div += '<li><a href="/topic/' + url_pas(data[0]) + '/sub/' + url_pas(data[1]) + '">' + html.escape(data[0]) + ' (' + data[1] + ')</a></li>'
  795. div += '</ul>'
  796. return easy_minify(flask.render_template(skin_check(),
  797. imp = [load_lang('open') + ' ' + load_lang('discussion') + ' ' + load_lang('list'), wiki_set(), custom(), other2([0, 0])],
  798. data = div,
  799. menu = [['manager', load_lang('admin')]]
  800. ))
  801. @app.route('/image/<name>')
  802. def image_view(name = None):
  803. if os.path.exists(os.path.join('image', name)):
  804. return flask.send_from_directory('./image', name)
  805. else:
  806. return redirect('/')
  807. @app.route('/acl_list')
  808. def acl_list():
  809. div = '''
  810. <table id="main_table_set">
  811. <tbody>
  812. <tr>
  813. <td id="main_table_width_quarter">''' + load_lang('document') + ' ' + load_lang('name') + '''</td>
  814. <td id="main_table_width_quarter">''' + load_lang('document') + ''' acl</td>
  815. <td id="main_table_width_quarter">''' + load_lang('discussion') + ''' acl</td>
  816. <td id="main_table_width_quarter">''' + load_lang('view') + ''' acl</td>
  817. '''
  818. curs.execute("select title, dec, dis, view, why from acl where dec = 'admin' or dec = 'user' or dis = 'admin' or dis = 'user' or view = 'admin' or view = 'user' order by title desc")
  819. list_data = curs.fetchall()
  820. for data in list_data:
  821. if not re.search('^user:', data[0]) and not re.search('^file:', data[0]):
  822. acl = []
  823. for i in range(1, 4):
  824. if data[i] == 'admin':
  825. acl += [load_lang('admin')]
  826. else:
  827. acl += [load_lang('subscriber')]
  828. div += '''
  829. <tr>
  830. <td>
  831. <a href="/w/''' + url_pas(data[0]) + '">' + data[0] + '''</a>
  832. </td>
  833. <td>''' + acl[0] + '''</td>
  834. <td>''' + acl[1] + '''</td>
  835. <td>''' + acl[2] + '''</td>
  836. </tr>
  837. '''
  838. div += '''
  839. </tbody>
  840. </table>
  841. '''
  842. return easy_minify(flask.render_template(skin_check(),
  843. imp = ['acl ' + load_lang('document') + ' ' + load_lang('list'), wiki_set(), custom(), other2([0, 0])],
  844. data = div,
  845. menu = [['other', load_lang('other')]]
  846. ))
  847. @app.route('/admin_plus/<name>', methods=['POST', 'GET'])
  848. def admin_plus(name = None):
  849. if flask.request.method == 'POST':
  850. if admin_check(None, 'admin_plus (' + name + ')') != 1:
  851. return re_error('/error/3')
  852. curs.execute("delete from alist where name = ?", [name])
  853. if flask.request.form.get('ban', 0) != 0:
  854. curs.execute("insert into alist (name, acl) values (?, 'ban')", [name])
  855. if flask.request.form.get('toron', 0) != 0:
  856. curs.execute("insert into alist (name, acl) values (?, 'toron')", [name])
  857. if flask.request.form.get('check', 0) != 0:
  858. curs.execute("insert into alist (name, acl) values (?, 'check')", [name])
  859. if flask.request.form.get('acl', 0) != 0:
  860. curs.execute("insert into alist (name, acl) values (?, 'acl')", [name])
  861. if flask.request.form.get('hidel', 0) != 0:
  862. curs.execute("insert into alist (name, acl) values (?, 'hidel')", [name])
  863. if flask.request.form.get('give', 0) != 0:
  864. curs.execute("insert into alist (name, acl) values (?, 'give')", [name])
  865. if flask.request.form.get('owner', 0) != 0:
  866. curs.execute("insert into alist (name, acl) values (?, 'owner')", [name])
  867. conn.commit()
  868. return redirect('/admin_plus/' + url_pas(name))
  869. else:
  870. data = '<ul>'
  871. exist_list = ['', '', '', '', '', '', '', '']
  872. curs.execute('select acl from alist where name = ?', [name])
  873. acl_list = curs.fetchall()
  874. for go in acl_list:
  875. if go[0] == 'ban':
  876. exist_list[0] = 'checked="checked"'
  877. elif go[0] == 'toron':
  878. exist_list[2] = 'checked="checked"'
  879. elif go[0] == 'check':
  880. exist_list[3] = 'checked="checked"'
  881. elif go[0] == 'acl':
  882. exist_list[4] = 'checked="checked"'
  883. elif go[0] == 'hidel':
  884. exist_list[5] = 'checked="checked"'
  885. elif go[0] == 'give':
  886. exist_list[6] = 'checked="checked"'
  887. elif go[0] == 'owner':
  888. exist_list[7] = 'checked="checked"'
  889. if admin_check() != 1:
  890. state = 'disabled'
  891. else:
  892. state = ''
  893. data += '''
  894. <li><input type="checkbox" ''' + state + ' name="ban" ' + exist_list[0] + '> ' + load_lang('ban') + '''</li>
  895. <li><input type="checkbox" ''' + state + ' name="toron" ' + exist_list[2] + '> ' + load_lang('discussion') + '''</li>
  896. <li><input type="checkbox" ''' + state + ' name="check" ' + exist_list[3] + '> ' + load_lang('user') + ' ' + load_lang('check') + '''</li>
  897. <li><input type="checkbox" ''' + state + ' name="acl" ' + exist_list[4] + '> ' + load_lang('document') + ''' acl</li>
  898. <li><input type="checkbox" ''' + state + ' name="hidel" ' + exist_list[5] + '> ' + load_lang('history') + ' ' + load_lang('hide') + '''</li>
  899. <li><input type="checkbox" ''' + state + ' name="give" ' + exist_list[6] + '> ' + load_lang('authority') + '''</li>
  900. <li><input type="checkbox" ''' + state + ' name="owner" ' + exist_list[7] + '> ' + load_lang('owner') + '''</li>
  901. </ul>
  902. '''
  903. return easy_minify(flask.render_template(skin_check(),
  904. imp = [load_lang('admin_group') + ' ' + load_lang('plus'), wiki_set(), custom(), other2([0, 0])],
  905. data = '''
  906. <form method="post">
  907. ''' + data + '''
  908. <hr class=\"main_hr\">
  909. <button id="save" ''' + state + ''' type="submit">''' + load_lang('save') + '''</button>
  910. </form>
  911. ''',
  912. menu = [['manager', load_lang('admin')]]
  913. ))
  914. @app.route('/admin_list')
  915. def admin_list():
  916. div = '<ul>'
  917. curs.execute("select id, acl, date from user where not acl = 'user' order by date desc")
  918. for data in curs.fetchall():
  919. name = ip_pas(data[0]) + ' <a href="/admin_plus/' + url_pas(data[1]) + '">(' + data[1] + ')</a>'
  920. if data[2] != '':
  921. name += '(' + data[2] + ')'
  922. div += '<li>' + name + '</li>'
  923. div += '</ul>'
  924. return easy_minify(flask.render_template(skin_check(),
  925. imp = [load_lang('admin') + ' ' + load_lang('list'), wiki_set(), custom(), other2([0, 0])],
  926. data = div,
  927. menu = [['other', load_lang('other')]]
  928. ))
  929. @app.route('/hidden/<everything:name>')
  930. def history_hidden(name = None):
  931. num = int(flask.request.args.get('num', 0))
  932. if admin_check(6, 'history_hidden (' + name + '#' + str(num) + ')') == 1:
  933. curs.execute("select title from history where title = ? and id = ? and hide = 'O'", [name, str(num)])
  934. if curs.fetchall():
  935. curs.execute("update history set hide = '' where title = ? and id = ?", [name, str(num)])
  936. else:
  937. curs.execute("update history set hide = 'O' where title = ? and id = ?", [name, str(num)])
  938. conn.commit()
  939. return redirect('/history/' + url_pas(name))
  940. @app.route('/user_log')
  941. def user_log():
  942. num = int(flask.request.args.get('num', 1))
  943. if num * 50 > 0:
  944. sql_num = num * 50 - 50
  945. else:
  946. sql_num = 0
  947. list_data = '<ul>'
  948. admin_one = admin_check(1)
  949. curs.execute("select id, date from user order by date desc limit ?, '50'", [str(sql_num)])
  950. user_list = curs.fetchall()
  951. for data in user_list:
  952. if admin_one == 1:
  953. curs.execute("select block from ban where block = ?", [data[0]])
  954. if curs.fetchall():
  955. ban_button = ' <a href="/ban/' + url_pas(data[0]) + '">(' + load_lang('release') + ')</a>'
  956. else:
  957. ban_button = ' <a href="/ban/' + url_pas(data[0]) + '">(' + load_lang('ban') + ')</a>'
  958. else:
  959. ban_button = ''
  960. list_data += '<li>' + ip_pas(data[0]) + ban_button
  961. if data[1] != '':
  962. list_data += ' (' + data[1] + ')'
  963. list_data += '</li>'
  964. if num == 1:
  965. curs.execute("select count(id) from user")
  966. user_count = curs.fetchall()
  967. if user_count:
  968. count = user_count[0][0]
  969. else:
  970. count = 0
  971. list_data += '''
  972. </ul>
  973. <hr class=\"main_hr\">
  974. <ul>
  975. <li>all : ''' + str(count) + '''</li>
  976. </ul>
  977. '''
  978. list_data += next_fix('/user_log?num=', num, user_list)
  979. return easy_minify(flask.render_template(skin_check(),
  980. imp = [load_lang('recent') + ' ' + load_lang('subscriber'), wiki_set(), custom(), other2([0, 0])],
  981. data = list_data,
  982. menu = 0
  983. ))
  984. @app.route('/admin_log')
  985. def admin_log():
  986. num = int(flask.request.args.get('num', 1))
  987. if num * 50 > 0:
  988. sql_num = num * 50 - 50
  989. else:
  990. sql_num = 0
  991. list_data = '<ul>'
  992. curs.execute("select who, what, time from re_admin order by time desc limit ?, '50'", [str(sql_num)])
  993. get_list = curs.fetchall()
  994. for data in get_list:
  995. list_data += '<li>' + ip_pas(data[0]) + ' / ' + data[1] + ' / ' + data[2] + '</li>'
  996. list_data += '</ul>'
  997. list_data += next_fix('/admin_log?num=', num, get_list)
  998. return easy_minify(flask.render_template(skin_check(),
  999. imp = [load_lang('recent') + ' ' + load_lang('authority'), wiki_set(), custom(), other2([0, 0])],
  1000. data = list_data,
  1001. menu = 0
  1002. ))
  1003. @app.route('/give_log')
  1004. def give_log():
  1005. list_data = '<ul>'
  1006. back = ''
  1007. curs.execute("select distinct name from alist order by name asc")
  1008. for data in curs.fetchall():
  1009. if back != data[0]:
  1010. back = data[0]
  1011. list_data += '<li><a href="/admin_plus/' + url_pas(data[0]) + '">' + data[0] + '</a></li>'
  1012. list_data += '</ul><hr class=\"main_hr\"><a href="/manager/8">(' + load_lang('create') + ')</a>'
  1013. return easy_minify(flask.render_template(skin_check(),
  1014. imp = [load_lang('admin_group') + ' ' + load_lang('list'), wiki_set(), custom(), other2([0, 0])],
  1015. data = list_data,
  1016. menu = [['other', load_lang('other')]]
  1017. ))
  1018. @app.route('/indexing')
  1019. def indexing():
  1020. if admin_check(None, 'indexing') != 1:
  1021. return re_error('/error/3')
  1022. curs.execute("select name from sqlite_master where type = 'index'")
  1023. data = curs.fetchall()
  1024. if data:
  1025. for delete_index in data:
  1026. print('delete : ' + delete_index[0])
  1027. sql = 'drop index if exists ' + delete_index[0]
  1028. try:
  1029. curs.execute(sql)
  1030. except:
  1031. pass
  1032. else:
  1033. curs.execute("select name from sqlite_master where type in ('table', 'view') and name not like 'sqlite_%' union all select name from sqlite_temp_master where type in ('table', 'view') order by 1;")
  1034. for table in curs.fetchall():
  1035. curs.execute('select sql from sqlite_master where name = ?', [table[0]])
  1036. cul = curs.fetchall()
  1037. r_cul = re.findall('(?:([^ (]*) text)', str(cul[0]))
  1038. for n_cul in r_cul:
  1039. print('create : index_' + table[0] + '_' + n_cul)
  1040. sql = 'create index index_' + table[0] + '_' + n_cul + ' on ' + table[0] + '(' + n_cul + ')'
  1041. try:
  1042. curs.execute(sql)
  1043. except:
  1044. pass
  1045. conn.commit()
  1046. return redirect('/')
  1047. @app.route('/restart', methods=['POST', 'GET'])
  1048. def restart():
  1049. if admin_check(None, 'restart') != 1:
  1050. return re_error('/error/3')
  1051. if flask.request.method == 'POST':
  1052. os.execl(sys.executable, sys.executable, *sys.argv)
  1053. else:
  1054. print('restart')
  1055. return easy_minify(flask.render_template(skin_check(),
  1056. imp = [load_lang('server') + ' ' + load_lang('restart'), wiki_set(), custom(), other2([0, 0])],
  1057. data = '''
  1058. <form method="post">
  1059. <button type="submit">''' + load_lang('restart') + '''</button>
  1060. </form>
  1061. ''',
  1062. menu = [['manager', load_lang('admin')]]
  1063. ))
  1064. @app.route('/update')
  1065. def now_update():
  1066. if admin_check(None, 'update') != 1:
  1067. return re_error('/error/3')
  1068. curs.execute('select data from other where name = "update"')
  1069. up_data = curs.fetchall()
  1070. if up_data:
  1071. up_data = up_data[0][0]
  1072. else:
  1073. up_data = 'stable'
  1074. if platform.system() == 'Linux':
  1075. print('update')
  1076. os.system('git remote rm origin')
  1077. os.system('git remote add origin https://github.com/2DU/opennamu.git')
  1078. ok = os.system('git fetch origin ' + up_data)
  1079. ok = os.system('git reset --hard origin/' + up_data)
  1080. if ok == 0:
  1081. return redirect('/restart')
  1082. else:
  1083. if platform.system() == 'Windows':
  1084. print('download')
  1085. urllib.request.urlretrieve('https://github.com/2DU/opennamu/archive/' + up_data + '.zip', 'update.zip')
  1086. print('zip extract')
  1087. zipfile.ZipFile('update.zip').extractall('')
  1088. print('move')
  1089. ok = os.system('xcopy /y /r opennamu-' + up_data + ' .')
  1090. if ok == 0:
  1091. print('remove')
  1092. os.system('rd /s /q opennamu-' + up_data)
  1093. os.system('del update.zip')
  1094. return redirect('/restart')
  1095. return easy_minify(flask.render_template(skin_check(),
  1096. imp = [load_lang('update'), wiki_set(), custom(), other2([0, 0])],
  1097. data = 'auto update is not support. <a href="https://github.com/2DU/opennamu">(github)</a>',
  1098. menu = [['manager/1', load_lang('admin')]]
  1099. ))
  1100. @app.route('/oauth_settings', methods=['GET', 'POST'])
  1101. def oauth_settings():
  1102. if admin_check(None, 'oauth_settings') != 1:
  1103. return re_error('/error/3')
  1104. if flask.request.method == 'POST':
  1105. try:
  1106. facebook_client_id = flask.request.form['facebook_client_id']
  1107. facebook_client_secret = flask.request.form['facebook_client_secret']
  1108. naver_client_id = flask.request.form['naver_client_id']
  1109. naver_client_secret = flask.request.form['naver_client_secret']
  1110. except:
  1111. return easy_minify(flask.render_template(skin_check(),
  1112. imp = [load_lang('inter_error'), wiki_set(), custom(), other2([0, 0])],
  1113. data = '''
  1114. <p>''' + load_lang('inter_error_detail') + '''</p>
  1115. <hr>
  1116. <code>ie_no_data_required</code>
  1117. <p>''' + load_lang('ie_no_data_required') + '''</p>
  1118. ''',
  1119. menu = [['other', load_lang('other')]]
  1120. ))
  1121. with open('oauthsettings.json', 'r', encoding='utf-8') as f:
  1122. legacy = json.loads(f.read())
  1123. with open('oauthsettings.json', 'w', encoding='utf-8') as f:
  1124. f.write(
  1125. """{
  1126. "_README" : {
  1127. "en" : \"""" + legacy['_README']['en'] + """\",
  1128. "ko" : \"""" + legacy['_README']['ko'] + """\",
  1129. "support" : """ + str(legacy['_README']['support']).replace("'", '"') + """
  1130. },
  1131. "publish_url" : \"""" + legacy['publish_url'] + """\",
  1132. "facebook" : {
  1133. "client_id" : \"""" + facebook_client_id + """\",
  1134. "client_secret" : \"""" + facebook_client_secret + """\"
  1135. },
  1136. "naver" : {
  1137. "client_id" : \"""" + naver_client_id + """\",
  1138. "client_secret" : \"""" + naver_client_secret + """\"
  1139. }
  1140. }"""
  1141. )
  1142. return flask.redirect('/oauth_settings')
  1143. oauth_supported = load_oauth('_README')['support']
  1144. body_content = ''
  1145. body_content += '''
  1146. <script>function check_value (target) {
  1147. target_box = document.getElementById(target.id + "_box");
  1148. if (target.value !== "") {
  1149. target_box.checked = true;
  1150. } else {
  1151. target_box.checked = false;
  1152. } }
  1153. </script>'''
  1154. init_js = ''
  1155. body_content += '<form method="post">'
  1156. for i in range(len(oauth_supported)):
  1157. oauth_data = load_oauth(oauth_supported[i])
  1158. for j in range(2):
  1159. if j == 0:
  1160. load_target = 'id'
  1161. elif j == 1:
  1162. load_target = 'secret'
  1163. init_js += 'check_value(document.getElementById("{}_client_{}"));'.format(oauth_supported[i], load_target)
  1164. body_content += '''
  1165. <input id="{}_client_{}_box" type="checkbox" disabled>
  1166. <input placeholder="{}_client_{}" id="{}_client_{}" name="{}_client_{}" value="{}" type="text" onChange="check_value(this)" style="width: 80%;">
  1167. <hr>
  1168. '''.format(
  1169. oauth_supported[i],
  1170. load_target,
  1171. oauth_supported[i],
  1172. load_target,
  1173. oauth_supported[i],
  1174. load_target,
  1175. oauth_supported[i],
  1176. load_target,
  1177. oauth_data['client_{}'.format(load_target)]
  1178. )
  1179. body_content += '<button id="save" type="submit">' + load_lang('save') + '</button></form>'
  1180. body_content += '<script>' + init_js + '</script>'
  1181. return easy_minify(flask.render_template(skin_check(),
  1182. imp = [load_lang('oauth_settings'), wiki_set(), custom(), other2([0, 0])],
  1183. data = body_content,
  1184. menu = [['other', load_lang('other')]]
  1185. ))
  1186. @app.route('/adsense_settings', methods=['GET', 'POST'])
  1187. def adsense_settings():
  1188. if admin_check(None, 'oauth_settings') != 1:
  1189. return re_error('/error/3')
  1190. if flask.request.method == 'POST':
  1191. try:
  1192. adsense_enabled = flask.request.form.get('adsense_enabled')
  1193. adsense_code = flask.request.form['adsense_code']
  1194. except:
  1195. return easy_minify(flask.render_template(skin_check(),
  1196. imp = [load_lang('inter_error'), wiki_set(), custom(), other2([0, 0])],
  1197. data = '''
  1198. <p>''' + load_lang('inter_error_detail') + '''</p>
  1199. <hr>
  1200. <code>ie_no_data_required</code>
  1201. <p>''' + load_lang('ie_no_data_required') + '''</p>
  1202. ''',
  1203. menu = [['other', load_lang('other')]]
  1204. ))
  1205. if adsense_enabled == 'on':
  1206. curs.execute('update other set data = "True" where name = "adsense"')
  1207. else:
  1208. curs.execute('update other set data = "False" where name = "adsense"')
  1209. curs.execute('update other set data = ? where name = "adsense_code"', [adsense_code])
  1210. conn.commit()
  1211. return redirect('/adsense_settings')
  1212. body_content = ''
  1213. curs.execute('select data from other where name = "adsense"')
  1214. adsense_enabled = curs.fetchall()[0][0]
  1215. curs.execute('select data from other where name = "adsense_code"')
  1216. adsense_code = curs.fetchall()[0][0]
  1217. template = '''
  1218. <form action="" accept-charset="utf-8" method="post">
  1219. <div class="form-check">
  1220. <label class="form-check-label">
  1221. <input class="form-check-input" name="adsense_enabled" type="checkbox" %_html:adsense_enabled_%>
  1222. %_lang:adsense_enabled_%
  1223. </label>
  1224. </div>
  1225. <hr>
  1226. <div class="form-group">
  1227. <textarea class="form-control" id="adsense_code" name="adsense_code" rows="12">%_html:adsense_code_%</textarea>
  1228. </div>
  1229. <button type="submit" value="publish">%_lang:save_%</button>
  1230. </form>
  1231. '''
  1232. if adsense_enabled == 'True':
  1233. template = template.replace('%_html:adsense_enabled_%', 'checked')
  1234. else:
  1235. template = template.replace('%_html:adsense_enabled_%', '')
  1236. template = template.replace('%_lang:adsense_enabled_%', load_lang('adsense') + ' ' + load_lang('enable'))
  1237. template = template.replace('%_lang:save_%', load_lang('save'))
  1238. template = template.replace('%_html:adsense_code_%', adsense_code)
  1239. body_content += template
  1240. return easy_minify(flask.render_template(skin_check(),
  1241. imp = [load_lang('adsense') + ' ' + load_lang('setting'), wiki_set(), custom(), other2([0, 0])],
  1242. data = body_content,
  1243. menu = [['other', load_lang('other')]]
  1244. ))
  1245. @app.route('/xref/<everything:name>')
  1246. def xref(name = None):
  1247. num = int(flask.request.args.get('num', 1))
  1248. if num * 50 > 0:
  1249. sql_num = num * 50 - 50
  1250. else:
  1251. sql_num = 0
  1252. div = '<ul>'
  1253. curs.execute("select link, type from back where title = ? and not type = 'cat' and not type = 'no' order by link asc limit ?, '50'", [name, str(sql_num)])
  1254. data_list = curs.fetchall()
  1255. for data in data_list:
  1256. div += '<li><a href="/w/' + url_pas(data[0]) + '">' + data[0] + '</a>'
  1257. if data[1]:
  1258. div += ' (' + data[1] + ')'
  1259. curs.execute("select title from back where title = ? and type = 'include'", [data[0]])
  1260. db_data = curs.fetchall()
  1261. if db_data:
  1262. div += ' <a id="inside" href="/xref/' + url_pas(data[0]) + '">(' + load_lang('backlink') + ')</a>'
  1263. div += '</li>'
  1264. div += '</ul>' + next_fix('/xref/' + url_pas(name) + '?num=', num, data_list)
  1265. return easy_minify(flask.render_template(skin_check(),
  1266. imp = [name, wiki_set(), custom(), other2([' (' + load_lang('backlink') + ')', 0])],
  1267. data = div,
  1268. menu = [['w/' + url_pas(name), load_lang('document')]]
  1269. ))
  1270. @app.route('/please')
  1271. def please():
  1272. num = int(flask.request.args.get('num', 1))
  1273. if num * 50 > 0:
  1274. sql_num = num * 50 - 50
  1275. else:
  1276. sql_num = 0
  1277. div = '<ul>'
  1278. var = ''
  1279. curs.execute("select distinct title from back where type = 'no' order by title asc limit ?, '50'", [str(sql_num)])
  1280. data_list = curs.fetchall()
  1281. for data in data_list:
  1282. if var != data[0]:
  1283. div += '<li><a id="not_thing" href="/w/' + url_pas(data[0]) + '">' + data[0] + '</a></li>'
  1284. var = data[0]
  1285. div += '</ul>' + next_fix('/please?num=', num, data_list)
  1286. return easy_minify(flask.render_template(skin_check(),
  1287. imp = [load_lang('need') + ' ' + load_lang('document'), wiki_set(), custom(), other2([0, 0])],
  1288. data = div,
  1289. menu = [['other', load_lang('other')]]
  1290. ))
  1291. @app.route('/recent_discuss')
  1292. def recent_discuss():
  1293. div = ''
  1294. if flask.request.args.get('what', 'normal') == 'normal':
  1295. div += '<a href="/recent_discuss?what=close">(' + load_lang('close') + ')</a>'
  1296. m_sub = 0
  1297. else:
  1298. div += '<a href="/recent_discuss">(' + load_lang('open') + ')</a>'
  1299. m_sub = ' (' + load_lang('close') + ')'
  1300. div += '''
  1301. <hr class=\"main_hr\">
  1302. <table id="main_table_set">
  1303. <tbody>
  1304. <tr>
  1305. <td id="main_table_width_half">''' + load_lang('discussion') + ' ' + load_lang('name') + '''</td>
  1306. <td id="main_table_width_half">''' + load_lang('time') + '''</td>
  1307. </tr>
  1308. '''
  1309. if m_sub == 0:
  1310. curs.execute("select title, sub, date from rd where not stop = 'O' order by date desc limit 50")
  1311. else:
  1312. curs.execute("select title, sub, date from rd where stop = 'O' order by date desc limit 50")
  1313. for data in curs.fetchall():
  1314. title = html.escape(data[0])
  1315. sub = html.escape(data[1])
  1316. div += '<tr><td><a href="/topic/' + url_pas(data[0]) + '/sub/' + url_pas(data[1]) + '">' + title + '</a> (' + sub + ')</td><td>' + data[2] + '</td></tr>'
  1317. div += '</tbody></table>'
  1318. return easy_minify(flask.render_template(skin_check(),
  1319. imp = [load_lang('recent') + ' ' + load_lang('discussion'), wiki_set(), custom(), other2([m_sub, 0])],
  1320. data = div,
  1321. menu = 0
  1322. ))
  1323. @app.route('/block_log')
  1324. @app.route('/block_log/<regex("ip|user|never_end|can_end|end|now|edit_filter"):tool2>')
  1325. @app.route('/<regex("block_user|block_admin"):tool>/<name>')
  1326. def block_log(name = None, tool = None, tool2 = None):
  1327. num = int(flask.request.args.get('num', 1))
  1328. if num * 50 > 0:
  1329. sql_num = num * 50 - 50
  1330. else:
  1331. sql_num = 0
  1332. div = '''
  1333. <table id="main_table_set">
  1334. <tbody>
  1335. <tr>
  1336. <td id="main_table_width">''' + load_lang('blocked') + '''</td>
  1337. <td id="main_table_width">''' + load_lang('admin') + '''</td>
  1338. <td id="main_table_width">''' + load_lang('period') + '''</td>
  1339. </tr>
  1340. '''
  1341. data_list = ''
  1342. if not name:
  1343. if not tool2:
  1344. div = '''
  1345. <a href="/manager/11">(''' + load_lang('blocked') + ''')</a> <a href="/manager/12">(''' + load_lang('admin') + ''')</a>
  1346. <hr class=\"main_hr\">
  1347. <a href="/block_log/ip">(ip)</a> <a href="/block_log/user">(''' + load_lang('subscriber') + ')</a> <a href="/block_log/never_end">(' + load_lang('limitless') + ')</a> <a href="/block_log/can_end">(' + load_lang('period') + ')</a> <a href="/block_log/end">(' + load_lang('release') + ')</a> <a href="/block_log/now">(' + load_lang('now') + ')</a> <a href="/block_log/edit_filter">(' + load_lang('edit') + ' ' + load_lang('filter') + ''')</a>
  1348. <hr class=\"main_hr\">
  1349. ''' + div
  1350. sub = 0
  1351. menu = 0
  1352. curs.execute("select why, block, blocker, end, today from rb order by today desc limit ?, '50'", [str(sql_num)])
  1353. else:
  1354. menu = [['block_log', load_lang('normal')]]
  1355. if tool2 == 'ip':
  1356. sub = ' (ip)'
  1357. curs.execute("select why, block, blocker, end, today from rb where (block like ? or block like ?) order by today desc limit ?, '50'", ['%.%', '%:%', str(sql_num)])
  1358. elif tool2 == 'user':
  1359. sub = ' (' + load_lang('subscriber') + ')'
  1360. curs.execute("select why, block, blocker, end, today from rb where not (block like ? or block like ?) order by today desc limit ?, '50'", ['%.%', '%:%', str(sql_num)])
  1361. elif tool2 == 'never_end':
  1362. sub = '(' + load_lang('limitless') + ')'
  1363. curs.execute("select why, block, blocker, end, today from rb where not end like ? and not end like ? order by today desc limit ?, '50'", ['%:%', '%' + load_lang('release', 1) + '%', str(sql_num)])
  1364. elif tool2 == 'end':
  1365. sub = '(' + load_lang('release') + ')'
  1366. curs.execute("select why, block, blocker, end, today from rb where end = ? order by today desc limit ?, '50'", [load_lang('release', 1), str(sql_num)])
  1367. elif tool2 == 'now':
  1368. sub = '(' + load_lang('now') + ')'
  1369. data_list = []
  1370. curs.execute("select block from ban where end > ? limit ?, '50'", [get_time(), str(sql_num)])
  1371. for in_data in curs.fetchall():
  1372. curs.execute("select why, block, blocker, end, today from rb where block = ? order by today desc limit 1", [in_data[0]])
  1373. data_list = [curs.fetchall()[0]] + data_list
  1374. elif tool2 == 'edit_filter':
  1375. sub = '(' + load_lang('edit') + ' ' + load_lang('filter') + ')'
  1376. curs.execute("select why, block, blocker, end, today from rb where blocker = ? order by today desc limit ?, '50'", [load_lang('tool', 1) + ':' + load_lang('edit', 1) + ' ' + load_lang('filter', 1), str(sql_num)])
  1377. else:
  1378. sub = '(' + load_lang('period') + ')'
  1379. curs.execute("select why, block, blocker, end, today from rb where end like ? order by today desc limit ?, '50'", ['%\-%', str(sql_num)])
  1380. else:
  1381. menu = [['block_log', load_lang('normal')]]
  1382. if tool == 'block_user':
  1383. sub = ' (' + load_lang('blocked') + ')'
  1384. curs.execute("select why, block, blocker, end, today from rb where block = ? order by today desc limit ?, '50'", [name, str(sql_num)])
  1385. else:
  1386. sub = ' (' + load_lang('admin') + ')'
  1387. curs.execute("select why, block, blocker, end, today from rb where blocker = ? order by today desc limit ?, '50'", [name, str(sql_num)])
  1388. if data_list == '':
  1389. data_list = curs.fetchall()
  1390. for data in data_list:
  1391. why = html.escape(data[0])
  1392. if why == '':
  1393. why = '<br>'
  1394. band = re.search("^([0-9]{1,3}\.[0-9]{1,3})$", data[1])
  1395. if band:
  1396. ip = data[1] + ' (' + load_lang('band') + ')'
  1397. else:
  1398. ip = ip_pas(data[1])
  1399. if data[3] != '':
  1400. end = data[3]
  1401. else:
  1402. end = load_lang('limitless') + ''
  1403. div += '''
  1404. <tr>
  1405. <td>''' + ip + '''</td>
  1406. <td>''' + ip_pas(data[2]) + '''</td>
  1407. <td>
  1408. start : ''' + data[4] + '''
  1409. <br>
  1410. end : ''' + end + '''
  1411. </td>
  1412. </tr>
  1413. <tr>
  1414. <td colspan="3">''' + why + '''</td>
  1415. </tr>
  1416. </tbody>
  1417. </table>
  1418. '''
  1419. if not name:
  1420. if not tool2:
  1421. div += next_fix('/block_log?num=', num, data_list)
  1422. else:
  1423. div += next_fix('/block_log/' + url_pas(tool2) + '?num=', num, data_list)
  1424. else:
  1425. div += next_fix('/' + url_pas(tool) + '/' + url_pas(name) + '?num=', num, data_list)
  1426. return easy_minify(flask.render_template(skin_check(),
  1427. imp = [load_lang('recent') + ' ' + load_lang('ban'), wiki_set(), custom(), other2([sub, 0])],
  1428. data = div,
  1429. menu = menu
  1430. ))
  1431. @app.route('/search', methods=['POST'])
  1432. def search():
  1433. return redirect('/search/' + url_pas(flask.request.form.get('search', None)))
  1434. @app.route('/goto', methods=['POST'])
  1435. def goto():
  1436. curs.execute("select title from data where title = ?", [flask.request.form.get('search', None)])
  1437. data = curs.fetchall()
  1438. if data:
  1439. return redirect('/w/' + url_pas(flask.request.form.get('search', None)))
  1440. else:
  1441. return redirect('/search/' + url_pas(flask.request.form.get('search', None)))
  1442. @app.route('/search/<everything:name>')
  1443. def deep_search(name = None):
  1444. num = int(flask.request.args.get('num', 1))
  1445. if num * 50 > 0:
  1446. sql_num = num * 50 - 50
  1447. else:
  1448. sql_num = 0
  1449. div = '<ul>'
  1450. div_plus = ''
  1451. test = ''
  1452. curs.execute("select title from data where title = ?", [name])
  1453. if curs.fetchall():
  1454. link_id = ''
  1455. else:
  1456. link_id = 'id="not_thing"'
  1457. div = '''
  1458. <ul>
  1459. <li>
  1460. <a ''' + link_id + ' href="/w/' + url_pas(name) + '">' + name + '''</a>
  1461. </li>
  1462. </ul>
  1463. <hr class=\"main_hr\">
  1464. <ul>
  1465. '''
  1466. curs.execute("select distinct title, case when title like ? then '제목' else '내용' end from data where title like ? or data like ? order by case when title like ? then 1 else 2 end limit ?, '50'", ['%' + name + '%', '%' + name + '%', '%' + name + '%', '%' + name + '%', str(sql_num)])
  1467. all_list = curs.fetchall()
  1468. if all_list:
  1469. test = all_list[0][1]
  1470. for data in all_list:
  1471. if data[1] != test:
  1472. div_plus += '</ul><hr class=\"main_hr\"><ul>'
  1473. test = data[1]
  1474. div_plus += '<li><a href="/w/' + url_pas(data[0]) + '">' + data[0] + '</a> (' + data[1] + ')</li>'
  1475. else:
  1476. div += '<li>-</li>'
  1477. div += div_plus + '</ul>'
  1478. div += next_fix('/search/' + url_pas(name) + '?num=', num, all_list)
  1479. return easy_minify(flask.render_template(skin_check(),
  1480. imp = [name, wiki_set(), custom(), other2([' (' + load_lang('search') + ')', 0])],
  1481. data = div,
  1482. menu = 0
  1483. ))
  1484. @app.route('/raw/<everything:name>')
  1485. @app.route('/topic/<everything:name>/sub/<sub_title>/raw/<int:num>')
  1486. def raw_view(name = None, sub_title = None, num = None):
  1487. v_name = name
  1488. sub = ' (' + load_lang('raw') + ')'
  1489. if not num:
  1490. num = flask.request.args.get('num', None)
  1491. if num:
  1492. num = int(num)
  1493. if not sub_title and num:
  1494. curs.execute("select title from history where title = ? and id = ? and hide = 'O'", [name, str(num)])
  1495. if curs.fetchall() and admin_check(6) != 1:
  1496. return re_error('/error/3')
  1497. curs.execute("select data from history where title = ? and id = ?", [name, str(num)])
  1498. sub += ' (' + str(num) + load_lang('version') + ')'
  1499. menu = [['history/' + url_pas(name), load_lang('history')]]
  1500. elif sub_title:
  1501. curs.execute("select data from topic where id = ? and title = ? and sub = ? and block = ''", [str(num), name, sub_title])
  1502. v_name = load_lang('discussion') + ' Raw'
  1503. sub = ' (' + str(num) + ')'
  1504. menu = [['topic/' + url_pas(name) + '/sub/' + url_pas(sub_title) + '#' + str(num), load_lang('discussion')], ['topic/' + url_pas(name) + '/sub/' + url_pas(sub_title) + '/admin/' + str(num), load_lang('tool')]]
  1505. else:
  1506. curs.execute("select data from data where title = ?", [name])
  1507. menu = [['w/' + url_pas(name), load_lang('document')]]
  1508. data = curs.fetchall()
  1509. if data:
  1510. p_data = html.escape(data[0][0])
  1511. p_data = '<textarea readonly rows="25">' + p_data + '</textarea>'
  1512. return easy_minify(flask.render_template(skin_check(),
  1513. imp = [v_name, wiki_set(), custom(), other2([sub, 0])],
  1514. data = p_data,
  1515. menu = menu
  1516. ))
  1517. else:
  1518. return redirect('/w/' + url_pas(name))
  1519. @app.route('/revert/<everything:name>', methods=['POST', 'GET'])
  1520. def revert(name = None):
  1521. num = int(flask.request.args.get('num', 0))
  1522. curs.execute("select title from history where title = ? and id = ? and hide = 'O'", [name, str(num)])
  1523. if curs.fetchall() and admin_check(6) != 1:
  1524. return re_error('/error/3')
  1525. if acl_check(name) == 1:
  1526. return re_error('/ban')
  1527. if flask.request.method == 'POST':
  1528. if captcha_post(flask.request.form.get('g-recaptcha-response', '')) == 1:
  1529. return re_error('/error/13')
  1530. else:
  1531. captcha_post('', 0)
  1532. curs.execute("select data from history where title = ? and id = ?", [name, str(num)])
  1533. data = curs.fetchall()
  1534. if data:
  1535. if edit_filter_do(data[0][0]) == 1:
  1536. return re_error('/error/21')
  1537. curs.execute("delete from back where link = ?", [name])
  1538. conn.commit()
  1539. if data:
  1540. curs.execute("select data from data where title = ?", [name])
  1541. data_old = curs.fetchall()
  1542. if data_old:
  1543. leng = leng_check(len(data_old[0][0]), len(data[0][0]))
  1544. curs.execute("update data set data = ? where title = ?", [data[0][0], name])
  1545. else:
  1546. leng = '+' + str(len(data[0][0]))
  1547. curs.execute("insert into data (title, data) values (?, ?)", [name, data[0][0]])
  1548. history_plus(
  1549. name,
  1550. data[0][0],
  1551. get_time(),
  1552. ip_check(),
  1553. flask.request.form.get('send', None) + ' (' + str(num) + load_lang('version', 1) + ')',
  1554. leng
  1555. )
  1556. render_set(
  1557. title = name,
  1558. data = data[0][0],
  1559. num = 1
  1560. )
  1561. conn.commit()
  1562. return redirect('/w/' + url_pas(name))
  1563. else:
  1564. curs.execute("select title from history where title = ? and id = ?", [name, str(num)])
  1565. if not curs.fetchall():
  1566. return redirect('/w/' + url_pas(name))
  1567. return easy_minify(flask.render_template(skin_check(),
  1568. imp = [name, wiki_set(), custom(), other2([' (' + load_lang('revert') + ')', 0])],
  1569. data = '''
  1570. <form method="post">
  1571. <span>''' + flask.request.args.get('num', '0') + load_lang('version') + '''</span>
  1572. <hr class=\"main_hr\">
  1573. ''' + ip_warring() + '''
  1574. <input placeholder="''' + load_lang('why') + '''" name="send" type="text">
  1575. <hr class=\"main_hr\">
  1576. ''' + captcha_get() + '''
  1577. <button type="submit">''' + load_lang('revert') + '''</button>
  1578. </form>
  1579. ''',
  1580. menu = [['history/' + url_pas(name), load_lang('history')], ['recent_changes', load_lang('recent') + ' ' + load_lang('change')]]
  1581. ))
  1582. @app.route('/edit/<everything:name>', methods=['POST', 'GET'])
  1583. def edit(name = None):
  1584. ip = ip_check()
  1585. if acl_check(name) == 1:
  1586. return re_error('/ban')
  1587. if flask.request.method == 'POST':
  1588. if captcha_post(flask.request.form.get('g-recaptcha-response', '')) == 1:
  1589. return re_error('/error/13')
  1590. else:
  1591. captcha_post('', 0)
  1592. if len(flask.request.form.get('send', None)) > 500:
  1593. return re_error('/error/15')
  1594. if flask.request.form.get('otent', None) == flask.request.form.get('content', None):
  1595. return redirect('/w/' + url_pas(name))
  1596. if edit_filter_do(flask.request.form.get('content', '')) == 1:
  1597. return re_error('/error/21')
  1598. today = get_time()
  1599. content = savemark(flask.request.form.get('content', None))
  1600. curs.execute("select data from data where title = ?", [name])
  1601. old = curs.fetchall()
  1602. if old:
  1603. leng = leng_check(len(flask.request.form.get('otent', None)), len(content))
  1604. if flask.request.args.get('section', None):
  1605. content = old[0][0].replace(flask.request.form.get('otent', None), content)
  1606. curs.execute("update data set data = ? where title = ?", [content, name])
  1607. else:
  1608. leng = '+' + str(len(content))
  1609. curs.execute("insert into data (title, data) values (?, ?)", [name, content])
  1610. curs.execute("select user from scan where title = ?", [name])
  1611. for _ in curs.fetchall():
  1612. curs.execute("insert into alarm (name, data, date) values (?, ?, ?)", [ip, ip + ' - <a href="/w/' + url_pas(name) + '">' + name + '</a> (Edit)', today])
  1613. history_plus(
  1614. name,
  1615. content,
  1616. today,
  1617. ip,
  1618. flask.request.form.get('send', None),
  1619. leng
  1620. )
  1621. curs.execute("delete from back where link = ?", [name])
  1622. curs.execute("delete from back where title = ? and type = 'no'", [name])
  1623. render_set(
  1624. title = name,
  1625. data = content,
  1626. num = 1
  1627. )
  1628. conn.commit()
  1629. return redirect('/w/' + url_pas(name))
  1630. else:
  1631. curs.execute("select data from data where title = ?", [name])
  1632. new = curs.fetchall()
  1633. if new:
  1634. if flask.request.args.get('section', None):
  1635. test_data = '\n' + re.sub('\r\n', '\n', new[0][0]) + '\n'
  1636. section_data = re.findall('((?:={1,6}) ?(?:(?:(?!={1,6}\n).)+) ?={1,6}\n(?:(?:(?!(?:={1,6}) ?(?:(?:(?!={1,6}\n).)+) ?={1,6}\n).)*\n*)*)', test_data)
  1637. data = section_data[int(flask.request.args.get('section', None)) - 1]
  1638. else:
  1639. data = new[0][0]
  1640. else:
  1641. data = ''
  1642. data_old = data
  1643. if not flask.request.args.get('section', None):
  1644. get_name = '''
  1645. <a href="/manager/15?plus=''' + url_pas(name) + '">(' + load_lang('load') + ')</a> <a href="/edit_filter">(' + load_lang('edit') + ' ' + load_lang('filter') + ''')</a>
  1646. <hr class=\"main_hr\">
  1647. '''
  1648. action = ''
  1649. else:
  1650. get_name = ''
  1651. action = '?section=' + flask.request.args.get('section', None)
  1652. if flask.request.args.get('plus', None):
  1653. curs.execute("select data from data where title = ?", [flask.request.args.get('plus', None)])
  1654. get_data = curs.fetchall()
  1655. if get_data:
  1656. data = get_data[0][0]
  1657. get_name = ''
  1658. js_data = edit_help_button()
  1659. return easy_minify(flask.render_template(skin_check(),
  1660. imp = [name, wiki_set(), custom(), other2([' (' + load_lang('edit') + ')', 0])],
  1661. data = get_name + js_data[0] + '''
  1662. <form method="post" action="/edit/''' + url_pas(name) + action + '''">
  1663. ''' + js_data[1] + '''
  1664. <textarea id="content" rows="25" name="content">''' + html.escape(re.sub('\n$', '', data)) + '''</textarea>
  1665. <textarea style="display: none;" name="otent">''' + html.escape(re.sub('\n$', '', data_old)) + '''</textarea>
  1666. <hr class=\"main_hr\">
  1667. <input placeholder="''' + load_lang('why') + '''" name="send" type="text">
  1668. <hr class=\"main_hr\">
  1669. ''' + captcha_get() + ip_warring() + '''
  1670. <button id="save" type="submit">''' + load_lang('save') + '''</button>
  1671. <button id="preview" type="submit" formaction="/preview/''' + url_pas(name) + action + '">' + load_lang('preview') + '''</button>
  1672. </form>
  1673. ''',
  1674. menu = [['w/' + url_pas(name), load_lang('document')], ['delete/' + url_pas(name), load_lang('delete')], ['move/' + url_pas(name), load_lang('move')]]
  1675. ))
  1676. @app.route('/preview/<everything:name>', methods=['POST'])
  1677. def preview(name = None):
  1678. if acl_check(name) == 1:
  1679. return re_error('/ban')
  1680. new_data = re.sub('^\r\n', '', flask.request.form.get('content', None))
  1681. new_data = re.sub('\r\n$', '', new_data)
  1682. end_data = render_set(
  1683. title = name,
  1684. data = new_data
  1685. )
  1686. if flask.request.args.get('section', None):
  1687. action = '?section=' + flask.request.args.get('section', None)
  1688. else:
  1689. action = ''
  1690. js_data = edit_help_button()
  1691. return easy_minify(flask.render_template(skin_check(),
  1692. imp = [name, wiki_set(), custom(), other2([' (' + load_lang('preview') + ')', 0])],
  1693. data = '<a href="/edit_filter">(' + load_lang('edit') + ' ' + load_lang('filter') + ')</a>' + js_data[0] + '''
  1694. <form method="post" action="/edit/''' + url_pas(name) + action + '''">
  1695. ''' + js_data[1] + '''
  1696. <textarea id="content" rows="25" name="content">''' + html.escape(flask.request.form.get('content', None)) + '''</textarea>
  1697. <textarea style="display: none;" name="otent">''' + html.escape(flask.request.form.get('otent', None)) + '''</textarea>
  1698. <hr class=\"main_hr\">
  1699. <input placeholder="''' + load_lang('why') + '''" name="send" type="text">
  1700. <hr class=\"main_hr\">
  1701. ''' + captcha_get() + '''
  1702. <button id="save" type="submit">''' + load_lang('save') + '''</button>
  1703. <button id="preview" type="submit" formaction="/preview/''' + url_pas(name) + action + '">' + load_lang('preview') + '''</button>
  1704. </form>
  1705. <hr class=\"main_hr\">
  1706. ''' + end_data,
  1707. menu = [['w/' + url_pas(name), load_lang('document')]]
  1708. ))
  1709. @app.route('/delete/<everything:name>', methods=['POST', 'GET'])
  1710. def delete(name = None):
  1711. ip = ip_check()
  1712. if acl_check(name) == 1:
  1713. return re_error('/ban')
  1714. if flask.request.method == 'POST':
  1715. if captcha_post(flask.request.form.get('g-recaptcha-response', '')) == 1:
  1716. return re_error('/error/13')
  1717. else:
  1718. captcha_post('', 0)
  1719. curs.execute("select data from data where title = ?", [name])
  1720. data = curs.fetchall()
  1721. if data:
  1722. today = get_time()
  1723. leng = '-' + str(len(data[0][0]))
  1724. history_plus(
  1725. name,
  1726. '',
  1727. today,
  1728. ip,
  1729. flask.request.form.get('send', None) + ' (' + load_lang('delete', 1) + ')',
  1730. leng
  1731. )
  1732. curs.execute("select title, link from back where title = ? and not type = 'cat' and not type = 'no'", [name])
  1733. for data in curs.fetchall():
  1734. curs.execute("insert into back (title, link, type) values (?, ?, 'no')", [data[0], data[1]])
  1735. curs.execute("delete from back where link = ?", [name])
  1736. curs.execute("delete from data where title = ?", [name])
  1737. conn.commit()
  1738. return redirect('/w/' + url_pas(name))
  1739. else:
  1740. curs.execute("select title from data where title = ?", [name])
  1741. if not curs.fetchall():
  1742. return redirect('/w/' + url_pas(name))
  1743. return easy_minify(flask.render_template(skin_check(),
  1744. imp = [name, wiki_set(), custom(), other2([' (' + load_lang('delete') + ')', 0])],
  1745. data = '''
  1746. <form method="post">
  1747. ''' + ip_warring() + '''
  1748. <input placeholder="''' + load_lang('why') + '''" name="send" type="text">
  1749. <hr class=\"main_hr\">
  1750. ''' + captcha_get() + '''
  1751. <button type="submit">''' + load_lang('delete') + '''</button>
  1752. </form>
  1753. ''',
  1754. menu = [['w/' + url_pas(name), load_lang('document')]]
  1755. ))
  1756. @app.route('/move_data/<everything:name>')
  1757. def move_data(name = None):
  1758. data = '<ul>'
  1759. curs.execute("select send, date, ip from history where send like ? or send like ? order by date desc", ['%<a>' + name + '</a> ' + load_lang('move', 1) + ')%', '%(<a>' + name + '</a>%'])
  1760. for for_data in curs.fetchall():
  1761. match = re.findall('<a>((?:(?!<\/a>).)+)<\/a>', for_data[0])
  1762. send = re.sub('\([^\)]+\)$', '', for_data[0])
  1763. data += '<li><a href="/move_data/' + url_pas(match[0]) + '">' + match[0] + '</a> - <a href="/move_data/' + url_pas(match[1]) + '">' + match[1] + '</a>'
  1764. if re.search('^( *)+$', send):
  1765. data += ' / ' + for_data[2] + ' / ' + for_data[1] + '</li>'
  1766. else:
  1767. data += ' / ' + for_data[2] + ' / ' + for_data[1] + ' / ' + send + '</li>'
  1768. data += '</ul>'
  1769. return easy_minify(flask.render_template(skin_check(),
  1770. imp = [name, wiki_set(), custom(), other2([' (' + load_lang('move') + ' ' + load_lang('history') + ')', 0])],
  1771. data = data,
  1772. menu = [['history/' + url_pas(name), load_lang('history')]]
  1773. ))
  1774. @app.route('/move/<everything:name>', methods=['POST', 'GET'])
  1775. def move(name = None):
  1776. if acl_check(name) == 1:
  1777. return re_error('/ban')
  1778. if flask.request.method == 'POST':
  1779. if captcha_post(flask.request.form.get('g-recaptcha-response', '')) == 1:
  1780. return re_error('/error/13')
  1781. else:
  1782. captcha_post('', 0)
  1783. curs.execute("select title from history where title = ?", [flask.request.form.get('title', None)])
  1784. if curs.fetchall():
  1785. if admin_check(None, 'merge documents') == 1:
  1786. curs.execute("select data from data where title = ?", [flask.request.form.get('title', None)])
  1787. data = curs.fetchall()
  1788. if data:
  1789. curs.execute("delete from data where title = ?", [flask.request.form.get('title', None)])
  1790. curs.execute("delete from back where link = ?", [flask.request.form.get('title', None)])
  1791. curs.execute("select data from data where title = ?", [name])
  1792. data = curs.fetchall()
  1793. if data:
  1794. curs.execute("update data set title = ? where title = ?", [flask.request.form.get('title', None), name])
  1795. curs.execute("update back set link = ? where link = ?", [flask.request.form.get('title', None), name])
  1796. data_in = data[0][0]
  1797. else:
  1798. data_in = ''
  1799. history_plus(
  1800. name,
  1801. data_in,
  1802. get_time(),
  1803. ip_check(),
  1804. flask.request.form.get('send', None) + ' (marge <a>' + name + '</a> - <a>' + flask.request.form.get('title', None) + '</a> ' + load_lang('move', 1) + ')',
  1805. '0'
  1806. )
  1807. curs.execute("update back set type = 'no' where title = ? and not type = 'cat' and not type = 'no'", [name])
  1808. curs.execute("delete from back where title = ? and not type = 'cat' and type = 'no'", [flask.request.form.get('title', None)])
  1809. curs.execute("select id from history where title = ? order by id + 0 desc limit 1", [flask.request.form.get('title', None)])
  1810. data = curs.fetchall()
  1811. num = data[0][0]
  1812. curs.execute("select id from history where title = ? order by id + 0 asc", [name])
  1813. data = curs.fetchall()
  1814. for move in data:
  1815. curs.execute("update history set title = ?, id = ? where title = ? and id = ?", [flask.request.form.get('title', None), str(int(num) + int(move[0])), name, move[0]])
  1816. conn.commit()
  1817. return redirect('/w/' + url_pas(flask.request.form.get('title', None)))
  1818. else:
  1819. return re_error('/error/19')
  1820. else:
  1821. curs.execute("select data from data where title = ?", [name])
  1822. data = curs.fetchall()
  1823. if data:
  1824. curs.execute("update data set title = ? where title = ?", [flask.request.form.get('title', None), name])
  1825. curs.execute("update back set link = ? where link = ?", [flask.request.form.get('title', None), name])
  1826. data_in = data[0][0]
  1827. else:
  1828. data_in = ''
  1829. history_plus(
  1830. name,
  1831. data_in,
  1832. get_time(),
  1833. ip_check(),
  1834. flask.request.form.get('send', None) + ' (<a>' + name + '</a> - <a>' + flask.request.form.get('title', None) + '</a> ' + load_lang('move', 1) + ')',
  1835. '0'
  1836. )
  1837. curs.execute("update back set type = 'no' where title = ? and not type = 'cat' and not type = 'no'", [name])
  1838. curs.execute("delete from back where title = ? and not type = 'cat' and type = 'no'", [flask.request.form.get('title', None)])
  1839. curs.execute("update history set title = ? where title = ?", [flask.request.form.get('title', None), name])
  1840. conn.commit()
  1841. return redirect('/w/' + url_pas(flask.request.form.get('title', None)))
  1842. else:
  1843. return easy_minify(flask.render_template(skin_check(),
  1844. imp = [name, wiki_set(), custom(), other2([' (' + load_lang('move') + ')', 0])],
  1845. data = '''
  1846. <form method="post">
  1847. ''' + ip_warring() + '''
  1848. <input placeholder="''' + load_lang('document') + ' ' + load_lang('name') + '" value="' + name + '''" name="title" type="text">
  1849. <hr class=\"main_hr\">
  1850. <input placeholder="''' + load_lang('why') + '''" name="send" type="text">
  1851. <hr class=\"main_hr\">
  1852. ''' + captcha_get() + '''
  1853. <button type="submit">''' + load_lang('move') + '''</button>
  1854. </form>
  1855. ''',
  1856. menu = [['w/' + url_pas(name), load_lang('document')]]
  1857. ))
  1858. @app.route('/other')
  1859. def other():
  1860. return easy_minify(flask.render_template(skin_check(),
  1861. imp = [load_lang('other') + ' ' + load_lang('tool'), wiki_set(), custom(), other2([0, 0])],
  1862. data = '''
  1863. <h2>''' + load_lang('record') + '''</h2>
  1864. <ul>
  1865. <li><a href="/manager/6">''' + load_lang('edit') + '''</a></li>
  1866. <li><a href="/manager/7">''' + load_lang('discussion') + '''</a></li>
  1867. </ul>
  1868. <br>
  1869. <h2>''' + load_lang('list') + '''</h2>
  1870. <ul>
  1871. <li><a href="/admin_list">''' + load_lang('admin') + '''</a></li>
  1872. <li><a href="/give_log">''' + load_lang('admin_group') + '''</a></li>
  1873. <li><a href="/not_close_topic">''' + load_lang('open') + ' ' + load_lang('discussion') + '''</a></li>
  1874. <li><a href="/title_index">''' + load_lang('all') + ' ' + load_lang('document') + '''</a></li>
  1875. <li><a href="/acl_list">acl ''' + load_lang('document') + '''</a></li>
  1876. <li><a href="/please">''' + load_lang('need') + ' ' + load_lang('document') + '''</a></li>
  1877. </ul>
  1878. <br>
  1879. <h2>''' + load_lang('other') + '''</h2>
  1880. <ul>
  1881. <li><a href="/upload">''' + load_lang('upload') + '''</a></li>
  1882. <li><a href="/manager/10">''' + load_lang('document') + ' ' + load_lang('search') + '''</a></li>
  1883. </ul>
  1884. <br>
  1885. <h2>''' + load_lang('admin') + '''</h2>
  1886. <ul>
  1887. <li><a href="/manager/1">''' + load_lang('admin') + ' ' + load_lang('tool') + '''</a></li>
  1888. </ul>
  1889. <br>
  1890. <h2>''' + load_lang('normal_version') + '''</h2>
  1891. <ul>
  1892. <li>''' + load_lang('normal_version') + ' : <a id="out_link" href="https://github.com/2DU/opennamu/blob/master/version.md">' + r_ver + '''</a></li>
  1893. </ul>
  1894. ''',
  1895. menu = 0
  1896. ))
  1897. @app.route('/manager', methods=['POST', 'GET'])
  1898. @app.route('/manager/<int:num>', methods=['POST', 'GET'])
  1899. def manager(num = 1):
  1900. title_list = {
  1901. 0 : [load_lang('document') + ' ' + load_lang('name'), 'acl'],
  1902. 1 : [0, 'check'],
  1903. 2 : [0, 'ban'],
  1904. 3 : [0, 'admin'],
  1905. 4 : [0, 'record'],
  1906. 5 : [0, 'topic_record'],
  1907. 6 : [load_lang('name'), 'admin_plus'],
  1908. 7 : [load_lang('name'), 'plus_edit_filter'],
  1909. 8 : [load_lang('document') + ' ' + load_lang('name'), 'search'],
  1910. 9 : [0, 'block_user'],
  1911. 10 : [0, 'block_admin'],
  1912. 11 : [load_lang('document') + ' ' + load_lang('name'), 'watch_list'],
  1913. 12 : [load_lang('compare'), 'check'],
  1914. 13 : [load_lang('document') + ' ' + load_lang('name'), 'edit']
  1915. }
  1916. if num == 1:
  1917. return easy_minify(flask.render_template(skin_check(),
  1918. imp = [load_lang('admin') + ' ' + load_lang('tool'), wiki_set(), custom(), other2([0, 0])],
  1919. data = '''
  1920. <h2>''' + load_lang('admin') + '''</h2>
  1921. <ul>
  1922. <li><a href="/manager/2">''' + load_lang('document') + ''' acl</a></li>
  1923. <li><a href="/manager/3">''' + load_lang('user') + ' ' + load_lang('check') + '''</a></li>
  1924. <li><a href="/manager/4">''' + load_lang('user') + ' ' + load_lang('ban') + '''</a></li>
  1925. <li><a href="/manager/5">''' + load_lang('subscriber') + ' ' + load_lang('authority') + '''</a></li>
  1926. <li><a href="/edit_filter">''' + load_lang('edit') + ' ' + load_lang('filter') + '''</a></li>
  1927. </ul>
  1928. <br>
  1929. <h2>''' + load_lang('owner') + '''</h2>
  1930. <ul>
  1931. <li><a href="/manager/8">''' + load_lang('admin_group') + ' ' + load_lang('create') + '''</a></li>
  1932. <li><a href="/setting">''' + load_lang('setting') + ' ' + load_lang('edit') + '''</a></li>
  1933. </ul>
  1934. <h3>''' + load_lang('filter') + '''</h3>
  1935. <ul>
  1936. <li><a href="/inter_wiki">''' + load_lang('interwiki') + '''</a></li>
  1937. <li><a href="/html_filter">html ''' + load_lang('filter') + '''</a></li>
  1938. <li><a href="/email_filter">email ''' + load_lang('filter') + '''</a></li>
  1939. <li><a href="/name_filter">''' + load_lang('id') + ' ' + load_lang('filter') + '''</a></li>
  1940. </ul>
  1941. <br>
  1942. <h2>''' + load_lang('server') + '''</h2>
  1943. <ul>
  1944. <li><a href="/indexing">''' + load_lang('indexing') + ' (' + load_lang('create') + ' or ' + load_lang('delete') + ''')</a></li>
  1945. <li><a href="/restart">''' + load_lang('server') + ' ' + load_lang('restart') + '''</a></li>
  1946. <li><a href="/update">''' + load_lang('update') + '''</a></li>
  1947. <li><a href="/oauth_settings">''' + load_lang('oauth_settings') + '''</a></li>
  1948. <li><a href="/adsense_settings">''' + load_lang('adsense') + ' ' + load_lang('setting') + '''</a></li>
  1949. </ul>
  1950. ''',
  1951. menu = [['other', load_lang('other')]]
  1952. ))
  1953. elif not num - 1 > len(title_list):
  1954. if flask.request.method == 'POST':
  1955. if flask.request.args.get('plus', None):
  1956. return redirect('/' + title_list[(num - 2)][1] + '/' + url_pas(flask.request.args.get('plus', None)) + '?plus=' + flask.request.form.get('name', None))
  1957. else:
  1958. return redirect('/' + title_list[(num - 2)][1] + '/' + url_pas(flask.request.form.get('name', None)))
  1959. else:
  1960. if title_list[(num - 2)][0] == 0:
  1961. placeholder = load_lang('user') + ' ' + load_lang('name')
  1962. else:
  1963. placeholder = title_list[(num - 2)][0]
  1964. return easy_minify(flask.render_template(skin_check(),
  1965. imp = ['Redirect', wiki_set(), custom(), other2([0, 0])],
  1966. data = '''
  1967. <form method="post">
  1968. <input placeholder="''' + placeholder + '''" name="name" type="text">
  1969. <hr class=\"main_hr\">
  1970. <button type="submit">''' + load_lang('move') + '''</button>
  1971. </form>
  1972. ''',
  1973. menu = [['manager', load_lang('admin')]]
  1974. ))
  1975. else:
  1976. return redirect('/')
  1977. @app.route('/title_index')
  1978. def title_index():
  1979. page = int(flask.request.args.get('page', 1))
  1980. num = int(flask.request.args.get('num', 100))
  1981. if page * num > 0:
  1982. sql_num = page * num - num
  1983. else:
  1984. sql_num = 0
  1985. all_list = sql_num + 1
  1986. if num > 1000:
  1987. return re_error('/error/3')
  1988. data = '<a href="/title_index?num=250">(250)</a> <a href="/title_index?num=500">(500)</a> <a href="/title_index?num=1000">(1000)</a>'
  1989. curs.execute("select title from data order by title asc limit ?, ?", [str(sql_num), str(num)])
  1990. title_list = curs.fetchall()
  1991. if title_list:
  1992. data += '<hr class=\"main_hr\"><ul>'
  1993. for list_data in title_list:
  1994. data += '<li>' + str(all_list) + '. <a href="/w/' + url_pas(list_data[0]) + '">' + list_data[0] + '</a></li>'
  1995. all_list += 1
  1996. if page == 1:
  1997. count_end = []
  1998. curs.execute("select count(title) from data")
  1999. count = curs.fetchall()
  2000. if count:
  2001. count_end += [count[0][0]]
  2002. else:
  2003. count_end += [0]
  2004. sql_list = [load_lang('template', 1) + ':', 'category:', 'user:', 'file:']
  2005. for sql in sql_list:
  2006. curs.execute("select count(title) from data where title like ?", [sql + '%'])
  2007. count = curs.fetchall()
  2008. if count:
  2009. count_end += [count[0][0]]
  2010. else:
  2011. count_end += [0]
  2012. count_end += [count_end[0] - count_end[1] - count_end[2] - count_end[3] - count_end[4]]
  2013. data += '''
  2014. </ul>
  2015. <hr class=\"main_hr\">
  2016. <ul>
  2017. <li>all : ''' + str(count_end[0]) + '''</li>
  2018. </ul>
  2019. <hr class=\"main_hr\">
  2020. <ul>
  2021. <li>''' + load_lang('template') + ' : ' + str(count_end[1]) + '''</li>
  2022. <li>''' + load_lang('category') + ' : ' + str(count_end[2]) + '''</li>
  2023. <li>''' + load_lang('user') + ' : ' + str(count_end[3]) + '''</li>
  2024. <li>''' + load_lang('file') + ' : ' + str(count_end[4]) + '''</li>
  2025. <li>other : ''' + str(count_end[5]) + '''</li>
  2026. '''
  2027. data += '</ul>' + next_fix('/title_index?num=' + str(num) + '&page=', page, title_list, num)
  2028. sub = ' (' + str(num) + ')'
  2029. return easy_minify(flask.render_template(skin_check(),
  2030. imp = [load_lang('all') + ' ' + load_lang('document'), wiki_set(), custom(), other2([sub, 0])],
  2031. data = data,
  2032. menu = [['other', load_lang('other')]]
  2033. ))
  2034. @app.route('/topic/<everything:name>/sub/<sub>/b/<int:num>')
  2035. def topic_block(name = None, sub = None, num = None):
  2036. if admin_check(3, 'blind (' + name + ' - ' + sub + '#' + str(num) + ')') != 1:
  2037. return re_error('/error/3')
  2038. curs.execute("select block from topic where title = ? and sub = ? and id = ?", [name, sub, str(num)])
  2039. block = curs.fetchall()
  2040. if block:
  2041. if block[0][0] == 'O':
  2042. curs.execute("update topic set block = '' where title = ? and sub = ? and id = ?", [name, sub, str(num)])
  2043. else:
  2044. curs.execute("update topic set block = 'O' where title = ? and sub = ? and id = ?", [name, sub, str(num)])
  2045. rd_plus(name, sub, get_time())
  2046. conn.commit()
  2047. return redirect('/topic/' + url_pas(name) + '/sub/' + url_pas(sub) + '#' + str(num))
  2048. @app.route('/topic/<everything:name>/sub/<sub>/notice/<int:num>')
  2049. def topic_top(name = None, sub = None, num = None):
  2050. if admin_check(3, 'notice (' + name + ' - ' + sub + '#' + str(num) + ')') != 1:
  2051. return re_error('/error/3')
  2052. curs.execute("select title from topic where title = ? and sub = ? and id = ?", [name, sub, str(num)])
  2053. if curs.fetchall():
  2054. curs.execute("select top from topic where id = ? and title = ? and sub = ?", [str(num), name, sub])
  2055. top_data = curs.fetchall()
  2056. if top_data:
  2057. if top_data[0][0] == 'O':
  2058. curs.execute("update topic set top = '' where title = ? and sub = ? and id = ?", [name, sub, str(num)])
  2059. else:
  2060. curs.execute("update topic set top = 'O' where title = ? and sub = ? and id = ?", [name, sub, str(num)])
  2061. rd_plus(name, sub, get_time())
  2062. conn.commit()
  2063. return redirect('/topic/' + url_pas(name) + '/sub/' + url_pas(sub) + '#' + str(num))
  2064. @app.route('/topic/<everything:name>/sub/<sub>/tool/<regex("close|stop|agree"):tool>')
  2065. def topic_stop(name = None, sub = None, tool = None):
  2066. if tool == 'close':
  2067. set_list = [
  2068. 'O',
  2069. 'S',
  2070. load_lang('discussion', 1) + ' ' + load_lang('close', 1),
  2071. load_lang('discussion', 1) + ' ' + load_lang('open', 1)
  2072. ]
  2073. elif tool == 'stop':
  2074. set_list = [
  2075. '',
  2076. 'O',
  2077. load_lang('discussion', 1) + ' ' + load_lang('stop', 1),
  2078. load_lang('discussion', 1) + ' ' + load_lang('restart', 1)
  2079. ]
  2080. elif tool == 'agree':
  2081. pass
  2082. else:
  2083. return redirect('/topic/' + url_pas(name) + '/sub/' + url_pas(sub))
  2084. if admin_check(3, 'topic ' + tool + ' (' + name + ' - ' + sub + ')') != 1:
  2085. return re_error('/error/3')
  2086. ip = ip_check()
  2087. time = get_time()
  2088. curs.execute("select id from topic where title = ? and sub = ? order by id + 0 desc limit 1", [name, sub])
  2089. topic_check = curs.fetchall()
  2090. if topic_check:
  2091. if tool == 'agree':
  2092. curs.execute("select title from rd where title = ? and sub = ? and agree = 'O'", [name, sub])
  2093. if curs.fetchall():
  2094. curs.execute("insert into topic (id, title, sub, data, date, ip, block, top) values (?, ?, ?, '" + load_lang('agreement', 1) + " X', ?, ?, '', '1')", [str(int(topic_check[0][0]) + 1), name, sub, time, ip])
  2095. curs.execute("update rd set agree = '' where title = ? and sub = ?", [name, sub])
  2096. else:
  2097. curs.execute("insert into topic (id, title, sub, data, date, ip, block, top) values (?, ?, ?, '" + load_lang('agreement', 1) + " O', ?, ?, '', '1')", [str(int(topic_check[0][0]) + 1), name, sub, time, ip])
  2098. curs.execute("update rd set agree = 'O' where title = ? and sub = ?", [name, sub])
  2099. else:
  2100. curs.execute("select title from rd where title = ? and sub = ? and stop = ?", [name, sub, set_list[0]])
  2101. if curs.fetchall():
  2102. curs.execute("insert into topic (id, title, sub, data, date, ip, block, top) values (?, ?, ?, ?, ?, ?, '', '1')", [str(int(topic_check[0][0]) + 1), name, sub, set_list[3], time, ip])
  2103. curs.execute("update rd set stop = '' where title = ? and sub = ?", [name, sub])
  2104. else:
  2105. curs.execute("insert into topic (id, title, sub, data, date, ip, block, top) values (?, ?, ?, ?, ?, ?, '', '1')", [str(int(topic_check[0][0]) + 1), name, sub, set_list[2], time, ip])
  2106. curs.execute("update rd set stop = ? where title = ? and sub = ?", [set_list[0], name, sub])
  2107. rd_plus(name, sub, time)
  2108. conn.commit()
  2109. return redirect('/topic/' + url_pas(name) + '/sub/' + url_pas(sub))
  2110. @app.route('/topic/<everything:name>/sub/<sub>/admin/<int:num>')
  2111. def topic_admin(name = None, sub = None, num = None):
  2112. curs.execute("select block, ip, date from topic where title = ? and sub = ? and id = ?", [name, sub, str(num)])
  2113. data = curs.fetchall()
  2114. if not data:
  2115. return redirect('/topic/' + url_pas(name) + '/sub/' + url_pas(sub))
  2116. ban = ''
  2117. if admin_check(3) == 1:
  2118. ban += '''
  2119. </ul>
  2120. <br>
  2121. <h2>''' + load_lang('admin') + ' ' + load_lang('tool') + '''</h2>
  2122. <ul>
  2123. '''
  2124. is_ban = '<li><a href="/topic/' + url_pas(name) + '/sub/' + url_pas(sub) + '/b/' + str(num) + '">'
  2125. if data[0][0] == 'O':
  2126. is_ban += load_lang('hide') + ' ' + load_lang('release')
  2127. else:
  2128. is_ban += load_lang('hide')
  2129. is_ban += '''
  2130. </a>
  2131. </li>
  2132. <li>
  2133. <a href="/topic/''' + url_pas(name) + '/sub/' + url_pas(sub) + '/notice/' + str(num) + '''">
  2134. '''
  2135. curs.execute("select id from topic where title = ? and sub = ? and id = ? and top = 'O'", [name, sub, str(num)])
  2136. if curs.fetchall():
  2137. is_ban += load_lang('notice') + ' ' + load_lang('release')
  2138. else:
  2139. is_ban += load_lang('notice') + ''
  2140. is_ban += '</a></li></ul>'
  2141. ban += '<li><a href="/ban/' + url_pas(data[0][1]) + '">'
  2142. curs.execute("select end from ban where block = ?", [data[0][1]])
  2143. if curs.fetchall():
  2144. ban += load_lang('ban') + ' ' + load_lang('release')
  2145. else:
  2146. ban += load_lang('ban')
  2147. ban += '</a></li>' + is_ban
  2148. ban += '''
  2149. </ul>
  2150. <br>
  2151. <h2>''' + load_lang('other') + ' ' + load_lang('tool') + '''</h2>
  2152. <ul>
  2153. <li>
  2154. <a href="/topic/''' + url_pas(name) + '/sub/' + url_pas(sub) + '/raw/' + str(num) + '''">raw</a>
  2155. </li>
  2156. '''
  2157. ban = '<li>' + load_lang('time') + ' : ' + data[0][2] + '</li>' + ban
  2158. if ip_or_user(data[0][1]) == 1:
  2159. ban = '<li>' + load_lang('writer') + ' : ' + data[0][1] + ' <a href="/record/' + url_pas(data[0][1]) + '">(' + load_lang('record') + ')</a></li>' + ban
  2160. else:
  2161. ban = '''
  2162. <li>
  2163. ''' + load_lang('writer') + ' : <a href="/w/user:' + data[0][1] + '">' + data[0][1] + '</a> <a href="/record/' + url_pas(data[0][1]) + '">(' + load_lang('record') + ''')</a>
  2164. </li>
  2165. ''' + ban
  2166. ban = '<h2>' + load_lang('state') + '</h2><ul>' + ban
  2167. return easy_minify(flask.render_template(skin_check(),
  2168. imp = [load_lang('discussion') + ' ' + load_lang('tool'), wiki_set(), custom(), other2([' (' + str(num) + ')', 0])],
  2169. data = ban,
  2170. menu = [['topic/' + url_pas(name) + '/sub/' + url_pas(sub) + '#' + str(num), load_lang('discussion')]]
  2171. ))
  2172. @app.route('/topic/<everything:name>/sub/<sub>', methods=['POST', 'GET'])
  2173. def topic(name = None, sub = None):
  2174. ban = topic_check(name, sub)
  2175. admin = admin_check(3)
  2176. if flask.request.method == 'POST':
  2177. if captcha_post(flask.request.form.get('g-recaptcha-response', '')) == 1:
  2178. return re_error('/error/13')
  2179. else:
  2180. captcha_post('', 0)
  2181. ip = ip_check()
  2182. today = get_time()
  2183. if ban == 1:
  2184. return re_error('/ban')
  2185. curs.execute("select id from topic where title = ? and sub = ? order by id + 0 desc limit 1", [name, sub])
  2186. old_num = curs.fetchall()
  2187. if old_num:
  2188. num = int(old_num[0][0]) + 1
  2189. else:
  2190. num = 1
  2191. match = re.search('^user:([^/]+)', name)
  2192. if match:
  2193. curs.execute('insert into alarm (name, data, date) values (?, ?, ?)', [match.groups()[0], ip + ' - <a href="/topic/' + url_pas(name) + '/sub/' + url_pas(sub) + '">' + load_lang('user', 1) + ' ' + load_lang('discussion', 1) + '</a>', today])
  2194. data = re.sub('\[\[((?:분류|category):(?:(?:(?!\]\]).)*))\]\]', '[br]', flask.request.form.get('content', None))
  2195. for rd_data in re.findall("(?:#([0-9]+))", data):
  2196. curs.execute("select ip from topic where title = ? and sub = ? and id = ?", [name, sub, rd_data])
  2197. ip_data = curs.fetchall()
  2198. if ip_data and ip_or_user(ip_data[0][0]) == 0:
  2199. curs.execute('insert into alarm (name, data, date) values (?, ?, ?)', [ip_data[0][0], ip + ' - <a href="/topic/' + url_pas(name) + '/sub/' + url_pas(sub) + '#' + str(num) + '">' + load_lang('discussion', 1) + '</a>', today])
  2200. data = re.sub("(?P<in>#(?:[0-9]+))", '[[\g<in>]]', data)
  2201. data = savemark(data)
  2202. rd_plus(name, sub, today)
  2203. curs.execute("insert into topic (id, title, sub, data, date, ip, block, top) values (?, ?, ?, ?, ?, ?, '', '')", [str(num), name, sub, data, today, ip])
  2204. conn.commit()
  2205. return redirect('/topic/' + url_pas(name) + '/sub/' + url_pas(sub) + '#reload')
  2206. else:
  2207. curs.execute("select title from rd where title = ? and sub = ? and stop = 'O'", [name, sub])
  2208. close_data = curs.fetchall()
  2209. curs.execute("select title from rd where title = ? and sub = ? and stop = 'S'", [name, sub])
  2210. stop_data = curs.fetchall()
  2211. curs.execute("select id from topic where title = ? and sub = ? limit 1", [name, sub])
  2212. topic_exist = curs.fetchall()
  2213. display = ''
  2214. all_data = ''
  2215. data = ''
  2216. number = 1
  2217. if admin == 1 and topic_exist:
  2218. if close_data:
  2219. all_data += '<a href="/topic/' + url_pas(name) + '/sub/' + url_pas(sub) + '/tool/close">(' + load_lang('open') + ')</a> '
  2220. else:
  2221. all_data += '<a href="/topic/' + url_pas(name) + '/sub/' + url_pas(sub) + '/tool/close">(' + load_lang('close') + ')</a> '
  2222. if stop_data:
  2223. all_data += '<a href="/topic/' + url_pas(name) + '/sub/' + url_pas(sub) + '/tool/stop">(' + load_lang('restart') + ')</a> '
  2224. else:
  2225. all_data += '<a href="/topic/' + url_pas(name) + '/sub/' + url_pas(sub) + '/tool/stop">(' + load_lang('stop') + ')</a> '
  2226. curs.execute("select title from rd where title = ? and sub = ? and agree = 'O'", [name, sub])
  2227. if curs.fetchall():
  2228. all_data += '<a href="/topic/' + url_pas(name) + '/sub/' + url_pas(sub) + '/tool/agree">(' + load_lang('release') + ')</a>'
  2229. else:
  2230. all_data += '<a href="/topic/' + url_pas(name) + '/sub/' + url_pas(sub) + '/tool/agree">(' + load_lang('agreement') + ')</a>'
  2231. all_data += '<hr class=\"main_hr\">'
  2232. if (close_data or stop_data) and admin != 1:
  2233. display = 'display: none;'
  2234. curs.execute("select data, id, date, ip, block, top from topic where title = ? and sub = ? order by id + 0 asc", [name, sub])
  2235. topic = curs.fetchall()
  2236. curs.execute("select data, id, date, ip from topic where title = ? and sub = ? and top = 'O' order by id + 0 asc", [name, sub])
  2237. for topic_data in curs.fetchall():
  2238. who_plus = ''
  2239. curs.execute("select who from re_admin where what = ? order by time desc limit 1", ['notice (' + name + ' - ' + sub + '#' + topic_data[1] + ')'])
  2240. topic_data_top = curs.fetchall()
  2241. if topic_data_top:
  2242. who_plus += ' <span style="margin-right: 5px;">@' + topic_data_top[0][0] + ' </span>'
  2243. all_data += '''
  2244. <table id="toron">
  2245. <tbody>
  2246. <tr>
  2247. <td id="toron_color_red">
  2248. <a href="#''' + topic_data[1] + '''">
  2249. #''' + topic_data[1] + '''
  2250. </a> ''' + ip_pas(topic_data[3]) + who_plus + ''' <span style="float: right;">''' + topic_data[2] + '''</span>
  2251. </td>
  2252. </tr>
  2253. <tr>
  2254. <td>''' + render_set(data = topic_data[0]) + '''</td>
  2255. </tr>
  2256. </tbody>
  2257. </table>
  2258. <br>
  2259. '''
  2260. for topic_data in topic:
  2261. user_write = topic_data[0]
  2262. if number == 1:
  2263. start = topic_data[3]
  2264. if topic_data[4] == 'O':
  2265. blind_data = 'id="toron_color_grey"'
  2266. if admin != 1:
  2267. curs.execute("select who from re_admin where what = ? order by time desc limit 1", ['blind (' + name + ' - ' + sub + '#' + str(number) + ')'])
  2268. who_blind = curs.fetchall()
  2269. if who_blind:
  2270. user_write = '[[user:' + who_blind[0][0] + ']] ' + load_lang('hide')
  2271. else:
  2272. user_write = load_lang('hide')
  2273. else:
  2274. blind_data = ''
  2275. user_write = render_set(data = user_write)
  2276. ip = ip_pas(topic_data[3])
  2277. curs.execute('select acl from user where id = ?', [topic_data[3]])
  2278. user_acl = curs.fetchall()
  2279. if user_acl and user_acl[0][0] != 'user':
  2280. ip += ' <a href="javascript:void(0);" title="' + load_lang('admin') + '">★</a>'
  2281. if admin == 1 or blind_data == '':
  2282. ip += ' <a href="/topic/' + url_pas(name) + '/sub/' + url_pas(sub) + '/admin/' + str(number) + '">(' + load_lang('discussion') + ' ' + load_lang('tool') + ')</a>'
  2283. curs.execute("select end from ban where block = ?", [topic_data[3]])
  2284. if curs.fetchall():
  2285. ip += ' <a href="javascript:void(0);" title="' + load_lang('blocked') + '">†</a>'
  2286. if topic_data[5] == '1':
  2287. color = '_blue'
  2288. elif topic_data[3] == start:
  2289. color = '_green'
  2290. else:
  2291. color = ''
  2292. if user_write == '':
  2293. user_write = '<br>'
  2294. all_data += '''
  2295. <table id="toron">
  2296. <tbody>
  2297. <tr>
  2298. <td id="toron_color''' + color + '''">
  2299. <a href="javascript:void(0);" id="''' + str(number) + '">#' + str(number) + '</a> ' + ip + '''</span>
  2300. </td>
  2301. </tr>
  2302. <tr ''' + blind_data + '''>
  2303. <td>''' + user_write + '''</td>
  2304. </tr>
  2305. </tbody>
  2306. </table>
  2307. <br>
  2308. '''
  2309. number += 1
  2310. if ban != 1 or admin == 1:
  2311. data += '''
  2312. <div id="plus"></div>
  2313. <script type="text/javascript" src="/views/main_css/topic_reload.js"></script>
  2314. <script>topic_load("''' + name + '''", "''' + sub + '''");</script>
  2315. <a id="reload" href="javascript:void(0);" onclick="location.href.endsWith(\'#reload\')? location.reload(true):location.href=\'#reload\'">(''' + load_lang('reload') + ''')</a>
  2316. <form style="''' + display + '''" method="post">
  2317. <br>
  2318. <textarea style="height: 100px;" name="content"></textarea>
  2319. <hr class=\"main_hr\">
  2320. ''' + captcha_get()
  2321. if display == '':
  2322. data += ip_warring()
  2323. data += '''
  2324. <button type="submit">''' + load_lang('send') + '''</button>
  2325. </form>
  2326. '''
  2327. return easy_minify(flask.render_template(skin_check(),
  2328. imp = [name, wiki_set(), custom(), other2([' (' + load_lang('discussion') + ')', 0])],
  2329. data = '<h2 id="topic_top_title">' + sub + '</h2>' + all_data + data,
  2330. menu = [['topic/' + url_pas(name), load_lang('list')]]
  2331. ))
  2332. @app.route('/tool/<name>')
  2333. def user_tool(name = None):
  2334. data = '''
  2335. <h2>''' + load_lang('tool') + '''</h2>
  2336. <ul>
  2337. <li><a href="/record/''' + url_pas(name) + '''">''' + load_lang('record') + '''</a></li>
  2338. </ul>
  2339. '''
  2340. if admin_check(1) == 1:
  2341. curs.execute("select block from ban where block = ?", [name])
  2342. if curs.fetchall():
  2343. ban_name = load_lang('release')
  2344. else:
  2345. ban_name = load_lang('ban')
  2346. data += '''
  2347. <h2>''' + load_lang('admin') + '''</h2>
  2348. <ul>
  2349. <li><a href="/ban/''' + url_pas(name) + '''">''' + ban_name + '''</a></li>
  2350. <li><a href="/check/''' + url_pas(name) + '''">''' + load_lang('check') + '''</a></li>
  2351. </ul>
  2352. '''
  2353. return easy_minify(flask.render_template(skin_check(),
  2354. imp = [name, wiki_set(), custom(), other2([' (' + load_lang('tool') + ')', 0])],
  2355. data = data,
  2356. menu = [['topic/' + url_pas(name), load_lang('list')]]
  2357. ))
  2358. @app.route('/topic/<everything:name>', methods=['POST', 'GET'])
  2359. @app.route('/topic/<everything:name>/<regex("close|agree"):tool>', methods=['GET'])
  2360. def close_topic_list(name = None, tool = None):
  2361. div = ''
  2362. if flask.request.method == 'POST':
  2363. t_num = ''
  2364. while 1:
  2365. curs.execute("select title from topic where title = ? and sub = ? limit 1", [name, flask.request.form.get('topic', None) + t_num])
  2366. if curs.fetchall():
  2367. if t_num == '':
  2368. t_num = ' 2'
  2369. else:
  2370. t_num = ' ' + str(int(t_num.replace(' ', '')) + 1)
  2371. else:
  2372. break
  2373. return redirect('/topic/' + url_pas(name) + '/sub/' + url_pas(flask.request.form.get('topic', None) + t_num))
  2374. else:
  2375. plus = ''
  2376. menu = [['topic/' + url_pas(name), load_lang('list')]]
  2377. if tool == 'close':
  2378. curs.execute("select sub from rd where title = ? and stop = 'O' order by sub asc", [name])
  2379. sub = load_lang('close') + ''
  2380. elif tool == 'agree':
  2381. curs.execute("select sub from rd where title = ? and agree = 'O' order by sub asc", [name])
  2382. sub = load_lang('agreement') + ''
  2383. else:
  2384. curs.execute("select sub from rd where title = ? order by date desc", [name])
  2385. sub = load_lang('discussion') + ' ' + load_lang('list')
  2386. menu = [['w/' + url_pas(name), load_lang('document')]]
  2387. plus = '''
  2388. <a href="/topic/''' + url_pas(name) + '''/close">(''' + load_lang('close') + ''')</a> <a href="/topic/''' + url_pas(name) + '''/agree">(''' + load_lang('agreement') + ''')</a>
  2389. <hr class=\"main_hr\">
  2390. <input placeholder="''' + load_lang('discussion') + ' ' + load_lang('name') + '''" name="topic" type="text">
  2391. <hr class=\"main_hr\">
  2392. <button type="submit">''' + load_lang('open') + '''</button>
  2393. '''
  2394. for data in curs.fetchall():
  2395. curs.execute("select data, date, ip, block from topic where title = ? and sub = ? and id = '1'", [name, data[0]])
  2396. if curs.fetchall():
  2397. it_p = 0
  2398. if sub == load_lang('discussion') + ' ' + load_lang('list'):
  2399. curs.execute("select title from rd where title = ? and sub = ? and stop = 'O' order by sub asc", [name, data[0]])
  2400. if curs.fetchall():
  2401. it_p = 1
  2402. if it_p != 1:
  2403. div += '<h2><a href="/topic/' + url_pas(name) + '/sub/' + url_pas(data[0]) + '">' + data[0] + '</a></h2>'
  2404. if div == '':
  2405. plus = re.sub('^<br>', '', plus)
  2406. return easy_minify(flask.render_template(skin_check(),
  2407. imp = [name, wiki_set(), custom(), other2([' (' + sub + ')', 0])],
  2408. data = '<form method="post">' + div + plus + '</form>',
  2409. menu = menu
  2410. ))
  2411. @app.route('/login', methods=['POST', 'GET'])
  2412. def login():
  2413. if custom()[2] != 0:
  2414. return redirect('/user')
  2415. if ban_check(tool = 'login') == 1:
  2416. return re_error('/ban')
  2417. if flask.request.method == 'POST':
  2418. if captcha_post(flask.request.form.get('g-recaptcha-response', '')) == 1:
  2419. return re_error('/error/13')
  2420. else:
  2421. captcha_post('', 0)
  2422. ip = ip_check()
  2423. agent = flask.request.headers.get('User-Agent')
  2424. curs.execute("select pw, encode from user where id = ?", [flask.request.form.get('id', None)])
  2425. user = curs.fetchall()
  2426. if not user:
  2427. return re_error('/error/2')
  2428. pw_check_d = pw_check(
  2429. flask.request.form.get('pw', ''),
  2430. user[0][0],
  2431. user[0][1],
  2432. flask.request.form.get('id', None)
  2433. )
  2434. if pw_check_d != 1:
  2435. return re_error('/error/10')
  2436. flask.session['state'] = 1
  2437. flask.session['id'] = flask.request.form.get('id', None)
  2438. curs.execute("select css from custom where user = ?", [flask.request.form.get('id', None)])
  2439. css_data = curs.fetchall()
  2440. if css_data:
  2441. flask.session['head'] = css_data[0][0]
  2442. else:
  2443. flask.session['head'] = ''
  2444. curs.execute("insert into ua_d (name, ip, ua, today, sub) values (?, ?, ?, ?, '')", [flask.request.form.get('id', None), ip_check(1), agent, get_time()])
  2445. conn.commit()
  2446. return redirect('/user')
  2447. else:
  2448. oauth_content = '<link rel="stylesheet" href="/views/main_css/oauth.css"><div class="oauth-wrapper"><ul class="oauth-list">'
  2449. oauth_supported = load_oauth('_README')['support']
  2450. for i in range(len(oauth_supported)):
  2451. oauth_data = load_oauth(oauth_supported[i])
  2452. if oauth_data['client_id'] != '' and oauth_data['client_secret'] != '':
  2453. oauth_content += '''
  2454. <li>
  2455. <a href="/oauth/{}/init">
  2456. <div class="oauth-btn oauth-btn-{}">
  2457. <div class="oauth-btn-logo oauth-btn-{}"></div>
  2458. {}
  2459. </div>
  2460. </a>
  2461. </li>
  2462. '''.format(
  2463. oauth_supported[i],
  2464. oauth_supported[i],
  2465. oauth_supported[i],
  2466. load_lang('oauth_signin_' + oauth_supported[i])
  2467. )
  2468. oauth_content += '</ul></div>'
  2469. return easy_minify(flask.render_template(skin_check(),
  2470. imp = [load_lang('login'), wiki_set(), custom(), other2([0, 0])],
  2471. data = '''
  2472. <form method="post">
  2473. <input placeholder="''' + load_lang('id') + '''" name="id" type="text">
  2474. <hr class=\"main_hr\">
  2475. <input placeholder="''' + load_lang('password') + '''" name="pw" type="password">
  2476. <hr class=\"main_hr\">
  2477. ''' + captcha_get() + '''
  2478. <button type="submit">''' + load_lang('login') + '''</button><a href="/register">''' + load_lang('register_suggest') + '''</a>
  2479. <hr class=\"main_hr\">
  2480. ''' + oauth_content + '''
  2481. <hr class=\"main_hr\">
  2482. <span>''' + load_lang('http_warring') + '''</span>
  2483. </form>
  2484. ''',
  2485. menu = [['user', load_lang('user')]]
  2486. ))
  2487. @app.route('/oauth/<regex("naver|facebook"):platform>/<regex("init|callback"):func>', methods=['GET', 'POST'])
  2488. def login_oauth(platform = None, func = None):
  2489. publish_url = load_oauth('publish_url')
  2490. oauth_data = load_oauth(platform)
  2491. api_url = {}
  2492. data = {
  2493. 'client_id' : oauth_data['client_id'],
  2494. 'client_secret' : oauth_data['client_secret'],
  2495. 'redirect_uri' : publish_url + '/oauth/' + platform + '/callback',
  2496. 'state' : 'RAMDOMVALUE'
  2497. }
  2498. if platform == 'naver':
  2499. api_url['redirect'] = 'https://nid.naver.com/oauth2.0/authorize'
  2500. api_url['token'] = 'https://nid.naver.com/oauth2.0/token'
  2501. api_url['profile'] = 'https://openapi.naver.com/v1/nid/me'
  2502. elif platform == 'facebook':
  2503. api_url['redirect'] = 'https://www.facebook.com/v3.1/dialog/oauth'
  2504. api_url['token'] = 'https://graph.facebook.com/v3.1/oauth/access_token'
  2505. api_url['profile'] = 'https://graph.facebook.com/me'
  2506. if func == 'init':
  2507. if oauth_data['client_id'] == '' or oauth_data['client_secret'] == '':
  2508. return easy_minify(flask.render_template(skin_check(),
  2509. imp = [load_lang('login'), wiki_set(), custom(), other2([0, 0])],
  2510. data = load_lang('oauth_disabled'),
  2511. menu = [['user', load_lang('user')]]
  2512. ))
  2513. elif publish_url == 'https://':
  2514. return easy_minify(flask.render_template(skin_check(),
  2515. imp = [load_lang('login'), wiki_set(), custom(), other2([0, 0])],
  2516. data = load_lang('oauth_settings_not_found'),
  2517. menu = [['user', load_lang('user')]]
  2518. ))
  2519. referrer_re = re.compile(r'(?P<host>^(https?):\/\/([^\/]+))\/(?P<refer>[^\/?]+)')
  2520. if flask.request.referrer != None:
  2521. referrer = referrer_re.search(flask.request.referrer)
  2522. if referrer.group('host') != load_oauth('publish_url'):
  2523. return redirect('/')
  2524. else:
  2525. flask.session['referrer'] = referrer.group('refer')
  2526. else:
  2527. return redirect('/')
  2528. flask.session['refer'] = flask.request.referrer
  2529. if platform == 'naver':
  2530. return redirect(api_url['redirect'] + '?response_type=code&client_id={}&redirect_uri={}&state={}'.format(data['client_id'], data['redirect_uri'], data['state']))
  2531. elif platform == 'facebook':
  2532. return redirect(api_url['redirect'] + '?client_id={}&redirect_uri={}&state={}'.format(data['client_id'], data['redirect_uri'], data['state']))
  2533. elif func == 'callback':
  2534. code = flask.request.args.get('code')
  2535. state = flask.request.args.get('state')
  2536. if code == None or state == None:
  2537. return easy_minify(flask.render_template(skin_check(),
  2538. imp = [load_lang('inter_error'), wiki_set(), custom(), other2([0, 0])],
  2539. data = '''
  2540. <p>''' + load_lang('inter_error_detail') + '''</p>
  2541. <hr>
  2542. <code>ie_wrong_callback</code>
  2543. <p>''' + load_lang('ie_wrong_callback') + '''</p>
  2544. ''',
  2545. menu = [['user', load_lang('user')]]
  2546. ))
  2547. if platform == 'naver':
  2548. token_access = api_url['token']+'?grant_type=authorization_code&client_id={}&client_secret={}&code={}&state={}'.format(data['client_id'], data['client_secret'], code, state)
  2549. token_result = urllib.request.urlopen(token_access).read().decode('utf-8')
  2550. token_result_json = json.loads(token_result)
  2551. headers = {'Authorization': 'Bearer {}'.format(token_result_json['access_token'])}
  2552. profile_access = urllib.request.Request(api_url['profile'], headers = headers)
  2553. profile_result = urllib.request.urlopen(profile_access).read().decode('utf-8')
  2554. profile_result_json = json.loads(profile_result)
  2555. stand_json = {'id' : profile_result_json['response']['id'], 'name' : profile_result_json['response']['name'], 'picture' : profile_result_json['response']['profile_image']}
  2556. elif platform == 'facebook':
  2557. token_access = api_url['token']+'?client_id={}&redirect_uri={}&client_secret={}&code={}'.format(data['client_id'], data['redirect_uri'], data['client_secret'], code)
  2558. token_result = urllib.request.urlopen(token_access).read().decode('utf-8')
  2559. token_result_json = json.loads(token_result)
  2560. profile_access = api_url['profile']+'?fields=id,name,picture&access_token={}'.format(token_result_json['access_token'])
  2561. profile_result = urllib.request.urlopen(profile_access).read().decode('utf-8')
  2562. profile_result_json = json.loads(profile_result)
  2563. stand_json = {'id': profile_result_json['id'], 'name': profile_result_json['name'], 'picture': profile_result_json['picture']['data']['url']}
  2564. if flask.session['referrer'][0:6] == 'change':
  2565. curs.execute('select * from oauth_conn where wiki_id = ? and provider = ?', [flask.session['id'], platform])
  2566. oauth_result = curs.fetchall()
  2567. if len(oauth_result) == 0:
  2568. curs.execute('insert into oauth_conn (provider, wiki_id, sns_id, name, picture) values(?, ?, ?, ?, ?)', [platform, flask.session['id'], stand_json['id'], stand_json['name'], stand_json['picture']])
  2569. else:
  2570. curs.execute('update oauth_conn set name = ? picture = ? where wiki_id = ?', [stand_json['name'], stand_json['pricture'], flask.session['id']])
  2571. conn.commit()
  2572. elif flask.session['referrer'][0:5] == 'login':
  2573. curs.execute('select * from oauth_conn where provider = ? and sns_id = ?', [platform, stand_json['id']])
  2574. curs_result = curs.fetchall()
  2575. if len(curs_result) == 0:
  2576. return re_error('/error/2')
  2577. else:
  2578. flask.session['state'] = 1
  2579. flask.session['id'] = curs_result[0][2]
  2580. return redirect(flask.session['refer'])
  2581. @app.route('/change', methods=['POST', 'GET'])
  2582. def change_password():
  2583. global support_language
  2584. if ban_check() == 1:
  2585. return re_error('/ban')
  2586. if custom()[2] == 0:
  2587. return redirect('/login')
  2588. ip = ip_check()
  2589. user_state = flask.request.args.get('user', 'ip')
  2590. if user_state == 'ip':
  2591. if flask.request.method == 'POST':
  2592. if flask.request.form.get('pw4', None) and flask.request.form.get('pw2', None):
  2593. if flask.request.form.get('pw2', None) != flask.request.form.get('pw3', None):
  2594. return re_error('/error/20')
  2595. curs.execute("select pw, encode from user where id = ?", [flask.session['id']])
  2596. user = curs.fetchall()
  2597. if not user:
  2598. return re_error('/error/2')
  2599. pw_check_d = pw_check(
  2600. flask.request.form.get('pw4', ''),
  2601. user[0][0],
  2602. user[0][1],
  2603. flask.request.form.get('id', None)
  2604. )
  2605. if pw_check_d != 1:
  2606. return re_error('/error/10')
  2607. hashed = pw_encode(flask.request.form.get('pw2', None))
  2608. curs.execute("update user set pw = ? where id = ?", [hashed, flask.session['id']])
  2609. auto_list = ['email', 'skin', 'lang']
  2610. for auto_data in auto_list:
  2611. curs.execute('select data from user_set where name = ? and id = ?', [auto_data, ip])
  2612. if curs.fetchall():
  2613. curs.execute("update user_set set data = ? where name = ? and id = ?", [flask.request.form.get(auto_data, ''), auto_data, ip])
  2614. else:
  2615. curs.execute("insert into user_set (name, id, data) values (?, ?, ?)", [auto_data, ip, flask.request.form.get(auto_data, '')])
  2616. conn.commit()
  2617. return redirect('/change')
  2618. else:
  2619. curs.execute('select data from user_set where name = "email" and id = ?', [ip])
  2620. data = curs.fetchall()
  2621. if data:
  2622. email = data[0][0]
  2623. else:
  2624. email = ''
  2625. div2 = load_skin()
  2626. div3 = ''
  2627. var_div3 = ''
  2628. curs.execute('select data from user_set where name = "lang" and id = ?', [flask.session['id']])
  2629. data = curs.fetchall()
  2630. for lang_data in support_language:
  2631. if data and data[0][0] == lang_data:
  2632. div3 = '<option value="' + lang_data + '">' + lang_data + '</option>'
  2633. else:
  2634. var_div3 += '<option value="' + lang_data + '">' + lang_data + '</option>'
  2635. div3 += var_div3
  2636. oauth_provider = load_oauth('_README')['support']
  2637. oauth_content = '<ul>'
  2638. for i in range(len(oauth_provider)):
  2639. curs.execute('select name, picture from oauth_conn where wiki_id = ? and provider = ?', [flask.session['id'], oauth_provider[i]])
  2640. oauth_data = curs.fetchall()
  2641. if len(oauth_data) == 1:
  2642. oauth_content += '<li>{} - {}</li>'.format(oauth_provider[i], load_lang('connection') + load_lang('oauth_conn_done') + ': <img src="{}" width="17px" height="17px">{}'.format(oauth_data[0][1], oauth_data[0][0]))
  2643. else:
  2644. oauth_content += '<li>{} - {}</li>'.format(oauth_provider[i], load_lang('connection') + load_lang('oauth_conn_not') + '. <a href="/oauth/{}/init">{}</a>'.format(oauth_provider[i], load_lang('oauth_conn_new')))
  2645. oauth_content += '</ul>'
  2646. return easy_minify(flask.render_template(skin_check(),
  2647. imp = [load_lang('user') + ' ' + load_lang('setting') + ' ' + load_lang('edit'), wiki_set(), custom(), other2([0, 0])],
  2648. data = '''
  2649. <form method="post">
  2650. <span>id : ''' + ip + '''</span>
  2651. <hr class=\"main_hr\">
  2652. <input placeholder="''' + load_lang('now') + ' ' + load_lang('password') + '''" name="pw4" type="password">
  2653. <br>
  2654. <br>
  2655. <input placeholder="''' + load_lang('new') + ' ' + load_lang('password') + '''" name="pw2" type="password">
  2656. <br>
  2657. <br>
  2658. <input placeholder="''' + load_lang('password') + ' ' + load_lang('confirm') + '''" name="pw3" type="password">
  2659. <hr class=\"main_hr\">
  2660. <span>''' + load_lang('user') + ' ' + load_lang('skin') + '''</span>
  2661. <br>
  2662. <br>
  2663. <select name="skin">''' + div2 + '''</select>
  2664. <hr class=\"main_hr\">
  2665. <span>''' + load_lang('user') + ' ' + load_lang('language') + '''</span>
  2666. <br>
  2667. <br>
  2668. <select name="lang">''' + div3 + '''</select>
  2669. <hr class=\"main_hr\">
  2670. <span>OAuth ''' + load_lang('connection') + '''</span>
  2671. ''' + oauth_content + '''
  2672. <hr class=\"main_hr\">
  2673. <button type="submit">''' + load_lang('edit') + '''</button>
  2674. <hr class=\"main_hr\">
  2675. <span>''' + load_lang('http_warring') + '''</span>
  2676. </form>
  2677. ''',
  2678. menu = [['user', load_lang('user')]]
  2679. ))
  2680. else:
  2681. pass
  2682. @app.route('/check/<name>')
  2683. def user_check(name = None):
  2684. curs.execute("select acl from user where id = ? or id = ?", [name, flask.request.args.get('plus', '-')])
  2685. user = curs.fetchall()
  2686. if user and user[0][0] != 'user':
  2687. if admin_check() != 1:
  2688. return re_error('/error/4')
  2689. if admin_check(4, 'check (' + name + ')') != 1:
  2690. return re_error('/error/3')
  2691. num = int(flask.request.args.get('num', 1))
  2692. if num * 50 > 0:
  2693. sql_num = num * 50 - 50
  2694. else:
  2695. sql_num = 0
  2696. if flask.request.args.get('plus', None):
  2697. end_check = 1
  2698. if ip_or_user(name) == 1:
  2699. if ip_or_user(flask.request.args.get('plus', None)) == 1:
  2700. curs.execute("select name, ip, ua, today from ua_d where ip = ? or ip = ? order by today desc limit ?, '50'", [name, flask.request.args.get('plus', None), sql_num])
  2701. else:
  2702. curs.execute("select name, ip, ua, today from ua_d where ip = ? or name = ? order by today desc limit ?, '50'", [name, flask.request.args.get('plus', None), sql_num])
  2703. else:
  2704. if ip_or_user(flask.request.args.get('plus', None)) == 1:
  2705. curs.execute("select name, ip, ua, today from ua_d where name = ? or ip = ? order by today desc limit ?, '50'", [name, flask.request.args.get('plus', None), sql_num])
  2706. else:
  2707. curs.execute("select name, ip, ua, today from ua_d where name = ? or name = ? order by today desc limit ?, '50'", [name, flask.request.args.get('plus', None), sql_num])
  2708. else:
  2709. end_check = 0
  2710. if ip_or_user(name) == 1:
  2711. curs.execute("select name, ip, ua, today from ua_d where ip = ? order by today desc limit ?, '50'", [name, sql_num])
  2712. else:
  2713. curs.execute("select name, ip, ua, today from ua_d where name = ? order by today desc limit ?, '50'", [name, sql_num])
  2714. record = curs.fetchall()
  2715. if record:
  2716. if not flask.request.args.get('plus', None):
  2717. div = '<a href="/manager/14?plus=' + url_pas(name) + '">(' + load_lang('compare') + ')</a><hr class=\"main_hr\">'
  2718. else:
  2719. div = '<a href="/check/' + url_pas(name) + '">(' + name + ')</a> <a href="/check/' + url_pas(flask.request.args.get('plus', None)) + '">(' + flask.request.args.get('plus', None) + ')</a><hr class=\"main_hr\">'
  2720. div += '''
  2721. <table id="main_table_set">
  2722. <tbody>
  2723. <tr>
  2724. <td id="main_table_width">''' + load_lang('name') + '''</td>
  2725. <td id="main_table_width">ip</td>
  2726. <td id="main_table_width">''' + load_lang('time') + '''</td>
  2727. </tr>
  2728. '''
  2729. for data in record:
  2730. if data[2]:
  2731. ua = data[2]
  2732. else:
  2733. ua = '<br>'
  2734. div += '''
  2735. <tr>
  2736. <td>''' + ip_pas(data[0]) + '''</td>
  2737. <td>''' + ip_pas(data[1]) + '''</td>
  2738. <td>''' + data[3] + '''</td>
  2739. </tr>
  2740. <tr>
  2741. <td colspan="3">''' + ua + '''</td>
  2742. </tr>
  2743. '''
  2744. div += '''
  2745. </tbody>
  2746. </table>
  2747. '''
  2748. else:
  2749. return re_error('/error/2')
  2750. if end_check == 1:
  2751. div += next_fix('/check/' + url_pas(name) + '?plus=' + flask.request.args.get('plus', None) + '&num=', num, record)
  2752. else:
  2753. div += next_fix('/check/' + url_pas(name) + '?num=', num, record)
  2754. return easy_minify(flask.render_template(skin_check(),
  2755. imp = [load_lang('check'), wiki_set(), custom(), other2([0, 0])],
  2756. data = div,
  2757. menu = [['manager', load_lang('admin')]]
  2758. ))
  2759. @app.route('/register', methods=['POST', 'GET'])
  2760. def register():
  2761. if ban_check() == 1:
  2762. return re_error('/ban')
  2763. if custom()[2] != 0:
  2764. return redirect('/user')
  2765. if not admin_check() == 1:
  2766. curs.execute('select data from other where name = "reg"')
  2767. set_d = curs.fetchall()
  2768. if set_d and set_d[0][0] == 'on':
  2769. return re_error('/ban')
  2770. if flask.request.method == 'POST':
  2771. if captcha_post(flask.request.form.get('g-recaptcha-response', '')) == 1:
  2772. return re_error('/error/13')
  2773. else:
  2774. captcha_post('', 0)
  2775. if flask.request.form.get('pw', None) != flask.request.form.get('pw2', None):
  2776. return re_error('/error/20')
  2777. if re.search('(?:[^A-Za-zㄱ-힣0-9 ])', flask.request.form.get('id', None)):
  2778. return re_error('/error/8')
  2779. curs.execute('select html from html_filter where kind = "name"')
  2780. set_d = curs.fetchall()
  2781. for i in set_d:
  2782. check_r = re.compile(i[0], re.I)
  2783. if check_r.search(flask.request.form.get('id', None)):
  2784. return re_error('/error/8')
  2785. if len(flask.request.form.get('id', None)) > 32:
  2786. return re_error('/error/7')
  2787. curs.execute("select id from user where id = ?", [flask.request.form.get('id', None)])
  2788. if curs.fetchall():
  2789. return re_error('/error/6')
  2790. hashed = pw_encode(flask.request.form.get('pw', None))
  2791. curs.execute('select data from other where name = "email_have"')
  2792. sql_data = curs.fetchall()
  2793. if sql_data and sql_data[0][0] != '':
  2794. flask.session['c_id'] = flask.request.form.get('id', None)
  2795. flask.session['c_pw'] = hashed
  2796. flask.session['c_key'] = ''.join(random.choice("0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ") for i in range(16))
  2797. return redirect('/need_email')
  2798. else:
  2799. curs.execute('select data from other where name = "encode"')
  2800. db_data = curs.fetchall()
  2801. curs.execute("select id from user limit 1")
  2802. if not curs.fetchall():
  2803. curs.execute("insert into user (id, pw, acl, date, encode) values (?, ?, 'owner', ?, ?)", [flask.request.form.get('id', None), hashed, get_time(), db_data[0][0]])
  2804. first = 1
  2805. else:
  2806. curs.execute("insert into user (id, pw, acl, date, encode) values (?, ?, 'user', ?, ?)", [flask.request.form.get('id', None), hashed, get_time(), db_data[0][0]])
  2807. first = 0
  2808. ip = ip_check()
  2809. agent = flask.request.headers.get('User-Agent')
  2810. curs.execute("insert into ua_d (name, ip, ua, today, sub) values (?, ?, ?, ?, '')", [flask.request.form.get('id', None), ip, agent, get_time()])
  2811. flask.session['state'] = 1
  2812. flask.session['id'] = flask.request.form.get('id', None)
  2813. flask.session['head'] = ''
  2814. conn.commit()
  2815. if first == 0:
  2816. return redirect('/change')
  2817. else:
  2818. return redirect('/setting')
  2819. else:
  2820. contract = ''
  2821. curs.execute('select data from other where name = "contract"')
  2822. data = curs.fetchall()
  2823. if data and data[0][0] != '':
  2824. contract = data[0][0] + '<hr class=\"main_hr\">'
  2825. return easy_minify(flask.render_template(skin_check(),
  2826. imp = [load_lang('register'), wiki_set(), custom(), other2([0, 0])],
  2827. data = '''
  2828. <form method="post">
  2829. ''' + contract + '''
  2830. <input placeholder="''' + load_lang('id') + '''" name="id" type="text">
  2831. <hr class=\"main_hr\">
  2832. <input placeholder="''' + load_lang('password') + '''" name="pw" type="password">
  2833. <hr class=\"main_hr\">
  2834. <input placeholder="''' + load_lang('confirm') + '''" name="pw2" type="password">
  2835. <hr class=\"main_hr\">
  2836. ''' + captcha_get() + '''
  2837. <button type="submit">''' + load_lang('register') + '''</button>
  2838. <hr class=\"main_hr\">
  2839. <span>''' + load_lang('http_warring') + '''</span>
  2840. </form>
  2841. ''',
  2842. menu = [['user', load_lang('user')]]
  2843. ))
  2844. @app.route('/<regex("need_email|pass_find"):tool>', methods=['POST', 'GET'])
  2845. def need_email(tool = 'pass_find'):
  2846. if flask.request.method == 'POST':
  2847. if tool == 'need_email':
  2848. if 'c_id' in flask.session:
  2849. main_email = ['naver.com', 'gmail.com', 'daum.net', 'hanmail.net', 'hanmail2.net']
  2850. data = re.search('@([^@]+)$', flask.request.form.get('email', ''))
  2851. if data:
  2852. data = data.groups()[0]
  2853. curs.execute("select html from html_filter where html = ? and kind = 'email'", [data])
  2854. if curs.fetchall() or (data in main_email):
  2855. curs.execute('select id from user_set where name = "email" and data = ?', [flask.request.form.get('email', '')])
  2856. if curs.fetchall():
  2857. flask.session.pop('c_id', None)
  2858. flask.session.pop('c_pw', None)
  2859. flask.session.pop('c_key', None)
  2860. return redirect('/register')
  2861. else:
  2862. send_email(flask.request.form.get('email', ''), wiki_set()[0] + ' key', 'key : ' + flask.session['c_key'])
  2863. flask.session['c_email'] = flask.request.form.get('email', '')
  2864. return redirect('/check_key')
  2865. return redirect('/register')
  2866. else:
  2867. curs.execute("select id from user where id = ? and email = ?", [flask.request.form.get('id', ''), flask.request.form.get('email', '')])
  2868. if curs.fetchall():
  2869. flask.session['c_key'] = ''.join(random.choice("0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ") for i in range(16))
  2870. flask.session['c_id'] = flask.request.form.get('id', '')
  2871. send_email(flask.request.form.get('email', ''), wiki_set()[0] + ' ' + load_lang('password') + ' ' + load_lang('search') + ' key', 'key : ' + flask.session['c_key'])
  2872. return redirect('/check_pass_key')
  2873. else:
  2874. if tool == 'need_email':
  2875. return easy_minify(flask.render_template(skin_check(),
  2876. imp = ['email', wiki_set(), custom(), other2([0, 0])],
  2877. data = '''
  2878. <a href="/email_filter">(email ''' + load_lang('list') + ''')</a>
  2879. <hr class=\"main_hr\">
  2880. <form method="post">
  2881. <input placeholder="email" name="email" type="text">
  2882. <hr class=\"main_hr\">
  2883. <button type="submit">''' + load_lang('save') + '''</button>
  2884. </form>
  2885. ''',
  2886. menu = [['user', load_lang('user')]]
  2887. ))
  2888. else:
  2889. return easy_minify(flask.render_template(skin_check(),
  2890. imp = [load_lang('password') + ' ' + load_lang('search'), wiki_set(), custom(), other2([0, 0])],
  2891. data = '''
  2892. <form method="post">
  2893. <input placeholder="''' + load_lang('id') + '''" name="id" type="text">
  2894. <hr class=\"main_hr\">
  2895. <input placeholder="email" name="email" type="text">
  2896. <hr class=\"main_hr\">
  2897. <button type="submit">''' + load_lang('save') + '''</button>
  2898. </form>
  2899. ''',
  2900. menu = [['user', load_lang('user')]]
  2901. ))
  2902. @app.route('/<regex("check_key|check_pass_key"):tool>', methods=['POST', 'GET'])
  2903. def check_key(tool = 'check_pass_key'):
  2904. if flask.request.method == 'POST':
  2905. if tool == 'check_key':
  2906. if 'c_id' in flask.session and flask.session['c_key'] == flask.request.form.get('key', None):
  2907. curs.execute('select data from other where name = "encode"')
  2908. db_data = curs.fetchall()
  2909. curs.execute("select id from user limit 1")
  2910. if not curs.fetchall():
  2911. curs.execute("insert into user (id, pw, acl, date, encode) values (?, ?, 'owner', ?)", [flask.session['c_id'], flask.session['c_pw'], get_time(), db_data[0][0]])
  2912. first = 1
  2913. else:
  2914. curs.execute("insert into user (id, pw, acl, date, encode) values (?, ?, 'user', ?)", [flask.session['c_id'], flask.session['c_pw'], get_time(), db_data[0][0]])
  2915. first = 0
  2916. ip = ip_check()
  2917. agent = flask.request.headers.get('User-Agent')
  2918. curs.execute("insert into user_set (name, id, data) values ('email', ?, ?)", [flask.session['c_id'], flask.session['c_email']])
  2919. curs.execute("insert into ua_d (name, ip, ua, today, sub) values (?, ?, ?, ?, '')", [flask.session['c_id'], ip, agent, get_time()])
  2920. flask.session['state'] = 1
  2921. flask.session['id'] = flask.session['c_id']
  2922. flask.session['head'] = ''
  2923. conn.commit()
  2924. flask.session.pop('c_id', None)
  2925. flask.session.pop('c_pw', None)
  2926. flask.session.pop('c_key', None)
  2927. flask.session.pop('c_email', None)
  2928. if first == 0:
  2929. return redirect('/change')
  2930. else:
  2931. return redirect('/setting')
  2932. else:
  2933. flask.session.pop('c_id', None)
  2934. flask.session.pop('c_pw', None)
  2935. flask.session.pop('c_key', None)
  2936. flask.session.pop('c_email', None)
  2937. return redirect('/register')
  2938. else:
  2939. if 'c_id' in flask.session and flask.session['c_key'] == flask.request.form.get('key', None):
  2940. hashed = pw_encode(flask.session['c_key'])
  2941. curs.execute("update user set pw = ? where id = ?", [hashed, flask.session['c_id']])
  2942. d_id = flask.session['c_id']
  2943. pw = flask.session['c_key']
  2944. flask.session.pop('c_id', None)
  2945. flask.session.pop('c_key', None)
  2946. return easy_minify(flask.render_template(skin_check(),
  2947. imp = ['check', wiki_set(), custom(), other2([0, 0])],
  2948. data = '''
  2949. ''' + load_lang('id') + ' : ' + d_id + '''
  2950. <br>
  2951. ''' + load_lang('password') + ' : ' + pw + '''
  2952. ''',
  2953. menu = [['user', load_lang('user')]]
  2954. ))
  2955. else:
  2956. return redirect('/pass_find')
  2957. else:
  2958. return easy_minify(flask.render_template(skin_check(),
  2959. imp = ['check', wiki_set(), custom(), other2([0, 0])],
  2960. data = '''
  2961. <form method="post">
  2962. <input placeholder="key" name="key" type="text">
  2963. <hr class=\"main_hr\">
  2964. <button type="submit">''' + load_lang('save') + '''</button>
  2965. </form>
  2966. ''',
  2967. menu = [['user', load_lang('user')]]
  2968. ))
  2969. @app.route('/logout')
  2970. def logout():
  2971. flask.session['state'] = 0
  2972. flask.session.pop('id', None)
  2973. return redirect('/user')
  2974. @app.route('/ban/<name>', methods=['POST', 'GET'])
  2975. def user_ban(name = None):
  2976. if ip_or_user(name) == 0:
  2977. curs.execute("select acl from user where id = ?", [name])
  2978. user = curs.fetchall()
  2979. if not user:
  2980. return re_error('/error/2')
  2981. if user and user[0][0] != 'user':
  2982. if admin_check() != 1:
  2983. return re_error('/error/4')
  2984. if ban_check(ip = ip_check(), tool = 'login') == 1:
  2985. return re_error('/ban')
  2986. if flask.request.method == 'POST':
  2987. if admin_check(1, 'ban (' + name + ')') != 1:
  2988. return re_error('/error/3')
  2989. if flask.request.form.get('limitless', '') == '':
  2990. end = flask.request.form.get('second', '0')
  2991. else:
  2992. end = '0'
  2993. ban_insert(name, end, flask.request.form.get('why', ''), flask.request.form.get('login', ''), ip_check())
  2994. return redirect('/ban/' + url_pas(name))
  2995. else:
  2996. if admin_check(1) != 1:
  2997. return re_error('/error/3')
  2998. curs.execute("select end, why from ban where block = ?", [name])
  2999. end = curs.fetchall()
  3000. if end:
  3001. now = load_lang('release')
  3002. if end[0][0] == '':
  3003. data = '<ul><li>' + load_lang('limitless') + ' ' + load_lang('ban') + '</li>'
  3004. else:
  3005. data = '<ul><li>' + load_lang('ban') + ' : ' + end[0][0] + '</li>'
  3006. curs.execute("select block from ban where block = ? and login = 'O'", [name])
  3007. if curs.fetchall():
  3008. data += '<li>' + load_lang('login') + ' ' + load_lang('able') + '</li>'
  3009. if end[0][1] != '':
  3010. data += '<li>' + load_lang('why') + ' : ' + end[0][1] + '</li></ul><hr class=\"main_hr\">'
  3011. else:
  3012. data += '</ul><hr class=\"main_hr\">'
  3013. else:
  3014. if re.search("^([0-9]{1,3}\.[0-9]{1,3})$", name):
  3015. now = load_lang('band') + ' ' + load_lang('ban')
  3016. else:
  3017. now = load_lang('ban')
  3018. if ip_or_user(name) == 1:
  3019. plus = '<input type="checkbox" name="login"> ' + load_lang('login') + ' ' + load_lang('able') + '<hr class=\"main_hr\">'
  3020. else:
  3021. plus = ''
  3022. data = '''
  3023. <input placeholder="''' + load_lang('second') + '''" name="second" type="text">
  3024. <hr class=\"main_hr\">
  3025. <input type="checkbox" name="limitless"> ''' + load_lang('limitless') + '''
  3026. <hr class=\"main_hr\">
  3027. <input placeholder="''' + load_lang('why') + '''" name="why" type="text">
  3028. <hr class=\"main_hr\">
  3029. ''' + plus
  3030. return easy_minify(flask.render_template(skin_check(),
  3031. imp = [name, wiki_set(), custom(), other2([' (' + now + ')', 0])],
  3032. data = '''
  3033. <form method="post">
  3034. ''' + data + '''
  3035. <button type="submit">''' + now + '''</button>
  3036. </form>
  3037. ''',
  3038. menu = [['manager', load_lang('admin')]]
  3039. ))
  3040. @app.route('/acl/<everything:name>', methods=['POST', 'GET'])
  3041. def acl(name = None):
  3042. check_ok = ''
  3043. if flask.request.method == 'POST':
  3044. check_data = 'acl (' + name + ')'
  3045. else:
  3046. check_data = None
  3047. user_data = re.search('^user:(.+)$', name)
  3048. if user_data:
  3049. if check_data and custom()[2] == 0:
  3050. return redirect('/login')
  3051. if user_data.groups()[0] != ip_check():
  3052. if admin_check(5, check_data) != 1:
  3053. if check_data:
  3054. return re_error('/error/3')
  3055. else:
  3056. check_ok = 'disabled'
  3057. else:
  3058. if admin_check(5, check_data) != 1:
  3059. if check_data:
  3060. return re_error('/error/3')
  3061. else:
  3062. check_ok = 'disabled'
  3063. if flask.request.method == 'POST':
  3064. curs.execute("select title from acl where title = ?", [name])
  3065. if curs.fetchall():
  3066. curs.execute("update acl set dec = ? where title = ?", [flask.request.form.get('dec', ''), name])
  3067. curs.execute("update acl set dis = ? where title = ?", [flask.request.form.get('dis', ''), name])
  3068. curs.execute("update acl set why = ? where title = ?", [flask.request.form.get('why', ''), name])
  3069. curs.execute("update acl set view = ? where title = ?", [flask.request.form.get('view', ''), name])
  3070. else:
  3071. curs.execute("insert into acl (title, dec, dis, why, view) values (?, ?, ?, ?, ?)", [name, flask.request.form.get('dec', ''), flask.request.form.get('dis', ''), flask.request.form.get('why', ''), flask.request.form.get('view', '')])
  3072. curs.execute("select title from acl where title = ? and dec = '' and dis = ''", [name])
  3073. if curs.fetchall():
  3074. curs.execute("delete from acl where title = ?", [name])
  3075. conn.commit()
  3076. return redirect('/acl/' + url_pas(name))
  3077. else:
  3078. data = '' + load_lang('document') + ' acl<br><br><select name="dec" ' + check_ok + '>'
  3079. if re.search('^user:', name):
  3080. acl_list = [['', load_lang('normal')], ['user', load_lang('subscriber')], ['all', load_lang('all')]]
  3081. else:
  3082. acl_list = [['', load_lang('normal')], ['user', load_lang('subscriber')], ['admin', load_lang('admin')]]
  3083. curs.execute("select dec from acl where title = ?", [name])
  3084. acl_data = curs.fetchall()
  3085. for data_list in acl_list:
  3086. if acl_data and acl_data[0][0] == data_list[0]:
  3087. check = 'selected="selected"'
  3088. else:
  3089. check = ''
  3090. data += '<option value="' + data_list[0] + '" ' + check + '>' + data_list[1] + '</option>'
  3091. data += '</select>'
  3092. if not re.search('^user:', name):
  3093. data += '<hr class=\"main_hr\">' + load_lang('discussion') + ' acl<br><br><select name="dis" ' + check_ok + '>'
  3094. curs.execute("select dis, why, view from acl where title = ?", [name])
  3095. acl_data = curs.fetchall()
  3096. for data_list in acl_list:
  3097. if acl_data and acl_data[0][0] == data_list[0]:
  3098. check = 'selected="selected"'
  3099. else:
  3100. check = ''
  3101. data += '<option value="' + data_list[0] + '" ' + check + '>' + data_list[1] + '</option>'
  3102. data += '</select>'
  3103. data += '<hr class=\"main_hr\">' + load_lang('view') + ' acl<br><br><select name="view" ' + check_ok + '>'
  3104. for data_list in acl_list:
  3105. if acl_data and acl_data[0][2] == data_list[0]:
  3106. check = 'selected="selected"'
  3107. else:
  3108. check = ''
  3109. data += '<option value="' + data_list[0] + '" ' + check + '>' + data_list[1] + '</option>'
  3110. data += '</select>'
  3111. if check_ok == '':
  3112. if acl_data:
  3113. data += '<hr class=\"main_hr\"><input value="' + html.escape(acl_data[0][1]) + '" placeholder="' + load_lang('why') + '" name="why" type="text" ' + check_ok + '>'
  3114. else:
  3115. data += '<hr class=\"main_hr\"><input placeholder="' + load_lang('why') + '" name="why" type="text" ' + check_ok + '>'
  3116. return easy_minify(flask.render_template(skin_check(),
  3117. imp = [name, wiki_set(), custom(), other2([' (acl)', 0])],
  3118. data = '''
  3119. <form method="post">
  3120. ''' + data + '''
  3121. <hr class=\"main_hr\">
  3122. <button type="submit" ''' + check_ok + '''>acl ''' + load_lang('edit') + '''</button>
  3123. </form>
  3124. ''',
  3125. menu = [['w/' + url_pas(name), load_lang('document')], ['manager', load_lang('admin')]]
  3126. ))
  3127. @app.route('/admin/<name>', methods=['POST', 'GET'])
  3128. def user_admin(name = None):
  3129. owner = admin_check()
  3130. curs.execute("select acl from user where id = ?", [name])
  3131. user = curs.fetchall()
  3132. if not user:
  3133. return re_error('/error/2')
  3134. else:
  3135. if owner != 1:
  3136. curs.execute('select name from alist where name = ? and acl = "owner"', [user[0][0]])
  3137. if curs.fetchall():
  3138. return re_error('/error/3')
  3139. if ip_check() == name:
  3140. return re_error('/error/3')
  3141. if flask.request.method == 'POST':
  3142. if admin_check(7, 'admin (' + name + ')') != 1:
  3143. return re_error('/error/3')
  3144. if owner != 1:
  3145. curs.execute('select name from alist where name = ? and acl = "owner"', [flask.request.form.get('select', None)])
  3146. if curs.fetchall():
  3147. return re_error('/error/3')
  3148. if flask.request.form.get('select', None) == 'X':
  3149. curs.execute("update user set acl = 'user' where id = ?", [name])
  3150. else:
  3151. curs.execute("update user set acl = ? where id = ?", [flask.request.form.get('select', None), name])
  3152. conn.commit()
  3153. return redirect('/admin/' + url_pas(name))
  3154. else:
  3155. if admin_check(7) != 1:
  3156. return re_error('/error/3')
  3157. div = '<option value="X">X</option>'
  3158. curs.execute('select distinct name from alist order by name asc')
  3159. for data in curs.fetchall():
  3160. if user[0][0] == data[0]:
  3161. div += '<option value="' + data[0] + '" selected="selected">' + data[0] + '</option>'
  3162. else:
  3163. if owner != 1:
  3164. curs.execute('select name from alist where name = ? and acl = "owner"', [data[0]])
  3165. if not curs.fetchall():
  3166. div += '<option value="' + data[0] + '">' + data[0] + '</option>'
  3167. else:
  3168. div += '<option value="' + data[0] + '">' + data[0] + '</option>'
  3169. return easy_minify(flask.render_template(skin_check(),
  3170. imp = [name, wiki_set(), custom(), other2([' (' + load_lang('authority') + ')', 0])],
  3171. data = '''
  3172. <form method="post">
  3173. <select name="select">''' + div + '''</select>
  3174. <hr class=\"main_hr\">
  3175. <button type="submit">''' + load_lang('edit') + '''</button>
  3176. </form>
  3177. ''',
  3178. menu = [['manager', load_lang('admin')]]
  3179. ))
  3180. @app.route('/diff/<everything:name>')
  3181. def diff_data(name = None):
  3182. first = flask.request.args.get('first', '1')
  3183. second = flask.request.args.get('second', '1')
  3184. curs.execute("select data from history where id = ? and title = ?", [first, name])
  3185. first_raw_data = curs.fetchall()
  3186. if first_raw_data:
  3187. curs.execute("select data from history where id = ? and title = ?", [second, name])
  3188. second_raw_data = curs.fetchall()
  3189. if second_raw_data:
  3190. first_data = html.escape(first_raw_data[0][0])
  3191. second_data = html.escape(second_raw_data[0][0])
  3192. if first == second:
  3193. result = '-'
  3194. else:
  3195. diff_data = difflib.SequenceMatcher(None, first_data, second_data)
  3196. result = re.sub('\r', '', diff(diff_data))
  3197. return easy_minify(flask.render_template(skin_check(),
  3198. imp = [name, wiki_set(), custom(), other2([' (' + load_lang('compare') + ')', 0])],
  3199. data = '<pre>' + result + '</pre>',
  3200. menu = [['history/' + url_pas(name), load_lang('history')]]
  3201. ))
  3202. return redirect('/history/' + url_pas(name))
  3203. @app.route('/down/<everything:name>')
  3204. def down(name = None):
  3205. div = '<ul>'
  3206. curs.execute("select title from data where title like ?", ['%' + name + '/%'])
  3207. for data in curs.fetchall():
  3208. div += '<li><a href="/w/' + url_pas(data[0]) + '">' + data[0] + '</a></li>'
  3209. div += '</ul>'
  3210. return easy_minify(flask.render_template(skin_check(),
  3211. imp = [name, wiki_set(), custom(), other2([' (' + load_lang('under') + ')', 0])],
  3212. data = div,
  3213. menu = [['w/' + url_pas(name), load_lang('document')]]
  3214. ))
  3215. @app.route('/w/<everything:name>')
  3216. def read_view(name = None):
  3217. data_none = 0
  3218. sub = ''
  3219. acl = ''
  3220. div = ''
  3221. num = flask.request.args.get('num', None)
  3222. if num:
  3223. num = int(num)
  3224. else:
  3225. if not flask.request.args.get('from', None):
  3226. curs.execute("select title from back where link = ? and type = 'redirect'", [name])
  3227. redirect_data = curs.fetchall()
  3228. if redirect_data:
  3229. return redirect('/w/' + redirect_data[0][0] + '?from=' + name)
  3230. curs.execute("select sub from rd where title = ? and not stop = 'O' order by date desc", [name])
  3231. if curs.fetchall():
  3232. sub += ' (' + load_lang('discussion') + ')'
  3233. curs.execute("select link from back where title = ? and type = 'cat' order by link asc", [name])
  3234. curs.execute("select title from data where title like ?", ['%' + name + '/%'])
  3235. if curs.fetchall():
  3236. down = 1
  3237. else:
  3238. down = 0
  3239. m = re.search("^(.*)\/(.*)$", name)
  3240. if m:
  3241. uppage = m.groups()[0]
  3242. else:
  3243. uppage = 0
  3244. if re.search('^category:', name):
  3245. curs.execute("select link from back where title = ? and type = 'cat' order by link asc", [name])
  3246. back = curs.fetchall()
  3247. if back:
  3248. div = '<br><h2 id="cate_normal">' + load_lang('category') + '</h2><ul>'
  3249. u_div = ''
  3250. for data in back:
  3251. if re.search('^category:', data[0]):
  3252. u_div += '<li><a href="/w/' + url_pas(data[0]) + '">' + data[0] + '</a></li>'
  3253. else:
  3254. curs.execute("select title from back where title = ? and type = 'include'", [data[0]])
  3255. db_data = curs.fetchall()
  3256. if db_data:
  3257. div += '<li><a href="/w/' + url_pas(data[0]) + '">' + data[0] + '</a> <a id="inside" href="/xref/' + url_pas(data[0]) + '">(' + load_lang('backlink') + ')</a></li>'
  3258. else:
  3259. div += '<li><a href="/w/' + url_pas(data[0]) + '">' + data[0] + '</a></li>'
  3260. div += '</ul>'
  3261. if div == '<br><h2 id="cate_normal">' + load_lang('category') + '</h2><ul></ul>':
  3262. div = ''
  3263. if u_div != '':
  3264. div += '<br><h2 id="cate_under">' + load_lang('under') + ' ' + load_lang('category') + '</h2><ul>' + u_div + '</ul>'
  3265. if num:
  3266. curs.execute("select title from history where title = ? and id = ? and hide = 'O'", [name, str(num)])
  3267. if curs.fetchall() and admin_check(6) != 1:
  3268. return redirect('/history/' + url_pas(name))
  3269. curs.execute("select title, data from history where title = ? and id = ?", [name, str(num)])
  3270. else:
  3271. curs.execute("select title, data from data where title = ?", [name])
  3272. data = curs.fetchall()
  3273. if data:
  3274. else_data = data[0][1]
  3275. response_data = 200
  3276. else:
  3277. data_none = 1
  3278. response_data = 404
  3279. else_data = None
  3280. m = re.search("^user:([^/]*)", name)
  3281. if m:
  3282. g = m.groups()
  3283. curs.execute("select acl from user where id = ?", [g[0]])
  3284. test = curs.fetchall()
  3285. if test and test[0][0] != 'user':
  3286. acl = ' (' + load_lang('admin') + ')'
  3287. else:
  3288. if ban_check(g[0]) == 1:
  3289. sub += ' (' + load_lang('ban') + ')'
  3290. else:
  3291. acl = ''
  3292. curs.execute("select dec from acl where title = ?", [name])
  3293. data = curs.fetchall()
  3294. if data:
  3295. acl += ' (acl)'
  3296. if flask.request.args.get('from', None) and else_data:
  3297. else_data = re.sub('^\r\n', '', else_data)
  3298. else_data = re.sub('\r\n$', '', else_data)
  3299. end_data = render_set(
  3300. title = name,
  3301. data = else_data
  3302. )
  3303. if end_data == 'http request 401.3':
  3304. response_data = 401
  3305. if num:
  3306. menu = [['history/' + url_pas(name), load_lang('history')]]
  3307. sub = ' (' + str(num) + load_lang('version') + ')'
  3308. acl = ''
  3309. r_date = 0
  3310. else:
  3311. if data_none == 1:
  3312. menu = [['edit/' + url_pas(name), load_lang('create')]]
  3313. else:
  3314. menu = [['edit/' + url_pas(name), load_lang('edit')]]
  3315. menu += [['topic/' + url_pas(name), load_lang('discussion')], ['history/' + url_pas(name), load_lang('history')], ['xref/' + url_pas(name), load_lang('backlink')], ['acl/' + url_pas(name), 'acl']]
  3316. if flask.request.args.get('from', None):
  3317. menu += [['w/' + url_pas(name), load_lang('pass')]]
  3318. end_data = '''
  3319. <div id="redirect">
  3320. <a href="/w/''' + url_pas(flask.request.args.get('from', None)) + '?from=' + url_pas(name) + '">' + flask.request.args.get('from', None) + '</a> - ' + name + '''
  3321. </div>
  3322. <br>''' + end_data
  3323. if uppage != 0:
  3324. menu += [['w/' + url_pas(uppage), load_lang('upper')]]
  3325. if down:
  3326. menu += [['down/' + url_pas(name), load_lang('under')]]
  3327. curs.execute("select date from history where title = ? order by date desc limit 1", [name])
  3328. date = curs.fetchall()
  3329. if date:
  3330. r_date = date[0][0]
  3331. else:
  3332. r_date = 0
  3333. div = end_data + div
  3334. curs.execute("select data from other where name = 'adsense'")
  3335. adsense_enabled = curs.fetchall()[0][0]
  3336. adsense_code = '<div align="center" style="display: block; margin-bottom: 10px;">%_adsense_code_%</div>'
  3337. if adsense_enabled == 'True':
  3338. curs.execute("select data from other where name = 'adsense_code'")
  3339. adsense_code = adsense_code.replace('%_adsense_code_%', curs.fetchall()[0][0])
  3340. else:
  3341. adsense_code = adsense_code.replace('%_adsense_code_%', '')
  3342. curs.execute("select data from other where name = 'body'")
  3343. body = curs.fetchall()
  3344. if body:
  3345. div = body[0][0] + '<hr class=\"main_hr\">' + div
  3346. div = adsense_code + '<div>' + div + '</div>'
  3347. return easy_minify(flask.render_template(skin_check(),
  3348. imp = [flask.request.args.get('show', name), wiki_set(), custom(), other2([sub + acl, r_date])],
  3349. data = div,
  3350. menu = menu
  3351. )), response_data
  3352. @app.route('/topic_record/<name>')
  3353. def user_topic_list(name = None):
  3354. num = int(flask.request.args.get('num', 1))
  3355. if num * 50 > 0:
  3356. sql_num = num * 50 - 50
  3357. else:
  3358. sql_num = 0
  3359. one_admin = admin_check(1)
  3360. div = '''
  3361. <table id="main_table_set">
  3362. <tbody>
  3363. <tr>
  3364. <td id="main_table_width">''' + load_lang('discussion') + ' ' + load_lang('name') + '''</td>
  3365. <td id="main_table_width">''' + load_lang('writer') + '''</td>
  3366. <td id="main_table_width">''' + load_lang('time') + '''</td>
  3367. </tr>
  3368. '''
  3369. curs.execute("select title, id, sub, ip, date from topic where ip = ? order by date desc limit ?, '50'", [name, str(sql_num)])
  3370. data_list = curs.fetchall()
  3371. for data in data_list:
  3372. title = html.escape(data[0])
  3373. sub = html.escape(data[2])
  3374. if one_admin == 1:
  3375. curs.execute("select * from ban where block = ?", [data[3]])
  3376. if curs.fetchall():
  3377. ban = ' <a href="/ban/' + url_pas(data[3]) + '">(' + load_lang('release') + ')</a>'
  3378. else:
  3379. ban = ' <a href="/ban/' + url_pas(data[3]) + '">(' + load_lang('ban') + ')</a>'
  3380. else:
  3381. ban = ''
  3382. div += '<tr><td><a href="/topic/' + url_pas(data[0]) + '/sub/' + url_pas(data[2]) + '#' + data[1] + '">' + title + '#' + data[1] + '</a> (' + sub + ')</td>'
  3383. div += '<td>' + ip_pas(data[3]) + ban + '</td><td>' + data[4] + '</td></tr>'
  3384. div += '</tbody></table>'
  3385. div += next_fix('/topic_record/' + url_pas(name) + '?num=', num, data_list)
  3386. curs.execute("select end from ban where block = ?", [name])
  3387. if curs.fetchall():
  3388. sub = ' (' + load_lang('ban') + ')'
  3389. else:
  3390. sub = 0
  3391. return easy_minify(flask.render_template(skin_check(),
  3392. imp = [load_lang('discussion') + ' ' + load_lang('record'), wiki_set(), custom(), other2([sub, 0])],
  3393. data = div,
  3394. menu = [['other', load_lang('other')], ['user', load_lang('user')], ['count/' + url_pas(name), load_lang('count')], ['record/' + url_pas(name), load_lang('record')]]
  3395. ))
  3396. @app.route('/recent_changes')
  3397. @app.route('/<regex("record"):tool>/<name>')
  3398. @app.route('/<regex("history"):tool>/<everything:name>', methods=['POST', 'GET'])
  3399. def recent_changes(name = None, tool = 'record'):
  3400. if flask.request.method == 'POST':
  3401. return redirect('/diff/' + url_pas(name) + '?first=' + flask.request.form.get('b', None) + '&second=' + flask.request.form.get('a', None))
  3402. else:
  3403. one_admin = admin_check(1)
  3404. six_admin = admin_check(6)
  3405. ban = ''
  3406. select = ''
  3407. what = flask.request.args.get('what', 'all')
  3408. div = '''
  3409. <table id="main_table_set">
  3410. <tbody>
  3411. <tr>
  3412. '''
  3413. if name:
  3414. num = int(flask.request.args.get('num', 1))
  3415. if num * 50 > 0:
  3416. sql_num = num * 50 - 50
  3417. else:
  3418. sql_num = 0
  3419. if tool == 'history':
  3420. div += '''
  3421. <td id="main_table_width">''' + load_lang('version') + '''</td>
  3422. <td id="main_table_width">''' + load_lang('editor') + '''</td>
  3423. <td id="main_table_width">''' + load_lang('time') + '''</td></tr>
  3424. '''
  3425. curs.execute("select id, title, date, ip, send, leng from history where title = ? order by id + 0 desc limit ?, '50'", [name, str(sql_num)])
  3426. else:
  3427. div += '''
  3428. <td id="main_table_width">''' + load_lang('document') + ' ' + load_lang('name') + '''</td>
  3429. <td id="main_table_width">''' + load_lang('editor') + '''</td>
  3430. <td id="main_table_width">''' + load_lang('time') + '''</td>
  3431. </tr>
  3432. '''
  3433. if what == 'all':
  3434. div = '<a href="/topic_record/' + url_pas(name) + '">(' + load_lang('discussion') + ')</a> <a href="/record/' + url_pas(name) + '?what=delete">(' + load_lang('delete') + ')</a> <a href="/record/' + url_pas(name) + '?what=move">(' + load_lang('move') + ')</a> <a href="/record/' + url_pas(name) + '?what=revert">(' + load_lang('revert') + ')</a><hr class=\"main_hr\">' + div
  3435. curs.execute("select id, title, date, ip, send, leng from history where ip = ? order by date desc limit ?, '50'", [name, str(sql_num)])
  3436. else:
  3437. if what == 'delete':
  3438. sql = '%(' + load_lang('delete', 1) + ')'
  3439. elif what == 'move':
  3440. sql = '%' + load_lang('move', 1) + ')'
  3441. elif what == 'revert':
  3442. sql = '%' + load_lang('version', 1) + ')'
  3443. else:
  3444. return redirect('/')
  3445. curs.execute("select id, title, date, ip, send, leng from history where ip = ? and send like ? order by date desc limit ?, 50", [name, sql, str(sql_num)])
  3446. else:
  3447. num = int(flask.request.args.get('num', 1))
  3448. if num * 50 > 0:
  3449. sql_num = num * 50 - 50
  3450. else:
  3451. sql_num = 0
  3452. div += '''
  3453. <td id="main_table_width">''' + load_lang('document') + ' ' + load_lang('name') + '''</td>
  3454. <td id="main_table_width">''' + load_lang('editor') + '''</td>
  3455. <td id="main_table_width">''' + load_lang('time') + '''</td>
  3456. </tr>
  3457. '''
  3458. if what == 'all':
  3459. div = '<a href="/recent_changes?what=delete">(' + load_lang('delete') + ')</a> <a href="/recent_changes?what=move">(' + load_lang('move') + ')</a> <a href="/recent_changes?what=revert">(' + load_lang('revert') + ')</a><hr class=\"main_hr\">' + div
  3460. div = '<a href="/recent_discuss">(' + load_lang('discussion') + ')</a> <a href="/block_log">(' + load_lang('ban') + ')</a> <a href="/user_log">(' + load_lang('subscriber') + ')</a> <a href="/admin_log">(' + load_lang('authority') + ')</a><hr class=\"main_hr\">' + div
  3461. curs.execute("select id, title, date, ip, send, leng from history where not title like 'user:%' order by date desc limit ?, 50", [str(sql_num)])
  3462. else:
  3463. if what == 'delete':
  3464. sql = '%(' + load_lang('delete', 1) + ')'
  3465. elif what == 'move':
  3466. sql = '%' + load_lang('move', 1) + ')'
  3467. elif what == 'revert':
  3468. sql = '%' + load_lang('version', 1) + ')'
  3469. else:
  3470. return redirect('/')
  3471. curs.execute("select id, title, date, ip, send, leng from history where send like ? and not title like 'user:%' order by date desc limit ?, 50", [sql, str(sql_num)])
  3472. data_list = curs.fetchall()
  3473. for data in data_list:
  3474. select += '<option value="' + data[0] + '">' + data[0] + '</option>'
  3475. send = '<br>'
  3476. if data[4]:
  3477. if not re.search("^(?: *)$", data[4]):
  3478. send = data[4]
  3479. if re.search("\+", data[5]):
  3480. leng = '<span style="color:green;">(' + data[5] + ')</span>'
  3481. elif re.search("\-", data[5]):
  3482. leng = '<span style="color:red;">(' + data[5] + ')</span>'
  3483. else:
  3484. leng = '<span style="color:gray;">(' + data[5] + ')</span>'
  3485. ip = ip_pas(data[3])
  3486. if int(data[0]) - 1 == 0:
  3487. revert = ''
  3488. else:
  3489. revert = '<a href="/diff/' + url_pas(data[1]) + '?first=' + str(int(data[0]) - 1) + '&second=' + data[0] + '">(' + load_lang('compare') + ')</a> <a href="/revert/' + url_pas(data[1]) + '?num=' + str(int(data[0]) - 1) + '">(' + load_lang('revert') + ')</a>'
  3490. style = ['', '']
  3491. date = data[2]
  3492. curs.execute("select title from history where title = ? and id = ? and hide = 'O'", [data[1], data[0]])
  3493. hide = curs.fetchall()
  3494. if six_admin == 1:
  3495. if hide:
  3496. hidden = ' <a href="/hidden/' + url_pas(data[1]) + '?num=' + data[0] + '">(' + load_lang('release') + ')'
  3497. style[0] = 'id="toron_color_grey"'
  3498. style[1] = 'id="toron_color_grey"'
  3499. if send == '<br>':
  3500. send = '(' + load_lang('hide') + ')'
  3501. else:
  3502. send += ' (' + load_lang('hide') + ')'
  3503. else:
  3504. hidden = ' <a href="/hidden/' + url_pas(data[1]) + '?num=' + data[0] + '">(' + load_lang('hide') + ')'
  3505. elif not hide:
  3506. hidden = ''
  3507. else:
  3508. ip = ''
  3509. hidden = ''
  3510. ban = ''
  3511. date = ''
  3512. send = '(' + load_lang('hide') + ')'
  3513. style[0] = 'style="display: none;"'
  3514. style[1] = 'id="toron_color_grey"'
  3515. if tool == 'history':
  3516. title = '<a href="/w/' + url_pas(name) + '?num=' + data[0] + '">' + data[0] + load_lang('version') + '</a> <a href="/raw/' + url_pas(name) + '?num=' + data[0] + '">(' + load_lang('raw') + ')</a> '
  3517. else:
  3518. title = '<a href="/w/' + url_pas(data[1]) + '">' + html.escape(data[1]) + '</a> <a href="/history/' + url_pas(data[1]) + '">(' + data[0] + load_lang('version') + ')</a> '
  3519. div += '''
  3520. <tr ''' + style[0] + '''>
  3521. <td>''' + title + revert + ' ' + leng + '''</td>
  3522. <td>''' + ip + ban + hidden + '''</td>
  3523. <td>''' + date + '''</td>
  3524. </tr>
  3525. <tr ''' + style[1] + '''>
  3526. <td colspan="3">''' + send_parser(send) + '''</td>
  3527. </tr>
  3528. '''
  3529. div += '''
  3530. </tbody>
  3531. </table>
  3532. '''
  3533. sub = ''
  3534. if name:
  3535. if tool == 'history':
  3536. div = '''
  3537. <form method="post">
  3538. <select name="a">''' + select + '''</select> <select name="b">''' + select + '''</select>
  3539. <button type="submit">''' + load_lang('compare') + '''</button>
  3540. </form>
  3541. <hr class=\"main_hr\">
  3542. <a href="/move_data/''' + url_pas(name) + '''">(''' + load_lang('move') + ''')</a>
  3543. <hr class=\"main_hr\">
  3544. ''' + div
  3545. title = name
  3546. sub += ' (' + load_lang('history') + ')'
  3547. menu = [['w/' + url_pas(name), load_lang('document')], ['raw/' + url_pas(name), 'raw']]
  3548. div += next_fix('/history/' + url_pas(name) + '?num=', num, data_list)
  3549. else:
  3550. curs.execute("select end from ban where block = ?", [name])
  3551. if curs.fetchall():
  3552. sub += ' (' + load_lang('ban') + ')'
  3553. title = load_lang('edit') + ' ' + load_lang('record')
  3554. menu = [['other', load_lang('other')], ['user', load_lang('user')], ['count/' + url_pas(name), load_lang('count')]]
  3555. div += next_fix('/record/' + url_pas(name) + '/' + url_pas(what) + '?num=', num, data_list)
  3556. if what != 'all':
  3557. menu += [['record/' + url_pas(name), load_lang('normal')]]
  3558. else:
  3559. menu = 0
  3560. title = load_lang('recent') + ' ' + load_lang('change') + ''
  3561. if what != 'all':
  3562. menu = [['recent_changes', load_lang('normal')]]
  3563. div += next_fix('/recent_changes?num=', num, data_list)
  3564. if what == 'delete':
  3565. sub += ' (' + load_lang('delete') + ')'
  3566. elif what == 'move':
  3567. sub += ' (' + load_lang('move') + ')'
  3568. elif what == 'revert':
  3569. sub += ' (' + load_lang('revert') + ')'
  3570. if sub == '':
  3571. sub = 0
  3572. return easy_minify(flask.render_template(skin_check(),
  3573. imp = [title, wiki_set(), custom(), other2([sub, 0])],
  3574. data = div,
  3575. menu = menu
  3576. ))
  3577. @app.route('/upload', methods=['GET', 'POST'])
  3578. def upload():
  3579. if ban_check() == 1:
  3580. return re_error('/ban')
  3581. if flask.request.method == 'POST':
  3582. if captcha_post(flask.request.form.get('g-recaptcha-response', '')) == 1:
  3583. return re_error('/error/13')
  3584. else:
  3585. captcha_post('', 0)
  3586. data = flask.request.files.get('f_data', None)
  3587. if not data:
  3588. return re_error('/error/9')
  3589. if int(wiki_set(3)) * 1024 * 1024 < flask.request.content_length:
  3590. return re_error('/error/17')
  3591. value = os.path.splitext(data.filename)[1]
  3592. if not value in ['.jpeg', '.jpg', '.gif', '.png', '.webp', '.JPEG', '.JPG', '.GIF', '.PNG', '.WEBP']:
  3593. return re_error('/error/14')
  3594. if flask.request.form.get('f_name', None):
  3595. name = flask.request.form.get('f_name', None) + value
  3596. else:
  3597. name = data.filename
  3598. piece = os.path.splitext(name)
  3599. if re.search('[^ㄱ-힣0-9a-zA-Z_\- ]', piece[0]):
  3600. return re_error('/error/22')
  3601. e_data = sha224(piece[0]) + piece[1]
  3602. curs.execute("select title from data where title = ?", ['file:' + name])
  3603. if curs.fetchall():
  3604. return re_error('/error/16')
  3605. ip = ip_check()
  3606. if flask.request.form.get('f_lice', None):
  3607. lice = flask.request.form.get('f_lice', None)
  3608. else:
  3609. if custom()[2] == 0:
  3610. lice = ip + ' ' + load_lang('upload', 1)
  3611. else:
  3612. lice = '[[user:' + ip + ']] ' + load_lang('upload', 1)
  3613. if os.path.exists(os.path.join('image', e_data)):
  3614. os.remove(os.path.join('image', e_data))
  3615. data.save(os.path.join('image', e_data))
  3616. else:
  3617. data.save(os.path.join('image', e_data))
  3618. curs.execute("select title from data where title = ?", ['file:' + name])
  3619. if curs.fetchall():
  3620. curs.execute("delete from data where title = ?", ['file:' + name])
  3621. curs.execute("insert into data (title, data) values (?, ?)", ['file:' + name, '[[file:' + name + ']][br][br]{{{[[file:' + name + ']]}}}[br][br]' + lice])
  3622. curs.execute("insert into acl (title, dec, dis, why, view) values (?, 'admin', '', '', '')", ['file:' + name])
  3623. history_plus(
  3624. 'file:' + name, '[[file:' + name + ']][br][br]{{{[[file:' + name + ']]}}}[br][br]' + lice,
  3625. get_time(),
  3626. ip,
  3627. load_lang('upload', 1),
  3628. '0'
  3629. )
  3630. conn.commit()
  3631. return redirect('/w/file:' + name)
  3632. else:
  3633. return easy_minify(flask.render_template(skin_check(),
  3634. imp = [load_lang('upload'), wiki_set(), custom(), other2([0, 0])],
  3635. data = '''
  3636. <form method="post" enctype="multipart/form-data" accept-charset="utf8">
  3637. <input type="file" name="f_data">
  3638. <hr class=\"main_hr\">
  3639. <input placeholder="''' + load_lang('name') + '''" name="f_name" type="text">
  3640. <hr class=\"main_hr\">
  3641. <input placeholder="''' + load_lang('license') + '''" name="f_lice" type="text">
  3642. <hr class=\"main_hr\">
  3643. ''' + captcha_get() + '''
  3644. <button id="save" type="submit">''' + load_lang('save') + '''</button>
  3645. </form>
  3646. ''',
  3647. menu = [['other', load_lang('other')]]
  3648. ))
  3649. @app.route('/user')
  3650. def user_info():
  3651. ip = ip_check()
  3652. curs.execute("select acl from user where id = ?", [ip])
  3653. data = curs.fetchall()
  3654. if ban_check() == 0:
  3655. if data:
  3656. if data[0][0] != 'user':
  3657. acl = data[0][0]
  3658. else:
  3659. acl = load_lang('subscriber')
  3660. else:
  3661. acl = load_lang('normal')
  3662. else:
  3663. acl = load_lang('ban')
  3664. match = re.search("^([0-9]{1,3}\.[0-9]{1,3})", ip)
  3665. if match:
  3666. match = match.groups()[0]
  3667. else:
  3668. match = '-'
  3669. curs.execute("select end, login, band from ban where block = ? or block = ?", [ip, match])
  3670. block_data = curs.fetchall()
  3671. if block_data:
  3672. if block_data[0][0] != '':
  3673. acl += ' (end : ' + block_data[0][0] + ')'
  3674. else:
  3675. acl += ' (' + load_lang('limitless') + ')'
  3676. if block_data[0][1] != '':
  3677. acl += ' (' + load_lang('login') + ' ' + load_lang('able') + ')'
  3678. if block_data[0][2] == 'O':
  3679. acl += ' (' + load_lang('band') + ')'
  3680. if custom()[2] != 0:
  3681. ip_user = '<a href="/w/user:' + ip + '">' + ip + '</a>'
  3682. plus = '''
  3683. <li><a href="/logout">''' + load_lang('logout') + '''</a></li>
  3684. <li><a href="/change">''' + load_lang('user') + ' ' + load_lang('setting') + ' ' + load_lang('edit') + '''</a></li>
  3685. '''
  3686. curs.execute('select name from alarm where name = ? limit 1', [ip_check()])
  3687. if curs.fetchall():
  3688. plus2 = '<li><a href="/alarm">' + load_lang('alarm') + ' (O)</a></li>'
  3689. else:
  3690. plus2 = '<li><a href="/alarm">' + load_lang('alarm') + '</a></li>'
  3691. plus2 += '<li><a href="/watch_list">' + load_lang('watchlist') + '</a></li>'
  3692. plus3 = '<li><a href="/acl/user:' + url_pas(ip) + '">' + load_lang('user') + ' ' + load_lang('document') + ' acl</a></li>'
  3693. else:
  3694. ip_user = ip
  3695. plus = '''
  3696. <li><a href="/login">''' + load_lang('login') + '''</a></li>
  3697. <li><a href="/register">''' + load_lang('register') + '''</a></li>
  3698. '''
  3699. plus2 = ''
  3700. plus3 = ''
  3701. curs.execute("select data from other where name = 'email_have'")
  3702. test = curs.fetchall()
  3703. if test and test[0][0] != '':
  3704. plus += '<li><a href="/pass_find">' + load_lang('password') + ' ' + load_lang('search') + '</a></li>'
  3705. return easy_minify(flask.render_template(skin_check(),
  3706. imp = [load_lang('user') + ' ' + load_lang('tool'), wiki_set(), custom(), other2([0, 0])],
  3707. data = '''
  3708. <h2>''' + load_lang('state') + '''</h2>
  3709. <ul>
  3710. <li>''' + ip_user + ''' <a href="/record/''' + url_pas(ip) + '''">(''' + load_lang('record') + ''')</a></li>
  3711. <li>''' + load_lang('authority') + ''' : ''' + acl + '''</li>
  3712. </ul>
  3713. <br>
  3714. <h2>''' + load_lang('login') + '''</h2>
  3715. <ul>
  3716. ''' + plus + '''
  3717. </ul>
  3718. <br>
  3719. <h2>''' + load_lang('tool') + '''</h2>
  3720. <ul>
  3721. ''' + plus3 + '''
  3722. <li><a href="/custom_head">''' + load_lang('user') + ''' head</a></li>
  3723. </ul>
  3724. <br>
  3725. <h2>''' + load_lang('other') + '''</h2>
  3726. <ul>
  3727. ''' + plus2 + '''
  3728. <li>
  3729. <a href="/count">''' + load_lang('count') + '''</a>
  3730. </li>
  3731. </ul>
  3732. ''',
  3733. menu = 0
  3734. ))
  3735. @app.route('/watch_list')
  3736. def watch_list():
  3737. div = 'limit : 10<hr class=\"main_hr\">'
  3738. if custom()[2] == 0:
  3739. return redirect('/login')
  3740. curs.execute("select title from scan where user = ?", [ip_check()])
  3741. data = curs.fetchall()
  3742. for data_list in data:
  3743. div += '<li><a href="/w/' + url_pas(data_list[0]) + '">' + data_list[0] + '</a> <a href="/watch_list/' + url_pas(data_list[0]) + '">(' + load_lang('delete') + ')</a></li>'
  3744. if data:
  3745. div = '<ul>' + div + '</ul><hr class=\"main_hr\">'
  3746. div += '<a href="/manager/13">(' + load_lang('plus') + ')</a>'
  3747. return easy_minify(flask.render_template(skin_check(),
  3748. imp = [load_lang('watchlist') + ' ' + load_lang('list'), wiki_set(), custom(), other2([0, 0])],
  3749. data = div,
  3750. menu = [['manager', load_lang('admin')]]
  3751. ))
  3752. @app.route('/watch_list/<everything:name>')
  3753. def watch_list_name(name = None):
  3754. if custom()[2] == 0:
  3755. return redirect('/login')
  3756. ip = ip_check()
  3757. curs.execute("select count(title) from scan where user = ?", [ip])
  3758. count = curs.fetchall()
  3759. if count and count[0][0] > 9:
  3760. return redirect('/watch_list')
  3761. curs.execute("select title from scan where user = ? and title = ?", [ip, name])
  3762. if curs.fetchall():
  3763. curs.execute("delete from scan where user = ? and title = ?", [ip, name])
  3764. else:
  3765. curs.execute("insert into scan (user, title) values (?, ?)", [ip, name])
  3766. conn.commit()
  3767. return redirect('/watch_list')
  3768. @app.route('/custom_head', methods=['GET', 'POST'])
  3769. def custom_head_view():
  3770. ip = ip_check()
  3771. if flask.request.method == 'POST':
  3772. if custom()[2] != 0:
  3773. curs.execute("select user from custom where user = ?", [ip + ' (head)'])
  3774. if curs.fetchall():
  3775. curs.execute("update custom set css = ? where user = ?", [flask.request.form.get('content', None), ip + ' (head)'])
  3776. else:
  3777. curs.execute("insert into custom (user, css) values (?, ?)", [ip + ' (head)', flask.request.form.get('content', None)])
  3778. conn.commit()
  3779. flask.session['head'] = flask.request.form.get('content', None)
  3780. return redirect('/user')
  3781. else:
  3782. if custom()[2] != 0:
  3783. start = ''
  3784. curs.execute("select css from custom where user = ?", [ip + ' (head)'])
  3785. head_data = curs.fetchall()
  3786. if head_data:
  3787. data = head_data[0][0]
  3788. else:
  3789. data = ''
  3790. else:
  3791. start = '<span>' + load_lang('user_head_warring') + '</span><hr class=\"main_hr\">'
  3792. if 'head' in flask.session:
  3793. data = flask.session['head']
  3794. else:
  3795. data = ''
  3796. start += '<span>&lt;style&gt;css&lt;/style&gt;<br>&lt;script&gt;js&lt;/script&gt;</span><hr class=\"main_hr\">'
  3797. return easy_minify(flask.render_template(skin_check(),
  3798. imp = [load_lang('user') + ' head', wiki_set(), custom(), other2([0, 0])],
  3799. data = start + '''
  3800. <form method="post">
  3801. <textarea rows="25" cols="100" name="content">''' + data + '''</textarea>
  3802. <hr class=\"main_hr\">
  3803. <button id="save" type="submit">''' + load_lang('save') + '''</button>
  3804. </form>
  3805. ''',
  3806. menu = [['user', load_lang('user')]]
  3807. ))
  3808. @app.route('/count')
  3809. @app.route('/count/<name>')
  3810. def count_edit(name = None):
  3811. if name == None:
  3812. that = ip_check()
  3813. else:
  3814. that = name
  3815. curs.execute("select count(title) from history where ip = ?", [that])
  3816. count = curs.fetchall()
  3817. if count:
  3818. data = count[0][0]
  3819. else:
  3820. data = 0
  3821. curs.execute("select count(title) from topic where ip = ?", [that])
  3822. count = curs.fetchall()
  3823. if count:
  3824. t_data = count[0][0]
  3825. else:
  3826. t_data = 0
  3827. return easy_minify(flask.render_template(skin_check(),
  3828. imp = [load_lang('count'), wiki_set(), custom(), other2([0, 0])],
  3829. data = '''
  3830. <ul>
  3831. <li><a href="/record/''' + url_pas(that) + '''">''' + load_lang('edit') + '''</a> : ''' + str(data) + '''</li>
  3832. <li><a href="/topic_record/''' + url_pas(that) + '''">''' + load_lang('discussion') + '''</a> : ''' + str(t_data) + '''</a></li>
  3833. </ul>
  3834. ''',
  3835. menu = [['user', load_lang('user')]]
  3836. ))
  3837. @app.route('/random')
  3838. def title_random():
  3839. curs.execute("select title from data order by random() limit 1")
  3840. data = curs.fetchall()
  3841. if data:
  3842. return redirect('/w/' + url_pas(data[0][0]))
  3843. else:
  3844. return redirect('/')
  3845. @app.route('/skin_set')
  3846. def skin_set():
  3847. return re_error('/error/5')
  3848. @app.route('/api/w/<everything:name>')
  3849. def api_w(name = ''):
  3850. curs.execute("select data from data where title = ?", [name])
  3851. data = curs.fetchall()
  3852. if data:
  3853. json_data = { "title" : name, "data" : render_set(title = name, data = data[0][0]) }
  3854. return flask.jsonify(json_data)
  3855. else:
  3856. return flask.jsonify({})
  3857. @app.route('/api/raw/<everything:name>')
  3858. def api_raw(name = ''):
  3859. curs.execute("select data from data where title = ?", [name])
  3860. data = curs.fetchall()
  3861. if data:
  3862. json_data = { "title" : name, "data" : data[0][0] }
  3863. return flask.jsonify(json_data)
  3864. else:
  3865. return flask.jsonify({})
  3866. @app.route('/api/topic/<everything:name>/sub/<sub>')
  3867. def api_topic_sub(name = '', sub = '', time = ''):
  3868. if flask.request.args.get('time', None):
  3869. curs.execute("select id, data, ip from topic where title = ? and sub = ? and date >= ? order by id + 0 asc", [name, sub, flask.request.args.get('time', None)])
  3870. else:
  3871. curs.execute("select id, data, ip from topic where title = ? and sub = ? order by id + 0 asc", [name, sub])
  3872. data = curs.fetchall()
  3873. if data:
  3874. json_data = {}
  3875. for i in data:
  3876. json_data[i[0]] = {
  3877. "data" : i[1],
  3878. "id" : i[2]
  3879. }
  3880. return flask.jsonify(json_data)
  3881. else:
  3882. return flask.jsonify({})
  3883. @app.route('/views/<everything:name>')
  3884. def views(name = None):
  3885. if re.search('\/', name):
  3886. m = re.search('^(.*)\/(.*)$', name)
  3887. if m:
  3888. n = m.groups()
  3889. plus = '/' + n[0]
  3890. rename = n[1]
  3891. else:
  3892. plus = ''
  3893. rename = name
  3894. else:
  3895. plus = ''
  3896. rename = name
  3897. m = re.search('\.(.+)$', name)
  3898. if m:
  3899. g = m.groups()
  3900. else:
  3901. g = ['']
  3902. if g == 'css':
  3903. return easy_minify(flask.send_from_directory('./views' + plus, rename), 'css')
  3904. elif g == 'js':
  3905. return easy_minify(flask.send_from_directory('./views' + plus, rename), 'js')
  3906. elif g == 'html':
  3907. return easy_minify(flask.send_from_directory('./views' + plus, rename))
  3908. else:
  3909. return flask.send_from_directory('./views' + plus, rename)
  3910. @app.route('/<data>')
  3911. def main_file(data = None):
  3912. if re.search('\.txt$', data):
  3913. return flask.send_from_directory('./', data)
  3914. else:
  3915. return redirect('/w/' + url_pas(wiki_set(2)))
  3916. @app.route('/request/egg')
  3917. def request_egg():
  3918. return easter_egg[random.randint(0, len(easter_egg) - 1)]
  3919. @app.errorhandler(404)
  3920. def error_404(e):
  3921. return redirect('/w/' + url_pas(wiki_set(2)))
  3922. if __name__=="__main__":
  3923. app.secret_key = rep_key
  3924. http_server = tornado.httpserver.HTTPServer(tornado.wsgi.WSGIContainer(app))
  3925. http_server.listen(rep_port, address=rep_host)
  3926. tornado.ioloop.IOLoop.instance().start()