diff --git a/cmd/sl-feeds/main.go b/cmd/sl-feeds/main.go index f4ebb4b..e61fe4a 100644 --- a/cmd/sl-feeds/main.go +++ b/cmd/sl-feeds/main.go @@ -3,9 +3,13 @@ package main import ( "fmt" "io/ioutil" + "log" "os" + "path/filepath" + "time" - _ "../../fetch" + "../../changelog" + "../../fetch" "github.com/BurntSushi/toml" "github.com/urfave/cli" ) @@ -58,19 +62,84 @@ func main() { "slackwarearm-current", }, }, + Mirror{ + URL: "http://alphageek.noip.me/mirrors/alphageek/", + Prefix: "alphageek-", + Releases: []string{ + "slackware64-14.2", + }, + }, }, } toml.NewEncoder(os.Stdout).Encode(c) return nil } - fmt.Println(os.ExpandEnv(config.Dest)) + dest := os.ExpandEnv(config.Dest) + fmt.Printf("Writing to: %q\n", dest) /* for each mirror in Mirrors if there is not a $release.RSS file, then fetch the whole ChangeLog if there is a $release.RSS file, then stat the file and only fetch remote if it is newer than the local RSS file if the remote returns any error (404, 503, etc) then print a warning but continue */ + for _, mirror := range config.Mirrors { + for _, release := range mirror.Releases { + repo := fetch.Repo{ + URL: mirror.URL, + Release: release, + } + + log.Printf("processing %q", repo.URL+"/"+repo.Release) + + stat, err := os.Stat(filepath.Join(dest, mirror.Prefix+release+".rss")) + if err != nil && !os.IsNotExist(err) { + log.Println(release, err) + continue + } + var ( + entries []changelog.Entry + mtime time.Time + ) + if os.IsNotExist(err) { + entries, mtime, err = repo.ChangeLog() + if err != nil { + log.Println(release, err) + continue + } + } else { + // compare times + entries, mtime, err = repo.NewerChangeLog(stat.ModTime()) + if err != nil { + log.Println(release, err) + continue + } + } + + // write out the rss and chtime it to be mtime + feeds, err := changelog.ToFeed(repo.URL+"/"+release, entries) + if err != nil { + log.Println(release, err) + continue + } + fh, err := os.Create(filepath.Join(dest, mirror.Prefix+release+".rss")) + if err != nil { + log.Println(release, err) + continue + } + if err := feeds.WriteRss(fh); err != nil { + log.Println(release, err) + fh.Close() + continue + } + fh.Close() + err = os.Chtimes(filepath.Join(dest, mirror.Prefix+release+".rss"), mtime, mtime) + if err != nil { + log.Println(release, err) + continue + } + } + } return nil } @@ -103,4 +172,5 @@ type Config struct { type Mirror struct { URL string Releases []string + Prefix string } diff --git a/fetch/fetch.go b/fetch/fetch.go index a908dee..4bc2242 100644 --- a/fetch/fetch.go +++ b/fetch/fetch.go @@ -10,16 +10,19 @@ import ( // Repo represents a remote slackware software repo type Repo struct { - URL string + URL string + Release string } func (r Repo) head(file string) (*http.Response, error) { - return http.Head(r.URL + "/" + file) + return http.Head(r.URL + "/" + r.Release + "/" + file) } func (r Repo) get(file string) (*http.Response, error) { - return http.Get(r.URL + "/" + file) + return http.Get(r.URL + "/" + r.Release + "/" + file) } +// NewerChangeLog checks the last-modified time of the remote ChangeLog.txt and +// only fetches it if the remote is newer than the provided time. func (r Repo) NewerChangeLog(than time.Time) (e []changelog.Entry, mtime time.Time, err error) { resp, err := r.head("ChangeLog.txt") if err != nil {