Skip to content

Commit

Permalink
hackernews: combine types into Thread{}
Browse files Browse the repository at this point in the history
  • Loading branch information
azimut committed Apr 26, 2023
1 parent 9f9dfb3 commit 7e05424
Show file tree
Hide file tree
Showing 4 changed files with 78 additions and 70 deletions.
27 changes: 17 additions & 10 deletions cmd/hackerview/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,25 +14,27 @@ import (
)

type options struct {
leftPadding uint
maxComments uint
nWorkers uint
timeout time.Duration
useColors bool
useDate bool
usePretty bool
showColors bool
showDate bool
useTUI bool
width uint
}

var opts options

func init() {
flag.BoolVar(&opts.useColors, "C", true, "use colors")
flag.BoolVar(&opts.useDate, "d", false, "print date on comments")
flag.BoolVar(&opts.usePretty, "P", true, "use pretty formatting")
flag.BoolVar(&opts.showColors, "C", true, "use colors")
flag.BoolVar(&opts.showDate, "d", false, "print date on comments")
flag.BoolVar(&opts.useTUI, "x", false, "use TUI")
flag.DurationVar(&opts.timeout, "t", time.Second*5, "timeout in seconds")
flag.UintVar(&opts.maxComments, "l", 10, "limits the ammount of comments to fetch")
flag.UintVar(&opts.maxComments, "c", 10, "limits the ammount of comments to fetch")
flag.UintVar(&opts.nWorkers, "W", 3, "number of workers to fetch comments")
flag.UintVar(&opts.width, "w", 100, "fixed with")
flag.UintVar(&opts.leftPadding, "l", 3, "left padding")
}

func usage() {
Expand All @@ -43,17 +45,22 @@ func usage() {
func run(args []string, stdout io.Writer) error {
flag.Parse()
flag.Usage = usage
color.NoColor = !opts.useColors
color.NoColor = !opts.showColors
if flag.NArg() != 1 {
flag.Usage()
return errors.New("missing URL argument")
}

url := flag.Args()[0]
op, comments, err := hackernews.Fetch(url, opts.timeout, opts.maxComments, opts.nWorkers)
thread, err := hackernews.Fetch(url, opts.timeout, opts.maxComments, opts.nWorkers)
if err != nil {
return errors.New("could not fetch url")
}
hackernews.Format(int(opts.width), opts.useDate, op, comments)
thread.Width = opts.width
thread.LeftPadding = opts.leftPadding
thread.ShowDate = opts.showDate

fmt.Println(thread)
return nil
}

Expand Down
35 changes: 26 additions & 9 deletions internal/hackernews/fetch.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,24 +18,40 @@ func Fetch(
timeout time.Duration,
maxComments uint,
nWorkers uint,
) (Op, []Comment, error) {
) (*Thread, error) {

url, storyId, err := effectiveUrl(rawUrl)
if err != nil {
return Op{}, nil, err
return nil, err
}

client := gophernews.NewClient()
story, err := fetchStory(client, storyId)
if err != nil {
return Op{}, nil, err
return nil, err
}

thread := Thread{}
op := Op{
date: unix2time(story.Time()),
kids: story.Kids(),
ncomments: len(story.Kids()), // TODO: this only gets the direct replies
score: story.Score(),
selfUrl: url,
text: story.Text(),
thread: &thread,
title: story.Title(),
url: story.URL(),
user: story.By(),
}
op := newOp(story, url)

commentIds := op.kids
commentIds = commentIds[:min(len(commentIds), int(maxComments))]
comments := fetchComments(commentIds, nWorkers) // TODO: error
return op, comments, nil
comments := fetchComments(commentIds, nWorkers, &thread) // TODO: error
thread.op = op
thread.comments = comments

return &thread, nil
}

func fetchStory(client *gophernews.Client, id int) (gophernews.Item, error) {
Expand All @@ -49,7 +65,7 @@ func fetchStory(client *gophernews.Client, id int) (gophernews.Item, error) {
return item, nil
}

func fetchComments(commentIds []int, nWorkers uint) []Comment {
func fetchComments(commentIds []int, nWorkers uint, thread *Thread) []Comment {
if len(commentIds) == 0 {
return nil
}
Expand All @@ -62,7 +78,7 @@ func fetchComments(commentIds []int, nWorkers uint) []Comment {
for i := 0; i < int(nWorkers); i++ {
go worker(&wg, idsCh, commentsCh)
}
return collector(&wg, idsCh, commentsCh)
return collector(&wg, idsCh, commentsCh, thread)
}

func closeAfterWait(wg *sync.WaitGroup, commentsCh chan<- result) {
Expand Down Expand Up @@ -101,6 +117,7 @@ func collector(
wg *sync.WaitGroup,
commentsCh chan<- int,
responseCh <-chan result,
thread *Thread,
) []Comment {
var comments []Comment

Expand All @@ -110,7 +127,7 @@ func collector(
continue
}

comment := newComment(response.comment)
comment := newComment(response.comment, thread)
if isDeleted(comment) {
continue
}
Expand Down
49 changes: 18 additions & 31 deletions internal/hackernews/printer.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,32 +11,12 @@ import (
"github.com/jaytaylor/html2text"
)

const SPACES_PER_INDENT = 5

var max_width int
var useDate bool

func Format(width int, useDateArg bool, op Op, comments []Comment) {
max_width = width
useDate = useDateArg
fmt.Println(op)
for _, comment := range comments {
fmt.Println(comment)
}
}

func printChilds(c []*Comment) {
for _, value := range c {
fmt.Println(value)
printChilds(value.Childs)
func (thread Thread) String() (ret string) {
ret += fmt.Sprintln(thread.op)
for _, comment := range thread.comments {
ret += fmt.Sprintln(comment)
}
}

func pastLink(title string) string {
return fmt.Sprintf(
"https://hn.algolia.com/?query=%s&sort=byDate\n",
url.QueryEscape(title),
)
return
}

func (o Op) String() (ret string) {
Expand All @@ -47,7 +27,7 @@ func (o Op) String() (ret string) {
}
ret += fmt.Sprintf(" self: %s\n", o.selfUrl)
if o.text != "" {
ret += fmt.Sprintf("\n%s\n", fixupComment(o.text, 3))
ret += fmt.Sprintf("\n%s\n", fixupComment(o.text, 3, o.thread.Width))
}
ret += fmt.Sprintf(
"\n%s(%d) - %s - %d Comments\n",
Expand All @@ -60,13 +40,13 @@ func (o Op) String() (ret string) {
}

func (c Comment) String() (ret string) {
indent := c.indent * SPACES_PER_INDENT
ret += "\n" + fixupComment(c.msg, indent+1) + "\n"
indent := c.indent * int(c.thread.LeftPadding)
ret += "\n" + fixupComment(c.msg, indent+1, c.thread.Width) + "\n"
arrow := ">> "
if c.indent > 0 {
arrow = ">> "
}
if useDate {
if c.thread.ShowDate {
ret += strings.Repeat(" ", indent) + arrow + c.user + " - " + humanize.Time(c.date)
} else {
ret += strings.Repeat(" ", indent) + arrow + c.user
Expand All @@ -75,14 +55,21 @@ func (c Comment) String() (ret string) {
return
}

func fixupComment(html string, leftPad int) string {
func fixupComment(html string, leftPad int, width uint) string {
plainText, err := html2text.FromString(
html,
html2text.Options{OmitLinks: false, PrettyTables: true, CitationStyleLinks: true},
)
if err != nil {
panic(err)
}
wrapped, _ := text.WrapLeftPadded(format.GreenTextIt(plainText), max_width, leftPad)
wrapped, _ := text.WrapLeftPadded(format.GreenTextIt(plainText), int(width), leftPad)
return wrapped
}

func pastLink(title string) string {
return fmt.Sprintf(
"https://hn.algolia.com/?query=%s&sort=byDate\n",
url.QueryEscape(title),
)
}
37 changes: 17 additions & 20 deletions internal/hackernews/type.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,14 @@ import (
"github.com/caser/gophernews"
)

type Thread struct {
comments []Comment
op Op
Width uint
LeftPadding uint
ShowDate bool
}

type Op struct {
date time.Time
kids []int
Expand All @@ -16,6 +24,7 @@ type Op struct {
title string
url string
user string
thread *Thread
}

type Comment struct {
Expand All @@ -26,29 +35,17 @@ type Comment struct {
kids []int
msg string
user string
thread *Thread
}

func newOp(story gophernews.Item, selfUrl string) Op {
return Op{
date: unix2time(story.Time()),
kids: story.Kids(),
ncomments: len(story.Kids()), // TODO: this only gets the direct replies
score: story.Score(),
selfUrl: selfUrl,
text: story.Text(),
title: story.Title(),
url: story.URL(),
user: story.By(),
}
}

func newComment(comment gophernews.Comment) Comment {
func newComment(comment gophernews.Comment, thread *Thread) Comment {
return Comment{
id: comment.ID,
msg: comment.Text,
user: comment.By,
kids: comment.Kids,
date: unix2time(comment.Time),
date: unix2time(comment.Time),
id: comment.ID,
kids: comment.Kids,
msg: comment.Text,
thread: thread,
user: comment.By,
}
}

Expand Down

0 comments on commit 7e05424

Please sign in to comment.