fix(importer): use full file info endpoint for curseforge
This commit is contained in:
@@ -55,37 +55,35 @@ func (i *CurseForgeImporter) downloadAndProcessFile(url string) (hash string, si
|
|||||||
return baseImporter.processFile(resp.Body)
|
return baseImporter.processFile(resp.Body)
|
||||||
}
|
}
|
||||||
|
|
||||||
// getFileDownloadURL получает прямую ссылку на скачивание файла с API CurseForge.
|
// getFileInfo получает полную информацию о файле, включая URL для скачивания.
|
||||||
func (i *CurseForgeImporter) getFileDownloadURL(projectID, fileID int) (string, error) {
|
func (i *CurseForgeImporter) getFileInfo(projectID, fileID int) (*CurseForgeFile, error) {
|
||||||
apiURL := fmt.Sprintf("https://api.curseforge.com/v1/mods/%d/files/%d/download-url", projectID, fileID)
|
apiURL := fmt.Sprintf("https://api.curseforge.com/v1/mods/%d/files/%d", projectID, fileID)
|
||||||
req, err := http.NewRequestWithContext(context.Background(), "GET", apiURL, nil)
|
req, err := http.NewRequestWithContext(context.Background(), "GET", apiURL, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return nil, err
|
||||||
}
|
}
|
||||||
req.Header.Set("x-api-key", i.APIKey)
|
req.Header.Set("x-api-key", i.APIKey)
|
||||||
|
|
||||||
resp, err := i.HTTPClient.Do(req)
|
resp, err := i.HTTPClient.Do(req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return nil, err
|
||||||
}
|
}
|
||||||
defer resp.Body.Close()
|
defer resp.Body.Close()
|
||||||
|
|
||||||
if resp.StatusCode != http.StatusOK {
|
if resp.StatusCode != http.StatusOK {
|
||||||
return "", fmt.Errorf("bad status getting download URL: %s", resp.Status)
|
return nil, fmt.Errorf("bad status getting file info for fileID %d: %s", fileID, resp.Status)
|
||||||
}
|
}
|
||||||
|
|
||||||
var result struct {
|
var fileInfo CurseForgeFile
|
||||||
Data string `json:"data"`
|
if err := json.NewDecoder(resp.Body).Decode(&fileInfo); err != nil {
|
||||||
}
|
return nil, fmt.Errorf("failed to decode file info response: %w", err)
|
||||||
if err := json.NewDecoder(resp.Body).Decode(&result); err != nil {
|
|
||||||
return "", fmt.Errorf("failed to decode download URL response: %w", err)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if result.Data == "" {
|
if fileInfo.Data.DownloadURL == "" {
|
||||||
return "", fmt.Errorf("received empty download URL from API")
|
return nil, fmt.Errorf("received empty download URL from API for fileID %d", fileID)
|
||||||
}
|
}
|
||||||
|
|
||||||
return result.Data, nil
|
return &fileInfo, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// findModpackBySlug ищет ID проекта по его "слагу" (части URL).
|
// findModpackBySlug ищет ID проекта по его "слагу" (части URL).
|
||||||
@@ -223,17 +221,20 @@ func (i *CurseForgeImporter) Import(zipPath string) ([]models.ModpackFile, error
|
|||||||
var files []models.ModpackFile
|
var files []models.ModpackFile
|
||||||
|
|
||||||
for _, modFile := range manifest.Files {
|
for _, modFile := range manifest.Files {
|
||||||
downloadURL, err := i.getFileDownloadURL(modFile.ProjectID, modFile.FileID)
|
fileInfo, err := i.getFileInfo(modFile.ProjectID, modFile.FileID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("failed to get download url for fileID %d: %w", modFile.FileID, err)
|
return nil, fmt.Errorf("failed to get info for fileID %d: %w", modFile.FileID, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
downloadURL := fileInfo.Data.DownloadURL
|
||||||
|
fileName := fileInfo.Data.FileName
|
||||||
|
|
||||||
hash, size, err := i.downloadAndProcessFile(downloadURL)
|
hash, size, err := i.downloadAndProcessFile(downloadURL)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("failed to process downloaded file for fileID %d: %w", modFile.FileID, err)
|
return nil, fmt.Errorf("failed to process downloaded file '%s' (fileID %d): %w", fileName, modFile.FileID, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
relativePath := filepath.Join("mods", fmt.Sprintf("%d-%d.jar", modFile.ProjectID, modFile.FileID))
|
relativePath := filepath.Join("mods", fileName)
|
||||||
|
|
||||||
files = append(files, models.ModpackFile{
|
files = append(files, models.ModpackFile{
|
||||||
RelativePath: relativePath,
|
RelativePath: relativePath,
|
||||||
|
|||||||
@@ -40,3 +40,13 @@ type CurseForgeFilesResponse struct {
|
|||||||
TotalCount int `json:"totalCount"`
|
TotalCount int `json:"totalCount"`
|
||||||
} `json:"pagination"`
|
} `json:"pagination"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// CurseForgeFile представляет полную информацию о файле с API.
|
||||||
|
type CurseForgeFile struct {
|
||||||
|
Data struct {
|
||||||
|
ID int `json:"id"`
|
||||||
|
FileName string `json:"fileName"`
|
||||||
|
DownloadURL string `json:"downloadUrl"`
|
||||||
|
// ... можно добавить другие поля, если понадобятся
|
||||||
|
} `json:"data"`
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user