Skip to content

Commit

Permalink
feat ✨: add ability to configure a socks5 or http proxy in config file,
Browse files Browse the repository at this point in the history
close #40

Signed-off-by: Victor Hang <[email protected]>
  • Loading branch information
Banh-Canh committed Sep 30, 2024
1 parent 72d65e7 commit 4daa828
Show file tree
Hide file tree
Showing 8 changed files with 57 additions and 13 deletions.
5 changes: 4 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,7 @@ download_dir: ~/Videos/YouTube
history:
enable: true
invidious:
proxy: ''
instance: invidious.jing.rocks
loglevel: info
youtube:
Expand All @@ -140,14 +141,16 @@ youtube:
specified in the configuration file for subscribed channels.
If you prefer to use your Youtube user-subscribed channels, set this to `false`.

- `channels.subscribed: []` is a list of channel Ids. To be used with `local: true`.
- **`channels.subscribed: []`** is a list of channel Ids. To be used with `local: true`.

- **OAuth** - You need to enable OAuth authentication with YouTube
to access your subscribed channels.
Ensure that your `clientid` and `secretid` are properly configured.

The following scope is also required: `https://www.googleapis.com/auth/youtube.readonly`

- **`invidious.proxy:`** - Must be set with either `socks5://<socks5_proxy>:1234` or `http://<http_proxy>:4567`. Leave empty to disable.

## Files

