Compare commits

...

7 Commits

Author SHA1 Message Date
c51775592e Added subtitle language logic.
Some checks failed
ci / build-test (push) Has been cancelled
ci / publish-image (push) Has been cancelled
2025-12-22 23:33:46 -05:00
72fd878f99 Removed artifact logic from release workflow.
Some checks failed
ci / build-test (push) Successful in 2m10s
ci / publish-image (push) Has been skipped
release / Build & Publish Image (push) Successful in 20s
release / Create Gitea Release (push) Failing after 15s
release / Deploy API (Production) (push) Failing after 4s
2025-12-09 10:32:03 -05:00
69762d22ba Updated release workflow again.
Some checks failed
ci / build-test (push) Successful in 2m10s
ci / publish-image (push) Has been skipped
release / Build & Publish Image (push) Failing after 1m25s
release / Create Gitea Release (push) Has been skipped
release / Deploy API (Production) (push) Has been skipped
2025-12-09 10:21:09 -05:00
1b1e776031 Added fonts. 2025-12-09 00:59:30 -05:00
107a3b1906 Updated the release workflow.
Some checks failed
ci / build-test (push) Successful in 2m19s
ci / publish-image (push) Has been skipped
release / Build & Publish Image (push) Failing after 1m6s
release / Create Gitea Release (push) Has been skipped
release / Deploy API (Production) (push) Has been skipped
2025-12-08 23:33:35 -05:00
b6bdfd8f11 Updated release workflow.
Some checks failed
ci / build-test (push) Successful in 2m21s
ci / publish-image (push) Has been skipped
release / Build & Publish Image (push) Failing after 2s
release / Create Gitea Release (push) Has been skipped
release / Deploy API (Production) (push) Has been skipped
2025-12-08 10:20:27 -05:00
98138ad644 Added chip component. 2025-12-08 10:20:00 -05:00
14 changed files with 199 additions and 57 deletions

View File

