hopefully the the next-generation backend server of bgm.tv

Related tags

Network server
Overview

基于 python 的新 api server

开发环境

python 版本: 3.8

依赖管理: poetry

web 框架: fastapi

quick start:

git clone https://github.com/bangumi/server bangumi-server
cd bangumi-server
python -m venv .venv # MUST use python 3.8
source .venv/bin/activate
poetry install --remove-untracked
pre-commit install

设置

可设置的环境变量

  • MYSQL_HOST 默认 127.0.0.1
  • MYSQL_PORT 默认 3306
  • MYSQL_DB 默认 bangumi
  • MYSQL_USER 无默认值
  • MYSQL_PASS 无默认值

启动服务器

uvicorn pol.server:app --reload --port 3000

后端环境

https://github.com/bangumi/dev-env

测试(需要数据库)

pytest

代码风格

以 LF 为换行符

python

启用 pre-commit

pre-commit insall

pre-commit 会在当前仓库安装一个 git hook,在每次 commit 前自动运行。

也可以手动运行

pre-commit run #only check changed files
pre-commit run --all-files # check all files

lint: flake8

配置文件

非 python 文件(yaml, json, markdown 等)使用 prettier 进行格式化。

Issues
  • feat: redirect to image by id and type

    feat: redirect to image by id and type

    重定向至条目图片

    GET /v0/subjects/{subject_id}/image

    Request Query:

    • type: {small|grid|large|medium|common}

    Response: 302 image_url

    重定向至角色图片

    GET /v0/characters/{character_id}/image

    Request Query:

    • type: {small|grid|large|medium}

    Response: 302 image_url

    重定向至人物图片

    GET /v0/persons/{person_id}/image

    Request Query:

    • type: {small|grid|large|medium}

    Response: 302 image_url

    close #31

    opened by FDKevin0 15
  • 应用崩溃

    应用崩溃

    今天看错误日志看到有服务重启,检查了下log,没明白是为啥发生的。

    对应的是这个 commit https://github.com/bangumi/server/tree/v0.17.1

    runtime: marked free object in span 0x7fbb8e183db8, elemsize=2048 freeindex=1 (bad use of unsafe.Pointer? try -d=checkptr)
    0xc000724000 alloc marked  
    0xc000724800 free  unmarked
    0xc000725000 free  marked   zombie
    0x000000c000725000:  0x0000000000000000  0x0000000000000000 
    0x000000c000725010:  0x0000000000000000  0x0000000000000000 
    0x000000c000725020:  0x0000000000000000  0x0000000000000000 
    0x000000c000725030:  0x0000000000000000  0x0000000000000000 
    0x000000c000725040:  0x0000000000000000  0x0000000000000000 
    0x000000c000725050:  0x0000000000000000  0x0000000000000000 
    0x000000c000725060:  0x0000000000000000  0x0000000000000000 
    0x000000c000725070:  0x0000000000000000  0x0000000000000000 
    0x000000c000725080:  0x0000000000000000  0x0000000000000000 
    0x000000c000725090:  0x0000000000000000  0x0000000000000000 
    0x000000c0007250a0:  0x0000000000000000  0x0000000000000000 
    0x000000c0007250b0:  0x0000000000000000  0x0000000000000000 
    0x000000c0007250c0:  0x0000000000000000  0x0000000000000000 
    0x000000c0007250d0:  0x0000000000000000  0x0000000000000000 
    0x000000c0007250e0:  0x0000000000000000  0x0000000000000000 
    0x000000c0007250f0:  0x0000000000000000  0x0000000000000000 
    0x000000c000725100:  0x0000000000000000  0x0000000000000000 
    0x000000c000725110:  0x0000000000000000  0x0000000000000000 
    0x000000c000725120:  0x0000000000000000  0x0000000000000000 
    0x000000c000725130:  0x0000000000000000  0x0000000000000000 
    0x000000c000725140:  0x0000000000000000  0x0000000000000000 
    0x000000c000725150:  0x0000000000000000  0x0000000000000000 
    0x000000c000725160:  0x0000000000000000  0x0000000000000000 
    0x000000c000725170:  0x0000000000000000  0x0000000000000000 
    0x000000c000725180:  0x0000000000000000  0x0000000000000000 
    0x000000c000725190:  0x0000000000000000  0x0000000000000000 
    0x000000c0007251a0:  0x0000000000000000  0x0000000000000000 
    0x000000c0007251b0:  0x0000000000000000  0x0000000000000000 
    0x000000c0007251c0:  0x0000000000000000  0x0000000000000000 
    0x000000c0007251d0:  0x0000000000000000  0x0000000000000000 
    0x000000c0007251e0:  0x0000000000000000  0x0000000000000000 
    0x000000c0007251f0:  0x0000000000000000  0x0000000000000000 
    0x000000c000725200:  0x0000000000000000  0x0000000000000000 
    0x000000c000725210:  0x0000000000000000  0x0000000000000000 
    0x000000c000725220:  0x0000000000000000  0x0000000000000000 
    0x000000c000725230:  0x0000000000000000  0x0000000000000000 
    0x000000c000725240:  0x0000000000000000  0x0000000000000000 
    0x000000c000725250:  0x0000000000000000  0x0000000000000000 
    0x000000c000725260:  0x0000000000000000  0x0000000000000000 
    0x000000c000725270:  0x0000000000000000  0x0000000000000000 
    0x000000c000725280:  0x0000000000000000  0x0000000000000000 
    0x000000c000725290:  0x0000000000000000  0x0000000000000000 
    0x000000c0007252a0:  0x0000000000000000  0x0000000000000000 
    0x000000c0007252b0:  0x0000000000000000  0x0000000000000000 
    0x000000c0007252c0:  0x0000000000000000  0x0000000000000000 
    0x000000c0007252d0:  0x0000000000000000  0x0000000000000000 
    0x000000c0007252e0:  0x0000000000000000  0x0000000000000000 
    0x000000c0007252f0:  0x0000000000000000  0x0000000000000000 
    0x000000c000725300:  0x0000000000000000  0x0000000000000000 
    0x000000c000725310:  0x0000000000000000  0x0000000000000000 
    0x000000c000725320:  0x0000000000000000  0x0000000000000000 
    0x000000c000725330:  0x0000000000000000  0x0000000000000000 
    0x000000c000725340:  0x0000000000000000  0x0000000000000000 
    0x000000c000725350:  0x0000000000000000  0x0000000000000000 
    0x000000c000725360:  0x0000000000000000  0x0000000000000000 
    0x000000c000725370:  0x0000000000000000  0x0000000000000000 
    0x000000c000725380:  0x0000000000000000  0x0000000000000000 
    0x000000c000725390:  0x0000000000000000  0x0000000000000000 
    0x000000c0007253a0:  0x0000000000000000  0x0000000000000000 
    0x000000c0007253b0:  0x0000000000000000  0x0000000000000000 
    0x000000c0007253c0:  0x0000000000000000  0x0000000000000000 
    0x000000c0007253d0:  0x0000000000000000  0x0000000000000000 
    0x000000c0007253e0:  0x0000000000000000  0x0000000000000000 
    0x000000c0007253f0:  0x0000000000000000  0x0000000000000000 
    0xc000725800 free  unmarked
    fatal error: found pointer to free object
    runtime stack:
    runtime.throw({0x113fa1f, 0xc000725400})
    	/opt/hostedtoolcache/go/1.17.10/x64/src/runtime/panic.go:1198 +0x71
    runtime.(*mspan).reportZombies(0x7fbb8e183db8)
    	/opt/hostedtoolcache/go/1.17.10/x64/src/runtime/mgcsweep.go:691 +0x2e5
    runtime.(*sweepLocked).sweep(0x0, 0x0)
    	/opt/hostedtoolcache/go/1.17.10/x64/src/runtime/mgcsweep.go:519 +0x33a
    runtime.(*mcentral).uncacheSpan(0xc000061e60, 0xc000061e50)
    	/opt/hostedtoolcache/go/1.17.10/x64/src/runtime/mcentral.go:223 +0xa9
    runtime.(*mcache).releaseAll(0x7fbbb4f59108)
    	/opt/hostedtoolcache/go/1.17.10/x64/src/runtime/mcache.go:279 +0x125
    runtime.(*mcache).prepareForSweep(0x7fbbb4f59108)
    	/opt/hostedtoolcache/go/1.17.10/x64/src/runtime/mcache.go:317 +0x39
    runtime.procresize(0x2)
    	/opt/hostedtoolcache/go/1.17.10/x64/src/runtime/proc.go:5060 +0x476
    runtime.startTheWorldWithSema(0x1)
    	/opt/hostedtoolcache/go/1.17.10/x64/src/runtime/proc.go:1256 +0x8b
    runtime.gcMarkTermination.func3()
    	/opt/hostedtoolcache/go/1.17.10/x64/src/runtime/mgc.go:1032 +0x1e
    runtime.systemstack()
    	/opt/hostedtoolcache/go/1.17.10/x64/src/runtime/asm_amd64.s:383 +0x49
    goroutine 5 [running]:
    runtime.systemstack_switch()
    	/opt/hostedtoolcache/go/1.17.10/x64/src/runtime/asm_amd64.s:350 fp=0xc000048560 sp=0xc000048558 pc=0x464a60
    runtime.gcMarkTermination(0x1c38fa0)
    	/opt/hostedtoolcache/go/1.17.10/x64/src/runtime/mgc.go:1032 +0x4fa fp=0xc000048708 sp=0xc000048560 pc=0x41b93a
    runtime.gcMarkDone()
    	/opt/hostedtoolcache/go/1.17.10/x64/src/runtime/mgc.go:902 +0x27d fp=0xc000048760 sp=0xc000048708 pc=0x41b33d
    runtime.gcBgMarkWorker()
    	/opt/hostedtoolcache/go/1.17.10/x64/src/runtime/mgc.go:1330 +0x2f1 fp=0xc0000487e0 sp=0xc000048760 pc=0x41c4d1
    runtime.goexit()
    	/opt/hostedtoolcache/go/1.17.10/x64/src/runtime/asm_amd64.s:1581 +0x1 fp=0xc0000487e8 sp=0xc0000487e0 pc=0x466b41
    created by runtime.gcBgMarkStartWorkers
    	/opt/hostedtoolcache/go/1.17.10/x64/src/runtime/mgc.go:1124 +0x25
    goroutine 1 [chan receive, 359 minutes]:
    go.uber.org/fx.(*App).run(0xc00007f380, 0x0)
    	/home/runner/go/pkg/mod/go.uber.org/[email protected]/app.go:618 +0x91
    go.uber.org/fx.(*App).Run(0xc00007f380)
    	/home/runner/go/pkg/mod/go.uber.org/[email protected]/app.go:605 +0x2b
    main.start()
    	/home/runner/work/server/server/main.go:89 +0x615
    main.main()
    	/home/runner/work/server/server/main.go:48 +0x2b
    goroutine 22 [select, 2 minutes]:
    github.com/uber-go/tally/v4.(*scope).reportLoop(0xc000414900, 0x0)
    	/home/runner/go/pkg/mod/github.com/uber-go/tally/[email protected]/scope.go:238 +0xd6
    github.com/uber-go/tally/v4.newRootScope.func1()
    	/home/runner/go/pkg/mod/github.com/uber-go/tally/[email protected]/scope.go:180 +0x65
    created by github.com/uber-go/tally/v4.newRootScope
    	/home/runner/go/pkg/mod/github.com/uber-go/tally/[email protected]/scope.go:178 +0x78d
    goroutine 25 [select, 359 minutes]:
    database/sql.(*DB).connectionOpener(0xc0000a4c30, {0x139ded0, 0xc00065c140})
    	/opt/hostedtoolcache/go/1.17.10/x64/src/database/sql/sql.go:1196 +0x93
    created by database/sql.OpenDB
    	/opt/hostedtoolcache/go/1.17.10/x64/src/database/sql/sql.go:794 +0x188
    goroutine 26 [select, 2 minutes]:
    github.com/go-sql-driver/mysql.(*mysqlConn).startWatcher.func1()
    	/home/runner/go/pkg/mod/github.com/go-sql-driver/[email protected]/connection.go:614 +0xb0
    created by github.com/go-sql-driver/mysql.(*mysqlConn).startWatcher
    	/home/runner/go/pkg/mod/github.com/go-sql-driver/[email protected]/connection.go:611 +0x105
    goroutine 27 [select, 359 minutes]:
    database/sql.(*DB).connectionCleaner(0xc0000a4c30, 0x0)
    	/opt/hostedtoolcache/go/1.17.10/x64/src/database/sql/sql.go:1068 +0xbd
    created by database/sql.(*DB).startCleanerLocked
    	/opt/hostedtoolcache/go/1.17.10/x64/src/database/sql/sql.go:1055 +0x105
    goroutine 30 [select, 2 minutes]:
    github.com/go-redis/redis/v8/internal/pool.(*ConnPool).reaper(0xc0005c7860, 0xc0000b9860)
    	/home/runner/go/pkg/mod/github.com/go-redis/redis/[email protected]/internal/pool/pool.go:485 +0xda
    created by github.com/go-redis/redis/v8/internal/pool.NewConnPool
    	/home/runner/go/pkg/mod/github.com/go-redis/redis/[email protected]/internal/pool/pool.go:111 +0x229
    goroutine 35 [IO wait, 2 minutes]:
    internal/poll.runtime_pollWait(0x7fbb8e2f6278, 0x72)
    	/opt/hostedtoolcache/go/1.17.10/x64/src/runtime/netpoll.go:303 +0x85
    internal/poll.(*pollDesc).wait(0xc000684000, 0xc0006e9000, 0x0)
    	/opt/hostedtoolcache/go/1.17.10/x64/src/internal/poll/fd_poll_runtime.go:84 +0x32
    internal/poll.(*pollDesc).waitRead(...)
    	/opt/hostedtoolcache/go/1.17.10/x64/src/internal/poll/fd_poll_runtime.go:89
    internal/poll.(*FD).Read(0xc000684000, {0xc0006e9000, 0x1000, 0x1000})
    	/opt/hostedtoolcache/go/1.17.10/x64/src/internal/poll/fd_unix.go:167 +0x25a
    net.(*netFD).Read(0xc000684000, {0xc0006e9000, 0xc000684000, 0xc000778000})
    	/opt/hostedtoolcache/go/1.17.10/x64/src/net/fd_posix.go:56 +0x29
    net.(*conn).Read(0xc0006e6008, {0xc0006e9000, 0xfd7000, 0xc0006f9350})
    	/opt/hostedtoolcache/go/1.17.10/x64/src/net/net.go:183 +0x45
    bufio.(*Reader).fill(0xc0006fe300)
    	/opt/hostedtoolcache/go/1.17.10/x64/src/bufio/bufio.go:101 +0x103
    bufio.(*Reader).Peek(0xc0006fe300, 0x1)
    	/opt/hostedtoolcache/go/1.17.10/x64/src/bufio/bufio.go:139 +0x5d
    github.com/valyala/fasthttp.(*Server).serveConn(0xc00065ab40, {0x13b9990, 0xc0006e6008})
    	/home/runner/go/pkg/mod/github.com/valyala/[email protected]/server.go:2155 +0x5d1
    github.com/valyala/fasthttp.(*workerPool).workerFunc(0xc0007fe000, 0xc0006ec000)
    	/home/runner/go/pkg/mod/github.com/valyala/[email protected]/workerpool.go:224 +0xa9
    github.com/valyala/fasthttp.(*workerPool).getCh.func1()
    	/home/runner/go/pkg/mod/github.com/valyala/[email protected]/workerpool.go:196 +0x38
    created by github.com/valyala/fasthttp.(*workerPool).getCh
    	/home/runner/go/pkg/mod/github.com/valyala/[email protected]/workerpool.go:195 +0x1b5
    goroutine 8 [syscall, 359 minutes]:
    os/signal.signal_recv()
    	/opt/hostedtoolcache/go/1.17.10/x64/src/runtime/sigqueue.go:169 +0x98
    os/signal.loop()
    	/opt/hostedtoolcache/go/1.17.10/x64/src/os/signal/signal_unix.go:24 +0x19
    created by os/signal.Notify.func1.1
    	/opt/hostedtoolcache/go/1.17.10/x64/src/os/signal/signal.go:151 +0x2c
    goroutine 11 [sleep, 2 minutes]:
    time.Sleep(0x2540be400)
    	/opt/hostedtoolcache/go/1.17.10/x64/src/runtime/time.go:193 +0x12e
    github.com/valyala/fasthttp.(*workerPool).Start.func2()
    	/home/runner/go/pkg/mod/github.com/valyala/[email protected]/workerpool.go:67 +0x56
    created by github.com/valyala/fasthttp.(*workerPool).Start
    	/home/runner/go/pkg/mod/github.com/valyala/[email protected]/workerpool.go:59 +0xde
    goroutine 10 [IO wait, 2 minutes]:
    internal/poll.runtime_pollWait(0x7fbb8e2f6368, 0x72)
    	/opt/hostedtoolcache/go/1.17.10/x64/src/runtime/netpoll.go:303 +0x85
    internal/poll.(*pollDesc).wait(0xc0007bad00, 0xc000040800, 0x0)
    	/opt/hostedtoolcache/go/1.17.10/x64/src/internal/poll/fd_poll_runtime.go:84 +0x32
    internal/poll.(*pollDesc).waitRead(...)
    	/opt/hostedtoolcache/go/1.17.10/x64/src/internal/poll/fd_poll_runtime.go:89
    internal/poll.(*FD).Accept(0xc0007bad00)
    	/opt/hostedtoolcache/go/1.17.10/x64/src/internal/poll/fd_unix.go:402 +0x22c
    net.(*netFD).accept(0xc0007bad00)
    	/opt/hostedtoolcache/go/1.17.10/x64/src/net/fd_unix.go:173 +0x35
    net.(*TCPListener).accept(0xc0003e45b8)
    	/opt/hostedtoolcache/go/1.17.10/x64/src/net/tcpsock_posix.go:140 +0x28
    net.(*TCPListener).Accept(0xc0003e45b8)
    	/opt/hostedtoolcache/go/1.17.10/x64/src/net/tcpsock.go:262 +0x3d
    github.com/valyala/fasthttp.acceptConn(0xc00065ab40, {0x1395818, 0xc0003e45b8}, 0xc000804e80)
    	/home/runner/go/pkg/mod/github.com/valyala/[email protected]/server.go:1913 +0x62
    github.com/valyala/fasthttp.(*Server).Serve(0xc00065ab40, {0x1395818, 0xc0003e45b8})
    	/home/runner/go/pkg/mod/github.com/valyala/[email protected]/server.go:1826 +0x4ea
    github.com/gofiber/fiber/v2.(*App).Listener(0xc00000a780, {0x1395818, 0xc0003e45b8})
    	/home/runner/go/pkg/mod/github.com/gofiber/fiber/[email protected]/app.go:776 +0xd0
    github.com/bangumi/server/internal/web.Listen.func1.1()
    	/home/runner/work/server/server/internal/web/index.go:88 +0x37
    created by github.com/bangumi/server/internal/web.Listen.func1
    	/home/runner/work/server/server/internal/web/index.go:87 +0x1da
    goroutine 39 [sleep]:
    time.Sleep(0x3b9aca00)
    	/opt/hostedtoolcache/go/1.17.10/x64/src/runtime/time.go:193 +0x12e
    github.com/valyala/fasthttp.updateServerDate.func1()
    	/home/runner/go/pkg/mod/github.com/valyala/[email protected]/header.go:2050 +0x1e
    created by github.com/valyala/fasthttp.updateServerDate
    	/home/runner/go/pkg/mod/github.com/valyala/[email protected]/header.go:2048 +0x27
    goroutine 22000 [select, 2 minutes]:
    github.com/go-sql-driver/mysql.(*mysqlConn).startWatcher.func1()
    	/home/runner/go/pkg/mod/github.com/go-sql-driver/[email protected]/connection.go:614 +0xb0
    created by github.com/go-sql-driver/mysql.(*mysqlConn).startWatcher
    	/home/runner/go/pkg/mod/github.com/go-sql-driver/[email protected]/connection.go:611 +0x105
    goroutine 32742 [chan receive, 2 minutes]:
    github.com/valyala/fasthttp.(*workerPool).workerFunc(0xc0007fe000, 0xc0003380c0)
    	/home/runner/go/pkg/mod/github.com/valyala/[email protected]/workerpool.go:219 +0x65
    github.com/valyala/fasthttp.(*workerPool).getCh.func1()
    	/home/runner/go/pkg/mod/github.com/valyala/[email protected]/workerpool.go:196 +0x38
    created by github.com/valyala/fasthttp.(*workerPool).getCh
    	/home/runner/go/pkg/mod/github.com/valyala/[email protected]/workerpool.go:195 +0x1b5
    
    
    help wanted 
    opened by Trim21 10
  • feat(api): subject api

    feat(api): subject api

    条目

    GET /v0/subjects/{subject_id}

    {
      "id": 8,
      "type": 2,
      "name": "コードギアス 反逆のルルーシュR2",
      "name_cn": "Code Geass 反叛的鲁路修R2",
      "summary": "  “东京决战”一年后,布里塔尼亚少年鲁路修在11区(原日本国)过着平凡的学生生活。但是,鲁路修与弟弟罗洛的一次出行,遇到了黑色骑士团的余党。在与少女C.C再次结成契约之后,尘封的记忆摆在了鲁路修的面前。\r\n  身为帝国王子的鲁路修,为了建立人人平等的世界、让妹妹娜娜丽幸福的世界,而使用GEASS,令人绝对服从的力量,带领黑色骑士团向帝国宣战。带上假面化名ZERO的他,却在一年前的“东京决战”中被好友朱雀击败,被帝国皇帝抹去了记忆。\r\n  现在,恢复记忆的鲁路修不仅要面对帝国的强大军事力量,更要面对虚假的弟弟罗洛、失踪的妹妹娜娜丽、不知敌友的中华联盟、内部出现分歧的黑色骑士团。面对内忧外患,鲁路修走上了GEASS之力的诅咒——孤独的王之路。 ",
      "nsfw": false,
      "date": "2008-04-06",
      "platform": "TV",
      "images": {
        "large": "https://lain.bgm.tv/pic/cover/l/c9/f0/8_wK0z3.jpg",
        "common": "https://lain.bgm.tv/pic/cover/c/c9/f0/8_wK0z3.jpg",
        "medium": "https://lain.bgm.tv/pic/cover/m/c9/f0/8_wK0z3.jpg",
        "small": "https://lain.bgm.tv/pic/cover/s/c9/f0/8_wK0z3.jpg",
        "grid": "https://lain.bgm.tv/pic/cover/g/c9/f0/8_wK0z3.jpg"
      },
      "infobox": [
        {
          "key": "中文名",
          "value": "Code Geass 反叛的鲁路修R2"
        },
        {
          "key": "别名",
          "value": [
            {
              "v": "叛逆的鲁路修R2"
            },
            {
              "v": "Code Geass: Hangyaku no Lelouch R2"
            },
            {
              "v": "叛逆的勒鲁什R2"
            },
            {
              "v": "叛逆的鲁鲁修R2"
            },
            {
              "v": "コードギアス 反逆のルルーシュR2"
            },
            {
              "v": "Code Geass: Lelouch of the Rebellion R2"
            },
            {
              "v": "叛逆的勒路什R2"
            }
          ]
        },
        {
          "key": "话数",
          "value": "25"
        },
        {
          "key": "放送开始",
          "value": "2008年4月6日"
        },
        {
          "key": "官方网站",
          "value": "http://www.geass.jp/r2/"
        },
        {
          "key": "播放电视台",
          "value": "每日放送"
        },
        {
          "key": "播放结束",
          "value": "2008年9月28日"
        },
        {
          "key": "Copyright",
          "value": "(C)2006 SUNRISE inc./MBS"
        },
        {
          "key": "导演",
          "value": "谷口悟朗"
        },
        {
          "key": "系列构成",
          "value": "大河内一楼"
        },
        {
          "key": "人物原案",
          "value": "CLAMP"
        },
        {
          "key": "人物设定",
          "value": "木村貴宏"
        },
        {
          "key": "美术监督",
          "value": "菱沼由典"
        },
        {
          "key": "色彩设计",
          "value": "岩沢れい子"
        },
        {
          "key": "摄影监督",
          "value": "大矢創太"
        },
        {
          "key": "音响监督",
          "value": "浦上靖夫、井澤基"
        },
        {
          "key": "音乐",
          "value": "中川幸太郎、黒石ひとみ"
        },
        {
          "key": "音乐制作",
          "value": "AUDIO PLANNING U"
        },
        {
          "key": "动画制作",
          "value": "サンライズ"
        }
      ],
      "volumes": 0,
      "eps": 25,
      "total_episodes": 25,
      "rating": {
        "rank": 121,
        "total": 77255,
        "count": {
          "1": 44,
          "2": 15,
          "3": 32,
          "4": 66,
          "5": 145,
          "6": 457,
          "7": 1472,
          "8": 3190,
          "9": 2640,
          "10": 1377
        },
        "score": 8.2
      },
      "collection": {
        "wish": 622,
        "collect": 13216,
        "doing": 147,
        "on_hold": 224,
        "dropped": 115
      }
    }
    
    剧集

    GET /v0/episodes

    参数:

    • subject_id 章节关联的条目 id,必需提供的参数。
    • type 0,1,2,3 代表 本篇,sp,op,ed, 默认全部。
    • limit 最大 200
    • offset

    example: /v0/episodes?subject_id=8&limit=5

    {
      "total": 25,
      "limit": 5,
      "offset": 0,
      "data": [
        {
          "id": 522,
          "type": 0,
          "sort": 1,
          "name": "魔神 が 目覚める 日",
          "ep": 1, // 按照sort计算出的剧集数,仅本篇剧集有。sp,op,ed为 null
          "name_cn": "魔王的苏醒之日",
          "duration": "24m",
          "airdate": "2008-04-06",
          "comment": 11,
          "desc": "",
        },
        {
          "id": 523,
          "type": 0,
          "sort": 2,
          "name": "日本独立計画",
          "ep": 2,
          "name_cn": "日本独立计划",
          "duration": "24m",
          "airdate": "2008-04-13",
          "comment": 12,
          "desc": "",
        },
        {
          "id": 524,
          "type": 0,
          "sort": 3,
          "name": "囚われの学園",
          "ep": 3,
          "name_cn": "被囚禁的学园",
          "duration": "24m",
          "airdate": "2008-04-20",
          "comment": 8,
          "desc": "",
        },
        {
          "id": 525,
          "type": 0,
          "sort": 4,
          "name": "逆襲の処刑台",
          "ep": 4,
          "name_cn": "逆行的处刑台",
          "duration": "24m",
          "airdate": "2008-04-27",
          "comment": 20,
          "desc": "",
        },
        {
          "id": 526,
          "type": 0,
          "sort": 5,
          "name": "ナイト オブ ラウンズ",
          "ep": 5,
          "name_cn": "圆桌骑士",
          "duration": "24m",
          "airdate": "2008-05-04",
          "comment": 9,
          "desc": "",
        },
      ],
    }
    
    关联人物

    GET /v0/persons?subject_id={subject_id}

    {
      "total": 1,
      "limit": 30,
      "offset": 0,
      "data": [
        {
          "id": 1,
          "name": "水樹奈々",
          "type": 1,
          "career": ["artist", "seiyu"],
          "images": {
            "large": "https://lain.bgm.tv/pic/crt/l/a6/e8/1_prsn_ZdFfp.jpg?r=1597241889",
            "medium": "https://lain.bgm.tv/pic/crt/m/a6/e8/1_prsn_ZdFfp.jpg?r=1597241889",
            "small": "https://lain.bgm.tv/pic/crt/s/a6/e8/1_prsn_ZdFfp.jpg?r=1597241889",
            "grid": "https://lain.bgm.tv/pic/crt/g/a6/e8/1_prsn_ZdFfp.jpg?r=1597241889"
          },
          "short_summary": "原名 近藤 奈々(こんどう なな),日本女性声优兼歌手。有个妹妹名字是近藤美香,为Daisy×Daisy主唱。\r\n\r\n简介\r\n自小受业余经营歌谣教室的父母影响,",
          "img": "https://lain.bgm.tv/pic/crt/m/a6/e8/1_prsn_ZdFfp.jpg?r=1597241889",
          "locked": false,
          "relation": "开发"
        }
      ]
    }
    
    出场角色

    GET /v0/characters?subject_id={subject_id}

    [
      {
        "id": 1,
        "name": "ルルーシュ・ランペルージ",
        "type": 1,
        "images": {
          "large": "https://lain.bgm.tv/pic/crt/l/7b/3a/1_crt_8V556.jpg?r=1603459589",
          "medium": "https://lain.bgm.tv/pic/crt/m/7b/3a/1_crt_8V556.jpg?r=1603459589",
          "small": "https://lain.bgm.tv/pic/crt/s/7b/3a/1_crt_8V556.jpg?r=1603459589",
          "grid": "https://lain.bgm.tv/pic/crt/g/7b/3a/1_crt_8V556.jpg?r=1603459589"
        },
        "relation": "主角"
      },
      {
        "id": 2,
        "name": "枢木スザク",
        "type": 1,
        "images": {
          "large": "https://lain.bgm.tv/pic/crt/l/6f/40/2_crt_08diJ.jpg?r=1581939778",
          "medium": "https://lain.bgm.tv/pic/crt/m/6f/40/2_crt_08diJ.jpg?r=1581939778",
          "small": "https://lain.bgm.tv/pic/crt/s/6f/40/2_crt_08diJ.jpg?r=1581939778",
          "grid": "https://lain.bgm.tv/pic/crt/g/6f/40/2_crt_08diJ.jpg?r=1581939778"
        },
        "relation": "主角"
      },
      {
        "id": 3,
        "name": "C.C.",
        "type": 1,
        "images": {
          "large": "https://lain.bgm.tv/pic/crt/l/83/62/3_crt_7Jhis.jpg?r=1573280268",
          "medium": "https://lain.bgm.tv/pic/crt/m/83/62/3_crt_7Jhis.jpg?r=1573280268",
          "small": "https://lain.bgm.tv/pic/crt/s/83/62/3_crt_7Jhis.jpg?r=1573280268",
          "grid": "https://lain.bgm.tv/pic/crt/g/83/62/3_crt_7Jhis.jpg?r=1573280268"
        },
        "relation": "主角"
      }
    ]
    
    关联条目

    GET /v0/subjects/{subject_id}/subjects

    [
      {
        "id": 12,
        "type": 2,
        "name": "ちょびっツの「ツ」の字 - Chobits Fan Book",
        "name_cn": "1004",
        "images": {
          "large": "https://lain.bgm.tv/pic/cover/l/65/12/11_bsxG3.jpg",
          "common": "https://lain.bgm.tv/pic/cover/c/65/12/11_bsxG3.jpg",
          "medium": "https://lain.bgm.tv/pic/cover/m/65/12/11_bsxG3.jpg",
          "small": "https://lain.bgm.tv/pic/cover/s/65/12/11_bsxG3.jpg",
          "grid": "https://lain.bgm.tv/pic/cover/g/65/12/11_bsxG3.jpg"
        },
        "relation": "画集"
      },
      {
        "id": 497,
        "type": 1,
        "name": "ちょびっツの「ツ」の字 - Chobits Fan Book",
        "name_cn": "1002",
        "images": {
          "large": "https://lain.bgm.tv/pic/cover/l/65/12/11_bsxG3.jpg",
          "common": "https://lain.bgm.tv/pic/cover/c/65/12/11_bsxG3.jpg",
          "medium": "https://lain.bgm.tv/pic/cover/m/65/12/11_bsxG3.jpg",
          "small": "https://lain.bgm.tv/pic/cover/s/65/12/11_bsxG3.jpg",
          "grid": "https://lain.bgm.tv/pic/cover/g/65/12/11_bsxG3.jpg"
        },
        "relation": "系列"
      }
    ]
    

    close #17 #18 #9

    opened by Trim21 9
  • 获取编辑历史API设计

    获取编辑历史API设计

    编辑历史API拥有一个公用前缀 /v0/revisions/, 按照不同的编辑种类分成不同的子路由

    • 列出某个条目所有的修订 /v0/revsions/subjects?subject_id=$value
    • 条目编辑历史 /v0/revsions/subjects/{rev_id}

    其他wiki类型如人物/角色/章节类似。

    opened by Trim21 8
  • 关于获取用户收藏 API 的 limit 参数设计

    关于获取用户收藏 API 的 limit 参数设计

    现状

    获取用户收藏的 GET /v0/users/{username}/collections 其中 limit 参数接收最大值 100,默认值 30。

    当 limit 参数大于 用户总收藏数 时会 Bad Request,产生了无意义的失败请求,徒增 API 使用难度,也为服务器增大了压力。

    {
        "title": "Bad Request",
        "details": {
            "error": "limit should less equal than 40",
            "path": "/v0/users/{username}/collections",
            "query_string": "limit=50&offset=0"
        },
        "description": "limit should less equal than 40"
    }
    

    建议

    1. 新增一个获取用户收藏数的 API,开发者自行避免使用大于总数的 limit 参数进行请求。
    2. 修改逻辑。当 limit 大于用户总收藏数时,返回尽可能多的收藏条目数。

    临时方案

    个人认为当前可行的解决方案,采用一个小于 100 的 limit 参数进行请求,如果出现 Bad Request,从信息中拿到 limit 允许的最大值(即上面 description 中的数字),并进行第二次请求。

    enhancement 
    opened by KiritaniAyaka 7
  • feat(revision): person and character

    feat(revision): person and character

    人物 & 角色编辑历史

    /v0/revisions/persons?person_id=9

    {
        "total": 2,
        "limit": 30,
        "offset": 0,
        "data": [
            {
                "id": 348475,
                "type": 3,
                "creator": {
                    "id": 104510,
                    "nickname": "",
                    "avatar": ""
                },
                "summary": "",
                "timestamp": "2015-03-22T02:14:01+00:00"
            },
            {
                "id": 668431,
                "type": 3,
                "creator": {
                    "id": 181882,
                    "nickname": "",
                    "avatar": ""
                },
                "summary": "",
                "timestamp": "2017-02-20T05:50:35+00:00"
            }
        ]
    }
    

    /v0/revisions/persons?person_id=9&uid=104510

    {
        "total": 1,
        "limit": 30,
        "offset": 0,
        "data": [
            {
                "id": 348475,
                "type": 3,
                "creator": {
                    "id": 104510
                },
                "summary": "",
                "timestamp": "2015-03-22T02:14:01+00:00"
            }
        ]
    }
    

    /v0/revisions/persons/348475

    {
        "id": 348475,
        "type": 3,
        "creator": {
            "id": 104510,
            "nickname": "",
            "avatar": ""
        },
        "summary": "",
        "timestamp": "2015-03-22T02:14:01+00:00",
        "data": {
            "348475": {
                "prsn_name": "森岡浩之",
                "prsn_infobox": "",
                "prsn_summary": "",
                "profession": {
                    "producer": "1"
                },
                "extra": {
                    "img": "45/c4/9_prsn_anidb.jpg"
                }
            },
            "668431": {
                "prsn_name": "森岡浩之",
                "prsn_infobox":  "",
                "prsn_summary": "日本科幻小说作家。出生于兵库县。毕业于京都府立大学文学部。\r\n在渡过一段上班族生活后,森冈浩之于1992年发表首篇作品《触及梦中树》(暂译)。1996年发表《星界的纹章》,并于1997年以本作获得星云奖;本篇《星界的纹章》、续篇《星界的战旗》及外传《星界的断章》均已改编成动画。\r\n本尊出演过电影《立食师列传》。2011年因心肌梗塞入院,2013年发布《星界战旗》第5卷,再次开始作家生活。从2014年起,担当日本SF作家俱乐部事务局长。\r\n\r\n早期作品以所谓的硬科幻HSF居多,之后以《星界》系列为代表的硬派SF中加入了大量轻小说元素。值得一提的是其人对语言有强烈的个性追求。大学时专业是国语语法,毕业论文是《不断发展的语法・日语语态的几何学角度解释初论》。出道作品《若能触及梦中树》中创造了只存在名词的人造语言,在《ZOOK》中描写过只有一个普通名词的语言,在《星界》系列中完成了有完整体系的人造语言亚维语(Baronh)。",
                "profession": {
                    "writer": "1",
                    "producer": "1"
                },
                "extra": {
                    "img": "45/c4/9_prsn_anidb.jpg"
                }
            }
        }
    }
    

    /v0/revisions/characters?character_id=1

    {
        "total": 37,
        "limit": 30,
        "offset": 0,
        "data": [
            {
                "id": 1,
                "type": 2,
                "creator": {
                    "id": 1,
                    "nickname": "",
                    "avatar": ""
                },
                "summary": "",
                "timestamp": "2010-10-05T19:30:38+00:00"
            },
            {
                "id": 2,
                "type": 2,
                "creator": {
                    "id": 1,
                    "nickname": "",
                    "avatar": ""
                },
                "summary": "",
                "timestamp": "2010-10-05T19:31:41+00:00"
            },
            {
                "id": 3,
                "type": 2,
                "creator": {
                    "id": 1,
                    "nickname": "",
                    "avatar": ""
                },
                "summary": "",
                "timestamp": "2010-10-05T19:33:50+00:00"
            },
           ...
        ]
    }
    

    /v0/revisions/characters?character_id=1&uid=1

    {
        "total": 8,
        "limit": 30,
        "offset": 0,
        "data": [
            {
                "id": 1,
                "type": 2,
                "creator": {
                    "id": 1
                },
                "summary": "",
                "timestamp": "2010-10-05T19:30:38+00:00"
            },
            {
                "id": 2,
                "type": 2,
                "creator": {
                    "id": 1
                },
                "summary": "",
                "timestamp": "2010-10-05T19:31:41+00:00"
            },
            {
                "id": 3,
                "type": 2,
                "creator": {
                    "id": 1
                },
                "summary": "",
                "timestamp": "2010-10-05T19:33:50+00:00"
            },
           ...
       ]
    }
    

    /v0/revisions/characters/190704

    {
        "id": 190704,
        "type": 2,
        "creator": {
            "id": 14382,
            "nickname": "",
            "avatar": ""
        },
        "summary": "引用来源不能引用自身啊=_,=",
        "timestamp": "2014-01-14T19:27:08+00:00",
        "data": {
            "1": {
                "crt_name": "ルルーシュ・ランペルージ",
                "crt_infobox": "...",
                "crt_summary": "英文名:〈真〉Lelouch Vie Britannia/〈假〉Lelouch Lamperouge <><>\"\"\"\"\r\n一年前的东京攻略战中,黑色骑士团因为首领Zero的离开而最终战败。之后一年间,鲁路修的Geass能力被人封印而平静的生活在阿什弗德学园,在第二季开头,鲁路修重新与C.C相遇之后,Geass封印被解开,鲁路修也恢复了记忆。\r\n一年前最后的神根岛之战,鲁路修被朱雀制服,并被押到其父不列颠皇帝面前,被皇帝施以Geass封印一切记忆。\r\n封印解除之后,Geass能力恢复到封印之前的状态,依然暴走,无法关闭,为了防止尤菲米雅的悲剧再次上演,C.C给了鲁路修特制的隐形眼镜来应对暴走的Geass能力。",
                "extra": {
                    "img": "c4/ca/1_238a0b923820dcc509a6f75849b_EB48R.jpg"
                }
            },
            "2": {
                "crt_name": "ルルーシュ・ランペルージ",
                "crt_infobox": "...",
                "crt_summary": "英文名:〈真〉Lelouch Vie Britannia/〈假〉Lelouch Lamperouge <><>\"\r\n一年前的东京攻略战中,黑色骑士团因为首领Zero的离开而最终战败。之后一年间,鲁路修的Geass能力被人封印而平静的生活在阿什弗德学园,在第二季开头,鲁路修重新与C.C相遇之后,Geass封印被解开,鲁路修也恢复了记忆。\r\n一年前最后的神根岛之战,鲁路修被朱雀制服,并被押到其父不列颠皇帝面前,被皇帝施以Geass封印一切记忆。\r\n封印解除之后,Geass能力恢复到封印之前的状态,依然暴走,无法关闭,为了防止尤菲米雅的悲剧再次上演,C.C给了鲁路修特制的隐形眼镜来应对暴走的Geass能力。",
                "extra": {
                    "img": "c4/ca/1_238a0b923820dcc509a6f75849b_EB48R.jpg"
                }
            },
            "3": {
                "crt_name": "ルルーシュ・ランペルージ",
                "crt_infobox":  "..."
                "crt_summary": "英文名:〈真〉Lelouch Vie Britannia/〈假〉Lelouch Lamperouge <><>\"\r\n一年前的东京攻略战中,黑色骑士团因为首领Zero的离开而最终战败。之后一年间,鲁路修的Geass能力被人封印而平静的生活在阿什弗德学园,在第二季开头,鲁路修重新与C.C相遇之后,Geass封印被解开,鲁路修也恢复了记忆。\r\n一年前最后的神根岛之战,鲁路修被朱雀制服,并被押到其父不列颠皇帝面前,被皇帝施以Geass封印一切记忆。\r\n封印解除之后,Geass能力恢复到封印之前的状态,依然暴走,无法关闭,为了防止尤菲米雅的悲剧再次上演,C.C给了鲁路修特制的隐形眼镜来应对暴走的Geass能力。",
                "extra": {
                    "img": "c4/ca/1_238a0b923820dcc509a6f75849b_EB48R.jpg"
                }
            }
            ...
        }
    }
    
    opened by Sociosarbis 6
  • API 422 Response缺少 Access-Control-Allow-Origin Header

    API 422 Response缺少 Access-Control-Allow-Origin Header

    和 https://github.com/bangumi/api/issues/70 ~~相同的问题,sai只修改了老API。~~

    如果API返回422,响应缺少 Access-Control-Allow-Origin header

    image

    重现方法:

    1. 打开https://bangumi.github.io/api/
    2. 选择第一个API /v0/persons
    3. 点击Try it out
    4. 不做任何选项,直接点 Execute
    5. 查看console
    opened by markni 6
  • add __all__ to python files that misses it

    add __all__ to python files that misses it

    use tool (https://github.com/xwu64/python-auto-all) to generate__all__ for python files. This tool go through all python files and ignores file, class and function with prefix "_". In this commit, I manually remove __all__ for test files.

    opened by xwu64 5
  • feat: group

    feat: group

    https://github.com/bangumi/server/issues/182

    GET /p/groups/{name}

    {
      "id": 11,
      "created_at": "2008-08-01T06:11:29+08:00",
      "description": "本小组欢迎对各种技术有一定了解的人,\r\n比如像橘花热衷杀人技术……\r\n\r\n不过、本组主要谈论PC软硬件方面,\r\n想了解相关知识,结识可怕的技术宅,请进。",
      "icon": "https://lain.bgm.tv/pic/icon/l/000/00/00/11.jpg",
      "name": "a",
      "new_members": [
        {
          "avatar": {
            "large": "https://lain.bgm.tv/pic/user/l/000/00/00/1.jpg?r=1391790456",
            "medium": "https://lain.bgm.tv/pic/user/m/000/00/00/1.jpg?r=1391790456",
            "small": "https://lain.bgm.tv/pic/user/s/000/00/00/1.jpg?r=1391790456"
          },
          "id": 1,
          "nickname": "Sai🖖",
          "username": "sai",
          "joined_at": "2022-06-25T21:07:38.466+08:00"
        }
      ],
      "title": "~技术宅真可怕~",
      "total_members": 9450
    }
    

    GET /p/groups/{name}/members?type={normal|mod|all}&limit=30&offset=0

    type 默认为 all

    limit和offset是分页参数,跟之前的api一样。

    {
      "total": 0,
      "limit": 0,
      "offset": 0,
      "data": [
        [
          {
            "avatar": {
              "large": "https://lain.bgm.tv/pic/user/l/000/00/00/1.jpg?r=1391790456",
              "medium": "https://lain.bgm.tv/pic/user/m/000/00/00/1.jpg?r=1391790456",
              "small": "https://lain.bgm.tv/pic/user/s/000/00/00/1.jpg?r=1391790456"
            },
            "id": 1,
            "nickname": "Sai🖖",
            "username": "sai",
            "joined_at": "2022-06-25T21:07:38.466+08:00"
          }
        ]
      ]
    }
    
    opened by Trim21 4
  • feat(subject): return character related actors

    feat(subject): return character related actors

    如果你的 PR 添加了新的 API,请针对每一个 API 填写以下部分 related issue: #88

    添加actors字段

    GET /v0/subjects/{subject_id}/characters

    Request Query: subject_id: int

    响应:

    [
      {
        "id": 1,
        "name": "ルルーシュ・ランペルージ",
        "type": 1,
        "images": {
          "large": "https://lain.bgm.tv/pic/crt/l/7b/3a/1_crt_8V556.jpg?r=1603459589",
          "medium": "https://lain.bgm.tv/pic/crt/m/7b/3a/1_crt_8V556.jpg?r=1603459589",
          "small": "https://lain.bgm.tv/pic/crt/s/7b/3a/1_crt_8V556.jpg?r=1603459589",
          "grid": "https://lain.bgm.tv/pic/crt/g/7b/3a/1_crt_8V556.jpg?r=1603459589"
        },
        "relation": "主角",
        "actors": [
          {
            "id": 3890,
            "name": "person 3890",
            "type": 1,
            "career": [],
            "images": null,
            "short_summary": "",
            "img": null,
            "locked": false
          },
          {
            "id": 3818,
            "name": "person 3818",
            "type": 1,
            "career": [],
            "images": null,
            "short_summary": "",
            "img": null,
            "locked": false
          }
        ]
      }
    ]
    

    close #

    opened by Sociosarbis 4
  • feat(revision): subject and episode

    feat(revision): subject and episode

    条目 & 章节编辑历史

    subject revisions

    GET/POST /v0/revisions/subjects?subject_id=26

    响应:

    {
      "total": 11,
      "limit": 30,
      "offset": 0,
      "data": [
        {
          "id": 665556,
          "type": 1,
          "creator": null,
          "summary": "",
          "created_at": "2020-02-28T12:13:20+00:00"
        },
        {
          "id": 276459,
          "type": 1,
          "creator": {
            "username": "89561",
            "nickname": "nickname 89561"
          },
          "summary": "",
          "created_at": "2015-05-02T12:28:29+00:00"
        },
        {
          "id": 212593,
          "type": 1,
          "creator": {
            "username": "10327",
            "nickname": "nickname 10327"
          },
          "summary": "",
          "created_at": "2014-05-31T05:35:56+00:00"
        },
        {
          "id": 194079,
          "type": 1,
          "creator": {
            "username": "21804",
            "nickname": "nickname 21804"
          },
          "summary": "内容扩充",
          "created_at": "2014-02-17T14:49:58+00:00"
        },
        {
          "id": 194078,
          "type": 1,
          "creator": {
            "username": "21804",
            "nickname": "nickname 21804"
          },
          "summary": "恢复版本",
          "created_at": "2014-02-17T14:48:12+00:00"
        },
        {
          "id": 194077,
          "type": 11,
          "creator": {
            "username": "21804",
            "nickname": "nickname 21804"
          },
          "summary": "与 ID:97100 合体",
          "created_at": "2014-02-17T14:47:10+00:00"
        },
        {
          "id": 194043,
          "type": 1,
          "creator": null,
          "summary": "Amazon抓取条目",
          "created_at": "2014-02-17T11:48:40+00:00"
        },
        {
          "id": 147406,
          "type": 1,
          "creator": {
            "username": "89561",
            "nickname": "nickname 89561"
          },
          "summary": "",
          "created_at": "2013-06-05T04:53:30+00:00"
        },
        {
          "id": 44452,
          "type": 11,
          "creator": {
            "username": "5191",
            "nickname": "nickname 5191"
          },
          "summary": "与 ID:25670 合体",
          "created_at": "2011-11-08T09:43:34+00:00"
        },
        {
          "id": 44392,
          "type": 1,
          "creator": {
            "username": "36018",
            "nickname": "nickname 36018"
          },
          "summary": "新条目",
          "created_at": "2011-11-07T13:16:25+00:00"
        },
        {
          "id": 3748,
          "type": 1,
          "creator": {
            "username": "2627",
            "nickname": "nickname 2627"
          },
          "summary": "维基化",
          "created_at": "2009-10-06T15:21:40+00:00"
        }
      ]
    }
    
    subject revision

    GET/POST /v0/revisions/subjects/718391

    响应:

    {
      "id": 718391,
      "type": 1,
      "creator": {
        "username": "464691",
        "nickname": "nickname 464691"
      },
      "summary": "信息转更早出版的台版:内容扩充(出版社、页数、价格)&amp;资讯更新(发售日、ISBN[勘误])",
      "created_at": "2021-01-23T15:52:51+00:00",
      "data": {
        "subject_id": 1,
        "name": "第一次的親密接觸",
        "name_cn": "第一次的亲密接触",
        "vote_field": "",
        "type": 1,
        "type_id": 1,
        "field_infobox": "{{Infobox animanga/Novel\r\n|中文名= 第一次的亲密接触\r\n|别名={\r\n}\r\n|出版社= 紅色文化、知识出版社\r\n|价格= NT$160\r\n|连载杂志= \r\n|发售日= 1998-09-25\r\n|册数= \r\n|页数= 188\r\n|话数= \r\n|ISBN= 9577086705\r\n|其他= \r\n|作者= 蔡智恒\r\n}}",
        "field_summary": "  風靡華人世界的網戀小說經典,暢銷紀錄超過百萬冊!\r\n  有最初的《第一次的親密接觸》,才有今日網路文學。\r\n  蔡智恆的最新作品《暖暖》,提升你的戀愛幸福溫度。\r\n  紀念版收錄蔡智恆醞釀十年,最溫柔的純愛萬語宣言。\r\n  PH值小於7的微酸心情,讓十年後的痞子蔡告訴你。\r\n  一場最美麗的網路解逅,當痞子蔡遇見輕舞飛揚……\r\n  蔡智恆最真實的情感原點\r\n  痞子蔡與輕舞飛揚一起記錄的甜蜜日子\r\n  一則發生在成大校園的純愛故事,網路上一再被轉載的熱門小說。",
        "field_eps": 0,
        "platform": 1002
      }
    }
    
    episode revisions

    GET/POST /v0/revisions/episodes?episode_id=522

    响应:

    {
      "total": 1,
      "limit": 30,
      "offset": 0,
      "data": [
        {
          "id": 1435,
          "type": 18,
          "creator": {
            "username": "2959",
            "nickname": "nickname 2959"
          },
          "summary": "",
          "created_at": "2010-04-24T16:02:52+00:00"
        }
      ]
    }
    
    episode revision

    GET/POST /v0/revisions/episodes/1435

    响应:

    {
      "id": 1435,
      "type": 18,
      "creator": {
        "username": "2959",
        "nickname": "nickname 2959"
      },
      "summary": "",
      "created_at": "2010-04-24T16:02:52+00:00",
      "data": {
        "eids": "522,523,524,525,526,527,528,529,530,531,532,89,90,2,91,104,374,520,574,577",
        "ep_infobox": "1|魔神 が 目覚める 日|魔王的苏醒之日|24m|2008-04-06\r\n2|日本独立計画|日本独立计划|24m|2008-04-13\r\n3|囚われの学園|被囚禁的学园|24m|2008-04-20\r\n4|逆襲の処刑台|逆行的处刑台|24m|2008-04-27\r\n5|ナイト オブ ラウンズ|圆桌骑士|24m|2008-05-04\r\n6|太平洋 奇襲 作戦|太平洋奇袭作战|24m|2008-05-11\r\n7|棄てられた 仮面|被丢弃的面具|24m|2008-05-18\r\n8|百万のキセキ|百万的奇迹|24m|2008-05-25\r\n9|朱禁城の花嫁|朱禁城的花嫁|24m|2008-06-08\r\n10|神虎輝く刻|神虎闪耀之刻|24m|2008-06-15\r\n11|想いの力|思念的力量|24m|2008-06-22\r\n12|ラブ アタック!|爱的初体验|24m|2008-07-01\r\n13|過去からの刺客|来自过去的刺客|24m|2008-07-06\r\n14|ギアス 狩り|Geass 狩猎|24m|2008-07-12\r\n15|C の 世界|C的世界|24m|2008-07-20\r\n16|超合集国決議第壱號|超合众国决议第一号|24m|2008-07-27\r\n17|土の味|土之气味|24m|2008-08-03\r\n18|第二次 東京 決戦|第二次东京决战|24m|2008-08-10\r\n19|裏切り|背叛|24m|2008-08-17\r\n20|皇帝 失格||24m|2008-08-24",
        "subject_id": 8,
        "version": 0
      }
    }
    

    close #45 close #46

    opened by MichaelMai2000 4
  • feat: progress api

    feat: progress api

    blocked

    • [ ] https://github.com/bangumi/server/pull/181
    "/v0/users/-/collections/episodes/{episode_id}":
      put:
        tags:
          - 收藏
        summary: 更新用户章节收藏状态
        description: |
          修改章节收藏状况
          
          ## 限制
          
          只能修改已收藏的条目。
          
          只能修改动画和三次元的章节情况。
        operationId: putUserEpisodesCollection
        parameters:
          - *path_episode_id
        requestBody:
          required: true
          content:
            application/json:
              schema:
                $ref: "./components/put-user-episodes-collection.yaml"
        responses:
          "204":
            description: Successful Response
          "400":
            description: Validation Error
            content:
              application/json:
                schema:
                  "$ref": "#/components/schemas/ErrorDetail"
          
          "401":
            description: Unauthorized
            content:
            content:
              application/json:
                schema:
                  "$ref": "#/components/schemas/ErrorDetail"
          
          "404":
            description: 条目不存在或者已经被移除
            content:
              application/json:
                schema:
                  "$ref": "#/components/schemas/ErrorDetail"
          
          "422":
            description: 请求不是 JSON 或者无法以 JSON 解析请求体。
            content:
              application/json:
                schema:
                  "$ref": "#/components/schemas/ErrorDetail"
        
        security:
          - HTTPBearer: []
    

    close #

    opened by Trim21 1
  • [Feature Request]: 小组概览接口

    [Feature Request]: 小组概览接口

    你想添加的新功能

    私有小组概览接口

    你希望的解决方案 新增接口

    GET /p/group/${name}

    期望返回:

    | 字段 | 类型 | 意义 | |---|---|---| | name | string | 小组名称 | | created_at | string | 创建时间,格式 YYYY-MM-DD HH:mm | | description| string | 小组介绍 | | total_members | number | 小组成员数量 | | new_members | User[] | 最近加入的小组成员,最多 10 个 | | related_groups | Group[] | 成员喜欢去的小组,最多 6 个 | | new_topics | Topic[] | 最新讨论,最多 10 个 |

    其他可能的替代方案

    其他相关信息

    Screen Shot 2022-06-21 at 23 38 43

    enhancement 
    opened by Ayase-252 4
  • feat: timeline

    feat: timeline

    timeline is a post arrangement component in bgm, which based on posts' chrono order

    this commit introduces the package timeline and wraps its CRUD functionality into interface

    #176

    opened by TWT233 37
  • feat: topics and comments

    feat: topics and comments

    获取条目全部讨论

    GET /p/subjects/{subject_id}/topics

    Query

    • limit
    • offset

    响应:

    {
      "data": [
        {
          "created_at": "2008-07-14T15:34:07+08:00",
          "creator": {
            "username": "2",
            "nickname": "nickname 2"
          },
          "title": "拿这个来测试",
          "id": 1,
          "replies": 76
        }
      ],
      "hasMore": false,
      "limit": 10,
      "offset": 0
    }
    
    获取条目讨论内容

    GET /p/subjects/{subject_id}/topics/{topic_id}

    Query

    • limit
    • offset

    响应:

    {
      "created_at": "2008-07-14T15:34:07+08:00",
      "comments": {
        "data": [
          {
            "created_at": "2016-01-15T20:58:20+08:00",
            "creator": {
              "username": "",
              "nickname": ""
            },
            "text": "这个帖子竟然没人挖(bgm38)",
            "replies": [
              {
                "created_at": "2016-01-17T01:25:12+08:00",
                "creator": {
                  "username": "",
                  "nickname": ""
                },
                "text": "专业挖坟的么=_=",
                "id": 68013
              }
            ],
            "id": 67970
          }
        ],
        "has_more": true,
        "limit": 10,
        "offset": 0
      },
      "creator": {
        "username": "2",
        "nickname": "nickname 2"
      },
      "title": "拿这个来测试",
      "id": 1,
      "replies": 76
    }
    
    获取角色讨论内容

    GET /p/characters/{character_id}/comments

    Query

    • limit
    • offset

    响应:

    {
      "data": [
        {
          "created_at": "2012-11-08T22:36:32+08:00",
          "creator": {
            "username": "",
            "nickname": ""
          },
          "text": "9/101\n渣渣~",
          "replies": [
            {
              "created_at": "2012-11-08T22:40:32+08:00",
              "creator": {
                "username": "14127",
                "nickname": "nickname 14127"
              },
              "text": "哈哈 我也是9/101",
              "id": 1039
            }
      ],
      "has_more": false,
      "limit": 30,
      "offset": 0
    }
    

    close #67

    opened by FDKevin0 37
  • [Feature Request]: get /v0/persons/{person_id}/characters 与/v0/characters/{character_id}/persons 是否考虑增加关系字段

    [Feature Request]: get /v0/persons/{person_id}/characters 与/v0/characters/{character_id}/persons 是否考虑增加关系字段

    你想添加的新功能

    网页上,角色的出演列表,以及人物的角色列表,均包含了作品中,角色的类别:按照源码看,有三个类别: 1: 主角 2: 配角 3: 客串 这个字段目前只能从/v0/subjects/{subject_id}/characters或者characters/{character_id}/subjects结果获得。 那么实现网页上的效果,就要请求两次

    你希望的解决方案

    在上述API中加入staff字段

    其他可能的替代方案

    GraphQL(长远考虑

    其他相关信息

    help wanted enhancement 
    opened by EverettSummer 2
Releases(v0.20.10)
Owner
Bangumi
Bangumi
HttpRunner+ is the next generation of HttpRunner, written in golang

hrp (HttpRunner+) hrp is a golang implementation of HttpRunner. Ideally, hrp will be fully compatible with HttpRunner, including testcase format and u

HttpRunner 81 Jun 16, 2022
Core is the next-generation digital data engine.

tKeel-Core The digital engine of world ?? Core is the data centre of the tKeel IoT Open Platform, a high-performance, scalable and lightweight next-ge

null 21 Mar 28, 2022
Next Terminal是使用Golang和React开发的一款HTML5的远程桌面网关

Next Terminal是使用Golang和React开发的一款HTML5的远程桌面网关,具有小巧、易安装、易使用、资源占用小的特点,支持RDP、SSH、VNC和Telnet协议的连接和管理。

dushixiang 498 Jun 1, 2021
gh is GitHub on the command line. It brings pull requests, issues, and other GitHub concepts to the terminal next to where you are already working with git and your code

gh is GitHub on the command line. It brings pull requests, issues, and other GitHub concepts to the terminal next to where you are already working with git and your code

frenchy77 0 Jan 24, 2022
The server-pubsub is the main backend of DATAVOC project that manages all the other web-server modules of the same project such as the processor

server-pubsub The server-pubsub is the main backend of DATAVOC project that manages all the other web-server modules of the same project such as the p

null 0 Dec 3, 2021
Proxy that keeps clients active until the backend server is back online

HoneySmoke HoneySmoke is a prototype proxy for testing until it eventually becomes HoneyHive. HoneySmoke will eventually implement a limbo mode that k

Ethan 4 Nov 20, 2021
Go driven rpc code generation tool for right now.

Go driven rpc code generation tool for right now. 100% Go Describe services with Go interfaces (with structs, methods, comments, etc.) Generate server

pace.dev 588 Jun 25, 2022
A simulation to see what's the result among normal people、rich-second generation、hard-working people

A simulation to see what's the result of competion among normal people、rich-second generation and hard-working people. 假设: 一个社会集体中有部分富二代,部分努力的人,多数是普通人

Myrainhua 0 Feb 20, 2022
Build file generation is provided as a plugin for gazelle

JS rules for Bazel Ecosia specific JS Bazel rules to be used with the NodeJS rules Setup http_archive( name = "benchsci_bazel_rules_nodejs_contrib

BenchSci 3 Jun 9, 2022
The `protoc` compiler plugin which dumps the generation request details

Progotgen DUMP The protoc compiler plugin which dumps the generation request details in "google.golang.org/protobuf/compiler/protogen format to stderr

Albenik's Golang Projects 0 Jan 23, 2022
llb - It's a very simple but quick backend for proxy servers. Can be useful for fast redirection to predefined domain with zero memory allocation and fast response.

llb What the f--k it is? It's a very simple but quick backend for proxy servers. You can setup redirect to your main domain or just show HTTP/1.1 404

Kirill Danshin 12 Jan 23, 2022
A Socket.IO backend implementation written in Go

go-socket.io The socketio package is a simple abstraction layer for different web browser- supported transport mechanisms. It is fully compatible with

Jukka-Pekka Kekkonen 405 May 24, 2022
A pluggable backend API that enforces the Event Sourcing Pattern for persisting & broadcasting application state changes

A pluggable "Application State Gateway" that enforces the Event Sourcing Pattern for securely persisting & broadcasting application state changes

null 28 May 4, 2022
webrpc is a schema-driven approach to writing backend services for modern Web apps and networks

webrpc is a schema-driven approach to writing backend servers for the Web. Write your server's api interface in a schema format of RIDL or JSON, and t

null 453 Jun 20, 2022
A Xray backend framework that can easily support many panels. 一个基于Xray的后端框架,支持V2ay,Trojan,Shadowsocks协议,极易扩展,支持多面板对接

XRayR A Xray backend framework that can easily support many panels. 一个基于Xray的后端框架,支持V2ay,Trojan,Shadowsocks协议,极易扩展,支持多面板对接。 如果您喜欢本项目,可以右上角点个star+watch

null 989 Apr 25, 2022
protoc-gen-grpc-gateway-ts is a Typescript client generator for the grpc-gateway project. It generates idiomatic Typescript clients that connect the web frontend and golang backend fronted by grpc-gateway.

protoc-gen-grpc-gateway-ts protoc-gen-grpc-gateway-ts is a Typescript client generator for the grpc-gateway project. It generates idiomatic Typescript

gRPC Ecosystem 69 Jun 26, 2022
Findmentor.network backend project

Build Setup go get github.com/findmentor-network/backend make build <$ ./backend Findmentor API Usage: backend [command] Available Commands: a

null 24 Jan 28, 2022
TwitchHub Golang Backend

TwitchHub Golang Backend setup development environment: clone the repository

Bardia 6 Sep 18, 2021
Trello backend repo for Ladno Davayte Bez Roflov team

Trello Trello backend repository for Ladno Davayte Bez Roflov team, autumn of 2021. Team Anton Chumakov; Alexander Orletskiy; Georgij Sedojkin; Dmitri

null 3 Dec 25, 2021