예제 #1
0
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()
예제 #2
0
파일: datd.py 프로젝트: rihitosan/saku
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)
예제 #3
0
파일: keylib.py 프로젝트: namuyan/saku
    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')
예제 #4
0
파일: keylib.py 프로젝트: namuyan/saku
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()
예제 #5
0
파일: post.py 프로젝트: namuyan/saku
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()
예제 #6
0
파일: datd.py 프로젝트: rihitosan/saku
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
예제 #7
0
파일: dat.py 프로젝트: namuyan/saku
    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}(&gt;&gt;{no} {url})]]'.format(title=_title,
                                                            no=no,
                                                            url=url)
예제 #8
0
파일: post.py 프로젝트: namuyan/saku
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')]