Github Repo Updates

- Upgrades Docker Go to 1.24
 - Fixes lint errors
 - Adds github docker build and push workflow
 - Adds github golang lint workflow
 - Exposes port in Dockerfile
 - Adds gitignore file
pull/7/head
Nat Welch 8 months ago
parent 925dc8a40b
commit 866cd4e580
No known key found for this signature in database
GPG Key ID: A931B605C4EEF77F

@ -0,0 +1,47 @@
name: Create and publish Docker image
on:
push:
branches:
- main
pull_request:
env:
REGISTRY: ghcr.io
IMAGE_NAME: ${{ github.repository }}
jobs:
build-and-push-image:
runs-on: ubuntu-latest
permissions:
contents: read
packages: write
attestations: write
id-token: write
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Log in to the Container registry
uses: docker/login-action@v3
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Extract metadata (tags, labels) for Docker
id: meta
uses: docker/metadata-action@v5
with:
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
- name: Build and push Docker image
id: push
uses: docker/build-push-action@v6
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
context: .
push: ${{ github.ref == 'refs/heads/main' }}
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
- name: Generate artifact attestation
uses: actions/attest-build-provenance@v2
with:
subject-name: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME}}
subject-digest: ${{ steps.push.outputs.digest }}
push-to-registry: ${{ github.ref == 'refs/heads/main' }}

@ -0,0 +1,23 @@
name: golangci-lint
on:
push:
tags:
- v*
branches:
- master
- main
pull_request:
jobs:
golangci:
name: lint
runs-on: ubuntu-latest
permissions:
contents: write
pull-requests: write
steps:
- uses: actions/checkout@v4
- name: golangci-lint
uses: golangci/golangci-lint-action@v7
with:
version: latest
args: -E bodyclose,misspell,gosec,goconst,errorlint

1
.gitignore vendored

@ -0,0 +1 @@
sonarr-anime-importer

@ -1,5 +1,5 @@
## syntax=docker/dockerfile:1
FROM golang:1.23
FROM golang:1.24
WORKDIR /app
COPY go.mod go.sum ./
RUN go mod download

@ -102,9 +102,13 @@ func handleAniListAnimeSearch(idMap *ConcurrentMap, permaSkipIds []string) http.
search, err := getAniListAnimeSearch(idMap, permaSkipIds, r)
if err != nil {
w.WriteHeader(500)
w.Write([]byte(err.Error()))
if _, writeErr := w.Write([]byte(err.Error())); writeErr != nil {
log.Printf("Error writing error response: %v", writeErr)
}
} else {
w.Write(search)
if _, writeErr := w.Write(search); writeErr != nil {
log.Printf("Error writing response: %v", writeErr)
}
}
}
}
@ -187,7 +191,7 @@ func makeAniListApiCall(q url.Values) (*AniListApiResponse, error) {
// Build the GraphQL request body
variables := BuildGraphQLVariables(q)
body := map[string]interface{}{
body := map[string]any{
"query": anilistQuery,
"variables": variables,
}
@ -201,7 +205,11 @@ func makeAniListApiCall(q url.Values) (*AniListApiResponse, error) {
if err != nil {
return nil, err
}
defer resp.Body.Close()
defer func() {
if closeErr := resp.Body.Close(); closeErr != nil {
log.Printf("Error closing response body: %v", closeErr)
}
}()
respData := new(AniListApiResponse)
err = json.NewDecoder(resp.Body).Decode(respData)
@ -212,8 +220,8 @@ func makeAniListApiCall(q url.Values) (*AniListApiResponse, error) {
}
// BuildGraphQLVariables converts URL query parameters into a GraphQL variables map.
func BuildGraphQLVariables(params url.Values) map[string]interface{} {
vars := make(map[string]interface{})
func BuildGraphQLVariables(params url.Values) map[string]any {
vars := make(map[string]any)
// Helper to convert comma-separated strings into slices
parseList := func(key string) []string {

@ -20,11 +20,13 @@ type ResponseItem struct {
AniListId int `json:"anilistId,omitempty"`
TvdbId int `json:"tvdbId"`
}
type AnimeEntry struct {
TvdbId int `json:"tvdb_id"`
MalId interface{} `json:"mal_id"`
AniListId int `json:"anilist_id"`
TvdbId int `json:"tvdb_id"`
MalId any `json:"mal_id"`
AniListId int `json:"anilist_id"`
}
type ConcurrentMap struct {
mal map[int]int
mut sync.RWMutex
@ -38,8 +40,10 @@ func (m *ConcurrentMap) GetByMalId(i int) int {
var lastBuiltAnimeIdList time.Time
const Version = "v0.2.1"
func main() {
log.Println("sonarr-anime-importer v0.2.1")
log.Printf("sonarr-anime-importer %s", Version)
log.Println("Building Anime ID Associations...")
var idMap = new(ConcurrentMap)
buildIdMap(idMap)
@ -57,7 +61,14 @@ func main() {
http.HandleFunc("/v1/mal/anime", loggerMiddleware(buildIdMapMiddleware(handleMalAnimeSearch(idMap, permaSkipMalIds))))
http.HandleFunc("/v1/anilist/anime", loggerMiddleware(buildIdMapMiddleware(handleAniListAnimeSearch(idMap, permaSkipAniListIds))))
log.Println("Listening on :3333")
log.Fatal(http.ListenAndServe(":3333", nil))
srv := &http.Server{
Addr: ":3333",
ReadTimeout: 10 * time.Second,
WriteTimeout: 10 * time.Second,
IdleTimeout: 120 * time.Second,
}
log.Fatal(srv.ListenAndServe())
}
func buildIdMap(idMap *ConcurrentMap) {
@ -69,7 +80,11 @@ func buildIdMap(idMap *ConcurrentMap) {
if err != nil {
log.Fatal("Error fetching anime_ids.json: ", err)
}
defer resp.Body.Close()
defer func() {
if closeErr := resp.Body.Close(); closeErr != nil {
log.Printf("Error closing response body: %v", closeErr)
}
}()
idListBytes, err = io.ReadAll(resp.Body)
if err != nil {
log.Fatal("Error reading anime_ids.json: ", err)

@ -17,9 +17,13 @@ func handleMalAnimeSearch(idMap *ConcurrentMap, permaSkipMalIds []string) http.H
search, err := getJikanAnimeSearch(idMap, permaSkipMalIds, r)
if err != nil {
w.WriteHeader(500)
w.Write([]byte(err.Error()))
if _, writeErr := w.Write([]byte(err.Error())); writeErr != nil {
log.Printf("Error writing error response: %v", writeErr)
}
} else {
w.Write([]byte(search))
if _, writeErr := w.Write([]byte(search)); writeErr != nil {
log.Printf("Error writing response: %v", writeErr)
}
}
})
}

Loading…
Cancel
Save