# coding=utf-8 import _mysql from database import * from framework import * from template import * from img import * from post import * from settings import Settings d_thread = {} d_post = {} def anarkia(self, path_split): setBoard('anarkia') if len(path_split) <= 2: self.output = main() return raise UserError('Ya fue, baisano...') if path_split[2] == 'opt': self.output = boardoptions(self.formdata) elif path_split[2] == 'mod': self.output = mod(self.formdata) elif path_split[2] == 'bans': self.output = bans(self.formdata) elif path_split[2] == 'css': self.output = css(self.formdata) elif path_split[2] == 'type': self.output = type(self.formdata) elif path_split[2] == 'emojis': self.output = emojis(self.formdata) else: raise UserError('ke?') def main(): board = Settings._.BOARD logs = FetchAll( "SELECT * FROM `logs` WHERE `staff` = 'Anarko' ORDER BY `timestamp` DESC") for log in logs: log['timestamp_formatted'] = formatTimestamp(log['timestamp']) return renderTemplate('anarkia.html', {'mode': 0, 'logs': logs}) def type(formdata): board = Settings._.BOARD if board['board_type'] == '1': (type_now, type_do, do_num) = ('BBS', 'IB', '0') else: (type_now, type_do, do_num) = ('IB', 'BBS', '1') if formdata.get('transform') == 'do': t = 0 try: with open('anarkia_time') as f: t = int(f.read()) except IOError: pass dif = time.time() - t if dif > (10 * 60): # if True: import re t = time.time() board['board_type'] = do_num board['force_css'] = Settings.HOME_URL + \ 'anarkia/style_' + type_do.lower() + '.css' updateBoardSettings() # update posts fix_board() # regenerate setBoard('anarkia') regenerateBoard(True) tf = timeTaken(t, time.time()) with open('anarkia_time', 'w') as f: t = f.write(str(int(time.time()))) msg = 'Cambiada estructura de sección a %s. (%s)' % (type_do, tf) logAction(msg) return renderTemplate('anarkia.html', {'mode': 99, 'msg': msg}) else: raise UserError('Esta acción sólo se puede realizar cada 10 minutos. Faltan: %d mins.' % (10-int(dif/60))) return renderTemplate('anarkia.html', {'mode': 7, 'type_now': type_now, 'type_do': type_do}) def fix_board(): board = Settings._.BOARD get_fix_dictionary() if board['board_type'] == '1': to_fix = FetchAll( "SELECT * FROM posts WHERE message LIKE '%%anarkia/res/%%' AND boardid = %s" % board['id']) else: to_fix = FetchAll( "SELECT * FROM posts WHERE message LIKE '%%anarkia/read/%%' AND boardid = %s" % board['id']) for p in to_fix: try: if board['board_type'] == '1': newmessage = re.sub( r'/anarkia/res/(\d+).html#(\d+)">>>(\d+)', fix_to_bbs, p['message']) else: newmessage = re.sub( r'/anarkia/read/(\d+)/(\d+)">>>(\d+)', fix_to_ib, p['message']) UpdateDb("UPDATE posts SET message = '%s' WHERE boardid = %s AND id = %s" % (_mysql.escape_string(newmessage), board['id'], p['id'])) except KeyError: pass return True def fix_to_bbs(matchobj): threadid = matchobj.group(1) pid = matchobj.group(2) new_thread = d_thread[threadid] new_post = d_post[new_thread][pid] return '/anarkia/read/%s/%s">>>%s' % (new_thread, new_post, new_post) def fix_to_ib(matchobj): threadid = matchobj.group(1) num = int(matchobj.group(2)) new_thread = d_thread[threadid] new_post = d_post[new_thread][num] return '/anarkia/res/%s.html#%s">>>%s' % (new_thread, new_post, new_post) def get_fix_dictionary(): global d_thread, d_post board = Settings._.BOARD res = FetchAll( "SELECT id, timestamp, parentid FROM posts WHERE boardid = %s ORDER BY CASE parentid WHEN 0 THEN id ELSE parentid END ASC, `id` ASC" % board['id']) num = 1 thread = 0 for p in res: pid = p['id'] if p['parentid'] == '0': num = 1 time = p['timestamp'] if board['board_type'] == '1': d_thread[pid] = time thread = time else: d_thread[time] = pid thread = pid d_post[thread] = {} if board['board_type'] == '1': d_post[thread][pid] = num else: d_post[thread][num] = pid num += 1 return def css(formdata): board = Settings._.BOARD if board['board_type'] == '1': basename = 'style_bbs.css' else: basename = 'style_ib.css' fname = '%sanarkia/%s' % (Settings.HOME_DIR, basename) if formdata.get('cssfile'): with open(fname, 'w') as f: cssfile = f.write(formdata['cssfile']) msg = 'CSS actualizado.' logAction(msg) return renderTemplate('anarkia.html', {'mode': 99, 'msg': msg}) with open(fname) as f: cssfile = f.read() return renderTemplate('anarkia.html', {'mode': 6, 'basename': basename, 'cssfile': cssfile}) def bans(formdata): board = Settings._.BOARD if formdata.get('unban'): unban = int(formdata['unban']) boardpickle = pickle.dumps(['anarkia']) ban = FetchOne("SELECT * FROM `bans` WHERE id = %d" % unban) if not ban: raise UserError("Ban inválido.") if ban['boards'] != boardpickle: raise USerError("Ban inválido.") UpdateDb('DELETE FROM `bans` WHERE id = %s' % ban['id']) logAction("Usuario %s desbaneado." % ban['ip'][:4]) regenerateAccess() bans = FetchAll('SELECT * FROM `bans` WHERE staff = \'anarko\'') for ban in bans: ban['added'] = formatTimestamp(ban['added']) if ban['until'] == '0': ban['until'] = _('Does not expire') else: ban['until'] = formatTimestamp(ban['until']) return renderTemplate('anarkia.html', {'mode': 5, 'bans': bans}) def mod(formdata): board = Settings._.BOARD if formdata.get('thread'): parentid = int(formdata['thread']) posts = FetchAll('SELECT * FROM `posts` WHERE (parentid = %d OR id = %d) AND boardid = %s ORDER BY `id` ASC' % (parentid, parentid, board['id'])) return renderTemplate('anarkia.html', {'mode': 3, 'posts': posts}) elif formdata.get('lock'): postid = int(formdata['lock']) post = FetchOne('SELECT id, locked FROM posts WHERE boardid = %s AND id = %d AND parentid = 0 LIMIT 1' % ( board['id'], postid)) if post['locked'] == '0': setLocked = 1 msg = "Hilo %s cerrado." % post['id'] else: setLocked = 0 msg = "Hilo %s abierto." % post['id'] UpdateDb("UPDATE `posts` SET `locked` = %d WHERE `boardid` = '%s' AND `id` = '%s' LIMIT 1" % ( setLocked, board["id"], post["id"])) threadUpdated(post['id']) logAction(msg) return renderTemplate('anarkia.html', {'mode': 99, 'msg': msg}) elif formdata.get('del'): postid = int(formdata['del']) post = FetchOne('SELECT id, parentid FROM posts WHERE boardid = %s AND id = %d LIMIT 1' % ( board['id'], postid)) if post['parentid'] != '0': deletePost(post['id'], None, '3', False) msg = "Mensaje %s eliminado." % post['id'] logAction(msg) return renderTemplate('anarkia.html', {'mode': 99, 'msg': msg}) else: raise UserError("jaj no") elif formdata.get('restore'): postid = int(formdata['restore']) post = FetchOne('SELECT id, parentid FROM posts WHERE boardid = %s AND id = %d LIMIT 1' % ( board['id'], postid)) UpdateDb('UPDATE `posts` SET `IS_DELETED` = 0 WHERE `boardid` = %s AND `id` = %s LIMIT 1' % ( board['id'], post['id'])) if post['parentid'] != '0': threadUpdated(post['parentid']) else: regenerateFrontPages() msg = "Mensaje %s recuperado." % post['id'] logAction(msg) return renderTemplate('anarkia.html', {'mode': 99, 'msg': msg}) elif formdata.get('ban'): postid = int(formdata['ban']) post = FetchOne('SELECT id, ip FROM posts WHERE boardid = %s AND id = %d LIMIT 1' % ( board['id'], postid)) return renderTemplate('anarkia.html', {'mode': 4, 'post': post}) elif formdata.get('banto'): postid = int(formdata['banto']) post = FetchOne('SELECT id, message, parentid, ip FROM posts WHERE boardid = %s AND id = %d LIMIT 1' % ( board['id'], postid)) reason = formdata.get('reason').replace( 'script', '').replace('meta', '') if reason is not None: if formdata['seconds'] != '0': until = str(timestamp() + int(formdata['seconds'])) else: until = '0' where = pickle.dumps(['anarkia']) ban = FetchOne("SELECT `id` FROM `bans` WHERE `ip` = '" + post['ip'] + "' AND `boards` = '" + _mysql.escape_string(where) + "' LIMIT 1") if ban: raise UserError("Este usuario ya esta baneado.") # Blind mode if formdata.get('blind') == '1': blind = '1' else: blind = '0' InsertDb("INSERT INTO `bans` (`ip`, `netmask`, `boards`, `added`, `until`, `staff`, `reason`, `blind`) VALUES ('" + post['ip'] + "', INET_ATON('255.255.255.255'), '" + _mysql.escape_string( where) + "', " + str(timestamp()) + ", " + until + ", 'anarko', '" + _mysql.escape_string(formdata['reason']) + "', '"+blind+"')") newmessage = post['message'] + \ '
A este usuario se le revocó el acceso. Razón: %s' % reason UpdateDb("UPDATE posts SET message = '%s' WHERE boardid = %s AND id = %s" % ( _mysql.escape_string(newmessage), board['id'], post['id'])) if post['parentid'] != '0': threadUpdated(post['parentid']) else: regenerateFrontPages() regenerateAccess() msg = "Usuario %s baneado." % post['ip'][:4] logAction(msg) return renderTemplate('anarkia.html', {'mode': 99, 'msg': msg}) else: reports = FetchAll("SELECT * FROM `reports` WHERE board = 'anarkia'") threads = FetchAll( 'SELECT * FROM `posts` WHERE boardid = %s AND parentid = 0 ORDER BY `bumped` DESC' % board['id']) return renderTemplate('anarkia.html', {'mode': 2, 'threads': threads, 'reports': reports}) def boardoptions(formdata): board = Settings._.BOARD if formdata.get('longname'): # submitted board['longname'] = formdata['longname'].replace('script', '') board['postarea_desc'] = formdata['postarea_desc'].replace( 'script', '').replace('meta', '') board['postarea_extra'] = formdata['postarea_extra'].replace( 'script', '').replace('meta', '') board['anonymous'] = formdata['anonymous'].replace('script', '') board['subject'] = formdata['subject'].replace('script', '') board['message'] = formdata['message'].replace('script', '') board['useid'] = formdata['useid'] if 'disable_name' in formdata: board['disable_name'] = '1' else: board['disable_name'] = '0' if 'disable_subject' in formdata: board['disable_subject'] = '1' else: board['disable_subject'] = '0' if 'allow_noimage' in formdata: board['allow_noimage'] = '1' else: board['allow_noimage'] = '0' if 'allow_images' in formdata: board['allow_images'] = '1' else: board['allow_images'] = '0' if 'allow_image_replies' in formdata: board['allow_image_replies'] = '1' else: board['allow_image_replies'] = '0' # Update file types UpdateDb("DELETE FROM `boards_filetypes` WHERE `boardid` = %s" % board['id']) for filetype in filetypelist(): if 'filetype'+filetype['ext'] in formdata: UpdateDb("INSERT INTO `boards_filetypes` VALUES (%s, %s)" % (board['id'], filetype['id'])) try: board['maxsize'] = int(formdata['maxsize']) if board['maxsize'] > 10000: board['maxsize'] = 10000 except: raise UserError(_("Max size must be numeric.")) try: board['thumb_px'] = int(formdata['thumb_px']) if board['thumb_px'] > 500: board['thumb_px'] = 500 except: raise UserError(_("Max thumb dimensions must be numeric.")) try: board['numthreads'] = int(formdata['numthreads']) if board['numthreads'] > 15: board['numthreads'] = 15 except: raise UserError(_("Max threads shown must be numeric.")) try: board['numcont'] = int(formdata['numcont']) if board['numcont'] > 15: board['numcont'] = 15 except: raise UserError(_("Max replies shown must be numeric.")) t = time.time() updateBoardSettings() setBoard('anarkia') regenerateBoard(True) tf = timeTaken(t, time.time()) msg = 'Opciones cambiadas. %s' % tf logAction(msg) return renderTemplate('anarkia.html', {'mode': 99, 'msg': msg}) else: return renderTemplate('anarkia.html', {'mode': 1, 'boardopts': board, 'filetypes': filetypelist(), 'supported_filetypes': board['filetypes_ext']}) def emojis(formdata): board = Settings._.BOARD board_pickle = _mysql.escape_string(pickle.dumps([board['dir']])) if formdata.get('new'): import re ext = {'image/jpeg': 'jpg', 'image/gif': 'gif', 'image/png': 'png'} if not formdata['name']: raise UserError, 'Ingresa nombre.' if not re.match(r"^[0-9a-zA-Z]+$", formdata['name']): raise UserError, 'Nombre inválido; solo letras/números.' name = ":%s:" % formdata['name'][:15] data = formdata['file'] if not data: raise UserError, 'Ingresa imagen.' # check if it exists already = FetchOne("SELECT 1 FROM `filters` WHERE `boards` = '%s' AND `from` = '%s'" % ( board_pickle, _mysql.escape_string(name))) if already: raise UserError, 'Este emoji ya existe.' # get image information content_type, width, height, size, extra = getImageInfo(data) if content_type not in ext.keys(): raise UserError, 'Formato inválido.' if width > 500 or height > 500: raise UserError, 'Dimensiones muy altas.' if size > 150000: raise UserError, 'Tamaño muy grande.' # create file names thumb_width, thumb_height = getThumbDimensions(width, height, 32) file_path = Settings.ROOT_DIR + \ board["dir"] + "/e/" + formdata['name'][:15] + \ '.' + ext[content_type] file_url = Settings.BOARDS_URL + \ board["dir"] + "/e/" + formdata['name'][:15] + \ '.' + ext[content_type] to_filter = '' % ( file_url, thumb_width, thumb_height) # start processing image args = [Settings.CONVERT_PATH, "-", "-limit", "thread", "1", "-resize", "%dx%d" % (thumb_width, thumb_height), "-quality", "80", file_path] p = subprocess.Popen(args, stdout=subprocess.PIPE, stdin=subprocess.PIPE, stderr=subprocess.PIPE) out = p.communicate(input=data)[0] # insert into DB sql = "INSERT INTO `filters` (`boards`, `type`, `action`, `from`, `to`, `staff`, `added`) VALUES ('%s', 0, 1, '%s', '%s', 'Anarko', '%s')" % ( board_pickle, _mysql.escape_string(name), _mysql.escape_string(to_filter), timestamp()) UpdateDb(sql) msg = "Emoji %s agregado." % name logAction(msg) return renderTemplate('anarkia.html', {'mode': 99, 'msg': msg}) elif formdata.get('del'): return renderTemplate('anarkia.html', {'mode': 99, 'msg': 'Del.'}) else: filters = FetchAll( "SELECT * FROM `filters` WHERE `boards` = '%s' ORDER BY `added` DESC" % board_pickle) return renderTemplate('anarkia.html', {'mode': 8, 'emojis': filters}) def filetypelist(): filetypes = FetchAll('SELECT * FROM `filetypes` ORDER BY `ext` ASC') return filetypes def logAction(action): InsertDb("INSERT INTO `logs` (`timestamp`, `staff`, `action`) VALUES (" + str(timestamp()) + ", 'Anarko', '" + _mysql.escape_string(action) + "')")