85 lines
1.9 KiB
Go
85 lines
1.9 KiB
Go
// forgejo.go
|
|
package main
|
|
|
|
import (
|
|
"fmt"
|
|
|
|
forgejo "codeberg.org/mvdkleijn/forgejo-sdk/forgejo/v3"
|
|
)
|
|
|
|
// ForgejoScraper retrieves public repositories from a Forgejo instance.
|
|
type ForgejoScraper struct {
|
|
Client *forgejo.Client
|
|
PageSize int
|
|
}
|
|
|
|
// NewForgejoScraper creates a scraper for a Forgejo instance.
|
|
// BaseURL should be the instance URL, e.g. https://codeberg.org.
|
|
func NewForgejoScraper(baseURL string) (*ForgejoScraper, error) {
|
|
client, err := forgejo.NewClient(baseURL)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("create Forgejo client: %w", err)
|
|
}
|
|
|
|
return &ForgejoScraper{
|
|
Client: client,
|
|
PageSize: 50,
|
|
}, nil
|
|
}
|
|
|
|
// GetProjects retrieves every public repository visible through the
|
|
// Forgejo repository search API and maps it to the generic Project type.
|
|
func (s *ForgejoScraper) GetProjects() ([]Project, error) {
|
|
pageSize := s.PageSize
|
|
if pageSize <= 0 {
|
|
pageSize = 50
|
|
}
|
|
|
|
isPrivate := false
|
|
var projects []Project
|
|
|
|
for page := 1; ; page++ {
|
|
repos, _, err := s.Client.SearchRepos(forgejo.SearchRepoOptions{
|
|
ListOptions: forgejo.ListOptions{
|
|
Page: page,
|
|
PageSize: pageSize,
|
|
},
|
|
IsPrivate: &isPrivate,
|
|
Sort: "alpha",
|
|
Order: "asc",
|
|
})
|
|
if err != nil {
|
|
return nil, fmt.Errorf(
|
|
"list public Forgejo repositories (page %d): %w",
|
|
page,
|
|
err,
|
|
)
|
|
}
|
|
|
|
if len(repos) == 0 {
|
|
break
|
|
}
|
|
|
|
for _, repo := range repos {
|
|
if repo == nil {
|
|
continue
|
|
}
|
|
|
|
projects = append(projects, Project{
|
|
Name: repo.FullName,
|
|
Url: repo.HTMLURL,
|
|
Description: repo.Description,
|
|
Topics: repo.Topics,
|
|
OpenIssues: repo.OpenIssues,
|
|
OpenPRs: repo.OpenPulls,
|
|
})
|
|
}
|
|
|
|
// A short page indicates that there are no further results.
|
|
if len(repos) < pageSize {
|
|
break
|
|
}
|
|
}
|
|
|
|
return projects, nil
|
|
}
|