Prepared for in-memory-caching (not yet functional).

This commit is contained in:
Martin Dosch 2019-06-01 10:59:19 +02:00
parent 1bdf8c048f
commit fb21d01556
2 changed files with 106 additions and 95 deletions

View file

@ -17,104 +17,110 @@ import (
"jaytaylor.com/html2text"
)
// ToDo: If caching == false create a global variable to save timestamp in memory.
// Get new articles for specified feed.
func getArticles(feedURL string, max int, noExcerpt bool, filter []string) (string, error) {
func getArticles(feedURL string, max int, noExcerpt bool, filter []string, caching bool) (string, error) {
type feedCache struct {
LastChange string
}
var output, cachePath string
var output, cachePath, cacheFile string
var last time.Time
var lastUpdate feedCache
var file *os.File
var updateTime time.Time
// Get systems user cache path.
osCacheDir := os.Getenv("$XDG_CACHE_HOME")
if osCacheDir != "" {
// Create configPath if not yet existing.
cachePath = osCacheDir + "/feed-to-muc/"
if caching == true {
// Get systems user cache path.
osCacheDir := os.Getenv("$XDG_CACHE_HOME")
if osCacheDir != "" {
// Create configPath if not yet existing.
cachePath = osCacheDir + "/feed-to-muc/"
if _, err := os.Stat(cachePath); os.IsNotExist(err) {
err = os.MkdirAll(cachePath, 0700)
if err != nil {
log.Fatal("Error: Can't create cache path:", err)
}
}
} else { // Get the current user.
curUser, err := user.Current()
if err != nil {
log.Fatal("Error: Can't get current user:", err)
return "", err
}
// Get home directory.
home := curUser.HomeDir
if home == "" {
log.Fatal("Error: No home directory available.")
return "", err
}
// Create cachePath if not yet existing.
cachePath = home + "/.cache/feed-to-muc/"
if _, err := os.Stat(cachePath); os.IsNotExist(err) {
err = os.MkdirAll(cachePath, 0700)
if err != nil {
log.Fatal("Error: Can't create cache path:", err)
}
}
}
// Create a hash as identifier for the feed.
// The identifier will be used as filename for caching the update time.
h := fnv.New32a()
h.Write([]byte(feedURL))
if _, err := os.Stat(cachePath); os.IsNotExist(err) {
err = os.MkdirAll(cachePath, 0700)
if err != nil {
log.Fatal("Error: Can't create cache path:", err)
log.Fatal("Error: Can't create hash identifier for cache file:", err)
}
}
} else { // Get the current user.
curUser, err := user.Current()
if err != nil {
log.Fatal("Error: Can't get current user:", err)
return "", err
}
// Get home directory.
home := curUser.HomeDir
cacheFile = cachePath + strconv.Itoa(int(h.Sum32()))
if home == "" {
log.Fatal("Error: No home directory available.")
return "", err
}
// Create cachePath if not yet existing.
cachePath = home + "/.cache/feed-to-muc/"
if _, err := os.Stat(cachePath); os.IsNotExist(err) {
err = os.MkdirAll(cachePath, 0700)
if _, err := os.Stat(cacheFile); os.IsNotExist(err) {
file, err = os.Create(cacheFile)
if err != nil {
log.Fatal("Error: Can't create cache path:", err)
log.Fatal("Error: Can't create cache file:", err)
}
defer file.Close()
last = time.Now()
lastUpdate.LastChange = last.Format(time.RFC3339)
lastUpdateJSON, _ := json.MarshalIndent(lastUpdate, "", " ")
_, err = file.Write(lastUpdateJSON)
if err != nil {
log.Fatal("Error: Can't write last update time stamp to cache file:", err)
}
} else {
file, err = os.OpenFile(cacheFile, os.O_RDWR, 0600)
if err != nil {
log.Fatal("Error: Can't open cache file:", err)
}
defer file.Close()
decoder := json.NewDecoder(file)
lastUpdate := feedCache{}
if err := decoder.Decode(&lastUpdate); err != nil {
log.Fatal("Error: Can't decode laste updates time stamp:", err)
}
last, err = time.Parse(time.RFC3339, string(lastUpdate.LastChange))
if err != nil {
log.Fatal("Error: Can't parse last updates time stamp:", err)
}
}
}
// Create a hash as identifier for the feed.
// The identifier will be used as filename for caching the update time.
h := fnv.New32a()
h.Write([]byte(feedURL))
if _, err := os.Stat(cachePath); os.IsNotExist(err) {
err = os.MkdirAll(cachePath, 0700)
if err != nil {
log.Fatal("Error: Can't create hash identifier for cache file:", err)
}
}
cacheFile := cachePath + strconv.Itoa(int(h.Sum32()))
if _, err := os.Stat(cacheFile); os.IsNotExist(err) {
file, err = os.Create(cacheFile)
if err != nil {
log.Fatal("Error: Can't create cache file:", err)
}
defer file.Close()
last = time.Now()
lastUpdate.LastChange = last.Format(time.RFC3339)
lastUpdateJSON, _ := json.MarshalIndent(lastUpdate, "", " ")
_, err = file.Write(lastUpdateJSON)
if err != nil {
log.Fatal("Error: Can't write last update time stamp to cache file:", err)
}
} else {
file, err = os.OpenFile(cacheFile, os.O_RDWR, 0600)
if err != nil {
log.Fatal("Error: Can't open cache file:", err)
}
defer file.Close()
decoder := json.NewDecoder(file)
lastUpdate := feedCache{}
if err := decoder.Decode(&lastUpdate); err != nil {
log.Fatal("Error: Can't decode laste updates time stamp:", err)
}
last, err = time.Parse(time.RFC3339, string(lastUpdate.LastChange))
if err != nil {
log.Fatal("Error: Can't parse last updates time stamp:", err)
}
last = time.Now()
}
fp := gofeed.NewParser()
@ -174,24 +180,26 @@ func getArticles(feedURL string, max int, noExcerpt bool, filter []string) (stri
last = updateTime
lastUpdate.LastChange = updateTime.Format(time.RFC3339)
// Remove file with cached timestamp and create it
// again with updated timestamp.
// ToDo: Replace timestamp without deleting.
err = os.Remove(cacheFile)
if err != nil {
log.Fatal("Error: Can't delete cache file:", err)
}
if caching == true {
// Remove file with cached timestamp and create it
// again with updated timestamp.
// ToDo: Replace timestamp without deleting.
err = os.Remove(cacheFile)
if err != nil {
log.Fatal("Error: Can't delete cache file:", err)
}
file, err = os.Create(cacheFile)
if err != nil {
log.Fatal("Error: Can't create cache file:", err)
}
defer file.Close()
file, err = os.Create(cacheFile)
if err != nil {
log.Fatal("Error: Can't create cache file:", err)
}
defer file.Close()
lastUpdateJSON, _ := json.MarshalIndent(lastUpdate, "", " ")
_, err = file.Write(lastUpdateJSON)
if err != nil {
log.Fatal("Error: Can't write last update time stamp to cache file:", err)
lastUpdateJSON, _ := json.MarshalIndent(lastUpdate, "", " ")
_, err = file.Write(lastUpdateJSON)
if err != nil {
log.Fatal("Error: Can't write last update time stamp to cache file:", err)
}
}
// Remove redirects and tracking parameters from URL.

View file

@ -17,11 +17,12 @@ type configuration struct {
Password string
Muc string
MucNick string
Contact string
MaxArticles int
RefreshTime time.Duration
NoExcerpt bool
Quiet bool
Contact string
Caching bool
Filter []string
Feeds []string
}
@ -72,7 +73,8 @@ func main() {
go pingMUC(client, config.BotJid, config.Muc, config.MucNick)
// Starting goroutine to process received stanzas.
go processStanzas(client, config.Muc, config.MucNick, config.Feeds, config.Quiet, config.Contact)
go processStanzas(client, config.Muc, config.MucNick, config.Feeds, config.Quiet,
config.Contact)
// Set RefreshTime to 30 seconds if not defined.
if config.RefreshTime == 0 {
@ -83,7 +85,8 @@ func main() {
// Check all configured feeds for new articles and send
// new articles to configured MUC.
for i := 0; i < len(config.Feeds); i++ {
output, err := getArticles(config.Feeds[i], config.MaxArticles, config.NoExcerpt, config.Filter)
output, err := getArticles(config.Feeds[i], config.MaxArticles, config.NoExcerpt,
config.Filter, config.Caching)
if err != nil {
// Exit if an error occurs checking the feeds.
log.Fatal("Error: Can't check feeds for new articles: ", err)