mirror of
https://github.com/nkanaev/yarr.git
synced 2025-05-25 13:39:22 +00:00
readability integration
This commit is contained in:
parent
5d5f95725f
commit
ef0e404b90
@ -16,6 +16,7 @@ import (
|
|||||||
"math"
|
"math"
|
||||||
"html"
|
"html"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"io/ioutil"
|
||||||
)
|
)
|
||||||
|
|
||||||
func IndexHandler(rw http.ResponseWriter, req *http.Request) {
|
func IndexHandler(rw http.ResponseWriter, req *http.Request) {
|
||||||
@ -472,3 +473,16 @@ func OPMLExportHandler(rw http.ResponseWriter, req *http.Request) {
|
|||||||
rw.Write([]byte(builder.String()))
|
rw.Write([]byte(builder.String()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func PageCrawlHandler(rw http.ResponseWriter, req *http.Request) {
|
||||||
|
query := req.URL.Query()
|
||||||
|
if url := query.Get("url"); len(url) > 0 {
|
||||||
|
res, err := http.Get(url)
|
||||||
|
if err == nil {
|
||||||
|
body, err := ioutil.ReadAll(res.Body)
|
||||||
|
if err == nil {
|
||||||
|
rw.Write(body)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -82,6 +82,7 @@ var routes []Route = []Route{
|
|||||||
p("/api/settings", SettingsHandler),
|
p("/api/settings", SettingsHandler),
|
||||||
p("/opml/import", OPMLImportHandler),
|
p("/opml/import", OPMLImportHandler),
|
||||||
p("/opml/export", OPMLExportHandler),
|
p("/opml/export", OPMLExportHandler),
|
||||||
|
p("/page", PageCrawlHandler),
|
||||||
}
|
}
|
||||||
|
|
||||||
func Vars(req *http.Request) map[string]string {
|
func Vars(req *http.Request) map[string]string {
|
||||||
|
@ -117,6 +117,9 @@
|
|||||||
<a class="btn btn-link p-0" :href="itemSelectedDetails.link" target="_blank" style="line-height: 1">
|
<a class="btn btn-link p-0" :href="itemSelectedDetails.link" target="_blank" style="line-height: 1">
|
||||||
<img src="./static/images/external-link.svg" alt="" style="width: 20px; height: 20px;">
|
<img src="./static/images/external-link.svg" alt="" style="width: 20px; height: 20px;">
|
||||||
</a>
|
</a>
|
||||||
|
<button class="btn btn-link p-0" @click="getReadable(itemSelectedDetails)">
|
||||||
|
<img src="./static/images/book.svg" alt="" style="width: 20px; height: 20px;">
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<button class="btn btn-link p-0" v-b-modal.settings-modal style="line-height: 1">
|
<button class="btn btn-link p-0" v-b-modal.settings-modal style="line-height: 1">
|
||||||
@ -131,7 +134,8 @@
|
|||||||
</div>
|
</div>
|
||||||
<hr>
|
<hr>
|
||||||
<div class="content">
|
<div class="content">
|
||||||
<div v-html="itemSelectedDetails.content" v-if="itemSelectedDetails.content"></div>
|
<div v-html="itemSelectedReadability" v-if="itemSelectedReadability"></div>
|
||||||
|
<div v-html="itemSelectedDetails.content" v-else-if="itemSelectedDetails.content"></div>
|
||||||
<div v-html="itemSelectedDetails.description" v-else-if="itemSelectedDetails.description"></div>
|
<div v-html="itemSelectedDetails.description" v-else-if="itemSelectedDetails.description"></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -247,6 +251,7 @@
|
|||||||
<script src="./static/javascripts/popper.min.js"></script>
|
<script src="./static/javascripts/popper.min.js"></script>
|
||||||
<!-- <script src="./static/javascripts/bootstrap.min.js"></script> -->
|
<!-- <script src="./static/javascripts/bootstrap.min.js"></script> -->
|
||||||
<script src="./static/javascripts/bootstrap-vue.min.js"></script>
|
<script src="./static/javascripts/bootstrap-vue.min.js"></script>
|
||||||
|
<script src="./static/javascripts/Readability.js"></script>
|
||||||
<script src="./static/javascripts/api.js"></script>
|
<script src="./static/javascripts/api.js"></script>
|
||||||
<script src="./static/javascripts/app.js"></script>
|
<script src="./static/javascripts/app.js"></script>
|
||||||
</body>
|
</body>
|
||||||
|
1
template/static/images/book.svg
Normal file
1
template/static/images/book.svg
Normal file
@ -0,0 +1 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-book"><path d="M4 19.5A2.5 2.5 0 0 1 6.5 17H20"></path><path d="M6.5 2H20v20H6.5A2.5 2.5 0 0 1 4 19.5v-15A2.5 2.5 0 0 1 6.5 2z"></path></svg>
|
After Width: | Height: | Size: 345 B |
2071
template/static/javascripts/Readability.js
Normal file
2071
template/static/javascripts/Readability.js
Normal file
File diff suppressed because it is too large
Load Diff
@ -83,5 +83,10 @@
|
|||||||
body: new FormData(form),
|
body: new FormData(form),
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
crawl: function(url) {
|
||||||
|
return fetch('/page?url=' + url).then(function(res) {
|
||||||
|
return res.text()
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
})()
|
})()
|
||||||
|
@ -43,6 +43,7 @@ var vm = new Vue({
|
|||||||
},
|
},
|
||||||
'itemSelected': null,
|
'itemSelected': null,
|
||||||
'itemSelectedDetails': {},
|
'itemSelectedDetails': {},
|
||||||
|
'itemSelectedReadability': '',
|
||||||
'itemSearch': '',
|
'itemSearch': '',
|
||||||
'settings': 'create',
|
'settings': 'create',
|
||||||
'loading': {
|
'loading': {
|
||||||
@ -115,6 +116,7 @@ var vm = new Vue({
|
|||||||
this.refreshItems()
|
this.refreshItems()
|
||||||
},
|
},
|
||||||
'itemSelected': function(newVal, oldVal) {
|
'itemSelected': function(newVal, oldVal) {
|
||||||
|
this.itemSelectedReadability = ''
|
||||||
this.itemSelectedDetails = this.itemsById[newVal]
|
this.itemSelectedDetails = this.itemsById[newVal]
|
||||||
if (this.itemSelectedDetails.status == 'unread') {
|
if (this.itemSelectedDetails.status == 'unread') {
|
||||||
this.itemSelectedDetails.status = 'read'
|
this.itemSelectedDetails.status = 'read'
|
||||||
@ -303,5 +305,18 @@ var vm = new Vue({
|
|||||||
vm.refreshFeeds()
|
vm.refreshFeeds()
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
getReadable: function(item) {
|
||||||
|
if (item.link) {
|
||||||
|
var vm = this
|
||||||
|
api.crawl(item.link).then(function(body) {
|
||||||
|
if (!body.length) return
|
||||||
|
var doc = new DOMParser().parseFromString(body, 'text/html')
|
||||||
|
var parsed = new Readability(doc).parse()
|
||||||
|
if (parsed && parsed.content) {
|
||||||
|
vm.itemSelectedReadability = parsed.content
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
},
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
Loading…
x
Reference in New Issue
Block a user