Giter Site home page Giter Site logo

rss-bridge / rss-bridge Goto Github PK

View Code? Open in Web Editor NEW
6.9K 6.9K 1.0K 13.98 MB

The RSS feed for websites missing it

Home Page: https://rss-bridge.org/bridge01/

License: The Unlicense

PHP 99.18% CSS 0.26% JavaScript 0.35% Dockerfile 0.10% Shell 0.06% HCL 0.01% Hack 0.04%
atom-feed hacktoberfest json-feed php rss rss-bridge rss-feed unlicense

rss-bridge's Introduction

RSS-Bridge

RSS-Bridge

RSS-Bridge is a PHP web application.

It generates web feeds for websites that don't have one.

Officially hosted instance: https://rss-bridge.org/bridge01/

IRC channel #rssbridge at https://libera.chat/

Full documentation

Alternatively find another public instance.

Requires minimum PHP 7.4.

LICENSE GitHub release irc.libera.chat Actions Status

Screenshot #1 Screenshot #2
Screenshot #3 Screenshot #4
Screenshot #5 Screenshot #6

A subset of bridges (16/447)

Tutorial

How to install on traditional shared web hosting

RSS-Bridge can basically be unzipped in a web folder. Should be working instantly.

Latest zip as of Sep 2023: https://github.com/RSS-Bridge/rss-bridge/archive/refs/tags/2023-09-24.zip

How to install on Debian 12 (nginx + php-fpm)

These instructions have been tested on a fresh Debian 12 VM from Digital Ocean (1vcpu-512mb-10gb, 5 USD/month).

timedatectl set-timezone Europe/Oslo

apt install git nginx php8.2-fpm php-mbstring php-simplexml php-curl php-intl

# Create a new user account
useradd --shell /bin/bash --create-home rss-bridge

cd /var/www

# Create folder and change ownership
mkdir rss-bridge && chown rss-bridge:rss-bridge rss-bridge/

# Become user
su rss-bridge

# Fetch latest master
git clone https://github.com/RSS-Bridge/rss-bridge.git rss-bridge/
cd rss-bridge

# Copy over the default config
cp -v config.default.ini.php config.ini.php

# Give full permissions only to owner (rss-bridge)
chmod 700 -R ./

# Give read and execute to others (nginx and php-fpm)
chmod o+rx ./ ./static

# Give read to others (nginx)
chmod o+r -R ./static

Nginx config:

# /etc/nginx/sites-enabled/rss-bridge.conf

server {
    listen 80;
    server_name example.com;
    access_log /var/log/nginx/rss-bridge.access.log;
    error_log /var/log/nginx/rss-bridge.error.log;
    log_not_found off;

    # Intentionally not setting a root folder here

    # autoindex is off by default but feels good to explicitly turn off
    autoindex off;

    # Static content only served here
    location /static/ {
        alias /var/www/rss-bridge/static/;
    }

    # Pass off to php-fpm when location is exactly /
    location = / {
        root /var/www/rss-bridge/;
        include snippets/fastcgi-php.conf;
        fastcgi_read_timeout 45s;
        fastcgi_pass unix:/run/php/rss-bridge.sock;
    }

    # Reduce spam
    location = /favicon.ico {
        access_log off;
    }

    # Reduce spam
    location = /robots.txt {
        access_log off;
    }
}

PHP FPM pool config:

; /etc/php/8.2/fpm/pool.d/rss-bridge.conf

[rss-bridge]

user = rss-bridge
group = rss-bridge

listen = /run/php/rss-bridge.sock

listen.owner = www-data
listen.group = www-data

pm = static
pm.max_children = 10
pm.max_requests = 500

PHP ini config:

; /etc/php/8.2/fpm/conf.d/30-rss-bridge.ini

max_execution_time = 15
memory_limit = 64M

Restart fpm and nginx:

# Lint and restart php-fpm
php-fpm8.2 -t && systemctl restart php8.2-fpm

# Lint and restart nginx
nginx -t && systemctl restart nginx

How to install from Composer

Install the latest release.

cd /var/www
composer create-project -v --no-dev rss-bridge/rss-bridge

How to install with Caddy

TODO. See #3785

Install from Docker Hub:

Install by downloading the docker image from Docker Hub:

# Create container
docker create --name=rss-bridge --publish 3000:80 rssbridge/rss-bridge

# Start container
docker start rss-bridge

Browse http://localhost:3000/

Install by locally building from Dockerfile

# Build image from Dockerfile
docker build -t rss-bridge .

