diff --git a/Dockerfile b/Dockerfile index 06c0720..0104d6d 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,9 +1,10 @@ -FROM python:3.6-alpine +FROM python:3.11-alpine WORKDIR /pb ADD . /build -RUN apk add --no-cache --virtual .build-deps git \ +RUN apk add --no-cache --virtual .build-deps git gcc musl-dev \ + && pip install --upgrade pip setuptools setuptools-scm \ && pip install /build \ && apk del .build-deps diff --git a/README.md b/README.md new file mode 100644 index 0000000..f45e072 --- /dev/null +++ b/README.md @@ -0,0 +1,44 @@ +# pb 部署备忘 + +## 启动/停止 + +```bash +# 后台启动 +cd ~/pb && docker-compose up -d + +# 停止 +cd ~/pb && docker-compose down + +# 查看状态 +docker ps --filter "name=pb-" +``` + +## 服务端口 + +| 服务 | 端口 | +|------|------| +| pb | 10002 | +| MongoDB | 27017(内部)| + +## 踩坑记录 + +### 网络 +- Docker Hub 不通 → 手动从 `docker.1ms.run` 拉镜像再 `docker tag` +- PyPI 超时 → 阿里云镜像(apk + pip) + +### 依赖兼容 +- `pymongo==3.7.2` → `4.6.3`(Python 3.11 C 扩展不兼容) +- `docutils==0.14` → `0.20.1`(`rU` 模式已移除) +- `requirements.txt` 开头有 BOM 字符,已清除 +- `setup.py` 读依赖时带换行符,已修复 +- 构建前预装 `setuptools-scm` + +### 已修改的文件 +- `Dockerfile`:预装 setuptools-scm、升级 pip +- `requirements.txt`:升级 pymongo 和 docutils +- `setup.py`:修复依赖解析 + +## 相关链接 + +- [Issue #257](https://github.com/ptpb/pb/issues/257) +- [PR #258](https://github.com/ptpb/pb/pull/258) diff --git a/pb/namespace/model.py b/pb/namespace/model.py index d69440b..7583928 100644 --- a/pb/namespace/model.py +++ b/pb/namespace/model.py @@ -36,5 +36,5 @@ def create(name): _id=uuid4().hex, name=name ) - get_db().namespaces.insert(d) + get_db().namespaces.insert_one(d) return d diff --git a/pb/paste/model.py b/pb/paste/model.py index 2db659e..3a5f672 100644 --- a/pb/paste/model.py +++ b/pb/paste/model.py @@ -1,33 +1,38 @@ # -*- coding: utf-8 -*- """ - paste.model - ~~~~~~~~~~~ + model + ~~~~~ - paste database model. + the paste model. :copyright: Copyright (C) 2015 by the respective authors; see AUTHORS. :license: GPLv3, see LICENSE for details. """ -from datetime import datetime, timedelta from hashlib import sha1 -from itertools import filterfalse -from uuid import UUID, uuid4 +from mimetypes import guess_extension +from uuid import uuid4 -from bson import ObjectId -from pymongo import DESCENDING +from datetime import datetime +from bson.objectid import ObjectId +from werkzeug.urls import url_quote, url_unquote -from pb.db import get_db, get_fs +from pb.db import get_fs +from pb.paste.handler import handlers, label def _transform(kwargs): for key, value in kwargs.items(): - if not value: + if value is None: continue - if key == 'uuid': - yield '_id', value.hex - else: - yield key, value + + if key == 'content' or value is False: + continue + + if key == 'redirect': + key = 's' + + yield key, value def transform(kwargs): @@ -39,7 +44,7 @@ def _put(stream): digest = sha1(b).hexdigest() size = len(b) - if len(stream.getvalue()) > 2 ** 23: + if size > 2 ** 23: b = get_fs().put(b) return dict( @@ -63,26 +68,27 @@ def insert(stream, **kwargs): date=datetime.utcnow(), **transform(kwargs) ) - get_db().pastes.insert(d) + get_db().pastes.insert_one(d) return d def put(stream, mimetype=None, headers={}, **kwargs): args = _put(stream) args.update(mimetype=mimetype, headers=headers) - return get_db().pastes.update(transform(kwargs), { + return get_db().pastes.update_one(transform(kwargs), { '$set': transform(args) }) def delete(**kwargs): - return get_db().pastes.remove(transform(kwargs)) + return get_db().pastes.delete_many(transform(kwargs)) def get_digest(stream=None, content=None): cur = get_db().pastes.find(dict( digest=sha1(content if content else stream.read()).hexdigest() )).sort('date', DESCENDING) + # fixme: wtf? if stream: stream.seek(0) diff --git a/pb/paste/views.py b/pb/paste/views.py index e54824d..986ccea 100644 --- a/pb/paste/views.py +++ b/pb/paste/views.py @@ -181,7 +181,7 @@ def put(**kwargs): # FIXME: such query; wow invalidate(**kwargs) result = model.put(stream, headers=headers, **kwargs) - if result['n']: + if result.matched_count: paste = next(model.get_meta(**kwargs)) return PasteResponse(paste, "updated") @@ -196,7 +196,7 @@ def delete(**kwargs): paste = invalidate(**kwargs) result = model.delete(**kwargs) - if result['n']: + if result.deleted_count: return PasteResponse(paste, "deleted") return StatusResponse("not found", 404) diff --git a/requirements.txt b/requirements.txt index 56254b3..f56c2d2 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,7 +1,7 @@ certifi==2024.8.30 charset-normalizer==3.4.0 click==8.1.7 -docutils==0.14 +docutils==0.20.1 Flask==1.0.2 idna==3.10 itsdangerous==1.1.0 @@ -9,7 +9,7 @@ Jinja2==2.10.3 Markdown==3.0.1 MarkupSafe==1.1.1 Pygments==2.2.0 -pymongo==3.7.2 +pymongo==4.6.3 python-dateutil==2.7.3 pytz==2018.5 pyxdg==0.26 diff --git a/setup.py b/setup.py index 5a31ce0..4e1d419 100644 --- a/setup.py +++ b/setup.py @@ -2,7 +2,7 @@ with open('requirements.txt') as f: - install_requires = list(f) + install_requires = [line.strip() for line in f if line.strip()] setuptools.setup( use_scm_version=True,