├── README.md
├── cron_entries
├── paste_content
├── favicon.ico
├── img
│ ├── 11.png
│ ├── 12.png
│ ├── 13.png
│ ├── 14.png
│ ├── 15.png
│ ├── 16.png
│ └── bg.png
└── pomf.min.css
├── runipfs.conf
├── schema.sql
├── site
├── classes
│ ├── Response.class.php
│ ├── UploadException.class.php
│ └── UploadedFile.class.php
├── faq.html
├── favicon.ico
├── grill.php
├── img
│ ├── 11.png
│ ├── 12.png
│ ├── 13.png
│ ├── 14.png
│ ├── 15.png
│ ├── 16.png
│ ├── bg.png
│ ├── bitcoin.png
│ ├── donate.png
│ ├── flattr.png
│ └── paypal.png
├── includes
│ ├── database.inc.php
│ └── settings.inc.php
├── index.html
├── paste.html
├── paste.php
├── pomf.min.css
├── pomf.min.js
├── tools.html
└── upload.php
├── snapshot.py
└── vhosts
/README.md:
--------------------------------------------------------------------------------
1 | # Glop
2 | Included here is code for running an instance of glop.me, including the IPFS-specific scripts.
3 |
4 | ## Requirements
5 | Pomf's suggested setup was Nginx + PHP5.5 + MySQL, but was also confirmed to work with Apache 2.4
6 | and newer PHP versions. glop.me runs a standard Ubuntu LAMP stack, but Nginx should still work (note that install locations/vhosts/etc. would need to be adjusted appropriately). Python is required for the snapshot utility.
7 |
8 | ## Install
9 | * Follow the instructions at https://ipfs.io/docs/install/ to install IPFS.
10 | * Set up the local IPFS repo:
11 | ````
12 | mkdir /home/www-data
13 | chown -R -v www-data /home/www-data
14 | sudo -u www-data HOME=/home/www-data ipfs init
15 | ````
16 | * If you are using upstart, move runipfs.conf to /etc/init/, otherwise adapt it as appropriate for your system.
17 | * Set up the DB from schema.sql
18 | * Alter includes/settings.inc.php as appropriate
19 | * For the paste utility, you will need to either:
20 | ````
21 | sudo -u www-data HOME=/home/www-data ipfs pin add -r QmazFHudWq91G7GxuWTpyRWZ1Pc2jg3wnwc2RrgVy5GSa3
22 | ````
23 | OR if that doesn't work (i.e. glop.me is offline)
24 | ````
25 | sudo -u www-data HOME=/home/www-data ipfs add -rq paste_content/
26 | ````
27 | and move the hash to paste.php:34.
28 | * For the snapshot utility, move snapshot.py to /home/www-data/ and change the DB info as appropriate. You may also need to do
29 | ````
30 | sudo -u www-data HOME=/home/www-data ipfs object new unixfs-dir
31 | sudo -u www-data HOME=/home/www-data ipfs pin add -r QmUNLLsPACCz1vLxQVkXqqLX5R1X345qqfHbsf67hvA3Nn
32 | ````
33 | * Finally, merge cron_entries with your server's crontab.
34 |
--------------------------------------------------------------------------------
/cron_entries:
--------------------------------------------------------------------------------
1 | 0 * * * * sudo -u www-data HOME=/home/www-data python /home/www-data/snapshot.py
2 |
3 | # Enterprise grade administration(tm)
4 | # (this may no longer be necessary, an earlier version of IPFS had a memory leak that broke everything after a while)
5 | 30 6 * * * killall ipfs && sleep 60 && killall ipfs
6 |
--------------------------------------------------------------------------------
/paste_content/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/2yrs/Pomf/a10c84660685171aa562d7e4d48b6103323b71c9/paste_content/favicon.ico
--------------------------------------------------------------------------------
/paste_content/img/11.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/2yrs/Pomf/a10c84660685171aa562d7e4d48b6103323b71c9/paste_content/img/11.png
--------------------------------------------------------------------------------
/paste_content/img/12.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/2yrs/Pomf/a10c84660685171aa562d7e4d48b6103323b71c9/paste_content/img/12.png
--------------------------------------------------------------------------------
/paste_content/img/13.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/2yrs/Pomf/a10c84660685171aa562d7e4d48b6103323b71c9/paste_content/img/13.png
--------------------------------------------------------------------------------
/paste_content/img/14.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/2yrs/Pomf/a10c84660685171aa562d7e4d48b6103323b71c9/paste_content/img/14.png
--------------------------------------------------------------------------------
/paste_content/img/15.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/2yrs/Pomf/a10c84660685171aa562d7e4d48b6103323b71c9/paste_content/img/15.png
--------------------------------------------------------------------------------
/paste_content/img/16.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/2yrs/Pomf/a10c84660685171aa562d7e4d48b6103323b71c9/paste_content/img/16.png
--------------------------------------------------------------------------------
/paste_content/img/bg.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/2yrs/Pomf/a10c84660685171aa562d7e4d48b6103323b71c9/paste_content/img/bg.png
--------------------------------------------------------------------------------
/paste_content/pomf.min.css:
--------------------------------------------------------------------------------
1 | /*! pomf (https://github.com/nokonoko/Pomf.git) @ 2015-06-15 */
2 | textarea{width:100%;background-color:white;}
3 | *,:before,:after{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}body{background-attachment:fixed,fixed;background-color:#F7F7F7;background-image:url(img/bg.png),url(img/bg.png);background-position:85% 100%,top left;background-repeat:no-repeat,repeat;color:#333;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;height:100%;line-height:20px;margin:0;padding-top:20px;padding-bottom:40px}.container{margin:0 auto;max-width:700px}p{margin:0 0 10px}input[type=image],img{vertical-align:middle}a{color:#08C;text-decoration:none;transition:color .25s}a:hover,a:focus,a:active{color:#005580}a:focus{outline:thin dotted #333}.jumbotron{margin:60px 0;text-align:center;transition:width .5s,height .5s,margin .5s,padding .5s}.jumbotron h1{color:inherit;font-family:inherit;font-size:72px;font-weight:700;line-height:1;margin:10px 0;cursor:default;text-rendering:optimizelegibility}.jumbotron .lead{font-size:21px;font-weight:200;line-height:30px;margin-bottom:20px;transition:font-size .5s}.jumbotron .btn{background:rgba(202,230,190,.75);border:1px solid #B7D1A0;border-radius:4px;color:#468847;cursor:pointer;display:inline-block;font-size:24px;padding:28px 48px;text-shadow:0 1px rgba(255,255,255,.5);transition:background-color .25s,width .5s,height .5s}.jumbotron .btn:hover,.jumbotron .btn:active,.jumbotron .btn:focus,.jumbotron .btn.drop{background-color:#bce4aa;text-decoration:none}#no-file-api{display:none}.alert{background-color:#FCF8E3;border:1px solid #FBEED5;border-radius:4px;margin-bottom:20px;padding:8px 14px;text-shadow:0 1px rgba(255,255,255,.5);transition:width .5s,margin .5s,padding .5s,background-color .5s}.alert-error{background-color:#F2DEDE;border-color:#EED3D7;color:#B94A48}.alert-info{background-color:#D9EDF7;border-color:#BCE8F1;color:#3A87AD}span.donate-btns{display:block;text-align:center;margin:11px 0 3px}a.donate-btn{height:26px;display:inline-block;margin:2px 5px;background:#f2f2f2;line-height:16px;padding:3px 8px 3px 24px;border-radius:3px;color:#3f3f3f;border:1px solid #d8d8d8;transition:all .2s}a.donate-btn:hover{color:#000;border:1px solid #b2b2b2;background-color:#ccc}.icon{display:block;height:16px;width:16px;float:left;margin-left:-20px;margin-top:1px}.icon-paypal{background-image:url(img/paypal.png)}.icon-bitcoin{background-image:url(img/bitcoin.png)}.icon-flattr{background-image:url(img/flattr.png)}nav>ul,nav a{color:#3A87AD;list-style:none;margin:0;padding:0;text-align:center}nav>ul>li{display:inline-block;margin:0;padding:0;cursor:default}nav>ul>li:after{content:"|";margin:0 8px;opacity:.3}nav>ul>li:last-child:after{content:"";margin:0}#upload-input{position:absolute;top:0;left:-5000px}#upload-filelist{list-style-type:none;margin:20px 50px;padding:0;text-align:left}.error#upload-filelist{color:#891A18}.error#upload-filelist .file-size{color:#B94A48}.error#upload-filelist .file-progress{display:none}#upload-filelist>li{margin-top:5px;overflow:hidden}#upload-filelist>li.total{border-top:1px solid rgba(0,0,0,.05);font-weight:700;padding-top:5px}.file-name{float:left;overflow:hidden;max-width:70%;text-overflow:ellipsis;white-space:nowrap}.file-size,.file-url{display:inline-block;float:right;font-size:.9em;margin-left:8px;color:#5C5C5C;vertical-align:middle}.file-url a{color:#5C5C5C}.file-url a:hover{color:#1C1C1C}.completed .file-progress,.completed .file-size{display:none}.completed .file-url{display:block}.progress-outer{background-color:rgba(255,255,255,.8);border:1px solid #fff;border-radius:4px;box-shadow:0 0 0 1px #000;color:transparent;display:inline-block;font-size:0;float:right;height:8px;margin:6px 6px 0;overflow:hidden;vertical-align:middle;width:50px}.progress-inner{background-color:#000;height:6px;margin:0;width:0}.pocky{margin:20px auto;text-align:center}.pocky img{max-width:100%}span.old{text-transform:uppercase;font-size:.8em;border-radius:4px;background-color:#722726;color:#fff;padding:2px 8px;margin:0 4px;font-weight:200}section.ded{opacity:.5}@media only screen and (max-device-width:320px),only screen and (max-width:400px){body{padding:10px 0 0}.jumbotron{margin:20px 0 30px}.jumbotron .lead{font-size:18px}.jumbotron .btn,.alert,#upload-filelist{border-radius:0;border-width:1px 0;width:100%;margin-left:0;margin-right:0;padding-left:20px;padding-right:20px}#upload-filelist{background-color:rgba(255,255,255,.75);overflow:hidden}#upload-filelist>li.file{margin-top:12px;margin-bottom:12px}.file-progress{float:left;width:70%}.file-size{float:left;max-width:30%;overflow:hidden}.file-name,.file-url{width:100%;max-width:100%}.file-url a{text-decoration:underline;margin-left:15px}.file-url a:before{content:"http://"}.alert{font-size:13px}.alert-error{background-color:rgba(248,223,223,.75)}nav{background-color:rgba(255,255,255,.75);border:#FFF;padding:10px 0}}
4 |
--------------------------------------------------------------------------------
/runipfs.conf:
--------------------------------------------------------------------------------
1 | start on runlevel [2345]
2 | stop on runlevel [!2345]
3 |
4 | respawn
5 | respawn limit unlimited
6 |
7 | exec sudo -u www-data HOME=/home/www-data ipfs daemon
8 |
--------------------------------------------------------------------------------
/schema.sql:
--------------------------------------------------------------------------------
1 | -- MySQL dump 10.13 Distrib 5.6.21-70.1, for debian-linux-gnu (x86_64)
2 | --
3 | -- Host: localhost Database: pomf
4 |
5 | --
6 | -- Table structure for table `accounts`
7 | --
8 |
9 | CREATE TABLE `accounts` (
10 | `id` int(10) unsigned NOT NULL auto_increment,
11 | `email` varchar(255) NOT NULL,
12 | `pass` varchar(255) NOT NULL,
13 | `level` int(11) NOT NULL,
14 | PRIMARY KEY (`id`)
15 | ) ENGINE=InnoDB;
16 |
17 | --
18 | -- Table structure for table `files`
19 | --
20 |
21 | CREATE TABLE `files` (
22 | `id` int(10) unsigned NOT NULL auto_increment,
23 | `hash` char(40) default NULL,
24 | `originalname` varchar(255) default NULL,
25 | `filename` varchar(30) default NULL,
26 | `size` int(10) unsigned default NULL,
27 | `date` date default NULL,
28 | `expire` date default NULL,
29 | `delid` char(40) default NULL,
30 | `user` int(10) unsigned default '0',
31 | `dir` int(2) default '0',
32 | PRIMARY KEY (`id`)
33 | ) ENGINE=InnoDB;
34 | -- `filename` length (30) may be a bit excessive, since the average length would be smaller
35 | -- [6 for the name + the file extension length], but since there is no limit for the file
36 | -- extension length (at the moment, at least) let's keep it high in order to avoid problems
37 |
38 | --
39 | -- Table structure for table `invites`
40 | --
41 |
42 | CREATE TABLE `invites` (
43 | `id` int(10) unsigned NOT NULL auto_increment,
44 | `email` varchar(50) default '0',
45 | `code` varchar(50) default '0',
46 | `used` int(11) default '0',
47 | `level` int(11) default NULL,
48 | PRIMARY KEY (`id`)
49 | ) ENGINE=InnoDB;
50 |
51 | --
52 | -- Table structure for table `reports`
53 | --
54 |
55 | CREATE TABLE `reports` (
56 | `id` int(10) unsigned NOT NULL auto_increment,
57 | `hash` char(40) default '0',
58 | `date` date default NULL,
59 | `file` varchar(255) NOT NULL default '0',
60 | `fileid` int(11) default '0',
61 | `reporter` varchar(255) NOT NULL default '0',
62 | `status` int(11) default '0',
63 | PRIMARY KEY (`id`)
64 | ) ENGINE=InnoDB;
65 |
66 |
67 | -- Dump completed on 2014-12-07 19:30:13
68 |
--------------------------------------------------------------------------------
/site/classes/Response.class.php:
--------------------------------------------------------------------------------
1 | type = $response_type;
12 | break;
13 | default:
14 | header('Content-Type: application/json; charset=UTF-8');
15 | $this->type = 'json';
16 | break;
17 | }
18 | }
19 |
20 | public function error ($code, $desc) {
21 | $response = null;
22 |
23 | switch ($this->type) {
24 | case 'csv':
25 | $response = $this->csv_error($desc);
26 | break;
27 | case 'gyazo':
28 | $response = $this->gyazo_error($code, $desc);
29 | break;
30 | default:
31 | $response = $this->json_error($code, $desc);
32 | break;
33 | }
34 |
35 | http_response_code($code);
36 | echo $response;
37 | }
38 |
39 | public function send ($files) {
40 | $response = null;
41 |
42 | switch ($this->type) {
43 | case 'csv':
44 | $response = $this->csv_success($files);
45 | break;
46 | case 'gyazo':
47 | $response = $this->gyazo_success($files);
48 | break;
49 | default:
50 | $response = $this->json_success($files);
51 | break;
52 | }
53 |
54 | http_response_code(200);
55 | echo $response;
56 | }
57 |
58 | private static function csv_error ($description) {
59 | return "error\n" . $description . "\n";
60 | }
61 |
62 | private static function csv_success ($files) {
63 | $result = "name,url,hash,size\n";
64 | foreach ($files as $file) {
65 | $result .= $file['name'] . "," .
66 | $file['url'] . "," .
67 | $file['hash'] . "," .
68 | $file['size'] . "\n";
69 | }
70 |
71 | return $result;
72 | }
73 |
74 | private static function gyazo_error ($code, $description) {
75 | return "ERROR: (" . $code . ") " . $description;
76 | }
77 |
78 | private static function gyazo_success ($files) {
79 | return POMF_URL . $files[0]['url'];
80 | }
81 |
82 | private static function json_error ($code, $description) {
83 | return json_encode(array(
84 | 'success' => false,
85 | 'errorcode' => $code,
86 | 'description' => $description
87 | ));
88 | }
89 |
90 | private static function json_success ($files) {
91 | return json_encode(array(
92 | 'success' => true,
93 | 'files' => $files
94 | ));
95 | }
96 | }
97 |
98 | ?>
--------------------------------------------------------------------------------
/site/classes/UploadException.class.php:
--------------------------------------------------------------------------------
1 | codeToMessage($code);
9 | parent::__construct($message, 500);
10 | }
11 |
12 | private function codeToMessage($code) {
13 | switch ($code) {
14 | case UPLOAD_ERR_INI_SIZE:
15 | $message = "The uploaded file exceeds the upload_max_filesize directive in php.ini";
16 | break;
17 | case UPLOAD_ERR_FORM_SIZE:
18 | $message = "The uploaded file exceeds the MAX_FILE_SIZE directive that was " .
19 | "specified in the HTML form";
20 | break;
21 | case UPLOAD_ERR_PARTIAL:
22 | $message = "The uploaded file was only partially uploaded";
23 | break;
24 | case UPLOAD_ERR_NO_FILE:
25 | $message = "No file was uploaded";
26 | break;
27 | case UPLOAD_ERR_NO_TMP_DIR:
28 | $message = "Missing a temporary folder";
29 | break;
30 | case UPLOAD_ERR_CANT_WRITE:
31 | $message = "Failed to write file to disk";
32 | break;
33 | case UPLOAD_ERR_EXTENSION:
34 | $message = "File upload stopped by extension";
35 | break;
36 |
37 | default:
38 | $message = "Unknown upload error";
39 | break;
40 | }
41 | return $message;
42 | }
43 | }
44 |
45 | ?>
--------------------------------------------------------------------------------
/site/classes/UploadedFile.class.php:
--------------------------------------------------------------------------------
1 | sha1)
22 | $this->sha1 = sha1_file($this->tempfile);
23 |
24 | return $this->sha1;
25 | }
26 |
27 | /**
28 | * Generates the CRC32 or returns the cached CRC32 hash for the file.
29 | *
30 | * @return string
31 | */
32 | public function get_crc32 () {
33 | if (!$this->crc32)
34 | $this->crc32 = hash_file('crc32b', $this->tempfile);
35 |
36 | return $this->crc32;
37 | }
38 | }
39 | ?>
40 |
--------------------------------------------------------------------------------
/site/faq.html:
--------------------------------------------------------------------------------
1 |
Glop.me · FAQ
FAQ
2 |
3 |
4 |
5 |
6 |
This site works a bit differently from other Pomf clones. We use IPFS as our backend, as opposed to storing the files directly.
7 |
Consequently, Glop should be thought of as having two distinct components, the standard PHP frontend for uploading files, and an IPFS gateway for serving files.
8 |
This enables a bit (A LOT) more flexibility in managing your uploads than usual.
9 |
Firstly, it is possible to to grab your files through ANY IPFS gateway, both public and local by substituting in the domain name (i.e., replacing gateway.glop.me/ipfs/[hash] with gateway.ipfs.io/ipfs/[hash] for the official gateway, or localhost:8080/ipfs/[hash] if you have ipfs daemon running locally (the ideal scenario)).
10 |
You can back up your files locally by running ipfs pin add -r [hash], and I intend on setting up at least a couple more servers to do exactly that for all files. So long as any node (including any you choose to host yourself) stays up your files will remain accessible permanently, even should this site itself go down at some point.
11 |
If you would like to operate a Glop IPFS mirror yourself and contribute to the stability of the service, simply run ipfs name resolve QmbqE6UfCJaXST3i65zbr649s8cJCUoP9m3UFUrXcNgeDn | ipfs pin add -r (This takes a snapshot of the current state of the server, updated once hourly. Rerun it periodically to keep your node up to date)
All file types are allowed, and unlike Pomf both the extension AND file name are preserved.
14 |
The site is on a shoe-string budget right now, please don't abuse it. Presently the max filesize is 10MiB, we'll see how it goes. All going well (read: pending donations) we'll be able to raise/remove the limit, and also add mirrors of our own.
15 |
The site requires an up to date browser, and does not support Internet Exploder at all.
16 |
Do not upload any illegal content, or content you do not own the rights to.
17 |
To report illegal content or file a DMCA takedown request, please email toomuchglop@cock.li
18 |
19 |
20 |
Follow the rules and tips I have set up above, please. The FAQ may also be changed and updated at any time.
21 |
22 |
glop.me is a free service, and at current usage levels I can afford to float the site myself. However, to do this properly extra mirrors/backups should be utilized, and I'm going to need help for that. Anything you can contribute would be greatly appreciated. Bitcoin
19 |
20 |