# Create container
docker create --name rss-bridge --publish 3000:80 rss-bridge

# Start container
docker start rss-bridge

Browse http://localhost:3000/

Install with docker-compose

Create a docker-compose.yml file locally with with the following content:

version: '2'
services:
  rss-bridge:
    image: rssbridge/rss-bridge:latest
    volumes:
      - </local/custom/path>:/config
    ports:
      - 3000:80
    restart: unless-stopped

Then launch with docker-compose:

docker-compose up

Browse http://localhost:3000/

Other installation methods

Deploy on Scalingo Deploy to Heroku Deploy to Cloudron Run on PikaPods

The Heroku quick deploy currently does not work. It might work if you fork this repo and modify the repository in scalingo.json. See #2688

Learn more in Installation.

How-to

How to fix "Access denied."

Output is from php-fpm. It is unable to read index.php.

chown rss-bridge:rss-bridge /var/www/rss-bridge/index.php

How to password-protect the instance (token)

Modify config.ini.php:

[authentication]

token = "hunter2"

How to remove all cache items

As current user:

bin/cache-clear

As user rss-bridge:

sudo -u rss-bridge bin/cache-clear

As root:

sudo bin/cache-clear

How to remove all expired cache items

bin/cache-prune

How to fix "PHP Fatal error: Uncaught Exception: The FileCache path is not writable"

# Give rss-bridge ownership
chown rss-bridge:rss-bridge -R /var/www/rss-bridge/cache

# Or, give www-data ownership
chown www-data:www-data -R /var/www/rss-bridge/cache

# Or, give everyone write permission
chmod 777 -R /var/www/rss-bridge/cache

# Or last ditch effort (CAREFUL)
rm -rf /var/www/rss-bridge/cache/ && mkdir /var/www/rss-bridge/cache/

How to fix "attempt to write a readonly database"

The sqlite files (db, wal and shm) are not writeable.

