🚀 chore: add initial project setup with docker, go modules, and basic api structure

Add docker configuration for building and running the application, including a dockerfile and docker-compose.yml. Set up go modules with dependencies and create the basic api structure with main.go, models, and wrapper files. Include .dockerignore and .gitignore files to manage ignored files and directories. Add constants for ipatool path and global flags.
This commit is contained in:
2026-03-10 03:41:41 +03:00
commit d763b0b652
13 changed files with 565 additions and 0 deletions

101
main.go Normal file
View File

@ -0,0 +1,101 @@
package main
import (
"context"
"errors"
"flag"
"fmt"
"io"
"ipa/IPAGo/models"
"ipa/IPAGo/wrapper"
"net/http"
"os"
"path/filepath"
"time"
"github.com/danielgtaylor/huma/v2"
"github.com/danielgtaylor/huma/v2/adapters/humago"
)
const (
version = "1.0.1"
)
func main() {
port := flag.Int("port", 8888, "Port to listen on")
flag.Parse()
mux := http.NewServeMux()
config := huma.DefaultConfig("IPAGo", version)
config.CreateHooks = nil
api := humago.New(mux, config)
huma.Get(
api, "/auth/login",
func(ctx context.Context, input *models.AuthInput) (*models.AuthOutput, error) {
output := &models.AuthOutput{}
output.Body.Success = wrapper.Auth(input.User, input.Pswd, input.Code)
return output, nil
})
huma.Get(
api, "/auth/info",
func(ctx context.Context, input *models.AuthInfoInput) (*models.AuthInfoOutput, error) {
output := &models.AuthInfoOutput{}
output.Body.Success = wrapper.AuthInfo(input.User, input.Pswd)
return output, nil
})
huma.Get(
api, "/search",
func(ctx context.Context, input *models.SearchInput) (*models.SearchOutput, error) {
output := &models.SearchOutput{}
output.Body.Apps = []wrapper.App{}
output.Body.Success = false
if input.Limit == 0 {
input.Limit = 1
}
if input.Query == "" {
return output, nil
}
apps, err := wrapper.Search(input.Query, input.Limit)
if err != nil {
return output, nil
}
output.Body.Success = true
output.Body.Apps = apps
return output, nil
})
huma.Get(
api, "/download",
func(ctx context.Context, input *models.DownloadInput) (*models.DownloadOutput, error) {
outputPath := filepath.Join(os.TempDir(), fmt.Sprintf("%s.ipa", time.Now().Format("20060102150405")))
output := &models.DownloadOutput{}
if input.BundleID == "" {
return nil, errors.New("bundleID is empty")
}
success := wrapper.Download(input.BundleID, outputPath)
if !success {
return nil, errors.New("failed to download")
}
output.ContentDisposition = fmt.Sprintf("attachment; filename=%s", filepath.Base(outputPath))
output.ContentType = "application/octet-stream"
output.Body = func(hctx huma.Context) {
file, err := os.Open(outputPath)
if err != nil {
return
}
defer file.Close()
io.Copy(hctx.BodyWriter(), file)
}
return output, nil
})
addr := fmt.Sprintf(":%d", *port)
fmt.Printf("Server is running on %s\n", addr)
http.ListenAndServe(addr, mux)
}