- Go 1.23
- Node.js 18+ and npm
-
Build the web interface using the following command:
npm run build
-
After the build process is complete, a new
out
directory will be created insideseanime-web
. -
Move the contents of the
out
directory to a newweb
directory at the root of the project.
Build the server using the following command:
-
Windows (System Tray):
Set the environment variable
CGO_ENABLED=1
go build -o seanime.exe -trimpath -ldflags="-s -w -H=windowsgui -extldflags '-static'"
-
Windows (No System Tray):
This version is used by the desktop app for Windows.
go build -o seanime.exe -trimpath -ldflags="-s -w" -tags=nosystray
-
Linux, macOS:
go build -o seanime -trimpath -ldflags="-s -w"
Note that the web interface should be built first before building the server.
-
To get started, you must be familiar with Go and React.
-
I recommend creating a dummy AniList account to use for testing. This will prevent the tests from affecting your actual account.
-
Create/choose a dummy data directory for testing. This will prevent the server from writing to your actual data directory.
-
Create a dummy
web
folder if you want to develop the web interface too or build the web interface first and move the contents to aweb
directory at the root of the project before running the server. Either way, aweb
directory should be present at the root of the project. -
Run this command to start the server:
go run main.go --datadir="path/to/datadir"
-
Change the port in the
config.toml
located in the test data directory to43000
. The web interface will connect to this port during development. Change the host to0.0.0.0
to allow connections from other devices. -
The server will start on
http://127.0.0.1:43000
.
-
Run the web interface:
# get to web directory cd seanime-web # install dependencies npm install # run the next.js dev server npm run dev
Go to
http://127.0.0.1:43210
to access the web interface.
During development, the web interface is served by the Next.js development server instead of the Go server, leading to different ports.
The following points are very important for understanding the codebase.
- All routes are declared in
internal/handlers/routes.go
where ahandler
method is passed to each route. - Route handlers are defined in
internal/handlers
. - The comments above each route handler declaration is a form of documentation similar to OpenAPI
- These comments allow the internal code generator (
codegen/main.go
) to generate endpoint objects & types for the client. - Types for the frontend are auto-generated in
seanime-web/api/generated/types.ts
,seanime-web/api/generated/endpoint.types.ts
,seanime-web/api/generated/hooks_template.ts
based on the comments above route handlers and all public Go structs.
Run the go generate
command at the top of codegen/main.go
to generate the necessary types for the frontend.
This should be done each time you make changes to the route handlers or structs that are used in the frontend.
The following points are for understanding the AniList API integration.
Anilist queries are defined in internal/anilist/queries/*.graphql
and generated using gqlgenc
.
Run this when you make changes to the GraphQL schema.
go get github.com/Yamashou/gqlgenc
cd internal/api/anilist
go run github.com/Yamashou/gqlgenc
cd ../../..
go mod tidy
-
gqlgenc
will generate the different queries, mutations and structs associated with the AniList API and the queries we defined. These are located ininternal/api/anilist/client_gen.go
. -
In
internal/api/anilist/client.go
, we manually reimplements the different queries and mutations into aClientWrapper
struct and aMockClientWrapper
for testing. This is done to avoid using the generated code directly in the business logic. It also allows us to mock the AniList API for testing.
Do not run the tests all at once. Run them individually if you have to.
You should:
- Create a dummy AniList account and grab the access token (from the browser).
- Edit the
test/config.toml
file with the access token and the username. Useconfig.example.toml
as a template.
Tests are run using the test_utils
package. It provides a InitTestProvider
method that initializes the test config global variable.
This global variable contains the values from the test/config.toml
file.
Functions passed to InitTestProvider
skip the test if the corresponding flag is not enabled in the test/config.toml
file.
func (t *testing.T) {
test_utils.InitTestProvider(t, test_utils.Anilist())
}
Some tests will directly interact with third-party apps such as Transmission and qBittorrent. You should have them installed and running on your machine.
Edit the test/config.toml
file and individual tests to match your setup (e.g. port, password, files to open, etc.)