Skip to content

Commit 30f759b

Browse files
authored
Merge pull request #207 from cuducos/download-from-mirror
Adiciona `--mirror` no comando de download
2 parents 4702698 + 4a1b6fa commit 30f759b

File tree

4 files changed

+82
-0
lines changed

4 files changed

+82
-0
lines changed

cmd/download.go

+5
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ var (
3636
chunkSize int64
3737
skipExistingFiles bool
3838
restart bool
39+
mirror string
3940
)
4041

4142
var downloadCmd = &cobra.Command{
@@ -50,6 +51,9 @@ var downloadCmd = &cobra.Command{
5051
if err != nil {
5152
return err
5253
}
54+
if mirror != "" {
55+
return download.DownloadFromMirror(mirror, dir, dur, skipExistingFiles, restart, parallelDownloads, downloadRetries, chunkSize)
56+
}
5357
return download.Download(dir, dur, skipExistingFiles, restart, parallelDownloads, downloadRetries, chunkSize)
5458
},
5559
}
@@ -93,6 +97,7 @@ func downloadCLI() *cobra.Command {
9397
downloadCmd.Flags().IntVarP(&parallelDownloads, "parallel", "p", download.DefaultMaxParallel, "maximum parallel downloads")
9498
downloadCmd.Flags().Int64VarP(&chunkSize, "chunk-size", "c", download.DefaultChunkSize, "max length of the bytes range for each HTTP request")
9599
downloadCmd.Flags().BoolVarP(&restart, "restart", "e", false, "restart all downloads from the beginning")
100+
downloadCmd.Flags().StringVarP(&mirror, "mirror", "m", "", "download from the mirror, not from the original source (YYYY-MM-DD)")
96101
return downloadCmd
97102
}
98103

docs/servidor.md

+5
Original file line numberDiff line numberDiff line change
@@ -29,13 +29,18 @@ Caso o download falhe, é recomendado variar as configurações explicadas no `-
2929

3030
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.).
3131

32+
### Espelho dos dados
33+
34+
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.
35+
3236
### Exemplos de uso
3337

3438
Sem Docker:
3539

3640
```console
3741
$ minha-receita download --urls-only
3842
$ minha-receita download --timeout 1h42m12s
43+
$ minha-receita download --mirror 2022-12-17
3944
```
4045

4146
Com Docker:

download/download.go

+12
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,18 @@ func Download(dir string, timeout time.Duration, skip, restart bool, parallel in
7575
return nil
7676
}
7777

78+
// Download all the files from the project's mirror
79+
func DownloadFromMirror(mirror string, dir string, timeout time.Duration, skip, restart bool, parallel int, retries uint, chunkSize int64) error {
80+
urls, err := getMirrorURLs(mirror)
81+
if err != nil {
82+
return fmt.Errorf("error getting mirror urls: %w", err)
83+
}
84+
if err := download(dir, urls, parallel, retries, chunkSize, timeout, restart); err != nil {
85+
return fmt.Errorf("error downloading files from the mirror: %w", err)
86+
}
87+
return nil
88+
}
89+
7890
// URLs shows the URLs to be downloaded.
7991
func URLs(dir string, skip bool) error {
8092
urls := []string{federalRevenueURL, nationalTreasureBaseURL}

download/mirror.go

+60
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
package download
2+
3+
import (
4+
"encoding/json"
5+
"fmt"
6+
"net/http"
7+
"strings"
8+
)
9+
10+
const mirrorURL = "https://mirror.minhareceita.org"
11+
12+
// TODO: do we need to export these structs?
13+
type MirrorFile struct {
14+
URL string `json:"url"`
15+
Size uint `json:"size"`
16+
}
17+
18+
type MirrorGroup struct {
19+
Name string `json:"name"`
20+
URLs []MirrorFile `json:"urls"`
21+
}
22+
23+
type MirrorResponse struct {
24+
Data []MirrorGroup `json:"data"`
25+
}
26+
27+
func getMirrorURLs(t string) ([]string, error) {
28+
c := &http.Client{}
29+
req, err := http.NewRequest("GET", mirrorURL, nil)
30+
if err != nil {
31+
return []string{}, fmt.Errorf("error creating request for mirror: %w", err)
32+
}
33+
req.Header.Set("Accept", "application/json")
34+
r, err := c.Do(req)
35+
if err != nil {
36+
return []string{}, fmt.Errorf("error sending request to mirror: %w", err)
37+
}
38+
defer r.Body.Close()
39+
var gs MirrorResponse
40+
if err = json.NewDecoder(r.Body).Decode(&gs); err != nil {
41+
return []string{}, fmt.Errorf("error decoding response body: %w", err)
42+
}
43+
var urls []string
44+
var opts []string
45+
for _, g := range gs.Data {
46+
if g.Name == t {
47+
for _, u := range g.URLs {
48+
if u.Size > 0 {
49+
urls = append(urls, u.URL)
50+
}
51+
}
52+
break
53+
}
54+
opts = append(opts, g.Name)
55+
}
56+
if len(urls) == 0 {
57+
return []string{}, fmt.Errorf("unknown mirror identifier `%s`, options are: %s", t, strings.Join(opts, ", "))
58+
}
59+
return urls, nil
60+
}

0 commit comments

Comments
 (0)