@@ -5,39 +5,33 @@ on:
- 'v*' # v1.2.3, v1.2.3-rc.1, etc.
jobs:
build-and-publish-image:
publish-image:
name: Build & Publish Image
runs-on: [self-hosted, linux, x64, docker] # NAS or any Linux runner with Docker
runs-on: [self-hosted, linux, x64, docker]
container:
image: ghcr.io/catthehacker/ubuntu:act-latest
options: >-
--privileged
env:
REGISTRY: ${{ secrets.REGISTRY_HOST }}
OWNER_REPO: ${{ github.repository }}
DOCKERFILE: JSMR.Api/Dockerfile
CONTEXT: .
steps:
- uses: actions/checkout@v4
- uses: actions/setup-dotnet@v4
with: { dotnet-version: '9.0.x' }
- run: dotnet restore
- run: dotnet publish JSMR/JSMR.Api/JSMR.Api.csproj -c Release -o publish
- name: Create Dockerfile.ci
run: |
cat > Dockerfile.ci <<'EOF'
FROM mcr.microsoft.com/dotnet/aspnet:9.0
WORKDIR /app
COPY publish/ ./
ENV ASPNETCORE_URLS=http://+:8080
EXPOSE 8080
ENTRYPOINT ["dotnet", "JSMR.Api.dll"]
EOF
- name: Normalize image name
id: names
- name: Compute image name + tag + prerelease flag
id: meta
shell: bash
run: |
IMAGE_LC="$(echo "${REGISTRY}/${OWNER_REPO}" | tr '[:upper:]' '[:lower:]')"
echo "image=${IMAGE_LC}" >> "$GITHUB_OUTPUT"
# tag derived from ref, e.g. refs/tags/v1.3.0 -> v1.3.0
echo "tag=${GITHUB_REF_NAME}" >> "$GITHUB_OUTPUT"
if [[ "${GITHUB_REF_NAME}" == *"-"* ]]; then
echo "is_prerelease=true" >> "$GITHUB_OUTPUT"
else
echo "is_prerelease=false" >> "$GITHUB_OUTPUT"
fi
- name: Docker login
run: |
@@ -46,59 +40,106 @@ jobs:
-u "${{ secrets.REGISTRY_USER }}" \
--password-stdin
- name: Build image
run: docker build -f Dockerfile.ci -t "${{ steps.names.outputs.image }}:${{ steps.names.outputs.tag }}" .
- name: Enable BuildKit
run: echo "DOCKER_BUILDKIT=1" >> $GITHUB_ENV
- name: Push image
- name: Build (from your API Dockerfile)
run: |
docker push "${{ steps.names.outputs.image }}:${{ steps.names.outputs.tag }}"
docker tag "${{ steps.names.outputs.image }}:${{ steps.names.outputs.tag }}" "${{ steps.names.outputs.image }}:latest"
docker push "${{ steps.names.outputs.image }}:latest"
docker build \
-f "$DOCKERFILE" \
-t "${{ steps.meta.outputs.image }}:${{ steps.meta.outputs.tag }}" \
--label "org.opencontainers.image.source=${{ github.server_url }}/${{ github.repository }}" \
--label "org.opencontainers.image.version=${{ steps.meta.outputs.tag }}" \
"$CONTEXT"
- uses: actions/upload-artifact@v4
with:
name: api-publish-${{ steps.names.outputs.tag }}
path: publish
- name: Push (tagged)
run: docker push "${{ steps.meta.outputs.image }}:${{ steps.meta.outputs.tag }}"
- name: Also tag/push :latest for stable tags only
if: ${{ steps.meta.outputs.is_prerelease == 'false' }}
run: |
docker tag "${{ steps.meta.outputs.image }}:${{ steps.meta.outputs.tag }}" "${{ steps.meta.outputs.image }}:latest"
docker push "${{ steps.meta.outputs.image }}:latest"
# Optional: export a tiny text artifact with the image refs (handy for debugging)
- name: Emit image refs
run: |
echo "${{ steps.meta.outputs.image }}:${{ steps.meta.outputs.tag }}" > image.txt
if [ "${{ steps.meta.outputs.is_prerelease }}" = "false" ]; then
echo "${{ steps.meta.outputs.image }}:latest" >> image.txt
fi
create-gitea-release:
name: Create Gitea Release
needs: build-and-publish-image
needs: publish-image
runs-on: [self-hosted, linux, x64, docker]
container:
image: ghcr.io/catthehacker/ubuntu:act-latest
options: >-
--privileged
steps:
- uses: actions/checkout@v4
# simplest notes: use tag message (annotated) and attach image refs
- name: Generate basic notes
id: notes
- name: Install jq (for safe JSON quoting)
run: |
echo "## Release $GITHUB_REF_NAME" > REL_NOTES.md
echo "" >> REL_NOTES.md
echo "- Image: ${{ secrets.REGISTRY_HOST }}/${{ github.repository }}:${GITHUB_REF_NAME}" >> REL_NOTES.md
echo "- Latest: ${{ secrets.REGISTRY_HOST }}/${{ github.repository }}:latest" >> REL_NOTES.md
apt-get update -y
apt-get install -y jq curl
# Gitea has a create-release action too; if not, use API curl
- name: Create Release via API
- name: Prepare release notes
id: notes
env:
GITEA_BASE: ${{ secrets.GITEA_BASE_URL }} # e.g. https://gitea.example.com
TOKEN: ${{ secrets.GITEA_TOKEN }} # personal access token w/ repo write
REGISTRY: ${{ secrets.REGISTRY_HOST }}
REPO: ${{ github.repository }}
shell: bash
run: |
TAG="${GITHUB_REF_NAME}"
IMG="${REGISTRY}/${REPO}:${TAG}"
cat > REL_NOTES.md <<EOF
## ${TAG}
**Images**
- \`${IMG}\`
EOF
# Add :latest mention only for stable tags
if [[ "$TAG" != *"-"* ]]; then
echo "- \`${REGISTRY}/${REPO}:latest\`" >> REL_NOTES.md
fi
- name: Create or Update Release via Gitea API
env:
GITEA_BASE: ${{ secrets.GITEA_BASE_URL }}
TOKEN: ${{ secrets.GITEA_TOKEN }}
shell: bash
run: |
TAG="${GITHUB_REF_NAME}"
BODY="$(cat REL_NOTES.md)"
curl -sS -X POST "${GITEA_BASE}/api/v1/repos/${{ github.repository }}/releases" \
-H "Authorization: token ${TOKEN}" \
-H "Content-Type: application/json" \
-d @- <<JSON
{
"tag_name": "${GITHUB_REF_NAME}",
"name": "${GITHUB_REF_NAME}",
"body": ${jq@JSON:- <<<'$BODY'},
"draft": false,
"prerelease": ${GITHUB_REF_NAME##*-rc*:+false}${GITHUB_REF_NAME##*-rc*:-true}
}
JSON
IS_PRERELEASE=false
[[ "$TAG" == *"-"* ]] && IS_PRERELEASE=true
# Try to get existing release by tag
set +e
EXISTING=$(curl -s -H "Authorization: token ${TOKEN}" "${GITEA_BASE}/api/v1/repos/${{ github.repository }}/releases/tags/${TAG}")
STATUS=$?
set -e
if echo "$EXISTING" | jq -e .id >/dev/null 2>&1; then
REL_ID=$(echo "$EXISTING" | jq -r .id)
# Update
curl -sS -X PATCH "${GITEA_BASE}/api/v1/repos/${{ github.repository }}/releases/${REL_ID}" \
-H "Authorization: token ${TOKEN}" \
-H "Content-Type: application/json" \
-d "$(jq -n --arg t "$TAG" --arg b "$BODY" --argjson pre $IS_PRERELEASE '{name:$t, body:$b, prerelease:$pre}')" >/dev/null
else
# Create
curl -sS -X POST "${GITEA_BASE}/api/v1/repos/${{ github.repository }}/releases" \
-H "Authorization: token ${TOKEN}" \
-H "Content-Type: application/json" \
-d "$(jq -n --arg t "$TAG" --arg b "$BODY" --argjson pre $IS_PRERELEASE '{tag_name:$t, name:$t, body:$b, draft:false, prerelease:$pre}')" >/dev/null
fi
deploy-api:
name: Deploy API (Production)
needs: build-and-publish-image
needs: publish-image
runs-on: [self-hosted, linux, x64, docker] # your Synology runner
environment: production # optional: add env protection rules in Gitea
steps:

View File

@@ -190,6 +190,7 @@ public class VoiceWorkUpdater(AppDbContext dbContext, ITimeProvider timeProvider
voiceWork.StarRating = ingest.StarRating;
voiceWork.Votes = ingest.Votes;
voiceWork.OriginalProductId = ingest.Translation?.OriginalProductId;
voiceWork.SubtitleLanguage = GetSubtitleLanguage(ingest);
voiceWork.AIGeneration = (byte)ingest.AI;
voiceWork.IsValid = true;
voiceWork.LastScannedDate = ComputeLastScannedDate(voiceWork.LastScannedDate, state, upsertContext);
@@ -266,6 +267,36 @@ public class VoiceWorkUpdater(AppDbContext dbContext, ITimeProvider timeProvider
return state.WentOnSale ? current : existing ?? current;
}
private static byte GetSubtitleLanguage(VoiceWorkIngest ingest)
{
Language[] orderedLanguages =
[
Language.English,
Language.ChineseSimplified,
Language.ChineseTraditional,
Language.Korean
];
foreach (Language language in orderedLanguages)
{
if (ingest.SupportedLanguages.Any(x => x.Language == language))
{
switch (language)
{
case Language.English:
return 1;
case Language.ChineseSimplified:
case Language.ChineseTraditional:
return 2;
case Language.Korean:
return 3;
}
}
}
return 0;
}
private void UpsertTags(VoiceWorkIngest ingest, VoiceWorkUpsertContext upsertContext)
{
foreach (string tagName in ingest.Tags)

View File

@@ -0,0 +1,20 @@
@using JSMR.UI.Blazor.Enums
<div class="j-chip">
@if (Graphic != null)
{
<Icon Graphic="@Graphic.Value" Color="@Color"></Icon>
}
<span>@ChildContent</span>
</div>
@code {
[Parameter]
public RenderFragment? ChildContent { get; set; }
[Parameter]
public Graphic? Graphic { get; set; }
[Parameter]
public ColorVarient Color { get; set; } = ColorVarient.Primary;
}

View File

@@ -6,6 +6,7 @@
<ImplicitUsings>enable</ImplicitUsings>
<ServiceWorkerAssetsManifest>service-worker-assets.js</ServiceWorkerAssetsManifest>
<RunAOTCompilation>false</RunAOTCompilation>
<UserSecretsId>ef618c0a-0813-4cb9-a3db-81757469494a</UserSecretsId>
</PropertyGroup>
<ItemGroup>

View File

@@ -608,6 +608,15 @@ code {
font-weight: 500;*/
}
/* Chips */
.j-chip {
display: flex;
align-items: center;
gap: .5rem;
font-size: 1rem;
font-weight: 500;
}
/* Icons */
.j-icon {
mask-repeat: no-repeat;

View File

@@ -0,0 +1,39 @@
@font-face {
font-family: "Poppins";
src: url("../fonts/Poppins-Regular.otf") format("openType");
}
@font-face {
font-family: "Poppins";
src: url("../fonts/Poppins-Light.otf") format("openType");
font-weight: 300;
}
@font-face {
font-family: "Poppins";
src: url("../fonts/Poppins-Medium.otf") format("openType");
font-weight: 500;
}
@font-face {
font-family: "Poppins";
src: url("../fonts/Poppins-SemiBold.otf") format("openType");
font-weight: 600;
}
@font-face {
font-family: "Poppins";
src: url("../fonts/Poppins-Bold.otf") format("openType");
font-weight: 700;
}
@font-face {
font-family: "M+ 1p";
src: url("../fonts/mplus-1p-regular.ttf") format("trueType");
}
@font-face {
font-family: "M+ 1p";
src: url("../fonts/mplus-1p-bold.ttf") format("trueType");
font-weight: 700;
}

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -24,6 +24,7 @@
<link rel="stylesheet" href="css/radzen.css" />
<link href="_content/Bit.BlazorUI/styles/bit.blazorui.css" rel="stylesheet" />
<link rel="stylesheet" href="css/bit-blazor.css" />
<link rel="stylesheet" href="css/font.css" />
<link rel="stylesheet" href="css/app.css" />
<link rel="stylesheet" href="css/theme-base.css" />
<link rel="stylesheet" href="css/theme-frozen.css" />