Commit c45446ee authored by Iván Sánchez Ortega's avatar Iván Sánchez Ortega

Proof-of-concept display of streaming mastodon updates.

parent 60df56ad
......@@ -10,8 +10,11 @@
"chalk256": "^5.1.0",
"configstore": "^3.0.0",
"flatten-obj": "^3.1.0",
"he": "^1.1.1",
"inquirer": "^3.0.6",
"mastodon-api": "^1.1.1",
"oauth": "^0.9.15",
"striptags": "^3.0.1",
"vorpal": "^1.11.4"
},
"scripts": {
......
......@@ -22,7 +22,7 @@ import inquirer from 'inquirer';
class ClockAccount extends Account {
constructor(callback, opts) {
constructor(callback, vorpal, opts) {
this._timers = {};
this._opts = Object.assign({
......@@ -93,7 +93,7 @@ class ClockAccount extends Account {
export function signUp() {
console.log('Performing sign-up procedure for a new "clock" account');
// There is nothing asynchronous here, so...
/// TODO: Extend this with a prompt for the default channel to listen to, or a prompt for
......
......@@ -4,6 +4,9 @@ import Account from '../abstracts/account';
import inquirer from 'inquirer';
import { OAuth2 } from 'oauth';
import chalk from 'chalk256';
import Mastodon from 'mastodon-api';
import striptags from 'striptags';
import he from 'he';
// 🍂class MastodonAccount
......@@ -12,17 +15,125 @@ import chalk from 'chalk256';
class MastodonAccount extends Account {
constructor(callback, opts) {
constructor(callback, vorpal, opts) {
// this._timers = {};
this._opts = Object.assign({
colour: 'grey'
// colour: 'grey'
}, opts);
this._masto = new Mastodon({
access_token: opts.access_token,
api_url: opts.api_url
});
this._masto.get('accounts/verify_credentials')
/*.then(response=>response.json()).*/
.then(json=> {
// console.log(chalk.purple('>>> Mastodon account credentials: '), json);
vorpal.log(
chalk.purple('You are logged in the Mastodon platform as '),
chalk.cyan(json.data.username),
chalk.purple(' in server '),
chalk.cyan(opts.api_url.replace(/.*:\/\//,'').replace(/\/.*/, '')),
chalk.purple(', account badge is '),
chalk.cyan(opts.badge)
);
// Hackishly listen to the public timeline
let userListener = this._masto.stream('streaming/user');
userListener.on('message', msg => {
if (msg.event === 'update') {
this.emit({
sender: msg.data.account.acct,
str: this._cleanString(msg.data.content),
channel: 'user',
realtime: true,
}, msg);
} else {
vorpal.log(chalk.green(msg));
}
});
let publicListener = this._masto.stream('streaming/public');
publicListener.on('message', msg => {
if (msg.event === 'update') {
this.emit({
sender: msg.data.account.acct,
str: this._cleanString(msg.data.content),
channel: 'public',
realtime: true,
}, msg);
vorpal.log('Mentions: ', msg.data.mentions);
vorpal.log('Media: ', msg.data.media_attachments);
vorpal.log('Tags: ', msg.data.tags);
vorpal.log('Spoiler: ', msg.data.spoiler_text);
} else {
vorpal.log(chalk.green(msg));
}
});
/* A update msg looks like:
{ event: 'update',
data:
{ id: 2133504,
created_at: '2017-04-10T08:36:36.000Z',
in_reply_to_id: null,
in_reply_to_account_id: null,
sensitive: false,
spoiler_text: '',
visibility: 'public',
application: null,
account:
{ id: 52132,
username: 'Milady_Oscar',
acct: 'Milady_Oscar@oc.todon.fr',
display_name: 'Lady Oscar ',
locked: false,
created_at: '2017-04-05T15:18:04.424Z',
note: 'Un peu de vous et beaucoup de n\'importe moi, des trucs de filles, des blagues de mecs, et des fraises tagada.\nSur Twitter avec le même @ ',
url: 'https://oc.todon.fr/@Milady_Oscar',
avatar: 'https://files.mastodon.social/accounts/avatars/000/052/132/original/5d55de1a7e19b927.PNG?1491405483',
header: 'https://files.mastodon.social/accounts/headers/000/052/132/original/6e2afd6a5009629b.PNG?1491405483',
followers_count: 22,
following_count: 15,
statuses_count: 686
},
media_attachments: [],
mentions: [],
tags: [],
uri: 'tag:oc.todon.fr,2017-04-10:objectId=160722:objectType=Status',
content: '<p>Je sens bien le barbecue aujourd\'hui. Mais j\'ai pas acheté de charbon de bois. J\'ai envie de prendre Marine Le Pen à la place.</p>',
url: 'https://oc.todon.fr/users/Milady_Oscar/updates/11367',
reblogs_count: 0,
favourites_count: 0,
reblog: null
}
}
*/
publicListener.on('error', err => {
vorpal.log(chalk.red.bold(err));
});
});
return super.constructor(callback, opts);
}
listen(channel) {
/*
let delay = Number(channel) * 1000;
......@@ -47,6 +158,7 @@ class MastodonAccount extends Account {
return this;*/
}
unlisten(channel) {
// channel = Number(channel);
// if (channel <= 0) return;
......@@ -64,6 +176,13 @@ class MastodonAccount extends Account {
// The clock runs updates real-time, so
// return Date.now();
}
_cleanString(str) {
return striptags( he.decode( str.replace('</p><p>', ' // ') ) );
}
}
......
......@@ -13,6 +13,14 @@ import Account from '../abstracts/account';
class TemplateAccount extends Account {
// Constructor receives:
// - A callback function for emitting updates
// - The Vorpal instance, to enable printing out system messages
// - A dictionary of options, as initialized by the signUp() static method,
// possibly tweaked by the user running "config set ...".
constructor(callback, vorpal, opts) {
// ...
}
// ...
}
......
......@@ -32,7 +32,7 @@ const conf = new Configstore('soclial', {
vorpal.log(chalk.purple('>>> User configuration file read.'));
function handle(platform, data, metadata) {
function handle(account, data, metadata) {
let { str, channel, realtime, timestamp } = data;
......@@ -48,7 +48,8 @@ function handle(platform, data, metadata) {
.replace(/\..+/, ''); // delete the dot and everything after
// What's the badge for this platform/account??
let badge = platform.opts.badge;
let badge = account._opts.badge;
let sender = data.sender;
const timestampColour = conf.get('global.colours.timestamp');
const badgeColour = conf.get('global.colours.badge');
......@@ -57,6 +58,7 @@ function handle(platform, data, metadata) {
vorpal.log(
'[' + chalk.foreground(timestampColour)(timestampString) + '] ' +
chalk.foreground(badgeColour)(badge + '/' + channel) +
(sender ? (' <' + chalk.bold(sender) + '>') : '') +
': ' + chalk.foreground(updateColour)(str)
);
}
......@@ -87,13 +89,13 @@ vorpal.log(chalk.purple('>>> Initializing social accounts...'));
let activeAccounts = {};
function activateAccount(accId) {
console.log(accId, conf.all.accounts[accId]);
// console.log(accId, conf.all.accounts[accId]);
let accConf = conf.all.accounts[accId];
let pl = accConf.platform;
let badge = accConf.badge;
vorpal.log(
chalk.purple('>>> Activating account ') +
chalk.cyan(accId) +
......@@ -109,7 +111,7 @@ function activateAccount(accId) {
throw new Error('Unknown platform in a configured account. Please edit your configuration manually to remove the offending account.');
}
activeAccounts[accId] = new platforms[pl].Account(handle, accConf);
activeAccounts[accId] = new platforms[pl].Account(handle, vorpal, accConf);
for (let ch in accConf.channels) {
vorpal.log(
......@@ -200,7 +202,7 @@ vorpal
let accConf = conf.all.accounts[accId];
let pl = accConf.platform;
let badge = accConf.badge;
vorpal.log(
chalk.cyan(accId) +
chalk.purple(', represented by badge ') +
......@@ -246,12 +248,12 @@ vorpal
message: 'You are adding a new account to soCLIal. From which social platform?',
choices: Object.keys(platforms)
}]).then(answer=>{
// vorpal.ui.redraw();
this.log('Asking the platform code to perform the sign-up procedure');
return platforms[answer.platform].signUp().then((opts)=>{
this.log('Platform code says we can create a new account with data: ', opts);
// vorpal.ui.cancel();
......@@ -266,31 +268,31 @@ vorpal
opts.badge = answer2.badge;
opts.platform = answer.platform;
// Find the lowest unused account ID
let accId = 1;
while( accId in conf.all.accounts ) {
accId++;
}
// this.log( chalk.red.bold('>>> NOT IMPLEMENTED YET.'));
this.log( 'Should store config for a new account: ', opts);
// ui.redraw.done()
let flat = flatten(opts);
this.log(conf.all.accounts);
this.log('flat account config: ', flat);
for (let i in flat) {
conf.set('accounts.' + accId + '.' + i , flat[i]);
conf.set('accounts.' + accId + '.' + i , flat[i]);
this.log('accounts.' + accId + '.' + i + ' = ' + flat[i]);
}
this.log( 'New account added to config. Enabling now.');
activateAccount(accId);
callback();
// }).catch((err)=>{
......@@ -299,7 +301,7 @@ vorpal
// callback();
});
// }).catch((err)=>{
//
//
// this.log( chalk.red.bold('>>> Creation of new account cancelled (no data from sign-up procedure).', err));
// // ui.redraw.done()
// callback();
......
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment