-
229 |
├── .gitignore
├── README.md
├── app.js
└── index.html
/.gitignore:
--------------------------------------------------------------------------------
1 | *.swp
2 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | Memecached
2 | ==========
3 |
4 | Love **memes**?
5 |
6 | Want to generate memes and share them with everyone in **real-time**?
7 |
8 | Use **Memecached**.
9 |
10 | ## About
11 |
12 | Memecached is an **extremely** lightweight meme sharing service, written entirely in Javascript. The server itself, `app.js`, is exactly 50 lines of code.
13 | All meme images are stored in a public Dropbox directory. It differs from conventional meme generator apps in that there is **zero** server-side image handling code.
14 | Memes are shared in real-time using `now.js`, so once you hit **Publish**, everyone who is connected will see your meme image pop itself into the list.
15 |
16 | ## How it works
17 |
18 | All meme template images are stored on Dropbox.
19 |
20 | - When a new meme is published, the server takes a JSON object from the client, containing the meme `name` and `text`. No image whatsoever.
21 |
22 | - The received meme object is inserted into the mongo collection `memes` with a date timestamp added to it. The object is also sent to all connected clients immediately so that they may update their timelines. This also means that no further database queries are required to retrieve new memes.
23 |
24 | - When a client connects, the last few (25) memes are queried from the database and sent back. This can further be optimized by having an in-memory queue of the most recent memes, in addition to the database.
25 |
26 | - All meme generation is done entirely **client-side**, by drawing the text over the images using **Canvas**. The client doesn't have to download images, and the server doesn't have to handle them at all.
27 |
28 | ## How to run
29 |
30 | 1. First, run `mongod` to start the Mongo daemon.
31 | 2. Next, run the server: `node app.js`
32 | 3. Point your browser to `http://localhost:8080`.
33 | 4. Bask in Memetic paradise.
34 |
--------------------------------------------------------------------------------
/app.js:
--------------------------------------------------------------------------------
1 | var fs =require('fs');
2 | var http = require('http');
3 | var mongo = require('mongodb');
4 |
5 | var db = new mongo.Db('memedb', new mongo.Server("127.0.0.1", 27017));
6 | db.open(function(err) {
7 | if(err) {
8 | console.log(err);
9 | db.close();
10 | process.exit(1);
11 | }
12 | });
13 |
14 | server = http.createServer( function(req, res) {
15 | fs.readFile('index.html', function(err, page) {
16 | res.writeHead(200, {'Content-Type': 'text/html'});
17 | res.write(page);
18 | res.end();
19 | });
20 | });
21 | server.listen(8080);
22 |
23 | // now.js code
24 | var everyone = require("now").initialize(server, {socketio: {'transports': ['xhr-polling']}});
25 |
26 | // publish meme
27 | everyone.now.publish = function(meme) {
28 | if(meme.name && meme.text.line1 && meme.text.line2) {
29 | db.collection('memes', function(err, collection) {
30 | // add a date field and save
31 | meme.date = Date.now();
32 | collection.insert(meme, function(err) {
33 | if(!err)
34 | everyone.now.receiveMeme(meme);
35 | });
36 | });
37 | }
38 | };
39 |
40 | // retrieve the latest few memes of a name. If there is no name, retrieve a mixture
41 | everyone.now.getRecent = function(memeName) {
42 | var client = this;
43 | console.log("retrieving");
44 | db.collection('memes', function(err, collection) {
45 | if(memeName == undefined) {
46 | collection.find( {}, { sort: [[ "date", "desc" ]], limit: 25 }).toArray( function(err, docs) {
47 | client.now.getContent(docs);
48 | });
49 | }
50 | else {
51 | collection.find( {"name": memeName}, { sort: [[ "date", "desc" ]], limit: 25 }).toArray( function(err, docs) {
52 | client.now.getContent(docs);
53 | });
54 | }
55 | });
56 | };
57 |
--------------------------------------------------------------------------------
/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |