Browse Source

first commit for odl

Alexander Avery 1 month ago
commit
4756ffad63
  1. 3
      go.mod
  2. 102
      odl.go
  3. 62
      odl_test.go
  4. 1
      testdata/somefile

3
go.mod

@ -0,0 +1,3 @@
module gitea.beetbox.io/Alex/odl
go 1.18

102
odl.go

@ -0,0 +1,102 @@
package main
import (
"bufio"
"flag"
"fmt"
"io"
"log"
"net/http"
"net/url"
"os"
"path/filepath"
"strconv"
)
func main() {
flag.Parse()
var err error
f := os.Stdin
filename := flag.Arg(0)
if filename != "-" && filename != "" {
f, err = os.Open(filename)
if err != nil {
log.Fatalf("failed to open file %s: %v", filename, err)
}
}
Download(Read(".", f))
}
type request struct {
w io.Writer
url string
}
func Download(c <-chan request) {
dl := func(w io.Writer, url string) error {
response, err := http.Get(url)
if err != nil {
return fmt.Errorf("downloading file %s: %v", url, err)
}
defer response.Body.Close()
if response.StatusCode != http.StatusOK {
return fmt.Errorf("unexpected status code for %s: %d", url, response.StatusCode)
}
_, err = io.Copy(w, response.Body)
return err
}
for r := range c {
if err := dl(r.w, r.url); err != nil {
log.Println(err)
}
}
}
func Read(root string, r io.Reader) <-chan request {
scanner := bufio.NewScanner(r)
var n int
var name string
c := make(chan request)
create := func(name, uri string, n int) (io.Writer, error) {
var f io.Writer
u, err := url.Parse(uri)
if err != nil {
return f, fmt.Errorf("parsing url %s: %v", uri, err)
}
filename := filepath.Join(root, name+strconv.Itoa(n)+filepath.Ext(u.Path))
return os.Create(filename)
}
go func() {
for scanner.Scan() {
txt := scanner.Text()
if name == "" || txt == "" {
name = txt
n = 0
continue
}
f, err := create(name, txt, n)
if err != nil {
log.Println(err)
continue
}
c <- request{w: f, url: txt}
n++
}
close(c)
}()
return c
}

62
odl_test.go

@ -0,0 +1,62 @@
package main
import (
"bytes"
"net/http"
"net/http/httptest"
"strings"
"testing"
"os"
"testing/fstest"
)
var fs = http.FileServer(http.Dir("./testdata"))
var srv = httptest.NewServer(fs)
func TestDownload(t *testing.T) {
var (
b bytes.Buffer
c = make(chan request)
)
url := srv.URL + "/somefile"
t.Logf("file URL: %s", url)
go func() { c <- request{&b, url}; close(c) }()
Download(c)
want := "somefile inner data"
if got := b.String(); got != want {
t.Errorf("file buffer received unexpected value\nGot:\n%s\nWant:\n%s", got, want)
}
}
func TestRead(t *testing.T) {
input := `boston
http://localhost/someboston
http://localhost/anotherboston.mp4
http://localhost/finalboston.jpg
orlando
http://localhost/someorlando.jpg
`
dir := t.TempDir()
t.Logf("root directory: %s", dir)
c := Read(dir, strings.NewReader(input))
for range c {
} // drain the channel
err := fstest.TestFS(
os.DirFS(dir),
"boston0",
"boston1.mp4",
"boston2.jpg",
"orlando0.jpg",
)
if err != nil {
t.Fatal(err)
}
}

1
testdata/somefile

@ -0,0 +1 @@
somefile inner data
Loading…
Cancel
Save