All Projects → j0k3r → banditore

j0k3r / banditore

Licence: MIT license
Banditore retrieves new releases from your starred GitHub repositories and generate an Atom feed with them.

Programming Languages

PHP
23972 projects - #3 most used programming language
Twig
543 projects
CSS
56736 projects

Projects that are alternatives of or similar to banditore

f43.me
A more readable & cleaner feed
Stars: ✭ 60 (-49.15%)
Mutual labels:  rss, symfony-application
docker-symfony
Docker Symfony (PHP-FPM - NGINX - MySQL - MailHog - Redis - RabbitMQ)
Stars: ✭ 32 (-72.88%)
Mutual labels:  rabbitmq, symfony-application
rabbitmq-web-stomp-examples
www.rabbitmq.com/
Stars: ✭ 90 (-23.73%)
Mutual labels:  rabbitmq
rss
RSS订阅插件 for Hoshinobot
Stars: ✭ 28 (-76.27%)
Mutual labels:  rss
rabbitmq-auth-backend-oauth2-spike
See rabbitmq/rabbitmq-auth-backend-oauth2 instead.
Stars: ✭ 17 (-85.59%)
Mutual labels:  rabbitmq
exec
🐚 semantic-release plugin to execute custom shell commands
Stars: ✭ 94 (-20.34%)
Mutual labels:  release
pd-tech-fest-2019
Demo code for PD Tech Fest 2019 showcasing event driven autoscaling using KEDA
Stars: ✭ 21 (-82.2%)
Mutual labels:  rabbitmq
voter-service
The Voter Spring Boot RESTful Web Service, backed by MongoDB, and uses RabbitMQ for IPC
Stars: ✭ 53 (-55.08%)
Mutual labels:  rabbitmq
rabbitmq-auth-backend-cache
Authorisation result caching plugin (backend) for RabbitMQ
Stars: ✭ 17 (-85.59%)
Mutual labels:  rabbitmq
rss-finder
Find rss feeds url
Stars: ✭ 62 (-47.46%)
Mutual labels:  rss
amqp-client
OCaml Amqp client library for Async and Lwt.
Stars: ✭ 58 (-50.85%)
Mutual labels:  rabbitmq
awesome-rss-feeds
Awesome RSS feeds - A curated list of RSS feeds (and OPML files) used in Recommended Feeds and local news sections of Plenary - an RSS reader, article downloader and a podcast player app for android
Stars: ✭ 114 (-3.39%)
Mutual labels:  rss
json-feed-viewer
The world's first JSON feed viewer 🥇
Stars: ✭ 40 (-66.1%)
Mutual labels:  rss
rabbitmq-stomp
RabbitMQ STOMP plugin
Stars: ✭ 49 (-58.47%)
Mutual labels:  rabbitmq
FeedReader
C# RSS and ATOM Feed reader library. Supports RSS 0.91, 0.92, 1.0, 2.0 and ATOM. Tested with multiple languages and feeds.
Stars: ✭ 221 (+87.29%)
Mutual labels:  rss
Pentest-Bookmarkz
A collection of useful links for Pentesters
Stars: ✭ 118 (+0%)
Mutual labels:  rss
filestore-server
基于golang实现的一种分布式云存储服务
Stars: ✭ 61 (-48.31%)
Mutual labels:  rabbitmq
Tweet-2-RSS
Convert your Twitter API requests to RSS Feeds
Stars: ✭ 14 (-88.14%)
Mutual labels:  rss
rabbit
Build Elixir applications with RabbitMQ
Stars: ✭ 36 (-69.49%)
Mutual labels:  rabbitmq
instagrammer
Get personal RSS feed access to your Instagrams
Stars: ✭ 15 (-87.29%)
Mutual labels:  rss

Banditore

CI Coveralls Status PHPStan level max

Banditore retrieves new releases from your GitHub starred repositories and put them in a RSS feed, just for you.

Requirements

  • PHP >= 7.4 (with pdo_mysql)
  • MySQL >= 5.7
  • Redis (to cache requests to the GitHub API)
  • RabbitMQ, which is optional (see below)
  • Supervisor (only if you use RabbitMQ)
  • NVM & Yarn to install assets

