Skip to content

Instantly share code, notes, and snippets.

@EdwardHinkle
Last active January 17, 2023 21:27
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save EdwardHinkle/80c1f012bdb5681961f834d1a2ada596 to your computer and use it in GitHub Desktop.
Save EdwardHinkle/80c1f012bdb5681961f834d1a2ada596 to your computer and use it in GitHub Desktop.
import * as request from 'request-promise-native';
import * as moment from 'moment';
import { Promise } from 'es6-promise';
import * as opmlToJSON from 'opml-to-json';
import * as cheerio from 'cheerio';
import * as fs from 'fs';
import * as cron from 'cron';
let requestJar = request.defaults({jar: true});
let config = {
"session_path": "session.json",
"opml_path": "opml_extended.opml",
"email": "OVERCAST_EMAIL",
"password": "OVERCAST_PASSWORD"
};
console.log('Setting up Cron Job');
new cron.CronJob('0 0 0,12 * * *', function () {
console.log('running routine cron job');
checkOvercast();
}).start();
function checkOvercast() {
console.log('checking overcast');
startSession().then(() => {
return fetchOPMLFile();
}).then(opmlFile => {
console.log("next, save file");
return new Promise((resolve, reject) => {
console.log("saving file");
fs.writeFile(config.opml_path, opmlFile, {
encoding: 'utf8'
}, (err) => {
if (err) {
reject('opml file failed to save');
return console.log(err);
}
console.log('opml saved');
resolve(opmlFile);
});
});
})
.then(() => {
return openOPMLFile();
})
.then((overcastJSON: any) => {
let listensForMicropub = [];
let listenPromises = [];
new Promise((resolve, reject) => {
let today = moment().hour(0).minute(0).second(0);
let podcasts = overcastJSON.children.filter(item => item.text === "feeds")[0]
.children.filter(item => item.type === "rss" && item.children !== undefined);
podcasts.map(podcast => podcast.children = podcast.children.filter(episode => episode.played === "1" && today.diff(moment(episode.userupdateddate), "seconds") <= 12*60*60));
// console.log(JSON.stringify(podcasts, null, 2));
podcasts.forEach(podcast => {
console.log('processing podcast: ' + podcast.title);
if (podcast.children !== undefined) {
podcast.children.forEach(episode => {
listenPromises.push(requestJar({
uri: episode.overcasturl,
transform: function(body) {
return cheerio.load(body);
}
}).then(($) => {
let episodeArtwork = $("img.art.fullart").attr('src')
let episodeDescription = $("meta[name='og:description']").attr('content');
return {
"type": ["h-entry"],
"properties": {
"published": [moment(episode.userupdateddate).format()],
"listen-of": {
"type": "h-cite",
"properties": {
"name": episode.title,
"url": episode.url,
"audio": episode.enclosureurl,
"photo": episodeArtwork,
"summary": episodeDescription,
"author": {
"type": "h-card",
"properties": {
"name": podcast.title,
"url": podcast.htmlurl,
"photo": episodeArtwork
}
}
}
},
'task-status': 'finished'
}
};
}).catch(err => {
console.log(err);
reject(err);
}));
});
}
});
});
return Promise.all(listenPromises).then((listenPosts) => {
console.log('reached the end of episode processing');
return listenPosts;
});
}).then((listens) => {
console.log('finished fetching episodes');
console.log(JSON.stringify(listens, null, 2));
sendEpisodesViaMicropub(listens);
});
}
function startSession() {
console.log('starting new session');
return requestJar({
method: "POST",
uri: "https://overcast.fm/login",
form: {
"email": config.email,
"password": config.password
},
simple: false,
resolveWithFullResponse: true
}).then((response) => {
if (response.statusCode != 200 && response.statusCode != 302) {
console.log('Failed to login to Overcast');
throw new Error("Failed to login to Overcast");
} else {
console.log('Successful login');
}
}).catch(err => {
console.log('overcast login failed');
console.log(err);
});
}
function fetchOPMLFile() {
console.log('fetching opml file');
return requestJar({
method: "GET",
uri: "https://overcast.fm/account/export_opml/extended"
}).then(opmlFile => {
console.log('retrieved opml file');
return opmlFile;
}).catch(error => {
console.log('failed to fetch opml file');
console.log(error);
});
}
function openOPMLFile() {
return new Promise((resolve, reject) => {
fs.readFile(config.opml_path, {
encoding: 'utf8'
}, (err, opml_data) => {
if (err) {
console.log(err);
reject(err);
}
console.log('opened opml file');
opmlToJSON(opml_data, (error, opml_json) => {
if (error) {
console.log(error);
reject(error);
}
console.log('converted opml to json');
resolve(opml_json);
});
});
});
}
function complete() {
console.log('done');
}
function sendEpisodesViaMicropub(episodesToSend) {
episodesToSend.forEach(postData => {
request.post(`MICROPUB_ENDPOINT`, {
'auth': {
'bearer': `BEARER_TOKEN`
},
body: postData,
json: true
}, (err, data) => {
if (err != undefined) {
console.log(`ERROR: ${err}`);
}
if (data.statusCode !== 201 && data.statusCode !== 202) {
console.log("Podcast Episode Micropub error");
} else {
console.log("Successfully created Micropub request for " + postData.properties['listen-of'].properties.name);
}
});
});
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment