aboutsummaryrefslogtreecommitdiff
path: root/cgi/formatting.py
diff options
context:
space:
mode:
Diffstat (limited to 'cgi/formatting.py')
-rw-r--r--cgi/formatting.py784
1 files changed, 409 insertions, 375 deletions
diff --git a/cgi/formatting.py b/cgi/formatting.py
index 373d685..6461a33 100644
--- a/cgi/formatting.py
+++ b/cgi/formatting.py
@@ -14,412 +14,446 @@ from post import regenerateAccess
from settings import Settings
+
def format_post(message, ip, parentid, parent_timestamp=0):
- """
- Formats posts using the specified format
- """
- board = Settings._.BOARD
- using_markdown = False
-
- # Escape any HTML if user is not using Markdown or HTML
- if not Settings.USE_HTML:
- message = cgi.escape(message)
-
- # Strip text
- message = message.rstrip()[0:8000]
-
- # Treat HTML
- if Settings.USE_MARKDOWN:
- message = markdown(message)
- using_markdown = True
- if Settings.USE_HTML:
- message = onlyAllowedHTML(message)
-
- # [code] tag
- if board["dir"] == "tech":
- message = re.compile(r"\[code\](.+)\[/code\]", re.DOTALL | re.IGNORECASE).sub(r"<pre><code>\1</code></pre>", message)
- if board["allow_spoilers"]:
- message = re.compile(r"\[spoiler\](.+)\[/spoiler\]", re.DOTALL | re.IGNORECASE).sub(r'<span class="spoil">\1</span>', message)
-
- if Settings.VIDEO_THUMBS:
- (message, affected) = videoThumbs(message)
- #if affected:
- # message = close_html(message)
-
- message = clickableURLs(message)
- message = checkRefLinks(message, parentid, parent_timestamp)
- message = checkWordfilters(message, ip, board["dir"])
-
- # If not using markdown quotes must be created and \n changed for HTML line breaks
- if not using_markdown:
- message = re.compile(r"^(\n)+").sub('', message)
- message = checkQuotes(message)
- message = message.replace("\n", "<br />")
-
- return message
-
+ """
+ Formats posts using the specified format
+ """
+ board = Settings._.BOARD
+ using_markdown = False
+
+ # Escape any HTML if user is not using Markdown or HTML
+ if not Settings.USE_HTML:
+ message = cgi.escape(message)
+
+ # Strip text
+ message = message.rstrip()[0:8000]
+
+ # Treat HTML
+ if Settings.USE_MARKDOWN:
+ message = markdown(message)
+ using_markdown = True
+ if Settings.USE_HTML:
+ message = onlyAllowedHTML(message)
+
+ # [code] tag
+ if board["dir"] == "tech":
+ message = re.compile(r"\[code\](.+)\[/code\]", re.DOTALL |
+ re.IGNORECASE).sub(r"<pre><code>\1</code></pre>", message)
+ if board["allow_spoilers"]:
+ message = re.compile(r"\[spoiler\](.+)\[/spoiler\]", re.DOTALL |
+ re.IGNORECASE).sub(r'<span class="spoil">\1</span>', message)
+
+ if Settings.VIDEO_THUMBS:
+ (message, affected) = videoThumbs(message)
+ # if affected:
+ # message = close_html(message)
+
+ message = clickableURLs(message)
+ message = checkRefLinks(message, parentid, parent_timestamp)
+ message = checkWordfilters(message, ip, board["dir"])
+
+ # If not using markdown quotes must be created and \n changed for HTML line breaks
+ if not using_markdown:
+ message = re.compile(r"^(\n)+").sub('', message)
+ message = checkQuotes(message)
+ message = message.replace("\n", "<br />")
+
+ return message
+
+
def tripcode(name):
- """
- Calculate tripcode to match output of most imageboards
- """
- if name == '':
- return '', ''
-
- board = Settings._.BOARD
-
- name = name.decode('utf-8')
- key = Settings.TRIP_CHAR.decode('utf-8')
-
- # if there's a trip
- (namepart, marker, trippart) = name.partition('#')
- if marker:
- namepart = cleanString(namepart)
- trip = ''
-
- # secure tripcode
- if Settings.ALLOW_SECURE_TRIPCODES and '#' in trippart:
- (trippart, securemarker, securepart) = trippart.partition('#')
- try:
- securepart = securepart.encode("sjis", "ignore")
- except:
- pass
-
- # encode secure tripcode
- trip = getMD5(securepart + Settings.SECRET)
- trip = trip.encode('base64').replace('\n', '')
- trip = trip.encode('rot13')
- trip = key+key+trip[2:12]
-
- # return it if we don't have a normal tripcode
- if trippart == '':
+ """
+ Calculate tripcode to match output of most imageboards
+ """
+ if name == '':
+ return '', ''
+
+ board = Settings._.BOARD
+
+ name = name.decode('utf-8')
+ key = Settings.TRIP_CHAR.decode('utf-8')
+
+ # if there's a trip
+ (namepart, marker, trippart) = name.partition('#')
+ if marker:
+ namepart = cleanString(namepart)
+ trip = ''
+
+ # secure tripcode
+ if Settings.ALLOW_SECURE_TRIPCODES and '#' in trippart:
+ (trippart, securemarker, securepart) = trippart.partition('#')
+ try:
+ securepart = securepart.encode("sjis", "ignore")
+ except:
+ pass
+
+ # encode secure tripcode
+ trip = getMD5(securepart + Settings.SECRET)
+ trip = trip.encode('base64').replace('\n', '')
+ trip = trip.encode('rot13')
+ trip = key+key+trip[2:12]
+
+ # return it if we don't have a normal tripcode
+ if trippart == '':
+ return namepart.encode('utf-8'), trip.encode('utf-8')
+
+ # do normal tripcode
+ from crypt import crypt
+ try:
+ trippart = trippart.encode("sjis", "ignore")
+ except:
+ pass
+
+ trippart = cleanString(trippart, True, True)
+ salt = re.sub(r"[^\.-z]", ".", (trippart + "H..")[1:3])
+ salt = salt.translate(string.maketrans(r":;=?@[\]^_`", "ABDFGabcdef"))
+ trip = key + crypt(trippart, salt)[-10:] + trip
+
return namepart.encode('utf-8'), trip.encode('utf-8')
-
- # do normal tripcode
- from crypt import crypt
- try:
- trippart = trippart.encode("sjis", "ignore")
- except:
- pass
-
- trippart = cleanString(trippart, True, True)
- salt = re.sub(r"[^\.-z]", ".", (trippart + "H..")[1:3])
- salt = salt.translate(string.maketrans(r":;=?@[\]^_`", "ABDFGabcdef"))
- trip = key + crypt(trippart, salt)[-10:] + trip
-
- return namepart.encode('utf-8'), trip.encode('utf-8')
-
- return name.encode('utf-8'), ''
+
+ return name.encode('utf-8'), ''
+
def iphash(ip, post, t, useid, mobile, agent, cap_id, hide_end, has_countrycode):
- current_t = time.time()
-
- if cap_id:
- id = cap_id
- elif 'sage' in post['email'] and useid == '1':
- id = '???'
- elif ip == "127.0.0.1":
- id = '???'
- else:
- day = int((current_t + (Settings.TIME_ZONE*3600)) / 86400)
- word = ',' + str(day) # IDs change every 24 hours
- word += ',' + str(t) # IDs vary depending on thread
- id = hide_data(ip + word, 6, "id", Settings.SECRET)
-
- if hide_end:
- id += '*'
- elif addressIsTor(ip):
- id += 'T'
- elif 'Dalvik' in agent:
- id += 'R'
- elif 'Android' in agent:
- id += 'a'
- elif 'iPhone' in agent:
- id += 'i'
- elif useid == '3':
- if 'Firefox' in agent:
- id += 'F'
- elif 'Safari' in agent and not 'Chrome' in agent:
- id += 's'
- elif 'Chrome' in agent:
- id += 'C'
- elif 'SeaMonkey' in agent:
- id += 'S'
- elif 'Edge' in agent:
- id += 'E'
- elif 'Opera' in agent or 'OPR' in agent:
- id += 'o'
- elif 'MSIE' in agent or 'Trident' in agent:
- id += 'I'
+ current_t = time.time()
+
+ if cap_id:
+ id = cap_id
+ elif 'sage' in post['email'] and useid == '1':
+ id = '???'
+ elif ip == "127.0.0.1":
+ id = '???'
+ else:
+ day = int((current_t + (Settings.TIME_ZONE*3600)) / 86400)
+ word = ',' + str(day) # IDs change every 24 hours
+ word += ',' + str(t) # IDs vary depending on thread
+ id = hide_data(ip + word, 6, "id", Settings.SECRET)
+
+ if hide_end:
+ id += '*'
+ elif addressIsTor(ip):
+ id += 'T'
+ elif 'Dalvik' in agent:
+ id += 'R'
+ elif 'Android' in agent:
+ id += 'a'
+ elif 'iPhone' in agent:
+ id += 'i'
+ elif useid == '3':
+ if 'Firefox' in agent:
+ id += 'F'
+ elif 'Safari' in agent and not 'Chrome' in agent:
+ id += 's'
+ elif 'Chrome' in agent:
+ id += 'C'
+ elif 'SeaMonkey' in agent:
+ id += 'S'
+ elif 'Edge' in agent:
+ id += 'E'
+ elif 'Opera' in agent or 'OPR' in agent:
+ id += 'o'
+ elif 'MSIE' in agent or 'Trident' in agent:
+ id += 'I'
+ elif mobile:
+ id += 'Q'
+ else:
+ id += '0'
elif mobile:
- id += 'Q'
+ id += 'Q'
else:
- id += '0'
- elif mobile:
- id += 'Q'
- else:
- id += '0'
-
- if addressIsBanned(ip, ""):
- id += '#'
- elif (not has_countrycode and not addressIsTor(ip) and
- (addressIsProxy(ip) or not addressIsES(ip))):
- id += '!'
-
- return id
+ id += '0'
+
+ if addressIsBanned(ip, ""):
+ id += '#'
+ elif (not has_countrycode and not addressIsTor(ip) and
+ (addressIsProxy(ip) or not addressIsES(ip))):
+ id += '!'
+
+ return id
+
def cleanString(string, escape=True, quote=False):
- string = string.strip()
- if escape:
- string = cgi.escape(string, quote)
- return string
+ string = string.strip()
+ if escape:
+ string = cgi.escape(string, quote)
+ return string
+
def clickableURLs(message):
- # URL
- message = re.compile(r'( |^|:|\(|\[)((?:https?://|ftp://|mailto:|news:|irc:)[^\s<>()"]*?(?:\([^\s<>()"]*?\)[^\s<>()"]*?)*)((?:\s|<|>|"|\.|\|\]|!|\?|,|&#44;|&quot;)*(?:[\s<>()"]|$))', re.M).sub(r'\1<a href="\2" rel="nofollow" target="_blank">\2</a>\3', message)
- # Emails
- message = re.compile(r"( |^|:)([A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,6})", re.I | re.M).sub(r'\1<a href="mailto:\2" rel="nofollow">&lt;\2&gt;</a>', message)
+ # URL
+ message = re.compile(r'( |^|:|\(|\[)((?:https?://|ftp://|mailto:|news:|irc:)[^\s<>()"]*?(?:\([^\s<>()"]*?\)[^\s<>()"]*?)*)((?:\s|<|>|"|\.|\|\]|!|\?|,|&#44;|&quot;)*(?:[\s<>()"]|$))',
+ re.M).sub(r'\1<a href="\2" rel="nofollow" target="_blank">\2</a>\3', message)
+ # Emails
+ message = re.compile(r"( |^|:)([A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,6})", re.I | re.M).sub(
+ r'\1<a href="mailto:\2" rel="nofollow">&lt;\2&gt;</a>', message)
+
+ return message
+
- return message
-
def videoThumbs(message):
- # Youtube
- __RE = re.compile(r"^(?: +)?(https?://(?:www\.)?youtu(?:be\.com/watch\?v=|\.be/)([\w\-]+))(?: +)?$", re.M)
- matches = __RE.finditer(message)
- if matches:
- import json
- import urllib, urllib2
-
- v_ids = []
- videos = {}
-
- for match in matches:
- v_id = match.group(2)
- if v_id not in v_ids:
- v_ids.append(v_id)
- videos[v_id] = {
- 'span': match.span(0),
- 'url': match.group(1),
+ # Youtube
+ __RE = re.compile(
+ r"^(?: +)?(https?://(?:www\.)?youtu(?:be\.com/watch\?v=|\.be/)([\w\-]+))(?: +)?$", re.M)
+ matches = __RE.finditer(message)
+ if matches:
+ import json
+ import urllib
+ import urllib2
+
+ v_ids = []
+ videos = {}
+
+ for match in matches:
+ v_id = match.group(2)
+ if v_id not in v_ids:
+ v_ids.append(v_id)
+ videos[v_id] = {
+ 'span': match.span(0),
+ 'url': match.group(1),
+ }
+ if len(v_ids) >= Settings.VIDEO_THUMBS_LIMIT:
+ raise UserError, "Has incluído muchos videos en tu mensaje. El máximo es %d." % Settings.VIDEO_THUMBS_LIMIT
+
+ if videos:
+ params = {
+ 'key': Settings.GOOGLE_API_KEY,
+ 'part': 'snippet,contentDetails',
+ 'id': ','.join(v_ids)
}
- if len(v_ids) >= Settings.VIDEO_THUMBS_LIMIT:
- raise UserError, "Has incluído muchos videos en tu mensaje. El máximo es %d." % Settings.VIDEO_THUMBS_LIMIT
-
- if videos:
- params = {
- 'key': Settings.GOOGLE_API_KEY,
- 'part': 'snippet,contentDetails',
- 'id': ','.join(v_ids)
- }
- r_url = "https://www.googleapis.com/youtube/v3/videos?"+urllib.urlencode(params)
- res = urllib2.urlopen(r_url)
- res_json = json.load(res)
-
- offset = 0
- for item in res_json['items']:
- v_id = item['id']
- (start, end) = videos[v_id]['span']
- end += 1 # remove endline
-
- try:
- new_url = '<a href="%(url)s" target="_blank" class="yt"><span class="pvw"><img src="%(thumb)s" /></span><b>%(title)s</b> (%(secs)s)<br />%(channel)s</a><br />' \
- % {'title': item['snippet']['title'].encode('utf-8'),
- 'channel': item['snippet']['channelTitle'].encode('utf-8'),
- 'secs': parseIsoPeriod(item['contentDetails']['duration']).encode('utf-8'),
- 'url': videos[v_id]['url'],
- 'id': v_id.encode('utf-8'),
- 'thumb': item['snippet']['thumbnails']['default']['url'].encode('utf-8'),}
- except UnicodeDecodeError:
- raise UserError, repr(v_id)
- message = message[:start+offset] + new_url + message[end+offset:]
- offset += len(new_url) - (end-start)
-
- return (message, len(videos))
+ r_url = "https://www.googleapis.com/youtube/v3/videos?" + \
+ urllib.urlencode(params)
+ res = urllib2.urlopen(r_url)
+ res_json = json.load(res)
+
+ offset = 0
+ for item in res_json['items']:
+ v_id = item['id']
+ (start, end) = videos[v_id]['span']
+ end += 1 # remove endline
+
+ try:
+ new_url = '<a href="%(url)s" target="_blank" class="yt"><span class="pvw"><img src="%(thumb)s" /></span><b>%(title)s</b> (%(secs)s)<br />%(channel)s</a><br />' \
+ % {'title': item['snippet']['title'].encode('utf-8'),
+ 'channel': item['snippet']['channelTitle'].encode('utf-8'),
+ 'secs': parseIsoPeriod(item['contentDetails']['duration']).encode('utf-8'),
+ 'url': videos[v_id]['url'],
+ 'id': v_id.encode('utf-8'),
+ 'thumb': item['snippet']['thumbnails']['default']['url'].encode('utf-8'), }
+ except UnicodeDecodeError:
+ raise UserError, repr(v_id)
+ message = message[:start+offset] + new_url + message[end+offset:]
+ offset += len(new_url) - (end-start)
+
+ return (message, len(videos))
+
def fixMobileLinks(message):
- """
- Shorten long links; Convert >># links into a mobile version
- """
- board = Settings._.BOARD
-
- # If textboard
- if board["board_type"] == '1':
- message = re.compile(r'<a href="/(\w+)/read/(\d+)(\.html)?/*(.+)"').sub(r'<a href="/cgi/mobileread/\1/\2/\4"', message)
- else:
- message = re.compile(r'<a href="/(\w+)/res/(\d+)\.html#(\d+)"').sub(r'<a href="/cgi/mobileread/\1/\2#\3"', message)
-
- return message
-
+ """
+ Shorten long links; Convert >># links into a mobile version
+ """
+ board = Settings._.BOARD
+
+ # If textboard
+ if board["board_type"] == '1':
+ message = re.compile(r'<a href="/(\w+)/read/(\d+)(\.html)?/*(.+)"').sub(
+ r'<a href="/cgi/mobileread/\1/\2/\4"', message)
+ else:
+ message = re.compile(r'<a href="/(\w+)/res/(\d+)\.html#(\d+)"').sub(
+ r'<a href="/cgi/mobileread/\1/\2#\3"', message)
+
+ return message
+
+
def checkRefLinks(message, parentid, parent_timestamp):
- """
- Check for >># links in posts and replace with the HTML to make them clickable
- """
- board = Settings._.BOARD
-
- if board["board_type"] == '1':
- # Textboard
- if parentid != '0':
- message = re.compile(r'&gt;&gt;(\d+(,\d+|-(?=[ \d\n])|\d+)*n?)').sub('<a href="' + Settings.BOARDS_URL + board['dir'] + '/read/' + str(parent_timestamp) + r'/\1">&gt;&gt;\1</a>', message)
- else:
- # Imageboard
- quotes_id_array = re.findall(r"&gt;&gt;([0-9]+)", message)
- for quotes in quotes_id_array:
- try:
- post = FetchOne('SELECT * FROM `posts` WHERE `id` = ' + quotes + ' AND `boardid` = ' + board['id'] + ' LIMIT 1')
- if post['parentid'] != '0':
- message = re.compile("&gt;&gt;" + quotes).sub('<a href="' + Settings.BOARDS_URL + board['dir'] + '/res/' + post['parentid'] + '.html#' + quotes + '">&gt;&gt;' + quotes + '</a>', message)
- else:
- message = re.compile("&gt;&gt;" + quotes).sub('<a href="' + Settings.BOARDS_URL + board['dir'] + '/res/' + post['id'] + '.html#' + quotes + '">&gt;&gt;' + quotes + '</a>', message)
- except:
- message = re.compile("&gt;&gt;" + quotes).sub(r'<span class="q">&gt;&gt;'+quotes+'</span>', message)
-
- return message
+ """
+ Check for >># links in posts and replace with the HTML to make them clickable
+ """
+ board = Settings._.BOARD
+
+ if board["board_type"] == '1':
+ # Textboard
+ if parentid != '0':
+ message = re.compile(r'&gt;&gt;(\d+(,\d+|-(?=[ \d\n])|\d+)*n?)').sub(
+ '<a href="' + Settings.BOARDS_URL + board['dir'] + '/read/' + str(parent_timestamp) + r'/\1">&gt;&gt;\1</a>', message)
+ else:
+ # Imageboard
+ quotes_id_array = re.findall(r"&gt;&gt;([0-9]+)", message)
+ for quotes in quotes_id_array:
+ try:
+ post = FetchOne('SELECT * FROM `posts` WHERE `id` = ' +
+ quotes + ' AND `boardid` = ' + board['id'] + ' LIMIT 1')
+ if post['parentid'] != '0':
+ message = re.compile("&gt;&gt;" + quotes).sub('<a href="' + Settings.BOARDS_URL +
+ board['dir'] + '/res/' + post['parentid'] + '.html#' + quotes + '">&gt;&gt;' + quotes + '</a>', message)
+ else:
+ message = re.compile("&gt;&gt;" + quotes).sub('<a href="' + Settings.BOARDS_URL +
+ board['dir'] + '/res/' + post['id'] + '.html#' + quotes + '">&gt;&gt;' + quotes + '</a>', message)
+ except:
+ message = re.compile(
+ "&gt;&gt;" + quotes).sub(r'<span class="q">&gt;&gt;'+quotes+'</span>', message)
+
+ return message
+
def checkQuotes(message):
- """
- Check for >text in posts and add span around it to color according to the css
- """
- message = re.compile(r"^&gt;(.*)$", re.MULTILINE).sub(r'<span class="q">&gt;\1</span>', message)
- return message
+ """
+ Check for >text in posts and add span around it to color according to the css
+ """
+ message = re.compile(
+ r"^&gt;(.*)$", re.MULTILINE).sub(r'<span class="q">&gt;\1</span>', message)
+ return message
+
def escapeHTML(string):
- string = string.replace('<', '&lt;')
- string = string.replace('>', '&gt;')
- return string
+ string = string.replace('<', '&lt;')
+ string = string.replace('>', '&gt;')
+ return string
+
def onlyAllowedHTML(message):
- """
- Allow <b>, <i>, <u>, <strike>, and <pre> in posts, along with the special <aa>
- """
- message = sanitize_html(message)
- #message = re.compile(r"\[aa\](.+?)\[/aa\]", re.DOTALL | re.IGNORECASE).sub("<span class=\"sjis\">\\1</span>", message)
-
- return message
+ """
+ Allow <b>, <i>, <u>, <strike>, and <pre> in posts, along with the special <aa>
+ """
+ message = sanitize_html(message)
+ #message = re.compile(r"\[aa\](.+?)\[/aa\]", re.DOTALL | re.IGNORECASE).sub("<span class=\"sjis\">\\1</span>", message)
+
+ return message
+
def close_html(message):
- """
- Old retarded version of sanitize_html, it just closes open tags.
- """
- import BeautifulSoup
-
- message = message.encode('utf-8')
- soup = BeautifulSoup.BeautifulSoup(message)
+ """
+ Old retarded version of sanitize_html, it just closes open tags.
+ """
+ import BeautifulSoup
+
+ message = message.encode('utf-8')
+ soup = BeautifulSoup.BeautifulSoup(message)
+
+ return unicode(soup).replace('&#13;', '').encode('utf-8')
- return unicode(soup).replace('&#13;', '').encode('utf-8')
def sanitize_html(message, decode=True):
- """
- Clean the code and allow only a few safe tags.
- """
- import BeautifulSoup
-
- # Decode message from utf-8 if required
- if decode:
- message = message.decode('utf-8', 'replace')
-
- # Create HTML Cleaner with our allowed tags
- whitelist_tags = ["a","b","br","blink","code","del","em","i","marquee","root","strike","strong","sub","sup","u"]
- whitelist_attr = ["href"]
-
- soup = BeautifulSoup.BeautifulSoup(message)
-
- # Remove tags that aren't allowed
- for tag in soup.findAll():
- if not tag.name.lower() in whitelist_tags:
- tag.name = "span"
- tag.attrs = []
- else:
- for attr in [attr for attr in tag.attrs if attr not in whitelist_attr]:
- del tag[attr]
+ """
+ Clean the code and allow only a few safe tags.
+ """
+ import BeautifulSoup
+
+ # Decode message from utf-8 if required
+ if decode:
+ message = message.decode('utf-8', 'replace')
+
+ # Create HTML Cleaner with our allowed tags
+ whitelist_tags = ["a", "b", "br", "blink", "code", "del", "em",
+ "i", "marquee", "root", "strike", "strong", "sub", "sup", "u"]
+ whitelist_attr = ["href"]
+
+ soup = BeautifulSoup.BeautifulSoup(message)
+
+ # Remove tags that aren't allowed
+ for tag in soup.findAll():
+ if not tag.name.lower() in whitelist_tags:
+ tag.name = "span"
+ tag.attrs = []
+ else:
+ for attr in [attr for attr in tag.attrs if attr not in whitelist_attr]:
+ del tag[attr]
+
+ # We export the soup into a correct XHTML string
+ string = unicode(soup).encode('utf-8')
+ # We remove some anomalies we don't want
+ string = string.replace('<br/>', '<br />').replace('&#13;', '')
+
+ return string
- # We export the soup into a correct XHTML string
- string = unicode(soup).encode('utf-8')
- # We remove some anomalies we don't want
- string = string.replace('<br/>', '<br />').replace('&#13;', '')
-
- return string
def markdown(message):
- import markdown
- if message.strip() != "":
- #return markdown.markdown(message).rstrip("\n").rstrip("<br />")
- return markdown.markdown(message, extras=["cuddled-lists", "code-friendly"]).encode('utf-8')
- else:
- return ""
+ import markdown
+ if message.strip() != "":
+ # return markdown.markdown(message).rstrip("\n").rstrip("<br />")
+ return markdown.markdown(message, extras=["cuddled-lists", "code-friendly"]).encode('utf-8')
+ else:
+ return ""
+
def checkWordfilters(message, ip, board):
- fixed_ip = inet_aton(ip)
- wordfilters = FetchAll("SELECT * FROM `filters` WHERE `type` = '0' ORDER BY `id` ASC")
- for wordfilter in wordfilters:
- if wordfilter["boards"] != "":
- boards = pickle.loads(wordfilter["boards"])
- if wordfilter["boards"] == "" or board in boards:
- if wordfilter['action'] == '0':
- if not re.search(wordfilter['from'], message, re.DOTALL | re.IGNORECASE) is None:
- raise UserError, wordfilter['reason']
- elif wordfilter['action'] == '1':
- message = re.compile(wordfilter['from'], re.DOTALL | re.IGNORECASE).sub(wordfilter['to'], message)
- elif wordfilter['action'] == '2':
- # Ban
- if not re.search(wordfilter['from'], message, re.DOTALL | re.IGNORECASE) is None:
- if wordfilter['seconds'] != '0':
- until = str(timestamp() + int(wordfilter['seconds']))
- else:
- until = '0'
-
- InsertDb("INSERT INTO `bans` (`ip`, `boards`, `added`, `until`, `staff`, `reason`, `note`, `blind`) VALUES (" + \
- "'" + str(fixed_ip) + "', '" + _mysql.escape_string(wordfilter['boards']) + \
- "', " + str(timestamp()) + ", " + until + ", 'System', '" + _mysql.escape_string(wordfilter['reason']) + \
- "', 'Word Auto-ban', '"+_mysql.escape_string(wordfilter['blind'])+"')")
- regenerateAccess()
- raise UserError, wordfilter['reason']
- elif wordfilter['action'] == '3':
- if not re.search(wordfilter['from'], message, re.DOTALL | re.IGNORECASE) is None:
- raise UserError, '<meta http-equiv="refresh" content="%s;url=%s" />%s' % (wordfilter['redirect_time'], wordfilter['redirect_url'], wordfilter['reason'])
- return message
-
+ fixed_ip = inet_aton(ip)
+ wordfilters = FetchAll(
+ "SELECT * FROM `filters` WHERE `type` = '0' ORDER BY `id` ASC")
+ for wordfilter in wordfilters:
+ if wordfilter["boards"] != "":
+ boards = pickle.loads(wordfilter["boards"])
+ if wordfilter["boards"] == "" or board in boards:
+ if wordfilter['action'] == '0':
+ if not re.search(wordfilter['from'], message, re.DOTALL | re.IGNORECASE) is None:
+ raise UserError, wordfilter['reason']
+ elif wordfilter['action'] == '1':
+ message = re.compile(wordfilter['from'], re.DOTALL | re.IGNORECASE).sub(
+ wordfilter['to'], message)
+ elif wordfilter['action'] == '2':
+ # Ban
+ if not re.search(wordfilter['from'], message, re.DOTALL | re.IGNORECASE) is None:
+ if wordfilter['seconds'] != '0':
+ until = str(timestamp() + int(wordfilter['seconds']))
+ else:
+ until = '0'
+
+ InsertDb("INSERT INTO `bans` (`ip`, `boards`, `added`, `until`, `staff`, `reason`, `note`, `blind`) VALUES (" +
+ "'" + str(fixed_ip) + "', '" + _mysql.escape_string(wordfilter['boards']) +
+ "', " + str(timestamp()) + ", " + until + ", 'System', '" + _mysql.escape_string(wordfilter['reason']) +
+ "', 'Word Auto-ban', '"+_mysql.escape_string(wordfilter['blind'])+"')")
+ regenerateAccess()
+ raise UserError, wordfilter['reason']
+ elif wordfilter['action'] == '3':
+ if not re.search(wordfilter['from'], message, re.DOTALL | re.IGNORECASE) is None:
+ raise UserError, '<meta http-equiv="refresh" content="%s;url=%s" />%s' % (wordfilter['redirect_time'], wordfilter['redirect_url'], wordfilter['reason'])
+ return message
+
+
def checkNamefilters(name, tripcode, ip, board):
- namefilters = FetchAll("SELECT * FROM `filters` WHERE `type` = '1'")
-
- for namefilter in namefilters:
- if namefilter["boards"] != "":
- boards = pickle.loads(namefilter["boards"])
- if namefilter["boards"] == "" or board in boards:
- # check if this filter applies
- match = False
-
- if namefilter['from'] and namefilter['from_trip']:
- # both name and trip filter
- if re.search(namefilter['from'], name, re.DOTALL | re.IGNORECASE) and tripcode == namefilter['from_trip']:
- match = True
- elif namefilter['from'] and not namefilter['from_trip']:
- # name filter
- if re.search(namefilter['from'], name, re.DOTALL | re.IGNORECASE):
- match = True
- elif not namefilter['from'] and namefilter['from_trip']:
- # trip filter
- if tripcode == namefilter['from_trip']:
- match = True
-
- if match:
- # do action
- if namefilter['action'] == '0':
- raise UserError, namefilter['reason']
- elif namefilter['action'] == '1':
- name = namefilter['to']
- tripcode = ''
- return name, tripcode
- elif namefilter['action'] == '2':
- # Ban
- if namefilter['seconds'] != '0':
- until = str(timestamp() + int(namefilter['seconds']))
- else:
- until = '0'
-
- InsertDb("INSERT INTO `bans` (`ip`, `boards`, `added`, `until`, `staff`, `reason`, `note`, `blind`) VALUES (" + \
- "'" + _mysql.escape_string(ip) + "', '" + _mysql.escape_string(namefilter['boards']) + \
- "', " + str(timestamp()) + ", " + until + ", 'System', '" + _mysql.escape_string(namefilter['reason']) + \
- "', 'Name Auto-ban', '"+_mysql.escape_string(namefilter['blind'])+"')")
- regenerateAccess()
- raise UserError, namefilter['reason']
- elif namefilter['action'] == '3':
- raise UserError, '<meta http-equiv="refresh" content="%s;url=%s" />%s' % (namefilter['redirect_time'], namefilter['redirect_url'], namefilter['reason'])
- return name, tripcode
+ namefilters = FetchAll("SELECT * FROM `filters` WHERE `type` = '1'")
+
+ for namefilter in namefilters:
+ if namefilter["boards"] != "":
+ boards = pickle.loads(namefilter["boards"])
+ if namefilter["boards"] == "" or board in boards:
+ # check if this filter applies
+ match = False
+
+ if namefilter['from'] and namefilter['from_trip']:
+ # both name and trip filter
+ if re.search(namefilter['from'], name, re.DOTALL | re.IGNORECASE) and tripcode == namefilter['from_trip']:
+ match = True
+ elif namefilter['from'] and not namefilter['from_trip']:
+ # name filter
+ if re.search(namefilter['from'], name, re.DOTALL | re.IGNORECASE):
+ match = True
+ elif not namefilter['from'] and namefilter['from_trip']:
+ # trip filter
+ if tripcode == namefilter['from_trip']:
+ match = True
+
+ if match:
+ # do action
+ if namefilter['action'] == '0':
+ raise UserError, namefilter['reason']
+ elif namefilter['action'] == '1':
+ name = namefilter['to']
+ tripcode = ''
+ return name, tripcode
+ elif namefilter['action'] == '2':
+ # Ban
+ if namefilter['seconds'] != '0':
+ until = str(timestamp() + int(namefilter['seconds']))
+ else:
+ until = '0'
+
+ InsertDb("INSERT INTO `bans` (`ip`, `boards`, `added`, `until`, `staff`, `reason`, `note`, `blind`) VALUES (" +
+ "'" + _mysql.escape_string(ip) + "', '" + _mysql.escape_string(namefilter['boards']) +
+ "', " + str(timestamp()) + ", " + until + ", 'System', '" + _mysql.escape_string(namefilter['reason']) +
+ "', 'Name Auto-ban', '"+_mysql.escape_string(namefilter['blind'])+"')")
+ regenerateAccess()
+ raise UserError, namefilter['reason']
+ elif namefilter['action'] == '3':
+ raise UserError, '<meta http-equiv="refresh" content="%s;url=%s" />%s' % (namefilter['redirect_time'], namefilter['redirect_url'], namefilter['reason'])
+ return name, tripcode