Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Put sqlite database to directory for better docker works #63

Open
wants to merge 9 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 30 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
FROM node:10-alpine

RUN apk add --no-cache \
python2 \
make \
g++

RUN mkdir /app

COPY ./app /app

RUN cd /app && \
npm i

COPY ./init.sh /

RUN chmod +x /init.sh

COPY ./init-update.sh /

RUN chmod +x /init-update.sh

COPY ./feed-cron /etc/periodic/15min/

RUN chmod +x /etc/periodic/15min/feed-cron

WORKDIR /app

CMD ["/init.sh"]

94 changes: 9 additions & 85 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,90 +1,14 @@
# RSS to ActivityPub Converter
# rss-to-activitypub
An RSS to ActivityPub converter.

This is a server that lets users convert any RSS feed to an ActivityPub actor that can be followed by users on ActivityPub-compliant social networks like Mastodon.

This is based on my [Express ActivityPub Server](https://github.com/dariusk/express-activitypub), a simple Node/Express server that supports a subset of ActivityPub.

## Requirements

This requires Node.js v10.10.0 or above.

You also need `beanstalkd` running. This is a simple and fast queueing system we use to manage polling RSS feeds. [Here are installation instructions](https://beanstalkd.github.io/download.html). On a production server you'll want to [install it as a background process](https://github.com/beanstalkd/beanstalkd/tree/master/adm).

## Installation

Clone the repository, then `cd` into its root directory. Install dependencies:

`npm i`

Then copy `config.json.template` to `config.json`:

`cp config.json.template config.json`

Update your new `config.json` file:

```js
{
"DOMAIN": "mydomain.com",
"PORT_HTTP": "3000",
"PORT_HTTPS": "8443",
"PRIVKEY_PATH": "/path/to/your/ssl/privkey.pem",
"CERT_PATH": "/path/to/your/ssl/cert.pem"
}
To build:
just run:
```

* `DOMAIN`: your domain! this should be a discoverable domain of some kind like "example.com" or "rss.example.com"
* `PORT_HTTP`: the http port that Express runs on
* `PORT_HTTPS`: the https port that Express runs on
* `PRIVKEY_PATH`: point this to your private key you got from Certbot or similar
* `CERT_PATH`: point this to your cert you got from Certbot or similar

Run the server!

`node index.js`

Go to `https://whateveryourdomainis.com:3000/convert` or whatever port you selected for HTTP, and enter an RSS feed and a username. If all goes well it will create a new ActivityPub user with instructions on how to view the user.

## Sending out updates to followers

There is also a file called `queueFeeds.js` that needs to be run on a cron job or similar scheduler. I like to run mine once a minute. It queries every RSS feed in the database to see if there has been a change to the feed. If there is a new post, it sends out the new post to everyone subscribed to its corresponding ActivityPub Actor.

## Local testing

You can use a service like [ngrok](https://ngrok.com/) to test things out before you deploy on a real server. All you need to do is install ngrok and run `ngrok http 3000` (or whatever port you're using if you changed it). Then go to your `config.json` and update the `DOMAIN` field to whatever `abcdef.ngrok.io` domain that ngrok gives you and restart your server.

Then make sure to manually run `updateFeed.js` when the feed changes. I recommend having your own test RSS feed that you can update whenever you want.

## Database

This server uses a SQLite database stored in the file `bot-node.db` to keep track of all the data. To connect directly to the database for debugging, from the root directory of the project, run:

```bash
sqlite3 bot-node.db
docker build -t rss-to-activity-pub .
```
and then
docker-compose up

There are two tables in the database: `accounts` and `feeds`.

### `accounts`

This table keeps track of all the data needed for the accounts. Columns:

* `name` `TEXT PRIMARY KEY`: the account name, in the form `[email protected]`
* `privkey` `TEXT`: the RSA private key for the account
* `pubkey` `TEXT`: the RSA public key for the account
* `webfinger` `TEXT`: the entire contents of the webfinger JSON served for this account
* `actor` `TEXT`: the entire contents of the actor JSON served for this account
* `apikey` `TEXT`: the API key associated with this account
* `followers` `TEXT`: a JSON-formatted array of the URL for the Actor JSON of all followers, in the form `["https://remote.server/users/somePerson", "https://another.remote.server/ourUsers/anotherPerson"]`
* `messages` `TEXT`: not yet used but will eventually store all messages so we can render them on a "profile" page

### `feeds`

This table keeps track of all the data needed for the feeds. Columns:

* `feed` `TEXT PRIMARY KEY`: the URI of the RSS feed
* `username` `TEXT`: the username associated with the RSS feed
* `content` `TEXT`: the most recent copy fetched of the RSS feed's contents

## License

Copyright (c) 2018 Darius Kazemi. Licensed under the MIT license.
docker-compose.yml is example for version with Treafik reverse proxy
also edit app/views/home.pug couse is our rebranded version for rss.fediwersum.pl
File renamed without changes.
File renamed without changes.
90 changes: 90 additions & 0 deletions app/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
# RSS to ActivityPub Converter

This is a server that lets users convert any RSS feed to an ActivityPub actor that can be followed by users on ActivityPub-compliant social networks like Mastodon.

This is based on my [Express ActivityPub Server](https://github.com/dariusk/express-activitypub), a simple Node/Express server that supports a subset of ActivityPub.

## Requirements

This requires Node.js v10.10.0 or above.

You also need `beanstalkd` running. This is a simple and fast queueing system we use to manage polling RSS feeds. [Here are installation instructions](https://beanstalkd.github.io/download.html). On a production server you'll want to [install it as a background process](https://github.com/beanstalkd/beanstalkd/tree/master/adm).

## Installation

Clone the repository, then `cd` into its root directory. Install dependencies:

`npm i`

Then copy `config.json.template` to `config.json`:

`cp config.json.template config.json`

Update your new `config.json` file:

```js
{
"DOMAIN": "mydomain.com",
"PORT_HTTP": "3000",
"PORT_HTTPS": "8443",
"PRIVKEY_PATH": "/path/to/your/ssl/privkey.pem",
"CERT_PATH": "/path/to/your/ssl/cert.pem"
}
```

* `DOMAIN`: your domain! this should be a discoverable domain of some kind like "example.com" or "rss.example.com"
* `PORT_HTTP`: the http port that Express runs on
* `PORT_HTTPS`: the https port that Express runs on
* `PRIVKEY_PATH`: point this to your private key you got from Certbot or similar
* `CERT_PATH`: point this to your cert you got from Certbot or similar

Run the server!

`node index.js`

Go to `https://whateveryourdomainis.com:3000/convert` or whatever port you selected for HTTP, and enter an RSS feed and a username. If all goes well it will create a new ActivityPub user with instructions on how to view the user.

## Sending out updates to followers

There is also a file called `queueFeeds.js` that needs to be run on a cron job or similar scheduler. I like to run mine once a minute. It queries every RSS feed in the database to see if there has been a change to the feed. If there is a new post, it sends out the new post to everyone subscribed to its corresponding ActivityPub Actor.

## Local testing

You can use a service like [ngrok](https://ngrok.com/) to test things out before you deploy on a real server. All you need to do is install ngrok and run `ngrok http 3000` (or whatever port you're using if you changed it). Then go to your `config.json` and update the `DOMAIN` field to whatever `abcdef.ngrok.io` domain that ngrok gives you and restart your server.

Then make sure to manually run `updateFeed.js` when the feed changes. I recommend having your own test RSS feed that you can update whenever you want.

## Database

This server uses a SQLite database stored in the file `bot-node.db` to keep track of all the data. To connect directly to the database for debugging, from the root directory of the project, run:

```bash
sqlite3 bot-node.db
```

There are two tables in the database: `accounts` and `feeds`.

### `accounts`

This table keeps track of all the data needed for the accounts. Columns:

* `name` `TEXT PRIMARY KEY`: the account name, in the form `[email protected]`
* `privkey` `TEXT`: the RSA private key for the account
* `pubkey` `TEXT`: the RSA public key for the account
* `webfinger` `TEXT`: the entire contents of the webfinger JSON served for this account
* `actor` `TEXT`: the entire contents of the actor JSON served for this account
* `apikey` `TEXT`: the API key associated with this account
* `followers` `TEXT`: a JSON-formatted array of the URL for the Actor JSON of all followers, in the form `["https://remote.server/users/somePerson", "https://another.remote.server/ourUsers/anotherPerson"]`
* `messages` `TEXT`: not yet used but will eventually store all messages so we can render them on a "profile" page

### `feeds`

This table keeps track of all the data needed for the feeds. Columns:

* `feed` `TEXT PRIMARY KEY`: the URI of the RSS feed
* `username` `TEXT`: the username associated with the RSS feed
* `content` `TEXT`: the most recent copy fetched of the RSS feed's contents

## License

Copyright (c) 2018 Darius Kazemi. Licensed under the MIT license.
File renamed without changes.
1 change: 1 addition & 0 deletions app/data/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
!.gitignore
2 changes: 1 addition & 1 deletion index.js → app/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ const { DOMAIN, PRIVKEY_PATH, CERT_PATH, PORT_HTTP, PORT_HTTPS } = config;
const express = require('express');
const app = express();
const Database = require('better-sqlite3');
const db = new Database('bot-node.db');
const db = new Database('data/bot-node.db');
const fs = require('fs');
const routes = require('./routes'),
bodyParser = require('body-parser'),
Expand Down
File renamed without changes.
File renamed without changes.
5 changes: 3 additions & 2 deletions queueFeeds.js → app/queueFeeds.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
const Database = require('better-sqlite3');
const db = new Database('bot-node.db');
const db = new Database('data/bot-node.db');
const Jackd = require('jackd');
const beanstalkd = new Jackd();



async function foo() {

// get all feeds from DB
Expand All @@ -13,7 +14,7 @@ async function foo() {

let count = 0;

await beanstalkd.connect()
await beanstalkd.connect({host: 'beanstalkd', port: 11300 })

for (feed of feeds) {
await beanstalkd.put(feed.feed)
Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
4 changes: 2 additions & 2 deletions updateFeeds.js → app/updateFeeds.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
const config = require('./config.json');
const { DOMAIN, PRIVKEY_PATH, CERT_PATH, PORT_HTTP, PORT_HTTPS } = config;
const Database = require('better-sqlite3');
const db = new Database('bot-node.db'),
const db = new Database('data/bot-node.db'),
Parser = require('rss-parser'),
request = require('request'),
crypto = require('crypto'),
Expand All @@ -10,7 +10,7 @@ const db = new Database('bot-node.db'),
const Jackd = require('jackd');
const beanstalkd = new Jackd();

beanstalkd.connect()
beanstalkd.connect({host: 'beanstalkd',port: 11300})

async function foo() {
while (true) {
Expand Down
15 changes: 15 additions & 0 deletions app/views/home.pug
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
html
head
<meta name="viewport" content="width=device-width, initial-scale=1">
title RSS2Fediwersum
style
include style.css
body
h1 Kanały RSS do Fediwersum (rss2fedi)
f4 od zespołu <a href="https://lhub.pl">Lhub.pl</a>
p To jest serwis oferujący Boty ActivityPub konwertujące kanały RSS do strumienia powiadomień. Możesz je subskrybować z Mastodona lub innych aplikacji zgodnych z Fediwersum/ActivityPub.
p Lista botów <a href="https://lhub.pl/rss2fedi/">Rss2Fedi</a>
p Chcesz nam zgłosić kolejny feed RSS do dodania? <a href="mailto:[email protected]">Napisz</a> lub kliknij do @[email protected]
p Bazuje na projekcie RSS to ActivityPub Converter (<a href="https://github.com/dariusk/rss-to-activitypub/">Kod</a>) od <a href="https://friend.camp/@darius">Darius Kazemi</a>.


File renamed without changes.
File renamed without changes.
File renamed without changes.
62 changes: 62 additions & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
version: '3'
services:
app:
restart: unless-stopped
image: rss-to-activity-pub
environment:
- DOMAIN=rss.fediwersum.pl
labels:
traefik.enable: "true"
# traefik.http.routers.rss-to-activity-pub-conv.entrypoints: websecure
# traefik.http.routers.rss-to-activity-pub-conv.rule: (Host(`rss.fediwersum.pl`) && PathPrefix(`/convert`))
# traefik.http.routers.rss-to-activity-pub-conv.middlewares: rss-to-activity-pub-auth
# traefik.http.routers.rss-to-activity-pub-conv.tls.certresolver: le
# traefik.http.middlewares.rss-to-activity-pub-auth.basicauth.users: some:user
traefik.http.routers.rss-to-activity-pub.entrypoints: websecure
traefik.http.routers.rss-to-activity-pub.rule: Host(`rss.fediwersum.pl`)
traefik.http.routers.rss-to-activity-pub.tls.certresolver: le
traefik.http.services.rss-to-activity-pub.loadbalancer.server.port: 3000
networks:
- frontend
- beanstalk
volumes:
- data:/app/data

cron:
restart: unless-stopped
image: rss-to-activity-pub
environment:
- DOMAIN=rss.fediwersum.pl
command: /usr/sbin/crond -f -l 0
volumes:
- data:/app/data
networks:
- beanstalk

update-feeds:
restart: unless-stopped
image: rss-to-activity-pub
environment:
- DOMAIN=rss.fediwersum.pl
command: /init-update.sh
volumes:
- data:/app/data
networks:
- beanstalk

beanstalkd:
restart: unless-stopped
image: schickling/beanstalkd
networks:
- beanstalk


networks:
frontend:
external: true
beanstalk:
driver: overlay

volumes:
data:
driver: local
1 change: 1 addition & 0 deletions feed-cron
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
/bin/sh -c "cd /app && node queueFeeds.js" >/dev/null 2>&1
36 changes: 36 additions & 0 deletions init-update.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
#!/bin/sh

cd /app

cp config.json.template config.json

if [[ ! -z ${DOMAIN+x} ]]; then
sed -i "s/\"DOMAIN\": \"\"/\"DOMAIN\": \"${DOMAIN}\"/g" config.json
else
echo 'Env var $DOMAIN is not set. Set it before starting the container'
exit 1
fi

if [[ ! -z ${PORT_HTTP+x} ]]; then
sed -i "s/\"PORT_HTTP\": \"3000\"/\"PORT_HTTP\": \"${PORT_HTTP}\"/g" config.json
fi

if [[ ! -z ${PORT_HTTPS+x} ]]; then
sed -i "s/\"PORT_HTTPS\": \"8443\"/\"PORT_HTTPS\": \"${PORT_HTTPS}\"/g" config.json
fi

if [[ ! -z ${PRIVKEY_PATH+x} ]]; then
sed -i "s@\"PRIVKEY_PATH\": \"\"@\"PRIVKEY_PATH\": \"${PRIVKEY_PATH}\"@g" config.json
fi

if [[ ! -z ${CERT_PATH+x} ]]; then
sed -i "s@\"CERT_PATH\": \"\"@\"CERT_PATH\": \"${CERT_PATH}\"@g" config.json
fi

echo "Configuration file :"

cat config.json


node updateFeeds.js

Loading