chown -v rss-bridge:rss-bridge cache/*

How to fix "Unable to prepare statement: 1, no such table: storage"

rm cache/*

How to create a new bridge from scratch

Create the new bridge in e.g. bridges/BearBlogBridge.php:

<?php

class BearBlogBridge extends BridgeAbstract
{
    const NAME = 'BearBlog (bearblog.dev)';

    public function collectData()
    {
        $dom = getSimpleHTMLDOM('https://herman.bearblog.dev/blog/');
        foreach ($dom->find('.blog-posts li') as $li) {
            $a = $li->find('a', 0);
            $this->items[] = [
                'title' => $a->plaintext,
                'uri' => 'https://herman.bearblog.dev' . $a->href,
            ];
        }
    }
}

Learn more in bridge api.

How to enable all bridges

enabled_bridges[] = *

How to enable some bridges

enabled_bridges[] = TwitchBridge
enabled_bridges[] = GettrBridge

How to enable debug mode

The debug mode disables the majority of caching operations.

enable_debug_mode = true

How to switch to memcached as cache backend

[cache]

; Cache backend: file (default), sqlite, memcached, null
type = "memcached"

How to switch to sqlite3 as cache backend

type = "sqlite"

How to disable bridge errors (as feed items)

When a bridge fails, RSS-Bridge will produce a feed with a single item describing the error.

This way, feed readers pick it up and you are notified.

If you don't want this behaviour, switch the error output to http:

[error]

; Defines how error messages are returned by RSS-Bridge
;
; "feed" = As part of the feed (default)
; "http" = As HTTP error message
; "none" = No errors are reported
output = "http"

How to accumulate errors before finally reporting it

Modify report_limit so that an error must occur 3 times before it is reported.

; Defines how often an error must occur before it is reported to the user
report_limit = 3

The report count is reset to 0 each day.

How to password-protect the instance (HTTP Basic Auth)

[authentication]

enable = true
username = "alice"
password = "cat"

Will typically require feed readers to be configured with the credentials.

It may also be possible to manually include the credentials in the URL:

https://alice:[email protected]/bridge01/?action=display&bridge=FabriceBellardBridge&format=Html

How to create a new output format

See formats/PlaintextFormat.php for an example.

How to run unit tests and linter

These commands require that you have installed the dev dependencies in composer.json.

./vendor/bin/phpunit
./vendor/bin/phpcs --standard=phpcs.xml --warning-severity=0 --extensions=php -p ./

https://github.com/squizlabs/PHP_CodeSniffer/wiki

How to spawn a minimal development environment

php -S 127.0.0.1:9001

http://127.0.0.1:9001/

Explanation

We are RSS-Bridge community, a group of developers continuing the project initiated by sebsauvage, webmaster of sebsauvage.net, author of Shaarli and ZeroBin.

See CONTRIBUTORS.md

RSS-Bridge uses caching to prevent services from banning your server for repeatedly updating feeds. The specific cache duration can be different between bridges. Cached files are deleted automatically after 24 hours.

RSS-Bridge allows you to take full control over which bridges are displayed to the user. That way you can host your own RSS-Bridge service with your favorite collection of bridges!

Current maintainers (as of 2024): @dvikan and @Mynacol #2519

Reference

Feed item structure

This is the feed item structure that bridges are expected to produce.

    $item = [
        'uri' => 'https://example.com/blog/hello',
        'title' => 'Hello world',
        // Publication date in unix timestamp
        'timestamp' => 1668706254,
        'author' => 'Alice',
        'content' => 'Here be item content',
        'enclosures' => [
            'https://example.com/foo.png',
            'https://example.com/bar.png'
        ],
        'categories' => [
            'news',
            'tech',
        ],
        // Globally unique id
        'uid' => 'e7147580c8747aad',
    ]

Output formats

  • Atom: Atom feed, for use in feed readers
  • Html: Simple HTML page
  • Json: JSON, for consumption by other applications
  • Mrss: MRSS feed, for use in feed readers
  • Plaintext: Raw text, for consumption by other applications
  • Sfeed: Text, TAB separated

Cache backends

  • File
  • SQLite
  • Memcached
  • Array
  • Null

Licenses

The source code for RSS-Bridge is Public Domain.

RSS-Bridge uses third party libraries with their own license:

Rant

Dear so-called "social" websites.

Your catchword is "share", but you don't want us to share. You want to keep us within your walled gardens. That's why you've been removing RSS links from webpages, hiding them deep on your website, or removed feeds entirely, replacing it with crippled or demented proprietary API. FUCK YOU.

You're not social when you hamper sharing by removing feeds. You're happy to have customers creating content for your ecosystem, but you don't want this content out - a content you do not even own. Google Takeout is just a gimmick. We want our data to flow, we want RSS or Atom feeds.

We want to share with friends, using open protocols: RSS, Atom, XMPP, whatever. Because no one wants to have your service with your applications using your API force-feeding them. Friends must be free to choose whatever software and service they want.

We are rebuilding bridges you have willfully destroyed.

Get your shit together: Put RSS/Atom back in.

rss-bridge's People

Contributors

bockiii avatar captn3m0 avatar corenting avatar csisoap avatar dvikan avatar em92 avatar frenzie avatar fulmeek avatar jtojnar avatar logmanoriginal avatar mdemoss avatar mitsukarenai avatar mruac avatar mynacol avatar orelio avatar phantop avatar quickwick avatar rmscoelho avatar roliga avatar sebsauvage avatar somini avatar sqrtminusone avatar sysadminstory avatar teromene avatar thescrabi avatar tone866 avatar triatic avatar user123698745 avatar verifiedjoseph avatar yamanq avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

rss-bridge's Issues

twitter image

Hello !
Si une image est présente dans le bridge twitter, est-ce possible de l'afficher directement ? Par exemple avec WebHistoryPics ?
Je pensais avec une regex pour détecter, mais mes connaissances ne sont pas assez poussé.

How to activate TLS lib in PHP config?

Hi guys,

I suppose to use Youtube bridge, I need to active TLS lib on PHP but I was not able to find the way to do it. Any tuto/info to share?

Thank you!!

Aide syntaxe Bridge

Hello ! Je cherche à faire un bridge, mais j'ai du mal avec la syntaxe du DOM. En gros, je veux récupérer les articles depuis div class="post-content" sur ce site http://www.captaineconomics.fr. Voici mon code :

function CaptaineconomicsExtractContent($url) {
$html2 = file_get_html($url);
$text = $html2->find('div.post-content', 0)->innertext;
return $html2;
}
Or PHP dit que ça bug au niveau de la fonction find(). Des idées ?

Could not request Youtube.

Le bridge Youtube ne fonctionne plus, et indique "Could not request Youtube".
Testé sur mon instance ainsi que celle de Mitsu.

Liste déroulante

Pour les flux (type journaux avec différents éditions régionales), proposer une liste déroulante pour choisir quels flux choisir.

Ship Simple HTML DOM Parser ?

During install, adding Simple HTML DOM Parser can be confusing: creating some folders, retrieving the file from ugly ad-spammed SF, renaming, and moving.

It seems to me that shipping the required script is better: it allows to clone the repo or download-extract the archive, putting it in the web folder, and tadaa, works out of the box in most cases ! Simple HTML DOM Parser is under MIT license.

Extract favicon

It would be neat to store the feed favicon with the feed data. It would make a better integration with tools such FreshRss.

suggestion : Configuration of bridge

Hello,
I think it could be very intresting to have a configuration for bridges but also for general purpose.

Example : I try to get google plus psots of someone, but if I came from an engluish country, I will have the most of the builded content from Google in english. If I run the same script in France, it will be in french. So globally or specifically to this bridge it could be intresting to have a HTTP context give automatically by the configuration to file_get_content. In this context we will set the accept-language

// to pass to file_get_content $context var
stream_context_create(array('http'=> array(
    'header'    => 'Accept-Language: fr,fr-be,fr-fr;q=0.8,fr;q=0.6,en;q=0.4,en-us;q=0.2' . "\r\n"
)))
//or simplier :
stream_context_create(array('http'=> array(
    'header'    => 'Accept-Language: fr-be' . "\r\n"
)))

TwitterBridge: hashtags not shown [RFC]

Hashtags are no longer shown, HTML issue. Possible corrections:

  • plaintext (no link): $tweet->find('p.tweet-text', 0)->plaintext
  • link params cleaning:
    <a href="https://twitter.com/search?q=%23OuiTwitterMeFaitChier&amp;src=hash" data-query-source="hashtag_click" class="twitter-hashtag pretty-link js-nav" dir="ltr" >#OuiTwitterMeFaitChier</a>
    Becomes:
    <a href="https://twitter.com/search?q=%23OuiTwitterMeFaitChier&amp;src=hash" dir="ltr" >#OuiTwitterMeFaitChier</a>

TwitterBridge.php line 37. "plaintext" is easier and deprecates strip_tags, but links wouldn't be clickable. I would prefer going the hard way and stripping out the shit Twitter adds to links (and use "data-expanded-url" for direct links, no need to flow this through Twitter t.co who can censor it)

Suggestions diverses

Quelques suggestions en vrac :

  • faire une blacklist pour afficher tout les flux sauf quelques uns
  • faire un bridge pour rue89
  • mettre à jour directement sur le serveur (téléchargement et extraction en php)
  • permettre la fusion de plusieurs flux
  • faire une doc pour faire ses propres bridges
  • certains flux font une erreur (forbidden) quand on se connecte (ex ledauphine.com), trouver un moyen de contourner ça.
    Voilà :)

Requested username can't be found. Timeout.

Salut,

Après génération du flux ATOM du compte Twitter MailpileTeam, au bout de 2/3 secondes, si je reloade le flux, je reçois une page blanche avec le message suivant :

Requested username can't be found. 

Ce qui n'arrive pas sur http://rssbridge.org/ où là, il y a persistance des flux.

J'utilise Nginx.

Je ne peux donc pas - pour l'instant - ajouter mes "flux spéciaux" parsés à OwnCloud News.

Que faire ?

Merci d'avance,

raymond.cc

Bonjour,

J'ai créé un bridge :

', '', $string); return $string; } function raymondExtractContent($url) { $html2 = file_get_html($url); $text = $html2->find('div.entry-content', 0)->innertext; $text = str_replace('', '', $text); $text = str_replace('', '', $text); return $text; } $html = file_get_html('http://www.raymond.cc/blog/feed') or $this->returnError('Could not request raymond.', 404); $limit = 0; foreach($html->find('item') as $element) { if($limit < 10) { $item = new \Item(); $item->title = raymondStripCDATA($element->find('title', 0)->innertext); $item->uri = raymondStripCDATA($element->find('guid', 0)->plaintext); $item->timestamp = strtotime($element->find('pubDate', 0)->plaintext); $item->content = raymondExtractContent($item->uri); $this->items[] = $item; $limit++; } } } public function getName(){ return 'raymond'; } public function getURI(){ return 'http://www.raymond.cc/blog'; } public function getCacheDuration(){ return 3600; // 1 hour } } Tout marche mais j'ai des scripts qui apparaissent : <‌script async src="http://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js"> Je ne reussi pas à les supprimer. J'ai essayer de rajouter dans la fonction raymondExtractContent -> ``` $text = str_replace('', '', $text); $text = str_replace('script*.script', '', $text); $text = str_replace('‌', '', $text); $text = str_replace('<', '<', $text); ``` Sans succès. Qq peut il m'aider ? Merci Pierre

Créer une classe de base facilitant la création de bridges cachant des pages HTML

J'en ai parlé avec Mitsu à propos des bridges que j'ai écrit (Sexactu, les 400 culs, lifehacker, WoT, ...). Le top, ce serait d'utiliser (en plus du parser HTML) un parser RSS pour lire directement le flux RSS tronqué puis, pour chaque page, charger la page, récupérer le contenu intéressant, et le claquer dans notre nouveau flux.
C'est un peu ce que j'ai fait avec mon HttpCachingBridgeAbstract (là : https://github.com/Riduidel/rss-bridge/blob/fd71ceae821a1e6b597a252e16c86bb682e72570/lib/Bridge.php#L95) mais c'est loin d'être parfaity. J'aimerais donc bien disposer d'un coup de main pour améliorer le truc ...

[new bridge] Soundcloud user feed

Hi, this is a suggestion to add a new bridge that would fetch latest tracks from a Soundcloud user. Example at https://soundcloud.com/thatrickaz

https://github.com/scarpentier/SoundCloudPodcast is able to generate feeds from soundcloud users (eg http://sc2podcast.azurewebsites.net/podcast?user=thatrickaz&keyword=&title=), attaching the audio stream to the ffed entry if possible. It's JS/C# though so maybe not easily mergeable in rss-bridge, but this is a good starting point.

Google Search : "ERROR: no results for this query."

Bonjour Seb,

Merci pour ce Bridge salvateur, nickel pour Twitter et Flickr, cependant pour Google Search j'ai ce message "ERROR: no results for this query." quelque soit la requête faite, Avez-vous une idée ?

cache path

In FileCache.php:

replace

$cacheDir = DIR . '/../cache/';

by

$cacheDir = DIR . '/../caches/';

Or cache can't work ;)

Add support for optional Atom icon field

Currently all rss-bridged feeds have the same icon. Wouldn't it better to provide source feed icon through the correct ATOM feed optional field ? Documentation states it exists :

icon
Identifies a small image which provides iconic visual identification for the feed. Icons should be square.
<icon>/icon.jpg</icon>

Add bridges for torrent search engines

On the web, there are a few islands that powerful people want to see sinking, or at least hidden in the fog. Our job is to connect these islands to our lands, using bridges.

Torrent search engines sometimes aren't very RSS-friendly. Well of course, they pay their bills with the ads on the website, and that doesn't work well with RSS. AFAIK, very few offer keyword-based feeds. That's what we will do.

  • The Pirate Bay
  • Burnbit

Le monde diplo

Le monde diplo utilise SPIP. En s'inspirant du code de Basta, on pourra en faire un bridge.

Youtube bridge still relying on old API

Hello everybody,
It seems that the youtube bridge is still relying on the old API to get the publication date of the video.
Because of that, all videos seem to have been published at the same time.

Message pas explicite lorsque simplehtmldom est manquant

Le message est "PHP Simple HTML DOM Parser" is missing. Get it from http://simplehtmldom.sourceforge.net and place the script "simple_html_dom.php" in the same folder to allow me to work."

Je pense qu'il vaudrait mieux mettre :
"PHP Simple HTML DOM Parser" is missing. Get it from http://simplehtmldom.sourceforge.net and place the folder "simple_html_dom" in the vendor folder to allow me to work. If vendor forlder is not available, please add it at the root."

question : Api blocked

Hello,
what to do when there is a lock limitatuion like for facebook and we need to go through an API with some key ?

If we have somethink like a configuration #76 it could be a start, but right after did we use the official "sdk" or whatever the name or if possible using the pure HTTP?

Any suggestions or clue to know where to go for future devs?

ATOM feed doesn't work properly

With the new version, there are issues with ATOM feeds. It's quite an issue because it's the main purpose of rss-bridge...

Let's take an example (cache have been disable for tests purpose):
https://workspace.hoa.ro/rss-bridge-01/?action=display&bridge=TwitterBridge&u=aryo&format=AtomFormat

  • Opera:

opera

  • Chrome:

chrome

  • Firefox (it's working!):

firefox-working

But even then, with another account (_@aryo), it doesn't work anymore:
firefox-ko

It is related to ATOM format because other formats like HTML works perfectly.

Create FreeNews bridge

It should support both main page news and sections ones (hopefully it is already written and only needs a git push)

versioning ?

Hi Seb!

hum, vais la faire en français ;)
tu peut intégrer un système de version histoire que ce soit plus facile à suivre ?
Même par date ça serais pas mal ;)

/* Flickr Explorer RSS bridge.
(...)
Version: 0.1 ou 2013/08/07
*/

Merci

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.