- **`watched_history.json`** - This file, located in `$HOME/.config/ytui/`,
Expand Down
2 changes: 1 addition & 1 deletion cmd/query_search.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ Press enter to run any of the videos.`,
}
utils.Logger.Debug("Config file read successfully.", zap.String("config_file", configPath))

result, err := youtube.SearchVideos(query, false)
result, err := youtube.SearchVideos(query, viper.GetString("invidious.proxy"), false)
if err != nil {
utils.Logger.Fatal("Error searching for videos.", zap.Error(err))
os.Exit(1)
Expand Down
4 changes: 2 additions & 2 deletions cmd/query_subscribed.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,14 +56,14 @@ It will also only pick from the 50 most relevants subscribed channels in your Yo
}
yt := <-apiChan
utils.Logger.Info("YouTube API authenticated successfully.")
result, err = yt.GetAllSubscribedChannelsVideos()
result, err = yt.GetAllSubscribedChannelsVideos(viper.GetString("invidious.proxy"))
if err != nil {
utils.Logger.Fatal("Failed to get all subscribed channels videos.", zap.Error(err))
os.Exit(1)
}
} else {
utils.Logger.Info("Using local configuration for subscribed channels.")
result, err = youtube.GetLocalSubscribedChannelsVideos()
result, err = youtube.GetLocalSubscribedChannelsVideos(viper.GetString("invidious.proxy"))
if err != nil {
utils.Logger.Fatal("Failed to get local subscribed channels videos.", zap.Error(err))
os.Exit(1)
Expand Down
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ require (
github.com/spf13/cobra v1.8.1
github.com/spf13/viper v1.19.0
go.uber.org/zap v1.27.0
golang.org/x/net v0.23.0
golang.org/x/oauth2 v0.23.0
)

Expand Down
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,8 @@ golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
golang.org/x/net v0.23.0 h1:7EYJ93RZ9vYSZAIb2x3lnuvqO5zneoD6IvWjuhfxjTs=
golang.org/x/net v0.23.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg=
golang.org/x/oauth2 v0.23.0 h1:PbgcYx2W7i4LvjJWEbf0ngHV6qJYr86PkAV3bXdLEbs=
golang.org/x/oauth2 v0.23.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
Expand Down
1 change: 1 addition & 0 deletions pkg/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ func CreateDefaultConfigFile(filePath string) {
viper.SetDefault("download_dir", downloadDir)
viper.SetDefault("logLevel", "info")
viper.SetDefault("invidious", map[string]interface{}{
"proxy": "",
"instance": "invidious.jing.rocks",
})
viper.SetDefault("history", map[string]interface{}{
Expand Down
47 changes: 42 additions & 5 deletions pkg/youtube/invidious_search.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (

"github.com/spf13/viper"
"go.uber.org/zap"
"golang.org/x/net/proxy"

"github.com/Banh-Canh/ytui/pkg/config"
"github.com/Banh-Canh/ytui/pkg/utils"
Expand Down Expand Up @@ -84,7 +85,7 @@ func getInvidiousInstance() (string, error) {
return invidiousInstance, nil
}

func SearchVideos(query string, subscription bool) (*[]SearchResultItem, error) {
func SearchVideos(query, proxyURLString string, subscription bool) (*[]SearchResultItem, error) {
var baseURL string
invidiousInstance, err := getInvidiousInstance()
if err != nil {
Expand All @@ -98,10 +99,46 @@ func SearchVideos(query string, subscription bool) (*[]SearchResultItem, error)
baseURL = fmt.Sprintf("https://%s/api/v1/channels/%s/videos", invidiousInstance, query)
utils.Logger.Debug("Subscription URL for channel videos constructed.", zap.String("subscription_url", baseURL))

resp, err := http.Get(baseURL)
if err != nil {
utils.Logger.Error("Error fetching data from Invidious API.", zap.String("url", baseURL), zap.Error(err))
return nil, fmt.Errorf("error fetching data from YouTube API: %v", err)
var resp *http.Response
if proxyURLString != "" {
proxyURL, err := url.Parse(proxyURLString)
utils.Logger.Info("A proxy is configured and will be used.", zap.String("proxy_url", proxyURLString))
if err != nil {
return nil, fmt.Errorf("error parsing proxy URL: %v", err)
}

var transport *http.Transport
switch proxyURL.Scheme {
case "socks5":
dialer, err := proxy.FromURL(proxyURL, proxy.Direct)
if err != nil {
return nil, fmt.Errorf("error creating proxy dialer: %v", err)
}
transport = &http.Transport{Dial: dialer.Dial}

case "http", "https":
transport = &http.Transport{Proxy: http.ProxyURL(proxyURL)}

default:
return nil, fmt.Errorf("unsupported proxy scheme: %s", proxyURL.Scheme)
}

// Create a client with the transport
client := &http.Client{Transport: transport}

// Make the request
resp, err = client.Get(baseURL)
if err != nil {
utils.Logger.Error("Error fetching data from Invidious API.", zap.String("url", baseURL), zap.Error(err))
return nil, fmt.Errorf("error creating the request: %v", err)
}
} else {
// Make the request without a proxy
resp, err = http.Get(baseURL)
if err != nil {
utils.Logger.Error("Error fetching data from Invidious API.", zap.String("url", baseURL), zap.Error(err))
return nil, fmt.Errorf("error fetching data from YouTube API: %v", err)
}
}
defer resp.Body.Close()

Expand Down
8 changes: 4 additions & 4 deletions pkg/youtube/subscribed.go
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ func GetLocalSubscribedChannels() ([]string, error) {
return subscribed, nil
}

func (yt *YouTubeAPI) GetAllSubscribedChannelsVideos() (*[]SearchResultItem, error) {
func (yt *YouTubeAPI) GetAllSubscribedChannelsVideos(proxyURLString string) (*[]SearchResultItem, error) {
utils.Logger.Info("Starting to fetch videos for all subscribed channels.")

channelIds, err := yt.GetSubscribedChannels()
Expand All @@ -121,7 +121,7 @@ func (yt *YouTubeAPI) GetAllSubscribedChannelsVideos() (*[]SearchResultItem, err

for _, channelId := range channelIds {
utils.Logger.Info("Fetching videos for channel.", zap.String("channel_id", channelId))
videosResponse, err := SearchVideos(channelId, true)
videosResponse, err := SearchVideos(channelId, proxyURLString, true)
if err != nil {
utils.Logger.Error("Failed to fetch videos for channel.", zap.String("channel_id", channelId), zap.Error(err))
return nil, err
Expand Down Expand Up @@ -155,7 +155,7 @@ func (yt *YouTubeAPI) GetAllSubscribedChannelsVideos() (*[]SearchResultItem, err
return aggregatedResponse, nil
}

func GetLocalSubscribedChannelsVideos() (*[]SearchResultItem, error) {
func GetLocalSubscribedChannelsVideos(proxyURLString string) (*[]SearchResultItem, error) {
utils.Logger.Info("Starting to fetch videos for local subscribed channels.")

// Get local subscribed channels
Expand All @@ -170,7 +170,7 @@ func GetLocalSubscribedChannelsVideos() (*[]SearchResultItem, error) {

for _, channelId := range channelIds {
utils.Logger.Debug("Fetching videos for channel.", zap.String("channel_id", channelId))
videosResponse, err := SearchVideos(channelId, true)
videosResponse, err := SearchVideos(channelId, proxyURLString, true)
if err != nil {
utils.Logger.Error("Failed to fetch videos for channel.", zap.String("channel_id", channelId), zap.Error(err))
return nil, err
Expand Down

0 comments on commit 4daa828

Please sign in to comment.