12 Commits

Author SHA1 Message Date
Gitea CI
b340e3f47c Bump version: 0.1.3 → 0.1.4 2025-06-17 19:15:50 +00:00
785b4fe9a4 Merge pull request 'fix: titles containing apostrophes now no longer break requests while still reporting back a success message' (#29) from dev into main
Reviewed-on: #29
2025-06-17 20:13:13 +01:00
6ee1c556e3 fix: titles containing apostrophes now no longer break requests while still reporting back a success message 2025-06-17 21:08:58 +02:00
b9386df233 Merge pull request 'chore: add secondary release workflow based on commit messages' (#28) from dev into main
Reviewed-on: #28
2025-06-07 18:07:25 +01:00
56d01d9e96 chore: add secondary release workflow based on commit messages 2025-06-07 19:06:29 +02:00
Gitea CI
d79c23cde4 Bump version: 0.1.2 → 0.1.3 2025-06-07 15:25:24 +00:00
5427501364 Merge pull request 'chore: Update changelog, fix bug' (#27) from dev into main
Reviewed-on: #27
2025-06-07 16:24:46 +01:00
eef6ac4ee0 change changelog template to include more parameters 2025-06-07 17:21:15 +02:00
c2fc3fd316 chore: fix bug where request site did not color grabbed / available titles 2025-06-07 17:17:45 +02:00
Gitea CI
265c493349 Bump version: 0.1.1 → 0.1.2 2025-06-07 08:07:09 +00:00
63adf36866 Merge pull request 'chore: fix bug where entries were not saved, implemented deplete function' (#26) from dev into main
Reviewed-on: #26
2025-06-07 09:06:21 +01:00
89ba33378f chore: fix bug where entries were not saved, implemented deplete function 2025-06-07 10:05:16 +02:00
5 changed files with 252 additions and 26 deletions

View File

@@ -2,7 +2,14 @@
"categories": [ "categories": [
{ {
"title": "## 🚀 Features", "title": "## 🚀 Features",
"labels": ["add","Add", "Kind/Feature"] "labels": [
"add",
"Add",
"Kind/Feature",
"feat",
"Feature",
"Feat"
]
}, },
{ {
"title": "## 🐛 Fixes", "title": "## 🐛 Fixes",
@@ -18,16 +25,50 @@
"labels": ["docs","Docs", "Kind/Documentation"] "labels": ["docs","Docs", "Kind/Documentation"]
}, },
{ {
"title": "## 🧹 Chore", "title": "## 🛠️ Maintenance",
"labels": ["chore","Chore", "Kind/Chore"] "labels": [
"maintenance",
"Maintenance",
"Kind/Maintenance",
"chore",
"Chore",
"Kind/Chore"
]
}, },
{ {
"title": "## 🛠️ Maintenance", "title": "## ⏪ Reverts",
"labels": ["maintenance","Maintenance", "Kind/Maintenance"] "labels": [
"revert",
"Revert",
"Kind/Revert",
"Kind/Reverts",
"reverts",
"Reverts"
]
}, },
{ {
"title": "## 🗑️ Deprecation", "title": "## 🗑️ Deprecation",
"labels": ["deprecation","Deprecation", "Kind/Deprecation"] "labels": ["deprecation","Deprecation", "Kind/Deprecation"]
},
{
"title": "## ⚡️ Performance Improvements",
"labels": [
"perf",
"Perf",
"Kind/Performance"
]
},
{
"title": "## 🎨 Styling",
"labels": [
"style",
"Style",
"Kind/Style"
]
},
{
"title": "## 🎯 Other Changes",
"labels": []
} }
], ],
"label_extractor": [ "label_extractor": [

View File

@@ -0,0 +1,180 @@
on:
workflow_dispatch:
inputs:
github_release:
description: 'Create Gitea Release'
default: true
type: boolean
docker_release:
description: 'Push Docker images'
default: true
type: boolean
bump:
description: 'Bump type'
required: true
default: 'patch'
type: choice
options:
- 'major'
- 'minor'
- 'patch'
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@master
with:
fetch-depth: 0
fetch-tags: true
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Set up QEMU
uses: docker/setup-qemu-action@v3
- name: Login to Docker Hub
uses: docker/login-action@v3
with:
registry: ${{ secrets.REGISTRY }}
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.TOKEN }}
- name: Install uv
uses: astral-sh/setup-uv@v5
- name: Set up Python
run: uv python install
with:
python-version-file: "pyproject.toml"
- name: Install the project
run: uv sync --all-extras --dev
- name: Create requirements.txt
run: |
echo "Creating requirements.txt"
uv export --format requirements.txt -o requirements.txt
echo "requirements.txt created"
- name: Set Git identity
run: |
git config user.name "Gitea CI"
git config user.email "ci@git.theprivateserver.de"
- name: Get Repository URL
id: get_repo_url
run: echo "REPO_URL=https://github.com/${{ github.repository }}" >> $GITHUB_OUTPUT
- name: Build Changelog
id: build_changelog
uses: https://github.com/mikepenz/release-changelog-builder-action@v5
with:
platform: "gitea"
mode: "COMMIT"
baseURL: "http://gitea:3000"
# configuration: ".gitea/changelog-config.json"
configurationJSON: |
{
"template": "#{{CHANGELOG}}",
"categories": [
{
"title": "## 🚀 Features",
"labels": ["feat"]
},
{
"title": "## 🐛 Fixes",
"labels": ["fix", "bug"]
},
{
"title": "## 🧹 Maintenance",
"labels": ["chore", "refactor", "cleanup"]
},
{
"title": "## 📦 Build",
"labels": ["build", "ci"]
},
{
"title": "## 📝 Documentation",
"labels": ["docs"]
},
{
"title": "## ⚡️ Performance Improvements",
"labels": ["perf"]
},
{
"title": "## 🧪 Tests",
"labels": ["test"]
},
{
"title": "## ⏪ Reverts",
"labels": ["revert"]
},
{
"title": "## 🎨 Styling",
"labels": ["style"]
},
{
"title": "## 🎯 Other Changes",
"labels": ["other", "misc", "enhancement"]
}
],
"label_extractor": [
{
"pattern": "^(build|chore|ci|docs|feat|fix|bug|perf|cleanup|refactor|revert|style|test){1}(\\([\\w\\-\\.]+\\))?(!)?: ([\\w ])+([\\s\\S]*)",
"target": "$1"
}
],
"empty_template": "- no changes",
"pr_template": "- [#{{TITLE}}](${{ steps.get_repo_url.outputs.REPO_URL }}/commit/#{{MERGE_SHA}}) by @#{{AUTHOR}}"
}
env:
GITHUB_TOKEN: ${{ secrets.GITEA_TOKEN }}
- name: Bump version
id: bump
run: |
uv tool install bump-my-version
uv tool run bump-my-version bump ${{ github.event.inputs.bump }} --allow-dirty
# echo the version to github env, the version is shown by using uv tool run bump-my-version show current_version
echo "VERSION<<EOF" >> $GITHUB_ENV
echo "$(uv tool run bump-my-version show current_version)" >> $GITHUB_ENV
echo "EOF" >> $GITHUB_ENV
- name: Check version
run: echo ${{ env.VERSION }}
- name: Build and store Docker image
if: ${{ github.event.inputs.docker_release == 'true' }}
run: |
REPO_NAME=$(echo "${{ github.repository }}" | tr '[:upper:]' '[:lower:]')
docker buildx build \
--platform linux/amd64 \
--tag ${{ secrets.REGISTRY }}/${REPO_NAME}:latest \
--tag ${{ secrets.REGISTRY }}/${REPO_NAME}:${{ env.VERSION }} \
--push .
- name: Push changes
uses: ad-m/github-push-action@master
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
branch: ${{ github.ref }}
- name: Create release
id: create_release
if: ${{ github.event.inputs.github_release == 'true' }}
uses: softprops/action-gh-release@master
with:
tag_name: v${{ env.VERSION }}
release_name: Release ${{ env.VERSION }}
body: ${{steps.build_changelog.outputs.changelog}}
draft: false
prerelease: false
make_latest: true
env:
GITHUB_TOKEN: ${{ secrets.TOKEN }}

View File

@@ -1,6 +1,6 @@
[project] [project]
name = "kompage" name = "kompage"
version = "0.1.1" version = "0.1.4"
description = "Add your description here" description = "Add your description here"
readme = "README.md" readme = "README.md"
requires-python = ">=3.13" requires-python = ">=3.13"
@@ -28,7 +28,7 @@ url = "https://git.theprivateserver.de/api/packages/KomSuite/pypi/simple/"
[tool.bumpversion] [tool.bumpversion]
current_version = "0.1.1" current_version = "0.1.4"
parse = "(?P<major>\\d+)\\.(?P<minor>\\d+)\\.(?P<patch>\\d+)" parse = "(?P<major>\\d+)\\.(?P<minor>\\d+)\\.(?P<patch>\\d+)"
serialize = ["{major}.{minor}.{patch}"] serialize = ["{major}.{minor}.{patch}"]
search = "{current_version}" search = "{current_version}"

View File

@@ -301,19 +301,20 @@ async def log_request():
log.debug(f"Received request data: {data}") log.debug(f"Received request data: {data}")
item = data.get("item") item = data.get("item")
if item: if item:
data = await fetch_requested_data([item]) # data = await fetch_requested_data([item])
if not data: if not data:
return jsonify({"status": "failed", "message": "Item not found"}), 404 return jsonify({"status": "failed", "message": "Item not found"}), 404
data = data[0] # data = data[0]
title = data.get("title") manga_id = item.get("id")
image_url = data.get("image") title = item.get("title")
image_url = item.get("image")
log.debug( log.debug(
f"Logging request for item: {item}, title: {title}, image_url: {image_url}" f"Logging request for item: {item}, title: {title}, image_url: {image_url}, manga_id: {manga_id}"
) )
asynccache = KomCache() asynccache = KomCache()
asynccache.insert( asynccache.insert(
f"INSERT INTO manga_requests (manga_id, title, image) VALUES ({item}, '{title}', :image)", f"INSERT INTO manga_requests (manga_id, title, image) VALUES (:manga_id, :title, :image)",
args={"image": image_url}, args={"manga_id": manga_id, "title": title, "image": image_url},
) )
return jsonify({"status": "success"}) return jsonify({"status": "success"})
return jsonify({"status": "failed"}), 400 return jsonify({"status": "failed"}), 400
@@ -324,7 +325,7 @@ async def requests_page():
cache = KomCache() cache = KomCache()
requests = ( requests = (
cache.fetch_all( cache.fetch_all(
query="SELECT manga_id, title, image grabbed FROM manga_requests" query="SELECT manga_id, title, image, grabbed FROM manga_requests"
) )
or [] or []
) )
@@ -332,23 +333,26 @@ async def requests_page():
req_ids = [req[0] for req in requests] req_ids = [req[0] for req in requests]
if req_ids: if req_ids:
entries = [ entries = [
{"manga_id": req[0], "title": req[1], "image": req[2]} for req in requests {"manga_id": req[0], "title": req[1], "image": req[2], "grabbed": req[3]}
for req in requests
] ]
else: else:
entries = [] entries = []
log.debug(f"Fetched {len(entries)} requests from the database")
log.debug(f"Requests entries: {entries}")
return await render_template("requests.html", requests=entries) return await render_template("requests.html", requests=entries)
@app.route("/delete", methods=["POST"]) @app.route("/delete", methods=["POST"])
async def delete_request(): async def delete_request():
# Delete a request from the database. ID is sent after the /delete endpoint, so: /delete/<id> # Delete a request from the database. ID is sent after the /delete endpoint, so: /delete/<id>
data = await request.get_json() data = await request.get_json()
item_id = data.get("item") log.debug(f"Received delete request data: {data}")
if item_id: if data:
title = data.get("title")
asynccache = KomCache() asynccache = KomCache()
asynccache.query( asynccache.delete(
"DELETE FROM manga_requests WHERE manga_id = :id", args={"id": item_id} "DELETE FROM manga_requests WHERE title = :title", args={"title": title}
) )
return jsonify({"status": "success"}) return jsonify({"status": "success"})
return jsonify({"status": "failed"}), 400 return jsonify({"status": "failed"}), 400

View File

@@ -20,7 +20,7 @@
{% if results %} {% if results %}
{% for result in results %} {% for result in results %}
<div class="card {{ result.type | lower }} {% if result.in_komga %}komga{% else %}requested{% endif %}"> <div class="card {{ result.type | lower }} {% if result.grabbed %}komga{% else %}requested{% endif %}">
<div class="image-container {{ 'nsfw' if result.isAdult else '' }}"> <div class="image-container {{ 'nsfw' if result.isAdult else '' }}">
@@ -44,7 +44,7 @@
{% if requests %} {% if requests %}
<div class="results"> <div class="results">
{% for request in requests %} {% for request in requests %}
<div class="card {{ request.type | lower }} {% if request.in_komga %}komga{% else %}requested{% endif %}"> <div class="card {{ request.type | lower }} {% if request.grabbed %}komga{% else %}requested{% endif %}">
<div class="image-container {{ 'nsfw' if request.isAdult else '' }}"> <div class="image-container {{ 'nsfw' if request.isAdult else '' }}">
<img src="{{ request.image }}" alt="Cover"> <img src="{{ request.image }}" alt="Cover">
@@ -56,7 +56,7 @@
<p>{{ request.title }}</p> <p>{{ request.title }}</p>
<div class="actions"> <div class="actions">
<button onclick="showInfo({{ request | tojson | safe }})" class="info">Info</button> <button onclick="showInfo({{ request | tojson | safe }})" class="info">Info</button>
<button onclick="deleteEntry({{ request.id }})" class="delete-button">Delete</button> <button onclick="deleteEntry('{{ request.title | escape }}')" class="delete-button">Delete</button>
</div> </div>
</div> </div>
{% endfor %} {% endfor %}
@@ -111,10 +111,11 @@
closeModal(); closeModal();
} }
} }
function deleteEntry(entryId) { function deleteEntry(title) {
console.log("Deleting entry with title:", title);
fetch(`/delete`, { fetch(`/delete`, {
method: 'POST', method: 'POST',
body: JSON.stringify({ item: entryId }), body: JSON.stringify({ title: title }), // Send title as part of a JSON object
headers: { headers: {
'Content-Type': 'application/json' 'Content-Type': 'application/json'
} }