”工欲善其事,必先利其器。“—孔子《论语.录灵公》
首页 > 编程 > 在 Golang 中构建 Google Drive 下载器(第 1 部分)

在 Golang 中构建 Google Drive 下载器(第 1 部分)

发布于2024-11-09
浏览:741

Building a Google Drive Downloader in Golang (Part 1)

介绍

在本教程中,我们将构建一个功能强大的下载器,允许从Google Drive和其他云提供商下载文件。借助 Golang 高效的并发模式,您将能够同时管理多个下载、流式传输大文件并实时跟踪进度。无论您是下载一些小文件还是处理大型数据集,该项目都将展示如何构建可扩展且强大的下载器,该下载器可以轻松扩展以支持多个云平台。

如果您正在寻找一种简化和自动下载大文件的方法,本教程非常适合您。最后,您将拥有一个灵活且可定制的基于 Go 的下载器来满足您的需求。

匆忙?

如果您只是想在 UI 中使用此下载器,请访问 evolvasdev.com 阅读完整文章和 Go Downloader 的 Github。您将找到使其快速运行的文档。

你将学到什么

  • Go 并发模式:
    了解如何使用 Goroutines、通道和互斥体有效地处理多个并发文件下载。

  • 流式传输大量下载:
    探索如何在有效管理内存和系统资源的同时传输大文件。

  • 并发文件下载:
    了解如何同时下载文件,加快进程并提高性能。

  • 实时进度更新:
    实施进度跟踪以提供下载状态的实时反馈。

  • 处理中断和取消:
    了解如何优雅地取消一项或所有正在进行的下载。

注:本教程仅关注核心下载逻辑。

环境设置

在做任何事情之前,请首先确保正确设置您的环境,以避免将来出现潜在的错误。

先决条件

  • 安装Go
  • AIR用于自动重新加载
  • Makefile 运行复杂命令
  • Goose 用于 PostgreSQL 迁移

配置Makefile

使用以下内容在项目的根目录创建一个 makefile。

# 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

设置环境变量

根据需要在根目录中创建 .env 文件或处理环境变量,我们将使用 joho/godotenv 包。

GOOGLE_CLIENT_ID
GOOGLE_CLIENT_SECRET
SESSION_SECRET=something-super-secret
APP_URL=http://localhost:3000
POSTGRES_USER
POSTGRES_PASSWORD
POSTGRES_DB

创建网络服务器

我们现在将开始创建处理所有传入请求的 Web 服务器。

注意! 本指南的主要部分从这里开始。准备好潜入吧!

API层

首先,在 api 文件夹 api.go 和 Route.go 中创建以下文件

Route.go 文件设置

所有API路由都将在这里定义。我们创建一个采用 env 配置的 NewRouter 结构,允许所有路由和处理程序访问环境变量。

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")
    })
}

api.go 文件设置

在这里,我们将在启动服务器之前添加所有必要的中间件,例如 CORS 和日志记录。

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)
}

主入口点

这是 main.go 文件中的主包,它将作为整体的入口点。

func main() {
    // Loads all Env vars from .env file.
    env := config.MustLoadEnv()

    log.Fatal(s.Start())
}

这足以启动服务器并测试它。

启动服务器

air

就是这样。?

测试

curl http://localhost:3000/healthcheck

响应应该正常,状态为 200

创建提供商商店

我们需要实施一个可扩展的解决方案,以便在必要时添加对多个云提供商的支持。

从事提供商注册工作

// 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
}

ProviderRegistry 作为一个中央地图来保存我们所有的 OAuth 提供者。当我们初始化我们的提供者时,我们将在这个映射中注册它们。这使我们能够在整个服务过程中轻松访问任何注册提供商的功能。

您稍后会看到此操作。

初始化提供程序存储

我们将根据提供的环境变量注册我们的提供程序。

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
}

在此处阅读全文。

总结

我们已经为 Go 中的 Google Drive Downloader 奠定了基础,涵盖了设置项目结构、处理 Google OAuth 等关键组件,并为未来的扩展奠定了基础。一路上,我们触及了一些重要的话题:

  • 使用 Goose 进行数据库迁移,以确保平稳且可扩展的数据管理。
  • 构建提供商注册表以便将来轻松扩展对其他云存储提供商的支持。
  • 设计一个灵活的架构,以便轻松处理未来更复杂的逻辑。

这对于一篇文章来说已经足够了,因为事情变得相当长了!我们将在第 2 部分中回来完成我们的工作,我们将在其中处理主要的下载功能。

在那之前,请随意探索我的 GitHub 中的当前实现,并继续关注后续步骤。祝您下载愉快!

版本声明 本文转载于:https://dev.to/evolvedev/building-a-google-drive-downloader-in-golang-part-1-3fmk?1如有侵犯,请联系[email protected]删除
最新教程 更多>

免责声明: 提供的所有资源部分来自互联网,如果有侵犯您的版权或其他权益,请说明详细缘由并提供版权或权益证明然后发到邮箱:[email protected] 我们会第一时间内为您处理。

Copyright© 2022 湘ICP备2022001581号-3