This commit is contained in:
Nicolas Wavrant 2019-05-01 00:06:07 +09:00
parent a8e1256f82
commit 8272b1a6bf
8 changed files with 16392 additions and 20 deletions

6
go.mod
View File

@ -2,8 +2,10 @@ module git.wavrant.xyz/webrss
require (
github.com/PuerkitoBio/goquery v1.5.0 // indirect
github.com/mattn/go-sqlite3 v1.10.0 // indirect
github.com/mmcdole/gofeed v1.0.0-beta2 // indirect
github.com/gorilla/mux v1.7.0
github.com/gorilla/rpc v1.1.0
github.com/mattn/go-sqlite3 v1.10.0
github.com/mmcdole/gofeed v1.0.0-beta2
github.com/mmcdole/goxpp v0.0.0-20181012175147-0068e33feabf // indirect
golang.org/x/net v0.0.0-20190322120337-addf6b3196f6 // indirect
)

4
go.sum
View File

@ -8,6 +8,10 @@ github.com/PuerkitoBio/goquery v1.5.0 h1:uGvmFXOA73IKluu/F84Xd1tt/z07GYm8X49XKHP
github.com/PuerkitoBio/goquery v1.5.0/go.mod h1:qD2PgZ9lccMbQlc7eEOjaeRlFQON7xY8kdmcsrnKqMg=
github.com/andybalholm/cascadia v1.0.0 h1:hOCXnnZ5A+3eVDX8pvgl4kofXv2ELss0bKcqRySc45o=
github.com/andybalholm/cascadia v1.0.0/go.mod h1:GsXiBklL0woXo1j/WYWtSYYC4ouU9PqHO0sqidkEA4Y=
github.com/gorilla/mux v1.7.0 h1:tOSd0UKHQd6urX6ApfOn4XdBMY6Sh1MfxV3kmaazO+U=
github.com/gorilla/mux v1.7.0/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=
github.com/gorilla/rpc v1.1.0 h1:marKfvVP0Gpd/jHlVBKCQ8RAoUPdX7K1Nuh6l1BNh7A=
github.com/gorilla/rpc v1.1.0/go.mod h1:V4h9r+4sF5HnzqbwIez0fKSpANP0zlYd3qR7p36jkTQ=
github.com/mattn/go-sqlite3 v1.10.0 h1:jbhqpg7tQe4SupckyijYiy0mJJ/pRyHvXf7JdWK860o=
github.com/mattn/go-sqlite3 v1.10.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
github.com/mmcdole/gofeed v1.0.0-beta2 h1:CjQ0ADhAwNSb08zknAkGOEYqr8zfZKfrzgk9BxpWP2E=

167
main.go
View File

