Neste tutorial, construiremos um downloader poderoso que permite baixar arquivos do Google Drive e de outros provedores de nuvem. Com os padrões de simultaneidade eficientes do Golang, você poderá gerenciar vários downloads simultaneamente, transmitir arquivos grandes e acompanhar o progresso em tempo real. Esteja você baixando alguns arquivos pequenos ou lidando com grandes conjuntos de dados, este projeto mostrará como construir um downloader escalável e robusto que pode ser facilmente estendido para suportar múltiplas plataformas em nuvem.
Se você está procurando uma maneira de simplificar e automatizar o download de arquivos grandes, este tutorial é perfeito para você. No final, você terá um downloader baseado em Go flexível e personalizável para atender às suas necessidades.
Se você deseja apenas usar este downloader com uma IU, visite evolveasdev.com para ler o artigo completo e Go Downloader's Github. Você encontrará a documentação para fazê-lo funcionar rapidamente.
Padrões de simultaneidade Go:
Aprenda como usar Goroutines, canais e mutexes para lidar com vários downloads simultâneos de arquivos com eficiência.
Streaming de downloads grandes:
Explore como transmitir arquivos grandes enquanto gerencia a memória e os recursos do sistema de maneira eficaz.
Downloads simultâneos de arquivos:
Entenda como fazer download de arquivos simultaneamente, agilizando o processo e melhorando o desempenho.
Atualizações de progresso em tempo real:
Implemente o acompanhamento do progresso para fornecer feedback em tempo real sobre o status do download.
Tratamento de interrupções e cancelamentos:
Saiba como cancelar normalmente um ou todos os downloads em andamento.
Observação: Este tutorial se concentrará apenas na lógica principal de download.
Primeiro, antes de fazer qualquer coisa, certifique-se de configurar corretamente seu ambiente para evitar possíveis bugs no futuro.
Crie um makefile na raiz do projeto com o seguinte.
# Load environment variables from .env file include ./.env # To run the application run: build @./bin/go-downloader # Build the application build: @go build -tags '!dev' -o bin/go-downloader # Database migration status db-status: @GOOSE_DRIVER=postgres GOOSE_DBSTRING=$(DB_URL) goose -dir=$(migrationPath) status # Run database migrations up: @GOOSE_DRIVER=postgres GOOSE_DBSTRING=$(DB_URL) goose -dir=$(migrationPath) up # Roll back the last database migration down: @GOOSE_DRIVER=postgres GOOSE_DBSTRING=$(DB_URL) goose -dir=$(migrationPath) down # Reset database migrations reset: @GOOSE_DRIVER=postgres GOOSE_DBSTRING=$(DB_URL) goose -dir=$(migrationPath) reset
go-downloader/ ├── api ├── config ├── migrations ├── service ├── setting ├── store ├── types ├── util ├── .env ├── .air.toml ├── Makefile ├── go.mod ├── go.sum └── main.go
Crie um arquivo .env na raiz ou manipule variáveis de ambiente como quiser, usaremos o pacote joho/godotenv.
GOOGLE_CLIENT_ID GOOGLE_CLIENT_SECRET SESSION_SECRET=something-super-secret APP_URL=http://localhost:3000 POSTGRES_USER POSTGRES_PASSWORD POSTGRES_DB
Agora começaremos a criar o servidor web que irá lidar com todas as solicitações recebidas.
Atenção! A parte principal deste guia começa aqui. Prepare-se para mergulhar!
Para começar, crie os seguintes arquivos dentro da pasta api api.go e route.go
Todas as rotas de API serão definidas aqui. Criamos uma estrutura NewRouter que leva a configuração do env, permitindo que todas as rotas e manipuladores acessem variáveis de ambiente.
package api import ( "github.com/gofiber/fiber/v2" "github.com/nilotpaul/go-downloader/config" ) type Router struct { env config.EnvConfig } func NewRouter(env config.EnvConfig) *Router { return &Router{ env: env, } } func (h *Router) RegisterRoutes(r fiber.Router) { r.Get("/healthcheck", func(c *fiber.Ctx) error { return c.JSON("OK") }) }
Aqui, adicionaremos todos os middlewares necessários, como CORS e logging, antes de iniciar o servidor.
type APIServer struct { listenAddr string env config.EnvConfig } func NewAPIServer(listenAddr string, env config.EnvConfig) *APIServer { return &APIServer{ listenAddr: listenAddr, env: env, } } func (s *APIServer) Start() error { app := fiber.New(fiber.Config{ AppName: "Go Downloader", }) handler := NewRouter() handler.RegisterRoutes(app) log.Printf("Server started on http://localhost:%s", s.listenAddr) return app.Listen(":" s.listenAddr) }
Este é o pacote principal no arquivo main.go que atuará como ponto de entrada para o todo.
func main() { // Loads all Env vars from .env file. env := config.MustLoadEnv() log.Fatal(s.Start()) }
Isso é suficiente para inicializar o servidor e testá-lo.
air
é isso.?
curl http://localhost:3000/healthcheck
A resposta deve estar OK com status 200
Precisamos implementar uma solução escalável para adicionar suporte para vários provedores de nuvem, se necessário.
// Better to keep it in a seperate folder. // Specific only to OAuth Providers. type OAuthProvider interface { Authenticate(string) error GetAccessToken() string GetRefreshToken() string RefreshToken(*fiber.Ctx, string, bool) (*oauth2.Token, error) IsTokenValid() bool GetAuthURL(state string) string CreateOrUpdateAccount() (string, error) CreateSession(c *fiber.Ctx, userID string) error UpdateTokens(*GoogleAccount) error } type ProviderRegistry struct { Providers map[string]OAuthProvider } func NewProviderRegistry() *ProviderRegistry { return &ProviderRegistry{ Providers: make(map[string]OAuthProvider), } } func (r *ProviderRegistry) Register(providerName string, p OAuthProvider) { r.Providers[providerName] = p } func (r *ProviderRegistry) GetProvider(providerName string) (OAuthProvider, error) { p, exists := r.Providers[providerName] if !exists { return nil, fmt.Errorf("Provider not found") } return p, nil }
O ProviderRegistry serve como um mapa central para armazenar todos os nossos provedores OAuth. Ao inicializarmos nossos provedores, iremos registrá-los neste mapa. Isso nos permite acessar facilmente as funcionalidades de qualquer provedor registrado em todo o nosso serviço.
Você verá esta ação mais tarde.
Registraremos nossos provedores com base nas variáveis de ambiente fornecidas.
func InitStore(env config.EnvConfig) *ProviderRegistry { r := NewProviderRegistry() if len(env.GoogleClientSecret) != 0 || len(env.GoogleClientID) != 0 { googleProvider := NewGoogleProvider(googleProviderConfig{ googleClientID: env.GoogleClientID, googleClientSecret: env.GoogleClientSecret, googleRedirectURL: env.AppURL "/callback/google", }, env) r.Register("google", googleProvider) } return r }
Leia o artigo completo aqui.
Lançamos as bases para o Google Drive Downloader em Go, abrangendo componentes importantes, como a configuração da estrutura do projeto, o gerenciamento do Google OAuth e o estabelecimento das bases para futuras expansões. Ao longo do caminho, abordamos alguns tópicos importantes:
Isso é mais que suficiente para uma postagem, já que as coisas estavam ficando bem longas! Voltaremos na Parte 2 para finalizar nosso trabalho, onde trabalharemos a principal funcionalidade de download.
Até então, fique à vontade para explorar a implementação atual em meu GitHub e fique atento às próximas etapas. Bom download!
Isenção de responsabilidade: Todos os recursos fornecidos são parcialmente provenientes da Internet. Se houver qualquer violação de seus direitos autorais ou outros direitos e interesses, explique os motivos detalhados e forneça prova de direitos autorais ou direitos e interesses e envie-a para o e-mail: [email protected]. Nós cuidaremos disso para você o mais rápido possível.
Copyright© 2022 湘ICP备2022001581号-3