Installation

  1. Clone the project

    git clone https://github.com/j0k3r/banditore.git
  2. Register a new OAuth GitHub application and get the Client ID & Client Secret for the next step (for the Authorization callback URL put http://127.0.0.1:8000/callback)

  3. Install dependencies using Composer and define your parameter during the installation

    SYMFONY_ENV=prod composer install -o --no-dev

    If you want to use:

    • Sentry to retrieve all errors, register here and get your dsn (in Project Settings > DSN).
  4. Setup the database

    php bin/console doctrine:database:create -e prod
    php bin/console doctrine:schema:create -e prod
  5. Install assets

    nvm install
    yarn install
  6. You can now launch the website:

    php bin/console server:run -e prod

    And access it at this address: http://127.0.0.1:8000

Running the instance

Once the website is up, you now have to setup few things to retrieve new releases. You have two choices:

  • using crontab command (very simple and ok if you are alone)
  • using RabbitMQ (might be better if you plan to have more than few persons but it's more complex) 🤙

Without RabbitMQ

You just need to define these 2 cronjobs (replace all /path/to/banditore with real value):

# retrieve new release of each repo every 10 minutes
*/10  *   *   *   *   php /path/to/banditore/bin/console -e prod banditore:sync:versions >> /path/to/banditore/var/logs/command-sync-versions.log 2>&1
# sync starred repos of each user every 5 minutes
*/5   *   *   *   *   php /path/to/banditore/bin/console -e prod banditore:sync:starred-repos >> /path/banditore/to/var/logs/command-sync-repos.log 2>&1

With RabbitMQ

  1. You'll need to declare exchanges and queues. Replace guest by the user of your RabbitMQ instance (guest is the default one):
php bin/rabbit vhost:mapping:create -p guest app/config/rabbit_vhost.yml
  1. You now have two queues and two exchanges defined:
  • banditore.sync_starred_repos: will receive messages to sync starred repos of all users
  • banditore.sync_versions: will receive message to retrieve new release for repos
  1. Enable these 2 cronjobs which will periodically push messages in queues (replace all /path/to/banditore with real value):
# retrieve new release of each repo every 10 minutes
*/10  *   *   *   *   php /path/to/banditore/bin/console -e prod banditore:sync:versions --use_queue >> /path/to/banditore/var/logs/command-sync-versions.log 2>&1
# sync starred repos of each user every 5 minutes
*/5   *   *   *   *   php /path/to/banditore/bin/console -e prod banditore:sync:starred-repos --use_queue >> /path/banditore/to/var/logs/command-sync-repos.log 2>&1
  1. Setup Supervisor using the sample file from the repo. You can copy/paste it into /etc/supervisor/conf.d/ and adjust path. The default file will launch:
  • 2 workers for sync starred repos
  • 4 workers to fetch new releases

Once you've put the file in the supervisor conf repo, run supervisorctl update && supervisorctl start all (update will read your conf, start all will start all workers)

Monitoring

There is a status page available at /status, it returns a json with some information about the freshness of fetched versions:

{
    "latest": {
        "date": "2019-09-17 19:50:50.000000",
        "timezone_type": 3,
        "timezone": "Europe\/Berlin"
    },
    "diff": 1736,
    "is_fresh": true
}
  • latest: the latest created version as a DateTime
  • diff: the difference between now and the latest created version (in seconds)
  • is_fresh: indicate if everything is fine by comparing the diff above with the status_minute_interval_before_alert parameter

For example, I've setup a check on updown.io to check that status page and if the page contains "is_fresh":true. So I receive an alert when is_fresh is false: which means there is a potential issue on the server.

Running the test suite

If you plan to contribute (you're awesome, I know that ✌️), you'll need to install the project in a different way (for example, to retrieve dev packages):

git clone https://github.com/j0k3r/banditore.git
composer install -o
php bin/console doctrine:database:create -e=test
php bin/console doctrine:schema:create -e=test
php bin/console doctrine:fixtures:load --env=test -n
php bin/simple-phpunit -v

By default the test connexion login is root without password. You can change it in app/config/config_test.yml.

How it works

Ok, if you goes that deeper in the readme, it means you're a bit more than interested, I like that.

Retrieving new release / tag

This is the complex part of the app. Here is a simplified solution to achieve it.

New release

It's not as easy as using the /repos/:owner/:repo/releases API endpoint to retrieve latest release for a given repo. Because not all repo owner use that feature (which is a shame in my case).

All information for a release are available on that endpoint:

  • name of the tag (ie: v1.0.0)
  • name of the release (ie: yay first release)
  • published date
  • description of the release

Check a new release of that repo as example: https://api.github.com/repos/j0k3r/banditore/releases/5770680

New tag

Some owners also use tag which is a bit more complex to retrieve all information because a tag only contains information about the SHA-1 of the commit which was used to make the tag. We only have these information:

  • name of the tag (ie: v1.4.2)
  • name of the release will be the name of the tag, in that case

Check tag list of swarrot/SwarrotBundle as example: https://api.github.com/repos/swarrot/SwarrotBundle/tags

After retrieving the tag, we need to retrieve the commit to get these information:

  • date of the commit
  • message of the commit

Check a commit from the previous tag list as example: https://api.github.com/repos/swarrot/SwarrotBundle/commits/84c7c57622e4666ae5706f33cd71842639b78755

GitHub Client Discovery

This is the most important piece of the app. One thing that I ran though is hitting the rate limit on GitHub. The rate limit for a given authenticated client is 5.000 calls per hour. This limit is never reached when looking for new release (thanks to the conditional requests of the GitHub API) on a daily basis.

But when new user sign in, we need to sync all its starred repositories and also all their releases / tags. And here come the gourmand part:

  • one call for the list of release
  • one call to retrieve information of each tag (if the repo doesn't have release)
  • one call for each release to convert markdown text to html

Let's say the repo:

  • has 50 tags: 1 (get tag list) + 50 (get commit information) + 50 (convert markdown) = 101 calls.
  • has 50 releases: 1 (get tag list) + 50 (get each release) + 50 (convert markdown) = 101 calls.

And keep in mind that some repos got also 1.000+ tags (!!).

To avoid hitting the limit in such case and wait 1 hour to be able to make requests again I created the GitHub Client Discovery class. It aims to find the best client with enough rate limit remain (defined as 50).

  • it first checks using the GitHub OAuth app
  • then it checks using all user GitHub token

Which means, if you have 5 users on the app, you'll be able to make (1 + 5) x 5.000 = 30.000 calls per hour

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].