def post_comment(thread_key, name, mail, body, passwd, tag=None): """Post article.""" stamp = int(time.time()) recbody = {} if body != '': recbody['body'] = gateway.CGI.escape(None, body) if name != '': recbody['name'] = gateway.CGI.escape(None, name) if mail != '': recbody['mail'] = gateway.CGI.escape(None, mail) c = cache.Cache(thread_key) rec = cache.Record(datfile=c.datfile) id = rec.build(stamp, recbody, passwd=passwd) if spam.check(rec.recstr): raise SpamError() # utils.log('post %s/%d_%s' % (c.datfile, stamp, id)) c.add_data(rec) c.sync_status() if tag: utils.save_tag(c, tag) queue = updatequeue.UpdateQueue() queue.append(c.datfile, stamp, id, None) queue.start()
def thread_app(env, resp): path = env['PATH_INFO'] # utils.log('thread_app', path) m = thread_re.match(path) board, datkey = m.group(1), m.group(2) key = keylib.get_filekey(datkey) data = cache.Cache(key) data.load() if check_get_cache(env): if not data.exists() or len(data) == 0: # when first access, load data from network data.search() elif _count_is_update(key): # update thread # limit `data.search` calling. it's slow! threading.Thread(target=data.search, daemon=True).start() if not data.exists(): resp('404 Not Found', [('Content-Type', 'text/plain; charset=Shift_JIS')]) return [b'404 Not Found'] thread = dat.make_dat(data, env, board) headers = Headers([('Content-Type', 'text/plain; charset=Shift_JIS')]) last_m = eutils.formatdate(data.stamp) headers['Last-Modified'] = last_m resp("200 OK", headers.items()) return (c.encode('cp932', 'replace') for c in thread)
def get_datkey(self, filekey): if filekey in self.filekey2datkey: return self.filekey2datkey[filekey] # because saku don't have this cache at start c = cache.Cache(filekey) c.load() self.set_from_cache(c) self.save() # don't lose entry if filekey in self.filekey2datkey: return self.filekey2datkey[filekey] raise DatkeyNotFound(filekey + ' not found')
def load(): _datkey_table.load() for c in cache.CacheList(): c.load() _datkey_table.set_from_cache(c) # Because CacheList don't list all cache for rec in cache.RecentList(): c = cache.Cache(rec.datfile) c.load() c.recent_stamp = rec.stamp # if cache has no records, use recent_stamp _datkey_table.set_from_cache(c) save()
def post_comment(env, thread_key, name, mail, body, passwd, tag=None): """Post article.""" if config.server_name: dat_host = config.server_name else: host = env['HTTP_HOST'] dat_host = re.sub(r':\d+', ':' + str(config.dat_port), host) p = re.compile(r'https?://' + dat_host + '/test/read.cgi/2ch(?:_[0-9A-Z]+)?/([0-9]+)/') for x in p.finditer(body): try: file = keylib.get_filekey(x.group(1)) body = body.replace(x.group(0), '[[' + title.file_decode(file) + ']]') except keylib.DatkeyNotFound: pass stamp = int(time.time()) recbody = {} if body != '': recbody['body'] = gateway.CGI.escape(None, body) if name != '': recbody['name'] = gateway.CGI.escape(None, name) if mail != '': recbody['mail'] = gateway.CGI.escape(None, mail) c = cache.Cache(thread_key) rec = cache.Record(datfile=c.datfile) id = rec.build(stamp, recbody, passwd=passwd) if spam.check(rec.recstr): raise SpamError() # utils.log('post %s/%d_%s' % (c.datfile, stamp, id)) c.add_data(rec) c.sync_status() if tag: utils.save_tag(c, tag) queue = updatequeue.UpdateQueue() queue.append(c.datfile, stamp, id, None) queue.start()
def make_subject_cachelist(board): """Make RecentList&CacheList""" recentlist = cache.RecentList() cachelist = cache.CacheList() seen = set(c.datfile for c in cachelist) result = cachelist for rec in recentlist: if rec.datfile not in seen: seen.add(rec.datfile) c = cache.Cache(rec.datfile) c.recent_stamp = rec.stamp result.append(c) result = [c for c in result if c.type == 'thread'] # same as order recent page result.sort(key=lambda c: c.recent_stamp, reverse=True) if board is not None: sugtags = tag.SuggestedTagTable() result = [c for c in result if has_tag(c, board, sugtags)] return result
def replace(match): link = match.group(1) # saku's link format for r in (r"^(?P<title>[^/]+)$", r"^/(?P<type>[a-z]+)/(?P<title>[^/]+)$", r"^(?P<title>[^/]+)/(?P<id>[0-9a-f]{8})$", r"^/(?P<type>[a-z]+)/(?P<title>[^/]+)/(?P<id>[0-9a-f]{8})$"): m = re.match(r, link) if m: d = m.groupdict() _title = d['title'] type = d.get('type', None) id = d.get('id', None) break else: return match.group(0) if not type: type = 'thread' file = title.file_encode(type, _title) datkey = keylib.get_datkey(file) if id is None: # same `board` is required for the dedicated browser to work properly url = 'http://{}/test/read.cgi/{}/{}/'.format( dat_host, board, datkey) return '[[{title}({url})]]'.format(title=_title, url=url) else: # anchor to specific comment cache = cachelib.Cache(file) table = ResTable(cache) no = table[id] # this format url expect that dedicated browser get res number url = 'http://{}/test/read.cgi/{}/{}/{}'.format( dat_host, board, datkey, no) return '[[{title}(>>{no} {url})]]'.format(title=_title, no=no, url=url)
def post_comment_app(env, resp): # print('post', env) if env['REQUEST_METHOD'] != 'POST': resp("404 Not Found", [('Content-Type', 'text/plain')]) return [b'404 Not Found'] # utils.log('post_comment_app') subject, name, mail, body, datkey = _get_comment_data(env) info = { 'host': env.get('REMOTE_ADDR', ''), 'name': name, 'mail': mail, 'body': body } if body == '': return error_resp('本文がありません.', resp, **info) if subject: key = title.file_encode('thread', subject) else: key = keylib.get_filekey(datkey) has_auth = env.get('shingetsu.isadmin', False) or env.get( 'shingetsu.isfriend', False) referer = env.get('HTTP_REFERER', '') m = re.search(r'/2ch_([^/]+)/', referer) tag = None if m and has_auth: tag = title.file_decode('dummy_' + m.group(1)) if cache.Cache(key).exists(): pass elif has_auth: pass elif subject: return error_resp('掲示版を作る権限がありません', resp, **info) else: return error_resp('掲示版がありません', resp, **info) if (not subject and not key): return error_resp('フォームが変です.', resp, **info) table = dat.ResTable(cache.Cache(key)) def replace(match): no = int(match.group(1)) return '>>' + table[no] # replace number anchor to id anchor body = re.sub(r'>>([1-9][0-9]*)', replace, body) # before escape '>>' if name.find('#') < 0: passwd = '' else: name, passwd = name.split('#', 1) if (passwd and not env['shingetsu.isadmin']): return error_resp('自ノード以外で署名機能は使えません', resp, **info) try: post_comment(env, key, name, mail, body, passwd, tag) except SpamError: return error_resp('スパムとみなされました', resp, **info) resp('200 OK', [('Content-Type', 'text/html; charset=Shift_JIS')]) return [success_msg.encode('cp932', 'replace')]