diff --git a/.travis.yml b/.travis.yml index aae111c2..6815c806 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,6 +2,7 @@ language: go go: - 1.x install: +- go get github.com/gorilla/feeds - go get github.com/gorilla/mux - go get github.com/mattn/go-sqlite3 - go get github.com/jinzhu/gorm diff --git a/index.html b/index.html index 01bcf80a..0c9889cf 100644 --- a/index.html +++ b/index.html @@ -109,6 +109,7 @@ {{.Hash}} + diff --git a/main.go b/main.go index b637d8f8..6845edc5 100644 --- a/main.go +++ b/main.go @@ -2,6 +2,7 @@ package main import ( "encoding/json" + "github.com/gorilla/feeds" "github.com/gorilla/mux" "github.com/jinzhu/gorm" _ "github.com/jinzhu/gorm/dialects/sqlite" @@ -24,7 +25,6 @@ func getDBHandle() *gorm.DB { // Migrate the schema of Torrents dbInit.AutoMigrate(&Torrents{}, &Categories{}, &Sub_Categories{}, &Statuses{}) - checkErr(err) return dbInit } @@ -62,6 +62,7 @@ func apiHandler(w http.ResponseWriter, r *http.Request) { return } } + func singleapiHandler(w http.ResponseWriter, r *http.Request) { vars := mux.Vars(r) @@ -138,6 +139,53 @@ func faqHandler(w http.ResponseWriter, r *http.Request) { } } +func rssHandler(w http.ResponseWriter, r *http.Request) { + //vars := mux.Vars(r) + //category := vars["c"] + + // db params url + //maxPerPage := 50 // default Value maxPerPage + + torrents := getFeeds() + created := time.Now().String() + if ( len(torrents) > 0 ) { + created = torrents[0].Timestamp + } + created_as_time, err := time.Parse("2006-01-02 15:04:05", created) + if err == nil { + ; + } + feed := &feeds.Feed{ + Title: "Nyaa Pantsu", + Link: &feeds.Link{Href: "https://nyaa.pantsu.cat/"}, + Created: created_as_time, + } + feed.Items = []*feeds.Item{} + feed.Items = make( []*feeds.Item, len(torrents)) + + for i, _ := range torrents { + timestamp_as_time, err := time.Parse("2006-01-02 15:04:05", torrents[i].Timestamp) + if err == nil { + feed.Items[i] = &feeds.Item{ + // need a torrent view first + //Id: URL + torrents[i].Hash, + Title: torrents[i].Name, + Link: &feeds.Link{Href: string(torrents[i].Magnet)}, + Description: "", + Created: timestamp_as_time, + Updated: timestamp_as_time, + } + } + } + + rss, err := feed.ToRss() + if err == nil { + w.Write( []byte( rss ) ) + } else { + http.Error(w, err.Error(), http.StatusInternalServerError) + } +} + func rootHandler(w http.ResponseWriter, r *http.Request) { vars := mux.Vars(r) page := vars["page"] @@ -187,6 +235,7 @@ func main() { router.HandleFunc("/api/{page}", apiHandler).Methods("GET") router.HandleFunc("/api/torrent/{id}", singleapiHandler).Methods("GET") router.HandleFunc("/faq", faqHandler) + router.HandleFunc("/feed.xml", rssHandler) http.Handle("/", router) diff --git a/models.go b/models.go index 6e62ba16..8fb5f467 100644 --- a/models.go +++ b/models.go @@ -8,18 +8,26 @@ import ( "strings" ) +type Feed struct { + Id int + Name string + Hash string + Magnet string + Timestamp string +} + type Categories struct { - Category_id int - Category_name string - Torrents []Torrents `gorm:"ForeignKey:category_id;AssociationForeignKey:category_id"` - Sub_category []Sub_Categories `gorm:"ForeignKey:category_id;AssociationForeignKey:parent_id"` + Category_id int + Category_name string + Torrents []Torrents `gorm:"ForeignKey:category_id;AssociationForeignKey:category_id"` + Sub_Categories []Sub_Categories `gorm:"ForeignKey:category_id;AssociationForeignKey:parent_id"` } type Sub_Categories struct { - Sub_category_id int + Sub_category_id int Sub_category_name string - Parent_id int - Torrents []Torrents `gorm:"ForeignKey:sub_category_id;AssociationForeignKey:sub_category_id"` + Parent_id int + Torrents []Torrents `gorm:"ForeignKey:sub_category_id;AssociationForeignKey:sub_category_id"` } type Statuses struct { @@ -88,6 +96,27 @@ type HomeTemplateVariables struct { * */ +// don't need raw SQL once we get MySQL +func getFeeds() []Feed { + var result []Feed + rows, err := db.DB(). + Query( + "SELECT `torrent_id` AS `id`, `torrent_name` AS `name`, `torrent_hash` AS `hash`, `timestamp` FROM `torrents` " + + "ORDER BY `timestamp` desc LIMIT 50") + if ( err == nil ) { + for rows.Next() { + item := Feed{} + rows.Scan( &item.Id, &item.Name, &item.Hash, &item.Timestamp ) + magnet := "magnet:?xt=urn:btih:" + strings.TrimSpace(item.Hash) + "&dn=" + item.Name + trackers + item.Magnet = magnet + // memory hog + result = append( result, item ) + } + rows.Close() + } + return result +} + func getTorrentById(id string) (Torrents, error) { var torrent Torrents @@ -98,32 +127,51 @@ func getTorrentById(id string) (Torrents, error) { return torrent, nil } -func getTorrents(parameters WhereParams, limit int, offset int) []Torrents { +func getTorrentsOrderBy(parameters *WhereParams, orderBy string, limit int, offset int) []Torrents { var torrents []Torrents - db.Limit(limit).Offset(offset).Order("torrent_id DESC").Where(parameters.conditions, parameters.params...).Preload("Categories").Preload("Sub_Categories").Find(&torrents) + var dbQuery *gorm.DB + + if (parameters != nil) { // if there is where parameters + dbQuery = db.Model(&torrents).Where(parameters.conditions, parameters.params...) + } else { + dbQuery = db.Model(&torrents) + } + + if (orderBy == "") { orderBy = "torrent_id DESC" } // Default OrderBy + if limit != 0 || offset != 0 { // if limits provided + dbQuery = dbQuery.Limit(limit).Offset(offset) + } + dbQuery.Order(orderBy).Preload("Categories").Preload("Sub_Categories").Find(&torrents) return torrents } +/* Functions to simplify the get parameters of the main function + * + * Get Torrents with where parameters and limits, order by default + */ +func getTorrents(parameters WhereParams, limit int, offset int) []Torrents { + return getTorrentsOrderBy(¶meters, "", limit, offset) +} + +/* Get Torrents with where parameters but no limit and order by default (get all the torrents corresponding in the db) + */ func getTorrentsDB(parameters WhereParams) []Torrents { - var torrents []Torrents - db.Where(parameters.conditions, parameters.params...).Order("torrent_id DESC").Preload("Categories").Preload("Sub_Categories").Find(&torrents) - return torrents + return getTorrentsOrderBy(¶meters, "", 0, 0) } /* Function to get all torrents */ -func getAllTorrents(limit int, offset int) []Torrents { - var torrents []Torrents - db.Model(&torrents).Limit(limit).Offset(offset).Order("torrent_id DESC").Preload("Categories").Preload("Sub_Categories").Find(&torrents) +func getAllTorrentsOrderBy(orderBy string, limit int, offset int) [] Torrents { + return getTorrentsOrderBy(nil, orderBy, limit, offset) +} - return torrents +func getAllTorrents(limit int, offset int) []Torrents { + return getTorrentsOrderBy(nil, "", limit, offset) } func getAllTorrentsDB() []Torrents { - var torrents []Torrents - db.Order("torrent_id DESC").Preload("Categories").Preload("Sub_Categories").Find(&torrents) - return torrents + return getTorrentsOrderBy(nil, "", 0, 0) } /* Function to get all categories with/without torrents (bool)