Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adiciona --mirror no comando de download #207

Merged
merged 1 commit into from
Feb 27, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions cmd/download.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ var (
chunkSize int64
skipExistingFiles bool
restart bool
mirror string
)

var downloadCmd = &cobra.Command{
Expand All @@ -50,6 +51,9 @@ var downloadCmd = &cobra.Command{
if err != nil {
return err
}
if mirror != "" {
return download.DownloadFromMirror(mirror, dir, dur, skipExistingFiles, restart, parallelDownloads, downloadRetries, chunkSize)
}
return download.Download(dir, dur, skipExistingFiles, restart, parallelDownloads, downloadRetries, chunkSize)
},
}
Expand Down Expand Up @@ -93,6 +97,7 @@ func downloadCLI() *cobra.Command {
downloadCmd.Flags().IntVarP(&parallelDownloads, "parallel", "p", download.DefaultMaxParallel, "maximum parallel downloads")
downloadCmd.Flags().Int64VarP(&chunkSize, "chunk-size", "c", download.DefaultChunkSize, "max length of the bytes range for each HTTP request")
downloadCmd.Flags().BoolVarP(&restart, "restart", "e", false, "restart all downloads from the beginning")
downloadCmd.Flags().StringVarP(&mirror, "mirror", "m", "", "download from the mirror, not from the original source (YYYY-MM-DD)")
return downloadCmd
}

Expand Down
5 changes: 5 additions & 0 deletions docs/servidor.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,13 +29,18 @@ Caso o download falhe, é recomendado variar as configurações explicadas no `-

Em último caso, é possível listar as URLs para download dos arquivos com comando `urls`; e, então, tentar fazer o download de outra forma (manualmente, com alguma ferramenta que permite recomeçar downloads interrompidos, etc.).

### Espelho dos dados

O _Minha Receita_ mantém um [espelho dos dados em uma diretório compartilhado](https://mirror.minhareceita.org). Você pode fazer o download dos arquivos de lá (ao invés de utilisar o servidor oficial) com a opção `--mirror YYYY-MM-DD` substituindo a data por alguma das disponíveis no espelho.

### Exemplos de uso

Sem Docker:

```console
$ minha-receita download --urls-only
$ minha-receita download --timeout 1h42m12s
$ minha-receita download --mirror 2022-12-17
```

Com Docker:
Expand Down
12 changes: 12 additions & 0 deletions download/download.go
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,18 @@ func Download(dir string, timeout time.Duration, skip, restart bool, parallel in
return nil
}

// Download all the files from the project's mirror
func DownloadFromMirror(mirror string, dir string, timeout time.Duration, skip, restart bool, parallel int, retries uint, chunkSize int64) error {
urls, err := getMirrorURLs(mirror)
if err != nil {
return fmt.Errorf("error getting mirror urls: %w", err)
}
if err := download(dir, urls, parallel, retries, chunkSize, timeout, restart); err != nil {
return fmt.Errorf("error downloading files from the mirror: %w", err)
}
return nil
}

// URLs shows the URLs to be downloaded.
func URLs(dir string, skip bool) error {
urls := []string{federalRevenueURL, nationalTreasureBaseURL}
Expand Down
60 changes: 60 additions & 0 deletions download/mirror.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
package download

import (
"encoding/json"
"fmt"
"net/http"
"strings"
)

const mirrorURL = "https://mirror.minhareceita.org"

// TODO: do we need to export these structs?
type MirrorFile struct {
URL string `json:"url"`
Size uint `json:"size"`
}

type MirrorGroup struct {
Name string `json:"name"`
URLs []MirrorFile `json:"urls"`
}

type MirrorResponse struct {
Data []MirrorGroup `json:"data"`
}

func getMirrorURLs(t string) ([]string, error) {
c := &http.Client{}
req, err := http.NewRequest("GET", mirrorURL, nil)
if err != nil {
return []string{}, fmt.Errorf("error creating request for mirror: %w", err)
}
req.Header.Set("Accept", "application/json")
r, err := c.Do(req)
if err != nil {
return []string{}, fmt.Errorf("error sending request to mirror: %w", err)
}
defer r.Body.Close()
var gs MirrorResponse
if err = json.NewDecoder(r.Body).Decode(&gs); err != nil {
return []string{}, fmt.Errorf("error decoding response body: %w", err)
}
var urls []string
var opts []string
for _, g := range gs.Data {
if g.Name == t {
for _, u := range g.URLs {
if u.Size > 0 {
urls = append(urls, u.URL)
}
}
break
}
opts = append(opts, g.Name)
}
if len(urls) == 0 {
return []string{}, fmt.Errorf("unknown mirror identifier `%s`, options are: %s", t, strings.Join(opts, ", "))
}
return urls, nil
}
Loading