Skip to content

Commit 81aa86e

Browse files
authored
Merge pull request #72 from evan-buss/development
OpenBooks v4.3.0
2 parents 79ad1c3 + e7cb4da commit 81aa86e

39 files changed

+472
-330
lines changed

.devcontainer/Dockerfile

+1-1
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ RUN apt-get update && export DEBIAN_FRONTEND=noninteractive \
1313
&& apt-get -y install --no-install-recommends tmux
1414

1515
# [Optional] Uncomment the next line to use go get to install anything else you need
16-
# RUN go get -x <your-dependency-or-tool>
16+
RUN go get golang.org/x/tools/cmd/stringer
1717

1818
# [Optional] Uncomment this line to install global node packages.
1919
RUN su vscode -c "source /usr/local/share/nvm/nvm.sh && npm install -g npm-check-updates" 2>&1

.devcontainer/devcontainer.json

+2-1
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,8 @@
2626
"golang.Go",
2727
"eamodio.gitlens",
2828
"bradlc.vscode-tailwindcss",
29-
"esbenp.prettier-vscode"
29+
"esbenp.prettier-vscode",
30+
"GitHub.copilot"
3031
],
3132
// Use 'forwardPorts' to make a list of ports inside the container available locally.
3233
"forwardPorts": [

README.md

+5-5
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# openbooks
22

3-
> NOTE: OpenBooks has been updated to comply with requests from IRC admins. Please download the latest release to continue using it. See [Issue #52](https://github.com/evan-buss/openbooks/issues/52) for context.
3+
> NOTE: Going forward only the latest release will be supported. If you encounter any issues, be sure you are using the latest version.
44
55
[![Docker Pulls](https://img.shields.io/docker/pulls/evanbuss/openbooks.svg)](https://hub.docker.com/r/evanbuss/openbooks/)
66

@@ -64,8 +64,7 @@ that you can visit in your browser.
6464

6565
- The mock server allows you to debug responses and requests to simplified IRC / DCC
6666
servers that mimic the responses received from IRC Highway.
67-
-
68-
```bash
67+
- ```bash
6968
cd cmd/mock_server
7069
go run .
7170
# Another Terminal
@@ -82,11 +81,12 @@ that you can visit in your browser.
8281

8382
- Backend
8483
- Golang
85-
- Archiver (extract files from various archive formats)
84+
- Chi
8685
- gorilla/websocket
86+
- Archiver (extract files from various archive formats)
8787
- Frontend
8888
- React.js
8989
- TypeScript
9090
- Redux / Redux Toolkit
91-
- Styled Components
91+
- Tailwind CSS
9292
- Evergreen UI

cli/cli.go

+25-15
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package cli
33
import (
44
"context"
55
"fmt"
6+
"time"
67

78
"github.com/evan-buss/openbooks/core"
89
"github.com/evan-buss/openbooks/irc"
@@ -14,6 +15,7 @@ type Config struct {
1415
Dir string
1516
Server string
1617
irc *irc.Conn
18+
Version string
1719
}
1820

1921
// StartInteractive instantiates the OpenBooks CLI interface
@@ -22,30 +24,31 @@ func StartInteractive(config Config) {
2224
fmt.Println(" Welcome to OpenBooks ")
2325
fmt.Println("=======================================")
2426

25-
conn := instantiate(config)
26-
config.irc = conn
27+
instantiate(&config)
28+
defer config.irc.Close()
2729

2830
ctx, cancel := context.WithCancel(context.Background())
29-
registerShutdown(conn, cancel)
31+
registerShutdown(config.irc, cancel)
3032

3133
handler := fullHandler(config)
3234
if config.Log {
3335
file := config.setupLogger(handler)
3436
defer file.Close()
3537
}
3638

37-
go core.StartReader(ctx, conn, handler)
38-
terminalMenu(conn)
39+
go core.StartReader(ctx, config.irc, handler)
40+
terminalMenu(config.irc)
3941

4042
<-ctx.Done()
4143
}
4244

4345
func StartDownload(config Config, download string) {
44-
conn := instantiate(config)
45-
defer conn.Close()
46+
instantiate(&config)
47+
defer config.irc.Close()
4648
ctx, cancel := context.WithCancel(context.Background())
4749

4850
handler := core.EventHandler{}
51+
addEssentialHandlers(handler, &config)
4952
handler[core.BookResult] = func(text string) {
5053
fmt.Printf("%sReceived file response.\n", clearLine)
5154
config.downloadHandler(text)
@@ -57,21 +60,23 @@ func StartDownload(config Config, download string) {
5760
}
5861

5962
fmt.Printf("Sending download request.")
60-
go core.StartReader(ctx, conn, handler)
61-
core.DownloadBook(conn, download)
63+
go core.StartReader(ctx, config.irc, handler)
64+
core.DownloadBook(config.irc, download)
6265
fmt.Printf("%sSent download request.", clearLine)
6366
fmt.Printf("Waiting for file response.")
6467

65-
registerShutdown(conn, cancel)
68+
registerShutdown(config.irc, cancel)
6669
<-ctx.Done()
6770
}
6871

6972
func StartSearch(config Config, query string) {
70-
conn := instantiate(config)
71-
defer conn.Close()
73+
nextSearchTime := getLastSearchTime().Add(15 * time.Second)
74+
instantiate(&config)
75+
defer config.irc.Close()
7276
ctx, cancel := context.WithCancel(context.Background())
7377

7478
handler := core.EventHandler{}
79+
addEssentialHandlers(handler, &config)
7580
handler[core.SearchResult] = func(text string) {
7681
fmt.Printf("%sReceived file response.\n", clearLine)
7782
config.searchHandler(text)
@@ -84,11 +89,16 @@ func StartSearch(config Config, query string) {
8489
}
8590

8691
fmt.Printf("Sending search request.")
87-
go core.StartReader(ctx, conn, handler)
88-
core.SearchBook(conn, query)
92+
warnIfServerOffline(query)
93+
time.Sleep(time.Until(nextSearchTime))
94+
95+
go core.StartReader(ctx, config.irc, handler)
96+
core.SearchBook(config.irc, query)
97+
98+
setLastSearchTime()
8999
fmt.Printf("%sSent search request.", clearLine)
90100
fmt.Printf("Waiting for file response.")
91101

92-
registerShutdown(conn, cancel)
102+
registerShutdown(config.irc, cancel)
93103
<-ctx.Done()
94104
}

cli/handlers.go

+4
Original file line numberDiff line numberDiff line change
@@ -70,3 +70,7 @@ func (c Config) matchesFoundHandler(num string) {
7070
func (c Config) pingHandler(_ string) {
7171
c.irc.Pong(c.Server)
7272
}
73+
74+
func (c *Config) versionHandler(line string) {
75+
core.SendVersionInfo(c.irc, line, c.Version)
76+
}

cli/interactive.go

+16-8
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,8 @@ import (
1111
"github.com/evan-buss/openbooks/irc"
1212
)
1313

14-
var lastSearch time.Time
15-
1614
func terminalMenu(irc *irc.Conn) {
17-
fmt.Print("\ns)search\ng)et book\nd)one\n~> ")
15+
fmt.Print("\ns)search\ng)et book\nse)rvers\nd)one\n~> ")
1816

1917
// Trim user input so we don't send 2 messages
2018
clean := func(message string) string { return strings.Trim(message, "\r\n") }
@@ -26,16 +24,26 @@ func terminalMenu(irc *irc.Conn) {
2624
switch input {
2725
case "s":
2826
fmt.Print("@search ")
29-
message, _ := reader.ReadString('\n')
27+
query, _ := reader.ReadString('\n')
3028
fmt.Println("\nSent search request.")
31-
time.Sleep(time.Until(lastSearch.Add(time.Second * 15)))
32-
core.SearchBook(irc, clean(message))
33-
lastSearch = time.Now()
29+
30+
nextSearchTime := getLastSearchTime().Add(15 * time.Second)
31+
time.Sleep(time.Until(nextSearchTime))
32+
33+
core.SearchBook(irc, clean(query))
34+
setLastSearchTime()
3435
case "g":
3536
fmt.Print("Download String: ")
3637
message, _ := reader.ReadString('\n')
3738
core.DownloadBook(irc, clean(message))
3839
fmt.Println("\nSent download request.")
40+
warnIfServerOffline(clean(message))
41+
case "se":
42+
fmt.Println("\nAvailable Servers:")
43+
for _, server := range servers {
44+
fmt.Printf(" %s\n", server)
45+
}
46+
terminalMenu(irc)
3947
case "d":
4048
fmt.Println("Disconnecting.")
4149
irc.Disconnect()
@@ -48,6 +56,7 @@ func terminalMenu(irc *irc.Conn) {
4856

4957
func fullHandler(config Config) core.EventHandler {
5058
handler := core.EventHandler{}
59+
addEssentialHandlers(handler, &config)
5160

5261
handler[core.BadServer] = func(text string) {
5362
config.badServerHandler(text)
@@ -67,7 +76,6 @@ func fullHandler(config Config) core.EventHandler {
6776
terminalMenu(config.irc)
6877
}
6978
handler[core.MatchesFound] = config.matchesFoundHandler
70-
handler[core.Ping] = config.pingHandler
7179

7280
return handler
7381
}

cli/util.go

+31-6
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import (
99
"os"
1010
"os/signal"
1111
"path/filepath"
12+
"strings"
1213
"syscall"
1314
"time"
1415

@@ -17,6 +18,8 @@ import (
1718
"github.com/evan-buss/openbooks/util"
1819
)
1920

21+
var servers []string
22+
2023
const clearLine = "\r\033[2K"
2124

2225
func registerShutdown(conn *irc.Conn, cancel context.CancelFunc) {
@@ -30,12 +33,23 @@ func registerShutdown(conn *irc.Conn, cancel context.CancelFunc) {
3033
}()
3134
}
3235

33-
func instantiate(config Config) *irc.Conn {
36+
// Connect to IRC server and save connection to Config
37+
func instantiate(config *Config) {
3438
fmt.Printf("Connecting to %s.", config.Server)
35-
conn := irc.New(config.UserName, "OpenBooks CLI")
39+
conn := irc.New(config.UserName, config.Version)
40+
config.irc = conn
3641
core.Join(conn, config.Server)
3742
fmt.Printf("%sConnected to %s.\n", clearLine, config.Server)
38-
return conn
43+
}
44+
45+
// Required handlers are used regardless of what CLI mode is selected.
46+
// Keep alive pings and other core IRC client features
47+
func addEssentialHandlers(handler core.EventHandler, config *Config) {
48+
handler[core.Ping] = config.pingHandler
49+
handler[core.Version] = config.versionHandler
50+
handler[core.ServerList] = func(text string) {
51+
servers = core.ParseServers(text).ElevatedUsers
52+
}
3953
}
4054

4155
func (config *Config) setupLogger(handler core.EventHandler) io.Closer {
@@ -50,18 +64,29 @@ func (config *Config) setupLogger(handler core.EventHandler) io.Closer {
5064
return file
5165
}
5266

53-
func GetLastSearchTime() time.Time {
67+
// Show warning message if the server they are downloading from is not online.
68+
func warnIfServerOffline(bookLine string) {
69+
for _, server := range servers {
70+
if strings.HasPrefix(bookLine[1:], server) {
71+
return
72+
}
73+
}
74+
75+
fmt.Println("WARNING: That server is not online. Your request will never complete.")
76+
}
77+
78+
func getLastSearchTime() time.Time {
5479
timestampFilePath := filepath.Join(os.TempDir(), ".openbooks")
5580
fileInfo, err := os.Stat(timestampFilePath)
5681

5782
if errors.Is(err, os.ErrNotExist) {
58-
return time.Time{}
83+
return time.Now()
5984
}
6085

6186
return fileInfo.ModTime()
6287
}
6388

64-
func SetLastSearchTime() {
89+
func setLastSearchTime() {
6590
timestampFilePath := filepath.Join(os.TempDir(), ".openbooks")
6691
_, err := os.Stat(timestampFilePath)
6792

cmd/openbooks/cli.go

+10-12
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,16 @@ package main
22

33
import (
44
"errors"
5+
"fmt"
56
"log"
67
"os"
78
"strings"
8-
"time"
99

1010
"github.com/evan-buss/openbooks/cli"
1111
"github.com/spf13/cobra"
1212
)
1313

14-
var config cli.Config
14+
var cliConfig cli.Config
1515

1616
func init() {
1717
rootCmd.AddCommand(cliCmd)
@@ -23,17 +23,18 @@ func init() {
2323
log.Fatalln("Could not get current working directory.", err)
2424
}
2525

26-
cliCmd.PersistentFlags().StringVarP(&config.UserName, "name", "n", generateUserName(), "Use a name that isn't randomly generated. One word only.")
27-
cliCmd.PersistentFlags().StringVarP(&config.Dir, "directory", "d", cwd, "Directory where files are downloaded.")
28-
cliCmd.PersistentFlags().BoolVarP(&config.Log, "log", "l", false, "Whether or not to log IRC messages to an output file.")
29-
cliCmd.PersistentFlags().StringVarP(&config.Server, "server", "s", "irc.irchighway.net", "IRC server to connect to.")
26+
cliConfig.Version = fmt.Sprintf("OpenBooks CLI %s", version)
27+
cliCmd.PersistentFlags().StringVarP(&cliConfig.UserName, "name", "n", generateUserName(), "Use a name that isn't randomly generated. One word only.")
28+
cliCmd.PersistentFlags().StringVarP(&cliConfig.Dir, "directory", "d", cwd, "Directory where files are downloaded.")
29+
cliCmd.PersistentFlags().BoolVarP(&cliConfig.Log, "log", "l", false, "Whether or not to log IRC messages to an output file.")
30+
cliCmd.PersistentFlags().StringVarP(&cliConfig.Server, "server", "s", "irc.irchighway.net", "IRC server to connect to.")
3031
}
3132

3233
var cliCmd = &cobra.Command{
3334
Use: "cli",
3435
Short: "Run openbooks from the terminal in CLI mode.",
3536
Run: func(cmd *cobra.Command, args []string) {
36-
cli.StartInteractive(config)
37+
cli.StartInteractive(cliConfig)
3738
},
3839
}
3940

@@ -52,7 +53,7 @@ var downloadCmd = &cobra.Command{
5253
return nil
5354
},
5455
Run: func(cmd *cobra.Command, args []string) {
55-
cli.StartDownload(config, args[0])
56+
cli.StartDownload(cliConfig, args[0])
5657
},
5758
}
5859

@@ -61,9 +62,6 @@ var searchCmd = &cobra.Command{
6162
Short: "Searches for a book and exits.",
6263
Args: cobra.ExactArgs(1),
6364
Run: func(cmd *cobra.Command, args []string) {
64-
nextSearchTime := cli.GetLastSearchTime().Add(15 * time.Second)
65-
time.Sleep(time.Until(nextSearchTime))
66-
cli.StartSearch(config, args[0])
67-
cli.SetLastSearchTime()
65+
cli.StartSearch(cliConfig, args[0])
6866
},
6967
}

cmd/openbooks/main.go

+5-2
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,12 @@ import (
1010
"github.com/spf13/cobra"
1111
)
1212

13+
const version = "4.3.0"
14+
1315
var rootCmd = &cobra.Command{
14-
Use: "openbooks",
15-
Short: "Quickly and easily download eBooks from IRCHighway.",
16+
Use: "openbooks",
17+
Short: "Quickly and easily download eBooks from IRCHighway.",
18+
Version: version,
1619
}
1720

1821
func main() {

0 commit comments

Comments
 (0)