Compare commits

...

5 Commits

Author SHA1 Message Date
Jason Schwarzenberger
44b8b36547 add data cast in query. 2020-11-10 15:50:18 +13:00
Jason Schwarzenberger
4f49684194 remove logos from utils.js 2020-11-10 15:38:48 +13:00
Jason Schwarzenberger
1d78b1c592 fix favicon url. 2020-11-10 15:34:21 +13:00
Jason Schwarzenberger
0374794536 Sitemap and Category to get favicon into icon property of story. 2020-11-10 15:22:27 +13:00
Jason Schwarzenberger
943a1cfa4f reader server 2020-11-10 14:56:21 +13:00
8 changed files with 55 additions and 26 deletions

View File

@ -83,7 +83,7 @@ def get_stories(maxage=60*60*24*2):
q = session.query(Reflist, Story.meta).\ q = session.query(Reflist, Story.meta).\
join(Story).\ join(Story).\
filter(Story.title != None).\ filter(Story.title != None).\
filter(Story.meta['date'] > time).\ filter(Story.meta['date'].as_integer() > time).\
order_by(Story.meta['date'].desc()) order_by(Story.meta['date'].desc())
return [x[1] for x in q] return [x[1] for x in q]

View File

@ -139,6 +139,19 @@ class _Base:
s['url'] = ref s['url'] = ref
s['date'] = 0 s['date'] = 0
soup = BeautifulSoup(markup, features='html.parser')
icon32 = soup.find_all('link', rel="icon", href=True, sizes="32x32")
icon16 = soup.find_all('link', rel="icon", href=True, sizes="16x16")
favicon = soup.find_all('link', rel="shortcut icon", href=True)
others = soup.find_all('link', rel="icon", href=True)
icons = icon32 + icon16 + favicon + others
base_url = '/'.join(ref.split('/')[:3])
icons = list(set([i.get('href') for i in icons]))
icons = [i if i.startswith('http') else base_url + i for i in icons]
if icons:
s['icon'] = icons[0]
data = extruct.extract(markup) data = extruct.extract(markup)
s = parse_extruct(s, data) s = parse_extruct(s, data)
if s['date']: if s['date']:

View File

@ -0,0 +1,4 @@
module.exports.headers = {
'User-Agent': 'Googlebot/2.1 (+http://www.google.com/bot.html)',
'X-Forwarded-For': '66.249.66.1',
};

View File