@ -2,10 +2,16 @@ package main
import (
"database/sql"
"encoding/json"
"fmt"
"github.com/gorilla/mux"
_ "github.com/mattn/go-sqlite3"
librss "github.com/mmcdole/gofeed"
"log"
"net/http"
"os"
"strconv"
"time"
)
type FeedManager struct {
@ -68,7 +74,7 @@ Custom TEXT,
FOREIGN KEY(Feed) REFERENCES feeds(Id)
)
`}
for _, stmt := range createStmts {
_, err = db.Exec(stmt)
if err != nil {
@ -126,9 +132,9 @@ func (f *FeedManager) AddFeed(url string) (*sql.Result, error) {
return nil, err
}
query := `insert into feeds (title, description, link, feedLink, updated, updatedParsed,
published, publishedParsed, image) values(?, ?, ?, ?, ?, ?, ?, ?, ?);`
published, publishedParsed) values(?, ?, ?, ?, ?, ?, ?, ?);`
return f.ExecDB(query, feed.Title, feed.Description, feed.Link, feed.FeedLink, feed.Updated, feed.UpdatedParsed,
feed.Published, feed.PublishedParsed, feed.Image)
feed.Published, feed.PublishedParsed)
}
func (f *FeedManager) RemoveFeed(url string) (*sql.Result, error) {
@ -146,31 +152,30 @@ func (f *FeedManager) DownloadFeed(url string) (*librss.Feed, error) {
return feed, nil
}
func (f *FeedManager) GetFeeds () (map[int]librss.Feed, error) {
func (f *FeedManager) GetFeeds() (map[int]librss.Feed, error) {
feeds := make(map[int]librss.Feed)
rows, err := f.QueryDB("select id, link from feeds;")
rows, err := f.QueryDB("select id, title, feedlink, link from feeds;")
if err != nil {
return feeds, err
}
defer rows.Close()
for rows.Next() {
var link string
var link, title, feedLink string
var id int
err = rows.Scan(&id, &link)
err = rows.Scan(&id, &title, &feedLink, &link)
if err != nil {
return feeds, err
}
fmt.Println(id, link)
feeds[id] = librss.Feed{Link:link}
feeds[id] = librss.Feed{Link: link, FeedLink: feedLink, Title: title}
}
return feeds, nil
}
func (f *FeedManager) Sync() (error) {
func (f *FeedManager) Sync() error {
feeds, err := f.GetFeeds()
if err != nil {
return err
@ -183,8 +188,8 @@ func (f *FeedManager) Sync() (error) {
}
for _, item := range res.Items {
_, err := f.ExecDB("insert into items (feed, Title, Description, Content, Link, Author, GUID, Image) values (?, ?, ?, ?, ?, ?, ?, ?)",
id, item.Title, item.Description, item.Content, item.Link, item.Author, item.GUID, item.Image)
_, err := f.ExecDB("insert into items (feed, Title, Description, Content, Link, Author, GUID) values (?, ?, ?, ?, ?, ?, ?)",
id, item.Title, item.Description, item.Content, item.Link, item.Author, item.GUID)
if err != nil {
return err
}
@ -194,6 +199,105 @@ func (f *FeedManager) Sync() (error) {
return nil
}
func HomeHandler(w http.ResponseWriter, r *http.Request) {
//fmt.Fprintf(w, "hello")
http.ServeFile(w, r, "./ui/index.html")
}
func GetFeedsHandler(w http.ResponseWriter, r *http.Request) {
defaultDBPath := "./database.db"
feedManager := FeedManager{DBPath: defaultDBPath}
feeds, err := feedManager.GetFeeds()
if err != nil {
return
}
feedList := make([]librss.Feed, 0)
for _, feed := range feeds {
feedList = append(feedList, feed)
}
json, err := json.Marshal(feedList)
fmt.Fprintf(w, string(json))
}
func PostFeed(w http.ResponseWriter, r *http.Request) {
defaultDBPath := "./database.db"
feedManager := FeedManager{DBPath: defaultDBPath}
new_feed_url := r.FormValue("new_feed_url")
if new_feed_url == "" {
w.WriteHeader(500)
}
feeds, err := feedManager.GetFeeds()
if err != nil {
log.Print(err)
w.WriteHeader(500)
return
}
for _, feed := range feeds {
if feed.FeedLink == new_feed_url {
log.Print("Not adding feed ", new_feed_url, " because it already exists")
w.WriteHeader(500)
return
}
}
log.Print("Adding new feed : ", new_feed_url)
_, err = feedManager.AddFeed(r.FormValue("new_feed_url"))
if err != nil {
fmt.Fprintf(w, "ERROR")
}
fmt.Fprintf(w, "OK")
}
func (f *FeedManager) GetItems(feedId int) ([]librss.Item, error) {
rows, err := f.QueryDB("select title, description from items where feed=?;", feedId)
if err != nil {
log.Print(err)
return nil, err
}
defer rows.Close()
items := make([]librss.Item, 0)
for rows.Next() {
var title, description string
err = rows.Scan(&title, &description)
if err != nil {
return nil, err
}
items = append(items, librss.Item{Title: title, Description: description})
}
return items, nil
}
func GetItemsHandler(w http.ResponseWriter, r *http.Request) {
defaultDBPath := "./database.db"
feedManager := FeedManager{DBPath: defaultDBPath}
vars := mux.Vars(r)
feedId, err := strconv.Atoi(vars["feedId"])
if err != nil {
log.Print(err)
return
}
items, err := feedManager.GetItems(feedId)
if err != nil {
log.Print(err)
return
}
json, err := json.Marshal(items)
fmt.Fprintf(w, string(json))
}
func main() {
defaultDBPath := "./database.db"
@ -205,13 +309,40 @@ func main() {
if err != nil {
panic(err)
}
_, err = feedManager.AddFeed("https://www.lemonde.fr/rss/une.xml")
if err != nil {
panic(err)
}
err = feedManager.Sync()
if err != nil {
panic(err)
}
} else if err != nil {
panic(err)
}
router := mux.NewRouter()
err := feedManager.Sync()
if err != nil {
panic(err)
router.HandleFunc("/", HomeHandler)
router.PathPrefix("/static/").Handler(
http.StripPrefix(
"/static/", http.FileServer(http.Dir("./ui/static"))))
router.HandleFunc("/api/feeds/", GetFeedsHandler)
router.HandleFunc("/api/feeds/{feedId:[0-9]+}/items", GetItemsHandler)
router.HandleFunc("/api/feeds/new/", PostFeed).Methods("POST")
http.Handle("/", router)
server := &http.Server{
Handler: router,
Addr: "127.0.0.1:8000",
WriteTimeout: 10 * time.Second,
ReadTimeout: 10 * time.Second,
}
log.Print("Listening on 127.0.0.1:8000")
log.Fatal(server.ListenAndServe())
}

13
ui/index.html Normal file
View File

@ -0,0 +1,13 @@
<html>
<head>
<script src="/static/vue-2.6.10.js"></script>
<script src="/static/vue-router-3.0.2.js"></script>
</head>
<body>
<h1>WebRSS</h1>
<div id="app">
<router-view></router-view>
</div>
</body>
<script src="/static/index.js"></script>
</html>

67
ui/static/index.js Normal file
View File

@ -0,0 +1,67 @@
const FeedListView = Vue.component("feed-list-view", {
data: function () {
return {
feed_list: [],
new_feed_url: "https://linuxfr.org/news.atom"
};
},
methods: {
fetchFeeds: function() {
let component = this;
fetch("/api/feeds/")
.then(function(response) {
return response.json();
})
.then(function(json) {
component.feed_list = json;
})
.catch(function(err) {
console.log(err);
})
},
onSubmit: function () {
let c = this,
fd = new FormData();
fd.set('new_feed_url', this.new_feed_url);
fetch("/api/feeds/new/", {
method: "POST",
body: fd
})
.then(function(response) {
console.log(response);
c.fetchFeeds();
})
.catch(function(err) {
console.log(err);
})
}
},
beforeMount: function () {
return this.fetchFeeds();
},
template:`
<div>
<ul>
<li v-for="feed in feed_list">{{ feed.title }}</li>
</ul>
<form v-on:submit.prevent="onSubmit" action="/api/feeds/new/" method="POST">
<input v-model="new_feed_url" name="feed_url">
<button type="submit">Add</button>
</form>
</div>
`
})
const router = new VueRouter({
routes: [{
path: '/',
component: FeedListView
}]
})
const app = new Vue({
router
}).$mount("#app")

File diff suppressed because it is too large Load Diff

11944
ui/static/vue-2.6.10.js Normal file

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff