Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor: Add TerminalWriter, MarkdownWriter Implementing Writer Interface #37

Merged
merged 4 commits into from
Sep 12, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 14 additions & 15 deletions config.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import (
"encoding/xml"
"flag"
"fmt"
"io/ioutil"
"log"
"net/url"
"os"
Expand Down Expand Up @@ -66,7 +65,7 @@ func getFeedAndLimit(feedURL string) (string, int) {
var err error
limit, err = strconv.Atoi(chopped[1])
if err != nil {
check(err)
fatal(err)
}
}
return chopped[0], limit
Expand All @@ -78,7 +77,7 @@ func bootstrapConfig() {
log.Println(direrr)
}
// if -t parameter is passed overwrite terminal_mode setting in config.yml
flag.BoolVar(&terminal_mode, "t", terminal_mode, "Run Matcha in Terminal Mode, no markdown files will be created")
flag.BoolVar(&terminalMode, "t", terminalMode, "Run Matcha in Terminal Mode, no markdown files will be created")
configFile := flag.String("c", "", "Config file path (if you want to override the current directory config.yaml)")
opmlFile := flag.String("o", "", "OPML file path to append feeds from opml files")
build := flag.Bool("build", false, "Dev: Build matcha binaries in the bin directory")
Expand All @@ -105,9 +104,9 @@ func bootstrapConfig() {
}

if viper.IsSet("markdown_dir_path") {
markdown_dir_path = viper.Get("markdown_dir_path").(string)
markdownDirPath = viper.Get("markdown_dir_path").(string)
} else {
markdown_dir_path = currentDir
markdownDirPath = currentDir
}
myFeeds = []RSS{}
feeds := viper.Get("feeds")
Expand Down Expand Up @@ -158,18 +157,18 @@ func bootstrapConfig() {
// Import any config.opml file on current direcotory
configPath := currentDir + "/" + "config.opml"
if _, err := os.Stat(configPath); err == nil {
xmlContent, _ := ioutil.ReadFile(currentDir + "/" + "config.opml")
xmlContent, _ := os.ReadFile(currentDir + "/" + "config.opml")
myFeeds = append(myFeeds, parseOPML(xmlContent)...)
}
// Append any opml file added by -o parameter
if len(*opmlFile) > 0 {
xmlContent, _ := ioutil.ReadFile(*opmlFile)
xmlContent, _ := os.ReadFile(*opmlFile)
myFeeds = append(myFeeds, parseOPML(xmlContent)...)
}

// Append opml file from config.yml
if viper.IsSet("opml_file_path") {
xmlContent, _ := ioutil.ReadFile(viper.Get("opml_file_path").(string))
xmlContent, _ := os.ReadFile(viper.Get("opml_file_path").(string))
myFeeds = append(myFeeds, parseOPML(xmlContent)...)
}

Expand All @@ -178,28 +177,28 @@ func bootstrapConfig() {
show_images = viper.GetBool("show_images")

// Overwrite terminal_mode from config file only if its not set through -t flag
if !terminal_mode {
terminal_mode = viper.GetBool("terminal_mode")
if !terminalMode {
terminalMode = viper.GetBool("terminal_mode")
}

databaseFilePath := viper.GetString("database_file_path")
if databaseFilePath == "" {
databaseDirPath, err := os.UserConfigDir()
check(err)
fatal(err)
databaseFilePath = filepath.Join(databaseDirPath, "brew", "matcha.db")
check(os.MkdirAll(filepath.Dir(databaseFilePath), os.ModePerm))
fatal(os.MkdirAll(filepath.Dir(databaseFilePath), os.ModePerm))
}

db, err = sql.Open("sqlite", databaseFilePath)
check(err)
fatal(err)
err = applyMigrations(db)
if err != nil {
log.Println("Coudn't apply migrations:", err)
}

if !terminal_mode {
if !terminalMode {
markdown_file_name := mdPrefix + currentDate + mdSuffix + ".md"
os.Remove(filepath.Join(markdown_dir_path, markdown_file_name))
os.Remove(filepath.Join(markdownDirPath, markdown_file_name))
}
}

Expand Down
100 changes: 29 additions & 71 deletions feeds_writer.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,21 +5,18 @@ import (
"fmt"
"log"
"net/url"
"os"
"path/filepath"
"strconv"
"strings"
"time"

"github.com/PuerkitoBio/goquery"
readability "github.com/go-shiori/go-readability"
"github.com/mmcdole/gofeed"
"github.com/savioxavier/termlink"
)

var markdown_dir_path string
var markdownDirPath string
var mdPrefix, mdSuffix string
var terminal_mode bool = false
var terminalMode bool = false
var currentDate = time.Now().Format("2006-01-02")
var lat, lon float64
var instapaper bool
Expand All @@ -37,26 +34,24 @@ type RSS struct {
summarize bool
}

func check(e error) {
if e != nil {
log.Fatal(e)
}
type Writer interface {
write(body string)
writeLink(title string, url string, newline bool, readingTime string) string
writeSummary(content string, newline bool) string
writeFavicon(s *gofeed.Feed) string
}

func writeLink(title string, url string, newline bool, readingTime string) string {
var content string
if terminal_mode {
content = termlink.Link(title, url)
} else {
content = "[" + title + "](" + url + ")"
func getWriter() Writer {
if terminalMode {
return TerminalWriter{}
}
if readingTime != "" {
content += " (" + readingTime + ")"
}
if newline {
content += "\n"
return MarkdownWriter{}
}

func fatal(e error) {
if e != nil {
log.Fatal(e)
}
return content
}

func getReadingTime(link string) string {
Expand All @@ -80,26 +75,7 @@ func getReadingTime(link string) string {
return strconv.Itoa(minutes) + " min"
}

func writeSummary(content string, newline bool) string {
if content == "" {
return content
}
if terminal_mode {
if newline {
content += "\n"
}
} else {
if newline {
content += " \n\n"
}
}
return content
}

func favicon(s *gofeed.Feed) string {
if terminal_mode {
return ""
}
func (w MarkdownWriter) writeFavicon(s *gofeed.Feed) string {
var src string
if s.FeedLink == "" {
// default feed favicon
Expand All @@ -121,24 +97,6 @@ func favicon(s *gofeed.Feed) string {
return fmt.Sprintf("<img src=\"%s\" width=\"32\" height=\"32\" />", src)
}

func writeToMarkdown(body string) {
if terminal_mode {
fmt.Println(body)
} else {
markdown_file_name := mdPrefix + currentDate + mdSuffix + ".md"
f, err := os.OpenFile(filepath.Join(markdown_dir_path, markdown_file_name), os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
if err != nil {
log.Fatal(err)
}
if _, err := f.Write([]byte(body)); err != nil {
log.Fatal(err)
}
if err := f.Close(); err != nil {
log.Fatal(err)
}
}
}

func ExtractImageTagFromHTML(htmlText string) string {
doc, err := goquery.NewDocumentFromReader(strings.NewReader(htmlText))
if err != nil {
Expand Down Expand Up @@ -199,7 +157,7 @@ func parseFeed(fp *gofeed.Parser, url string, limit int) *gofeed.Feed {
}

// Generates the feed items and returns them as a string
func generateFeedItems(feed *gofeed.Feed, rss RSS) string {
func generateFeedItems(w Writer, feed *gofeed.Feed, rss RSS) string {
var items string

for _, item := range feed.Items {
Expand All @@ -215,14 +173,14 @@ func generateFeedItems(feed *gofeed.Feed, rss RSS) string {
if strings.Contains(feed.Link, "news.ycombinator.com") {
commentsLink, commentsCount := getCommentsInfo(item)
if commentsCount < 100 {
items += writeLink("💬 ", commentsLink, false, "")
items += w.writeLink("💬 ", commentsLink, false, "")
} else {
items += writeLink("🔥 ", commentsLink, false, "")
items += w.writeLink("🔥 ", commentsLink, false, "")
}
}

// Add the Instapaper link if enabled
if instapaper && !terminal_mode {
if instapaper && !terminalMode {
items += getInstapaperLink(item.Link)
}

Expand All @@ -236,12 +194,12 @@ func generateFeedItems(feed *gofeed.Feed, rss RSS) string {
timeInMin = getReadingTime(link)
}

items += writeLink(title, link, true, timeInMin)
items += w.writeLink(title, link, true, timeInMin)
if rss.summarize {
items += writeSummary(summary, true)
items += w.writeSummary(summary, true)
}

if show_images && !terminal_mode {
if show_images && !terminalMode {
img := ExtractImageTagFromHTML(item.Content)
if img != "" {
items += img + "\n"
Expand All @@ -257,9 +215,9 @@ func generateFeedItems(feed *gofeed.Feed, rss RSS) string {
return items
}

// Writes the feed and its items to the markdown file
func writeFeedToMarkdown(feed *gofeed.Feed, items string) {
writeToMarkdown(fmt.Sprintf("\n### %s %s\n%s", favicon(feed), feed.Title, items))
// Writes the feed and its items
func writeFeed(w Writer, feed *gofeed.Feed, items string) {
w.write(fmt.Sprintf("\n### %s %s\n%s", w.writeFavicon(feed), feed.Title, items))
}

// Returns the title and link for the given feed item
Expand Down Expand Up @@ -296,9 +254,9 @@ func getCommentsInfo(item *gofeed.Item) (string, int) {

func addToSeenTable(link string, summary string) {
stmt, err := db.Prepare("INSERT INTO seen(url, date, summary) values(?,?,?)")
check(err)
fatal(err)
res, err := stmt.Exec(link, currentDate, summary)
check(err)
fatal(err)
_ = res
stmt.Close()
}
Expand Down
8 changes: 5 additions & 3 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,19 +7,21 @@ import (

func main() {
bootstrapConfig()
displayWeather()

fp := gofeed.NewParser()
writer := getWriter()
displayWeather(writer)

for _, feed := range myFeeds {
parsedFeed := parseFeed(fp, feed.url, feed.limit)

if parsedFeed == nil {
continue
}

items := generateFeedItems(parsedFeed, feed)
items := generateFeedItems(writer, parsedFeed, feed)
if items != "" {
writeFeedToMarkdown(parsedFeed, items)
writeFeed(writer, parsedFeed, items)
}
}

Expand Down
45 changes: 45 additions & 0 deletions markdown_writer.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package main

import (
"log"
"os"
"path/filepath"
)

type MarkdownWriter struct{}

func (w MarkdownWriter) write(body string) {
markdown_file_name := mdPrefix + currentDate + mdSuffix + ".md"
f, err := os.OpenFile(filepath.Join(markdownDirPath, markdown_file_name), os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
if err != nil {
log.Fatal(err)
}
if _, err := f.Write([]byte(body)); err != nil {
log.Fatal(err)
}
if err := f.Close(); err != nil {
log.Fatal(err)
}
}

func (w MarkdownWriter) writeLink(title string, url string, newline bool, readingTime string) string {
var content string
content = "[" + title + "](" + url + ")"
if readingTime != "" {
content += " (" + readingTime + ")"
}
if newline {
content += "\n"
}
return content
}

func (w MarkdownWriter) writeSummary(content string, newline bool) string {
if content == "" {
return content
}
if newline {
content += " \n\n"
}
return content
}
37 changes: 37 additions & 0 deletions terminal_writer.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package main

import (
"fmt"

"github.com/mmcdole/gofeed"
"github.com/savioxavier/termlink"
)

type TerminalWriter struct{}

func (w TerminalWriter) write(body string) {
fmt.Println(body)
}

func (w TerminalWriter) writeLink(title string, url string, newline bool, readingTime string) string {
var content string
content = termlink.Link(title, url)
if readingTime != "" {
content += " (" + readingTime + ")"
}
if newline {
content += "\n"
}
return content
}

func (w TerminalWriter) writeSummary(content string, newline bool) string {
if newline {
content += "\n"
}
return content
}

func (w TerminalWriter) writeFavicon(s *gofeed.Feed) string {
return ""
}
Loading