@ -1,14 +1,29 @@
const port = 33843; const port = 33843;
const express = require('express'); const express = require('express');
const app = express(); const app = express();
const simple = require('./simple'); const simple = require('./scraper/simple');
app.use(express.urlencoded({ extended: true })); app.use(express.urlencoded({ extended: true }));
app.get('/', (req, res) => res.send(simple.FORM));
app.post('/', (req, res) => simple.scrape(req, res)); app.get('/', (req, res) => {
app.post('/details', (req, res) => simple.details(req, res)); // const routes = ['/', '/details', '/browser', '/browser/details', '/browser/comments'];
// app.post('/browser', (req, res) => browser.scrape(req, res)); const routes = ['/', '/details'];
// app.post('/browser/details', (req, res) => browser.details(req, res));
const html = routes.map(route => `
<form method="POST" action="${route}" accept-charset="UTF-8">
<fieldset>
<legend>route: POST ${route}</legend>
<input name="url">
<button type="submit">SUBMIT</button>
</fieldset>
</form>`).join('<hr />');
res.send(html);
});
app.post('/', simple.scrape);
app.post('/details', simple.details);
// app.post('/browser', browser.scrape);
// app.post('/browser/details', browser.details);
// app.post('/browser/comments', browser.comments);
app.listen(port, () => { app.listen(port, () => {
console.log(`Example app listening on port ${port}!`); console.log(`Example app listening on port ${port}!`);

View File

@ -2,12 +2,11 @@ const request = require('request');
const JSDOM = require('jsdom').JSDOM; const JSDOM = require('jsdom').JSDOM;
const { Readability } = require('readability'); const { Readability } = require('readability');
const { headers } = require('../constants');
const options = url => ({ const options = url => ({
url: url, url,
headers: { headers,
'User-Agent': 'Googlebot/2.1 (+http://www.google.com/bot.html)',
'X-Forwarded-For': '66.249.66.1',
},
}); });
const extract = (url, body) => { const extract = (url, body) => {
@ -17,13 +16,12 @@ const extract = (url, body) => {
}; };
module.exports.FORM = '<form method="POST" action="/" accept-charset="UTF-8"><input name="url"><button type="submit">SUBMIT</button></form>';
module.exports.scrape = (req, res) => request(options(req.body.url), (error, response, body) => { module.exports.scrape = (req, res) => request(options(req.body.url), (error, response, body) => {
if (error || response.statusCode != 200) { if (error || response.statusCode != 200) {
console.log('Response error:', error ? error.toString() : response.statusCode); console.log('Response error:', error ? error.toString() : response.statusCode);
return res.sendStatus(response ? response.statusCode : 404); return res.sendStatus(response ? response.statusCode : 404);
} }
const article = extract(url, body); const article = extract(req.body.url, body);
if (article && article.content) { if (article && article.content) {
return res.send(article.content); return res.send(article.content);
} }
@ -35,7 +33,7 @@ module.exports.details = (req, res) => request(options(req.body.url), (error, re
console.log('Response error:', error ? error.toString() : response.statusCode); console.log('Response error:', error ? error.toString() : response.statusCode);
return res.sendStatus(response ? response.statusCode : 404); return res.sendStatus(response ? response.statusCode : 404);
} }
const article = extract(url, body); const article = extract(req.body.url, body);
if (article) { if (article) {
return res.send(article); return res.send(article);
} }

View File

@ -2,7 +2,7 @@ import React from 'react';
import { Link } from 'react-router-dom'; import { Link } from 'react-router-dom';
import { Helmet } from 'react-helmet'; import { Helmet } from 'react-helmet';
import localForage from 'localforage'; import localForage from 'localforage';
import { sourceLink, infoLine, logos } from './utils.js'; import { sourceLink, infoLine, getLogoUrl } from './utils.js';
class Feed extends React.Component { class Feed extends React.Component {
constructor(props) { constructor(props) {
@ -62,7 +62,7 @@ class Feed extends React.Component {
<div className='item' key={x.id}> <div className='item' key={x.id}>
<div className='title'> <div className='title'>
<Link className='link' to={'/' + x.id}> <Link className='link' to={'/' + x.id}>
<img className='source-logo' src={logos[x.source] || logos[x.source.split(' ')[0]]} alt='source logo' /> {x.title} <img className='source-logo' src={getLogoUrl(x)} alt='source logo' /> {x.title}
</Link> </Link>
<span className='source'> <span className='source'>

View File

@ -1,7 +1,7 @@
import React from 'react'; import React from 'react';
import { Link } from 'react-router-dom'; import { Link } from 'react-router-dom';
import { Helmet } from 'react-helmet'; import { Helmet } from 'react-helmet';
import { sourceLink, infoLine, logos } from './utils.js'; import { sourceLink, infoLine, getLogoUrl } from './utils.js';
import AbortController from 'abort-controller'; import AbortController from 'abort-controller';
class Results extends React.Component { class Results extends React.Component {
@ -68,7 +68,7 @@ class Results extends React.Component {
<div className='item' key={x.id}> <div className='item' key={x.id}>
<div className='title'> <div className='title'>
<Link className='link' to={'/' + x.id}> <Link className='link' to={'/' + x.id}>
<img className='source-logo' src={logos[x.source]} alt='source logo' /> {x.title} <img className='source-logo' src={getLogoUrl(x)} alt='source logo' /> {x.title}
</Link> </Link>
<span className='source'> <span className='source'>
@ -79,12 +79,12 @@ class Results extends React.Component {
{infoLine(x)} {infoLine(x)}
</div> </div>
) )
: :
<p>none</p> <p>none</p>
} }
</div> </div>
</> </>
: :
<p>loading...</p> <p>loading...</p>
} }
</div> </div>

File diff suppressed because one or more lines are too long