add channel auto join function
parent
21d2e5f7d2
commit
3cad908f1f
17
cmd/main.go
17
cmd/main.go
|
|
@ -10,6 +10,7 @@ import (
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
|
"xdcc-cli/config"
|
||||||
"xdcc-cli/pb"
|
"xdcc-cli/pb"
|
||||||
"xdcc-cli/search"
|
"xdcc-cli/search"
|
||||||
table "xdcc-cli/table"
|
table "xdcc-cli/table"
|
||||||
|
|
@ -158,7 +159,7 @@ func loadUrlListFile(filePath string) []string {
|
||||||
}
|
}
|
||||||
|
|
||||||
func printGetUsageAndExit(flagSet *flag.FlagSet) {
|
func printGetUsageAndExit(flagSet *flag.FlagSet) {
|
||||||
fmt.Printf("usage: get url1 url2 ... [-o path] [-i file] [--ssl-only]\n\nFlag set:\n")
|
fmt.Printf("usage: get url1 url2 ... [-o path] [-i file] [--ssl-only] [-c config]\n\nFlag set:\n")
|
||||||
flagSet.PrintDefaults()
|
flagSet.PrintDefaults()
|
||||||
os.Exit(0)
|
os.Exit(0)
|
||||||
}
|
}
|
||||||
|
|
@ -167,11 +168,18 @@ func execGet(args []string) {
|
||||||
getCmd := flag.NewFlagSet("get", flag.ExitOnError)
|
getCmd := flag.NewFlagSet("get", flag.ExitOnError)
|
||||||
path := getCmd.String("o", ".", "output folder of dowloaded file")
|
path := getCmd.String("o", ".", "output folder of dowloaded file")
|
||||||
inputFile := getCmd.String("i", "", "input file containing a list of urls")
|
inputFile := getCmd.String("i", "", "input file containing a list of urls")
|
||||||
|
configFile := getCmd.String("c", "", "config file for network-channel mappings (defaults to ~/.xdcc-cli-config.json)")
|
||||||
|
|
||||||
sslOnly := getCmd.Bool("ssl-only", false, "force the client to use TSL connection")
|
sslOnly := getCmd.Bool("ssl-only", false, "force the client to use TSL connection")
|
||||||
|
|
||||||
urlList := parseFlags(getCmd, args)
|
urlList := parseFlags(getCmd, args)
|
||||||
|
|
||||||
|
// Bestimme den Konfigurationspfad
|
||||||
|
configPath := *configFile
|
||||||
|
if configPath == "" {
|
||||||
|
configPath = config.DefaultConfigPath()
|
||||||
|
}
|
||||||
|
|
||||||
if *inputFile != "" {
|
if *inputFile != "" {
|
||||||
urlList = append(urlList, loadUrlListFile(*inputFile)...)
|
urlList = append(urlList, loadUrlListFile(*inputFile)...)
|
||||||
}
|
}
|
||||||
|
|
@ -194,9 +202,10 @@ func execGet(args []string) {
|
||||||
}
|
}
|
||||||
|
|
||||||
transfer := xdcc.NewTransfer(xdcc.Config{
|
transfer := xdcc.NewTransfer(xdcc.Config{
|
||||||
File: *url,
|
File: *url,
|
||||||
OutPath: *path,
|
OutPath: *path,
|
||||||
SSLOnly: *sslOnly,
|
SSLOnly: *sslOnly,
|
||||||
|
ConfigPath: configPath,
|
||||||
})
|
})
|
||||||
|
|
||||||
wg.Add(1)
|
wg.Add(1)
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,138 @@
|
||||||
|
package config
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
// NetworkChannelsConfig definiert die Konfiguration für automatische Channel-Joins
|
||||||
|
type NetworkChannelsConfig struct {
|
||||||
|
Networks map[string][]string `json:"networks"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// DefaultConfigPath gibt den Standardpfad für die Konfigurationsdatei zurück
|
||||||
|
func DefaultConfigPath() string {
|
||||||
|
homeDir, err := os.UserHomeDir()
|
||||||
|
if err != nil {
|
||||||
|
return ".xdcc-cli-config.json"
|
||||||
|
}
|
||||||
|
return filepath.Join(homeDir, ".xdcc-cli-config.json")
|
||||||
|
}
|
||||||
|
|
||||||
|
// LoadConfig lädt die Konfiguration aus einer JSON-Datei
|
||||||
|
func LoadConfig(configPath string) (*NetworkChannelsConfig, error) {
|
||||||
|
// Wenn die Datei nicht existiert, gibt eine leere Konfiguration zurück
|
||||||
|
if _, err := os.Stat(configPath); os.IsNotExist(err) {
|
||||||
|
return &NetworkChannelsConfig{
|
||||||
|
Networks: make(map[string][]string),
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
file, err := os.Open(configPath)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("fehler beim Öffnen der Konfigurationsdatei: %v", err)
|
||||||
|
}
|
||||||
|
defer file.Close()
|
||||||
|
|
||||||
|
data, err := io.ReadAll(file)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("fehler beim Lesen der Konfigurationsdatei: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
var config NetworkChannelsConfig
|
||||||
|
if err := json.Unmarshal(data, &config); err != nil {
|
||||||
|
return nil, fmt.Errorf("fehler beim Parsen der Konfigurationsdatei: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Initialisiere Networks falls nil
|
||||||
|
if config.Networks == nil {
|
||||||
|
config.Networks = make(map[string][]string)
|
||||||
|
}
|
||||||
|
|
||||||
|
return &config, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// SaveConfig speichert die Konfiguration in eine JSON-Datei
|
||||||
|
func SaveConfig(configPath string, config *NetworkChannelsConfig) error {
|
||||||
|
data, err := json.MarshalIndent(config, "", " ")
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("fehler beim Serialisieren der Konfiguration: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := os.WriteFile(configPath, data, 0644); err != nil {
|
||||||
|
return fmt.Errorf("fehler beim Schreiben der Konfigurationsdatei: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetChannelsForNetwork gibt die konfigurierten Channels für ein Netzwerk zurück
|
||||||
|
func (c *NetworkChannelsConfig) GetChannelsForNetwork(network string) []string {
|
||||||
|
channels, exists := c.Networks[network]
|
||||||
|
if !exists {
|
||||||
|
return []string{}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Stelle sicher, dass alle Channels mit # beginnen
|
||||||
|
normalizedChannels := make([]string, len(channels))
|
||||||
|
for i, channel := range channels {
|
||||||
|
if channel != "" && !strings.HasPrefix(channel, "#") {
|
||||||
|
normalizedChannels[i] = "#" + channel
|
||||||
|
} else {
|
||||||
|
normalizedChannels[i] = channel
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return normalizedChannels
|
||||||
|
}
|
||||||
|
|
||||||
|
// AddChannelToNetwork fügt einen Channel zu einem Netzwerk hinzu
|
||||||
|
func (c *NetworkChannelsConfig) AddChannelToNetwork(network, channel string) {
|
||||||
|
if c.Networks == nil {
|
||||||
|
c.Networks = make(map[string][]string)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Normalisiere den Channel-Namen
|
||||||
|
if channel != "" && !strings.HasPrefix(channel, "#") {
|
||||||
|
channel = "#" + channel
|
||||||
|
}
|
||||||
|
|
||||||
|
// Prüfe ob der Channel bereits existiert
|
||||||
|
for _, existingChannel := range c.Networks[network] {
|
||||||
|
if existingChannel == channel {
|
||||||
|
return // Channel bereits vorhanden
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
c.Networks[network] = append(c.Networks[network], channel)
|
||||||
|
}
|
||||||
|
|
||||||
|
// RemoveChannelFromNetwork entfernt einen Channel von einem Netzwerk
|
||||||
|
func (c *NetworkChannelsConfig) RemoveChannelFromNetwork(network, channel string) {
|
||||||
|
if c.Networks == nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Normalisiere den Channel-Namen
|
||||||
|
if channel != "" && !strings.HasPrefix(channel, "#") {
|
||||||
|
channel = "#" + channel
|
||||||
|
}
|
||||||
|
|
||||||
|
channels := c.Networks[network]
|
||||||
|
for i, existingChannel := range channels {
|
||||||
|
if existingChannel == channel {
|
||||||
|
// Entferne den Channel aus dem Slice
|
||||||
|
c.Networks[network] = append(channels[:i], channels[i+1:]...)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Entferne das Netzwerk wenn keine Channels mehr vorhanden sind
|
||||||
|
if len(c.Networks[network]) == 0 {
|
||||||
|
delete(c.Networks, network)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,16 @@
|
||||||
|
{
|
||||||
|
"networks": {
|
||||||
|
"irc.rizon.net": [
|
||||||
|
"#elitewarez"
|
||||||
|
],
|
||||||
|
"irc.highway.net": [
|
||||||
|
"#beast-xdcc",
|
||||||
|
"#moviegods"
|
||||||
|
],
|
||||||
|
"irc.abjects.net": [
|
||||||
|
"#beast-xdcc",
|
||||||
|
"#moviegods",
|
||||||
|
"#mg-chat"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
28
xdcc/xdcc.go
28
xdcc/xdcc.go
|
|
@ -13,6 +13,7 @@ import (
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
"xdcc-cli/config"
|
||||||
|
|
||||||
irc "github.com/fluffle/goirc/client"
|
irc "github.com/fluffle/goirc/client"
|
||||||
)
|
)
|
||||||
|
|
@ -168,9 +169,10 @@ type XdccTransfer struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
type Config struct {
|
type Config struct {
|
||||||
File IRCFile
|
File IRCFile
|
||||||
OutPath string
|
OutPath string
|
||||||
SSLOnly bool
|
SSLOnly bool
|
||||||
|
ConfigPath string
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewTransfer(c Config) Transfer {
|
func NewTransfer(c Config) Transfer {
|
||||||
|
|
@ -207,7 +209,7 @@ func newXdccTransfer(c Config, enableSSL bool, skipCertificateCheck bool) *XdccT
|
||||||
connAttempts: 0,
|
connAttempts: 0,
|
||||||
events: make(chan TransferEvent, defaultEventChanSize),
|
events: make(chan TransferEvent, defaultEventChanSize),
|
||||||
}
|
}
|
||||||
t.setupHandlers(file.Channel, file.UserName, file.Slot)
|
t.setupHandlers(file.Channel, file.UserName, file.Slot, c.ConfigPath)
|
||||||
return t
|
return t
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -215,14 +217,30 @@ func (transfer *XdccTransfer) send(req CTCPRequest) {
|
||||||
transfer.conn.Privmsg(transfer.url.UserName, req.String())
|
transfer.conn.Privmsg(transfer.url.UserName, req.String())
|
||||||
}
|
}
|
||||||
|
|
||||||
func (transfer *XdccTransfer) setupHandlers(channel string, userName string, slot int) {
|
func (transfer *XdccTransfer) setupHandlers(channel string, userName string, slot int, configPath string) {
|
||||||
conn := transfer.conn
|
conn := transfer.conn
|
||||||
|
|
||||||
// e.g. join channel on connect.
|
// e.g. join channel on connect.
|
||||||
conn.HandleFunc(irc.CONNECTED,
|
conn.HandleFunc(irc.CONNECTED,
|
||||||
func(conn *irc.Conn, line *irc.Line) {
|
func(conn *irc.Conn, line *irc.Line) {
|
||||||
transfer.connAttempts = 0
|
transfer.connAttempts = 0
|
||||||
|
|
||||||
|
// Betrete den Haupt-Channel (für den Download)
|
||||||
conn.Join(channel)
|
conn.Join(channel)
|
||||||
|
|
||||||
|
// Lade die Konfiguration und betrete zusätzliche Channels
|
||||||
|
if configPath != "" {
|
||||||
|
if cfg, err := config.LoadConfig(configPath); err == nil {
|
||||||
|
additionalChannels := cfg.GetChannelsForNetwork(transfer.url.Network)
|
||||||
|
for _, additionalChannel := range additionalChannels {
|
||||||
|
// Verhindere doppeltes Betreten des gleichen Channels
|
||||||
|
if !strings.EqualFold(additionalChannel, channel) {
|
||||||
|
conn.Join(additionalChannel)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Ignoriere Konfigurationsfehler stillschweigend - die Anwendung soll weiter funktionieren
|
||||||
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
conn.HandleFunc(irc.ERROR, func(conn *irc.Conn, line *irc.Line) {
|
conn.HandleFunc(irc.ERROR, func(conn *irc.Conn, line *irc.Line) {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue