diff --git a/Dockerfile b/Dockerfile index 6ad1c65..d887fa5 100644 --- a/Dockerfile +++ b/Dockerfile @@ -23,6 +23,9 @@ COPY --from=builder /app/webBridgeBot /app/webBridgeBot # Copy the run script COPY run.sh /app/run.sh +# Copy the run templates +COPY templates /app/templates + # Set the permissions for the binary and the run script RUN chmod +x /app/webBridgeBot RUN chmod +x /app/run.sh diff --git a/Makefile b/Makefile index f0222ee..4fc4756 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,6 @@ # Makefile for cloning, building TDLib, building OpenSSL, and building a Go application (webBridgeBot) that uses TDLib # Define variables -TDLIB_DIR=$(CURDIR)/tdlib DOCKER_IMAGE_NAME=webbridgebot DOCKER_TAG=latest DOCKER_USERNAME=mshafiee diff --git a/internal/bot/telegram_bot.go b/internal/bot/telegram_bot.go index 4938f07..cab3958 100644 --- a/internal/bot/telegram_bot.go +++ b/internal/bot/telegram_bot.go @@ -8,7 +8,6 @@ import ( "io" "log" "net/http" - "os" "strconv" "strings" "webBridgeBot/internal/data" @@ -57,22 +56,21 @@ var ( ) // NewTelegramBot creates a new instance of TelegramBot. -func NewTelegramBot(config *config.Configuration) (*TelegramBot, error) { +func NewTelegramBot(config *config.Configuration, logger *log.Logger) (*TelegramBot, error) { dsn := fmt.Sprintf("file:%s?mode=rwc", config.DatabasePath) tgClient, err := gotgproto.NewClient( config.ApiID, config.ApiHash, gotgproto.ClientTypeBot(config.BotToken), &gotgproto.ClientOpts{ - InMemory: true, - Session: sessionMaker.SqlSession(sqlite.Open(dsn)), + InMemory: true, + Session: sessionMaker.SqlSession(sqlite.Open(dsn)), + DisableCopyright: true, }) if err != nil { return nil, fmt.Errorf("failed to initialize Telegram client: %w", err) } - logger := log.New(os.Stdout, "TelegramBot: ", log.Ldate|log.Ltime|log.Lshortfile) - // Initialize the database connection db, err := sql.Open("sqlite", dsn) if err != nil { @@ -543,7 +541,7 @@ func (b *TelegramBot) handleStream(w http.ResponseWriter, r *http.Request) { } // Create a TelegramReader to stream the content. - lr, err := reader.NewTelegramReader(ctx, b.tgClient, file.Location, start, end, contentLength, b.config.BinaryCache) + lr, err := reader.NewTelegramReader(ctx, b.tgClient, file.Location, start, end, contentLength, b.config.BinaryCache, b.logger) if err != nil { b.logger.Printf("Error creating Telegram reader for message ID %d: %v", messageID, err) http.Error(w, "Failed to initialize file stream", http.StatusInternalServerError) diff --git a/internal/config/config.go b/internal/config/config.go index b1be912..9d9e2a3 100644 --- a/internal/config/config.go +++ b/internal/config/config.go @@ -3,15 +3,12 @@ package config import ( "fmt" "log" - "time" + "webBridgeBot/internal/reader" "github.com/spf13/viper" - "webBridgeBot/internal/reader" ) -const ( - DefaultChunkSize int64 = 1024 * 1024 // 1 MB -) +const DefaultChunkSize int64 = 1024 * 1024 // 1 MB type Configuration struct { ApiID int @@ -20,91 +17,88 @@ type Configuration struct { BaseURL string Port string HashLength int - BinaryCache *reader.BinaryCache CacheDirectory string MaxCacheSize int64 DatabasePath string - Timeout time.Duration DebugMode bool + BinaryCache *reader.BinaryCache +} + +func LoadConfig(logger *log.Logger) Configuration { + initializeViper(logger) + + var cfg Configuration + bindViperToConfig(&cfg) + validateMandatoryFields(cfg, logger) + setDefaultValues(&cfg) + initializeBinaryCache(&cfg, logger) + + if cfg.DebugMode { + logger.Printf("Loaded configuration: %+v", cfg) + } + + return cfg } -// initializeViper sets up viper with environment variable overrides -func initializeViper() { +func initializeViper(logger *log.Logger) { viper.SetConfigFile(".env") viper.AutomaticEnv() if err := viper.ReadInConfig(); err != nil { - log.Printf("Error reading config file: %v", err) + logger.Printf("Error reading config file: %v", err) } } -// validateMandatoryFields checks for mandatory fields and terminates if any are missing -func validateMandatoryFields(config Configuration) { - if config.ApiID == 0 { - log.Fatal("API_ID is required and not set") +func bindViperToConfig(cfg *Configuration) { + cfg.ApiID = viper.GetInt("API_ID") + cfg.ApiHash = viper.GetString("API_HASH") + cfg.BotToken = viper.GetString("BOT_TOKEN") + cfg.BaseURL = viper.GetString("BASE_URL") + cfg.Port = viper.GetString("PORT") + cfg.HashLength = viper.GetInt("HASH_LENGTH") + cfg.CacheDirectory = viper.GetString("CACHE_DIRECTORY") + cfg.MaxCacheSize = viper.GetInt64("MAX_CACHE_SIZE") + cfg.DebugMode = viper.GetBool("DEBUG_MODE") +} + +func validateMandatoryFields(cfg Configuration, logger *log.Logger) { + if cfg.ApiID == 0 { + logger.Fatal("API_ID is required and not set") } - if config.ApiHash == "" { - log.Fatal("API_HASH is required and not set") + if cfg.ApiHash == "" { + logger.Fatal("API_HASH is required and not set") } - if config.BotToken == "" { - log.Fatal("BOT_TOKEN is required and not set") + if cfg.BotToken == "" { + logger.Fatal("BOT_TOKEN is required and not set") } - if config.BaseURL == "" { - log.Fatal("BASE_URL is required and not set") + if cfg.BaseURL == "" { + logger.Fatal("BASE_URL is required and not set") } } -// setDefaultValues sets default values for optional configuration fields -func setDefaultValues(config *Configuration) { - if config.HashLength < 6 { - config.HashLength = 8 - } - if config.CacheDirectory == "" { - config.CacheDirectory = ".cache" +func setDefaultValues(cfg *Configuration) { + if cfg.HashLength < 6 { + cfg.HashLength = 8 } - if config.MaxCacheSize == 0 { - config.MaxCacheSize = 10 * 1024 * 1024 * 1024 // 10 GB default + if cfg.CacheDirectory == "" { + cfg.CacheDirectory = ".cache" } - if config.DatabasePath == "" { - config.DatabasePath = fmt.Sprintf("%s/webBridgeBot.db", config.CacheDirectory) + if cfg.MaxCacheSize == 0 { + cfg.MaxCacheSize = 10 * 1024 * 1024 * 1024 // 10 GB default } - if config.Timeout == 0 { - config.Timeout = 30 * time.Second + if cfg.DatabasePath == "" { + cfg.DatabasePath = fmt.Sprintf("%s/webBridgeBot.db", cfg.CacheDirectory) } } -func LoadConfig() Configuration { - initializeViper() - - config := Configuration{ - ApiID: viper.GetInt("API_ID"), - ApiHash: viper.GetString("API_HASH"), - BotToken: viper.GetString("BOT_TOKEN"), - BaseURL: viper.GetString("BASE_URL"), - Port: viper.GetString("PORT"), - HashLength: viper.GetInt("HASH_LENGTH"), - CacheDirectory: viper.GetString("CACHE_DIRECTORY"), - MaxCacheSize: viper.GetInt64("MAX_CACHE_SIZE"), - Timeout: viper.GetDuration("TIMEOUT"), - DebugMode: viper.GetBool("DEBUG_MODE"), - } - - validateMandatoryFields(config) - setDefaultValues(&config) - +func initializeBinaryCache(cfg *Configuration, logger *log.Logger) { var err error - config.BinaryCache, err = reader.NewBinaryCache( - config.CacheDirectory, - config.MaxCacheSize, + cfg.BinaryCache, err = reader.NewBinaryCache( + cfg.CacheDirectory, + cfg.MaxCacheSize, DefaultChunkSize, ) if err != nil { - log.Fatalf("Error initializing BinaryCache: %v", err) + logger.Fatalf("Error initializing BinaryCache: %v", err) } - - if config.DebugMode { - log.Printf("Loaded configuration: %+v", config) - } - - return config } diff --git a/internal/reader/reader.go b/internal/reader/reader.go index 8ae8881..8126a64 100644 --- a/internal/reader/reader.go +++ b/internal/reader/reader.go @@ -7,7 +7,6 @@ import ( "io" "log" "net" - "os" "regexp" "strconv" "sync" @@ -48,11 +47,7 @@ type telegramReader struct { } // NewTelegramReader initializes a new telegramReader with the given parameters, including a BinaryCache. -func NewTelegramReader(ctx context.Context, client *gotgproto.Client, - location *tg.InputDocumentFileLocation, - start int64, end int64, contentLength int64, cache *BinaryCache) (io.ReadCloser, error) { - logger := log.New(os.Stdout, "tgReader-", 0) - +func NewTelegramReader(ctx context.Context, client *gotgproto.Client, location *tg.InputDocumentFileLocation, start int64, end int64, contentLength int64, cache *BinaryCache, logger *log.Logger) (io.ReadCloser, error) { r := &telegramReader{ ctx: ctx, log: logger, diff --git a/main.go b/main.go index 2259764..98e9fdd 100644 --- a/main.go +++ b/main.go @@ -9,18 +9,16 @@ import ( "webBridgeBot/internal/config" ) -var ( - cfgFile string - cfg config.Configuration -) +var cfg config.Configuration func main() { + logger := log.New(os.Stdout, "webBridgeBot: ", log.Ldate|log.Ltime|log.Lshortfile) rootCmd := &cobra.Command{ - Use: "telegram-bot", - Short: "Telegram Bot", + Use: "webBridgeBot", + Short: "WebBridgeBot", Run: func(cmd *cobra.Command, args []string) { - cfg = config.LoadConfig() - b, err := bot.NewTelegramBot(&cfg) + cfg = config.LoadConfig(logger) + b, err := bot.NewTelegramBot(&cfg, logger) if err != nil { log.Fatalf("Error initializing Telegram bot: %v", err) } @@ -29,10 +27,23 @@ func main() { }, } - rootCmd.Flags().StringVarP(&cfgFile, "cfg", "c", "", "cfg file (default is .env)") + // Define flags + defineFlags(rootCmd) if err := rootCmd.Execute(); err != nil { fmt.Println(err) os.Exit(1) } } + +func defineFlags(cmd *cobra.Command) { + cmd.Flags().IntVar(&cfg.ApiID, "api_id", 0, "API ID") + cmd.Flags().StringVar(&cfg.ApiHash, "api_hash", "", "API Hash") + cmd.Flags().StringVar(&cfg.BotToken, "bot_token", "", "Bot Token") + cmd.Flags().StringVar(&cfg.BaseURL, "base_url", "", "Base URL") + cmd.Flags().StringVar(&cfg.Port, "port", "", "Port") + cmd.Flags().IntVar(&cfg.HashLength, "hash_length", 0, "Hash Length") + cmd.Flags().StringVar(&cfg.CacheDirectory, "cache_directory", "", "Cache Directory") + cmd.Flags().Int64Var(&cfg.MaxCacheSize, "max_cache_size", 0, "Max Cache Size") + cmd.Flags().BoolVar(&cfg.DebugMode, "debug_mode", false, "Enable Debug Mode") +} diff --git a/run.sh b/run.sh index b3a534e..3a62ba6 100644 --- a/run.sh +++ b/run.sh @@ -13,12 +13,12 @@ DEBUG_MODE=${DEBUG_MODE:-false} # Execute the Go application with command-line flags ./webBridgeBot \ - -apiID="$API_ID" \ - -apiHash="$API_HASH" \ - -botToken="$BOT_TOKEN" \ - -baseURL="$BASE_URL" \ - -port="$PORT" \ - -hashLength="$HASH_LENGTH" \ - -cacheDirectory="$CACHE_DIRECTORY" \ - -maxCacheSize="$MAX_CACHE_SIZE" \ - -debugMode="$DEBUG_MODE" + --api_id="$API_ID" \ + --api_hash="$API_HASH" \ + --bot_token="$BOT_TOKEN" \ + --base_url="$BASE_URL" \ + --port="$PORT" \ + --hash_length="$HASH_LENGTH" \ + --cache_directory="$CACHE_DIRECTORY" \ + --max_cache_size="$MAX_CACHE_SIZE" \ + --debug_mode="$DEBUG_MODE"