chore(server): Move api-server in to it's own DIR

This commit is contained in:
Bouncey
2018-08-31 16:04:04 +01:00
committed by mrugesh mohapatra
parent 9fba6bce4c
commit 46a217d0a5
369 changed files with 328 additions and 7431 deletions

View File

@ -0,0 +1,86 @@
import _ from 'lodash';
import compareDesc from 'date-fns/compare_desc';
import debug from 'debug';
import { getMediumFeed } from './medium';
import { getLybsynFeed } from './lybsyn';
const log = debug('fcc:rss:news-feed');
const fiveMinutes = 1000 * 60 * 5;
class NewsFeed {
constructor() {
this.state = {
readyState: false,
mediumFeed: [],
lybsynFeed: [],
combinedFeed: []
};
this.refreshFeeds();
setInterval(this.refreshFeeds, fiveMinutes);
}
setState = stateUpdater => {
const newState = stateUpdater(this.state);
this.state = _.merge({}, this.state, newState);
return;
}
refreshFeeds = () => {
const currentFeed = this.state.combinedFeed.slice(0);
log('grabbing feeds');
return Promise.all([
getMediumFeed(),
getLybsynFeed()
]).then(
([mediumFeed, lybsynFeed]) => this.setState(
state => ({
...state,
mediumFeed,
lybsynFeed
})
))
.then(() => {
log('crossing the streams');
const { mediumFeed, lybsynFeed} = this.state;
const combinedFeed = [ ...mediumFeed, ...lybsynFeed ].sort((a, b) => {
return compareDesc(a.isoDate, b.isoDate);
});
this.setState(state => ({
...state,
combinedFeed,
readyState: true
}));
})
.catch(err => {
console.log(err);
this.setState(state => ({
...state,
combinedFeed: currentFeed
}));
});
}
getFeed = () => new Promise((resolve) => {
let notReadyCount = 0;
function waitForReady() {
log('notReadyCount', notReadyCount);
notReadyCount++;
return this.state.readyState || notReadyCount === 5 ?
resolve(this.state.combinedFeed) :
setTimeout(waitForReady, 100);
}
log('are we ready?', this.state.readyState);
return this.state.readyState ?
resolve(this.state.combinedFeed) :
setTimeout(waitForReady, 100);
})
}
export default NewsFeed;

View File

@ -0,0 +1,47 @@
import http from 'http';
import _ from 'lodash';
const lybsynFeed = 'http://freecodecamp.libsyn.com/render-type/json';
export function getLybsynFeed() {
return new Promise((resolve, reject) => {
http.get(lybsynFeed, res => {
let raw = '';
res.on('data', chunk => {
raw += chunk;
});
res.on('error', err => reject(err));
res.on('end', () => {
let feed = [];
try {
feed = JSON.parse(raw);
} catch (err) {
return reject(err);
}
const items = feed.map(
item => _.pick(item, [
'full_item_url',
'item_title',
'release_date',
'item_body_short'
])
)
/* eslint-disable camelcase */
.map(({ full_item_url, item_title, release_date, item_body_short}) => ({
title: item_title,
extract: item_body_short,
isoDate: new Date(release_date).toISOString(),
link: full_item_url
}));
/* eslint-enable camelcase */
return resolve(items);
});
});
});
}

View File

@ -0,0 +1,39 @@
import Parser from 'rss-parser';
import _ from 'lodash';
const parser = new Parser();
const mediumFeed = 'https://medium.freecodecamp.org/feed';
function getExtract(str) {
return str.slice(0, str.indexOf('</p>') + 4);
}
function addResponsiveClass(str) {
return str.replace(/\<img/g, '<img class="img-responsive"');
}
export function getMediumFeed() {
return new Promise((resolve, reject) => {
parser.parseURL(mediumFeed, (err, feed) => {
if (err) {
reject(err);
}
const items = feed.items
.map(
item => _.pick(item, ['title', 'link', 'isoDate', 'content:encoded'])
)
.map(
(item) => ({
...item,
extract: getExtract(item['content:encoded'])
})
)
.map(item => _.omit(item, ['content:encoded']))
.map(item => ({ ...item, extract: addResponsiveClass(item.extract)}));
resolve(items);
});
});
}