258 Commits
0.2.1 ... dank

Author SHA1 Message Date
Jeff
ab69a2e9a4 Merge pull request #33 from 4cdn/patch-1
graph bleed-through, add spacing
2015-11-22 16:10:27 -05:00
4cdn
a6da70e7d3 fixes 2015-11-22 16:02:45 -05:00
4cdn
6e87271483 define table classes
defines classes to fix background colors bleeding through on some of the graphs and adds some spacing between graphs (3cecde002ed9c42197)
2015-11-22 15:59:21 -05:00
4cdn
fed34ed622 adds classes
adds classes to fix background colors bleeding through on some of the graphs (3cecde002ed9c42197)
2015-11-22 15:47:23 -05:00
Jeff
eb5ca66330 Merge pull request #32 from 4cdn/patch-1
hawt
2015-11-19 20:47:29 -05:00
4cdn
81f11be7c5 frontpage consistency </link> 2015-11-19 20:33:24 -05:00
4cdn
2c9f332fb0 issuecomment-158252057 2015-11-19 20:31:34 -05:00
4cdn
d6f3bdd9e8 consistency 2015-11-19 20:23:12 -05:00
4cdn
e75cf64769 consistency, see change in postform.mustache 2015-11-19 20:21:04 -05:00
4cdn
d030303ed3 consistency, see change in site.css 2015-11-19 20:20:57 -05:00
4cdn
9ad004e85f Update modpage.mustache 2015-11-19 20:09:38 -05:00
4cdn
83a4102e38 consistency 2015-11-19 20:07:23 -05:00
4cdn
57e2ebda6e bloat 2015-11-19 20:05:56 -05:00
4cdn
24b6ad9276 similar to PR22
"no such attribute for textfield"
2015-11-19 20:03:08 -05:00
Jeff
0e28120697 Merge pull request #31 from viniciusbo/master
Fix input file size in new post page
2015-11-19 11:50:04 -05:00
Vinícius Borriello
775dc470e5 Fix input file size in new post page 2015-11-19 14:36:41 -02:00
jeff
a929709924 Merge branch 'master' of ssh://github.com/majestrate/nntpchan 2015-11-12 22:13:18 -05:00
jeff
c23696aae5 fix psy 2015-11-12 22:13:09 -05:00
Jeff
ed97ca881d Merge pull request #28 from chen-chan/master
unused templates
2015-11-11 16:36:25 -05:00
chen-chan
ed041c1689 unused templates 2015-11-10 22:24:07 +01:00
jeff
67bcbc6289 remove link to create new board from front page 2015-11-10 13:00:28 -05:00
jeff
8eec2ce827 only mods can create new boards 2015-11-10 12:53:54 -05:00
jeff
749bd5a72b Merge branch 'master' of ssh://github.com/majestrate/nntpchan 2015-11-09 14:46:22 -05:00
jeff
d0ad0ae71d checkem 2015-11-09 13:59:54 -05:00
Jeff
4bff278a8f Merge pull request #26 from 4cdn/patch-6
truthier wording
2015-11-09 06:58:04 -05:00
4cdn
6453d405a6 truthier wording 2015-11-08 21:18:49 -05:00
jeff
1614cef91f remove duplicate css rule 2015-11-08 14:22:01 -05:00
jeff
0004483395 add border radius for fieldset 2015-11-08 11:37:23 -05:00
jeff
d1d846e2fe change captcha background color 2015-11-08 11:32:41 -05:00
Jeff
2a267f93be Merge pull request #23 from 4cdn/patch-5
using real attributes makes css 10x easier
2015-11-07 19:12:43 -05:00
4cdn
3c8fa13ffe block-inline --> inline-block & cater to firefox
19:03:41.183 Error in parsing value for 'display'.  Declaration dropped.1 site.css:44:13
19:03:41.183 Unknown property 'overflow-wrap'.  Declaration dropped.1 site.css:45:14
"You might as well use word-wrap as well because as the spec says, they are literally just alternate names for each other. Some browsers support one and not the other. Firefox (tested v43) only supports word-wrap"
—https://css-tricks.com/snippets/css/prevent-long-urls-from-breaking-out-of-container/
2015-11-07 19:09:34 -05:00
jeff
e50d145bbe Merge branch 'master' into dank 2015-11-07 18:48:19 -05:00
Jeff
f85eaf35ac Merge pull request #22 from chen-chan/patch-1
no such attribute for textfield
2015-11-07 18:43:24 -05:00
chen-chan
d16921d727 no such attribute for textfield 2015-11-07 23:20:32 +01:00
jeff
8bb13354a2 interchange image, post body placement 2015-11-07 12:58:44 -05:00
jeff
4c9ec43d30 redo icons 2015-11-07 12:54:16 -05:00
jeff
69ef6f2b71 css tweak 2015-11-07 12:50:49 -05:00
jeff
39c6c6b963 tweak post.mustache 2015-11-07 12:49:34 -05:00
jeff
5219bcefab fix tor/clearnet/i2p icon placement 2015-11-07 12:39:24 -05:00
jeff
322edd37cb fix icons 2015-11-07 12:33:32 -05:00
jeff
edfca55b8f fix post.mustace 2015-11-07 12:27:17 -05:00
jeff
1c405795b9 fix ukko 2015-11-07 12:25:27 -05:00
jeff
8ebba42030 fix templates 2015-11-07 12:23:56 -05:00
jeff
41643bc52a fix templates 2015-11-07 12:22:26 -05:00
jeff
ad5dfca2ef change color 2015-11-07 12:21:30 -05:00
jeff
a95ec269df make css more sane 2015-11-07 12:20:52 -05:00
jeff
dc3ec1c63d fix css a bit 2015-11-07 11:27:31 -05:00
jeff
371256e147 fix css a bit 2015-11-07 11:23:33 -05:00
jeff
edd4b13af4 fix css a bit 2015-11-07 11:21:44 -05:00
jeff
b12f6421fd fix css a bit 2015-11-07 11:18:56 -05:00
jeff
eb08ccb5d6 fix css a bit 2015-11-07 11:17:54 -05:00
jeff
e18f91c7e5 fix css a bit 2015-11-07 11:16:54 -05:00
jeff
0176f32bd4 try fixing board.mustache 2015-11-07 11:13:21 -05:00
jeff
ab83843ef6 fix css a bit 2015-11-07 11:10:43 -05:00
jeff
a0823c13db fix css a bit 2015-11-07 11:03:06 -05:00
jeff
26042749aa fix css a bit 2015-11-07 11:02:26 -05:00
jeff
cde9c1c641 fix css a bit 2015-11-07 11:00:36 -05:00
jeff
fdcd9181ad fix css a bit 2015-11-07 10:59:19 -05:00
jeff
9b3c073692 fix css a bit 2015-11-07 10:58:53 -05:00
jeff
ce74caabf9 fix css a bit 2015-11-07 10:57:37 -05:00
jeff
70ff3f487f fix css a bit 2015-11-07 10:55:50 -05:00
jeff
78025891df fix css a bit 2015-11-07 10:54:57 -05:00
jeff
1044989070 try fixing post.mustache; 2015-11-07 10:53:35 -05:00
jeff
34dcede98f fix css a bit 2015-11-07 10:50:28 -05:00
jeff
363743ac0c try fixing ukko 2015-11-07 10:48:25 -05:00
jeff
92c7102c50 try fixing ukko 2015-11-07 10:47:21 -05:00
jeff
38085620dc try fixing ukko 2015-11-07 10:46:03 -05:00
jeff
320966cca3 fix css a bit 2015-11-07 10:43:57 -05:00
jeff
4165a5c34b fix css a bit 2015-11-07 10:43:16 -05:00
jeff
f7504c7425 fix css a bit 2015-11-07 10:42:16 -05:00
jeff
8196274c0e for science :-DDD 2015-11-07 10:37:18 -05:00
jeff
32d4fe6307 add style tweaks 2015-11-01 12:15:15 -05:00
jeff
b57778cdcf close title tag :p 2015-11-01 11:48:37 -05:00
jeff
15b14980f8 history graph template added 2015-11-01 11:41:05 -05:00
jeff
82708039c2 truncate subject 2015-10-31 12:42:16 -04:00
jeff
f58f4258e8 ammend overview 2015-10-31 11:34:19 -04:00
jeff
68d011b42b try fixing placement 2015-10-31 11:30:17 -04:00
jeff
fdaf1dd9da try fixing placement 2015-10-31 11:28:54 -04:00
jeff
bf82420f99 try fixing placement 2015-10-31 11:27:36 -04:00
jeff
6cbe15988e try fixing placement on front page 2015-10-31 11:25:29 -04:00
jeff
3094108e59 css tweak 2015-10-31 11:22:50 -04:00
jeff
c084518622 try fixing placement 2015-10-31 11:21:36 -04:00
jeff
4e3d66ad52 try fixng css 2015-10-31 11:20:11 -04:00
jeff
b9e2202d04 try fixing css 2015-10-31 11:19:22 -04:00
jeff
44b63a11a0 try fixing placement of overview 2015-10-31 11:17:25 -04:00
jeff
1ad84780a8 make subjects clickable 2015-10-31 11:15:56 -04:00
jeff
4c822ba2cd add overview 2015-10-31 11:10:58 -04:00
jeff
2212f61ff0 try fixing css for front page 2015-10-31 08:04:14 -04:00
jeff
19198738c3 try fixing css for front page 2015-10-31 08:02:55 -04:00
jeff
7aa769d52d try fixing posts graph 2015-10-31 07:57:19 -04:00
jeff
e4a9d8ef8c scale graph 2015-10-31 07:49:59 -04:00
jeff
2d45920bc7 fix posts graph 2015-10-31 07:30:57 -04:00
jeff
ee7004fc42 add posts graph 2015-10-31 07:27:26 -04:00
jeff
e82058d961 ref -> rel 2015-10-29 08:16:17 -04:00
jeff
086eec72d8 add "root trust" keys 2015-10-27 10:02:34 -04:00
jeff
d3a423a72f ammend docs to reflect updated feed format and add note about database creds 2015-10-24 09:32:40 -04:00
jeff
0427135322 add overchan protocol spec to repo 2015-10-24 09:14:39 -04:00
jeff
f0ceac8d28 ammend mod page 2015-10-24 08:49:07 -04:00
jeff
e263ebde0b add dusty's docs 2015-10-21 12:12:04 -04:00
jeff
651bd33205 docs -> doc 2015-10-21 10:56:54 -04:00
jeff
7051da0e91 add clarifications 2015-10-21 10:51:17 -04:00
jeff
8dc4667666 have build.sh copy binary to root of repo 2015-10-21 10:49:08 -04:00
jeff
3eba7adc1c fix build.sh 2015-10-21 10:48:14 -04:00
jeff
8a7efa9929 use go 1.3 or higher 2015-10-21 10:45:49 -04:00
jeff
83f5855bba reorder instructions for clairity 2015-10-21 10:17:40 -04:00
jeff
c497a01e2d Merge branch 'master' of ssh://github.com/majestrate/nntpchan 2015-10-21 10:17:04 -04:00
Jeff
56b716d584 Merge pull request #17 from 4cdn/patch-4
add git to dependancies
2015-10-21 10:07:05 -04:00
jeff
688c9a746c add irc2p link 2015-10-20 19:48:50 -04:00
4cdn
7027b9e297 add git to dependancies 2015-10-20 18:56:37 -04:00
jeff
5d191c88bc add urc link 2015-10-20 10:45:55 -04:00
jeff
91367983ec try fixing attachment retry 2015-10-20 09:54:37 -04:00
jeff
bbba16380f try fixing repost of images 2015-10-20 09:23:16 -04:00
jeff
80e4d7beb4 try fixing attachment repost 2015-10-20 09:18:25 -04:00
jeff
a451a6b46e try fixing attachments 2015-10-20 09:16:42 -04:00
jeff
75c72e177c try fixing attachments when retrying 2015-10-20 09:11:45 -04:00
jeff
939472f5a4 try fixing post retry 2015-10-20 08:56:38 -04:00
jeff
cf033b03b6 try fixing post captcha retry 2015-10-20 08:55:09 -04:00
jeff
b16b0c72b0 add post retry template (initial) 2015-10-20 08:41:46 -04:00
jeff
566c88dc28 put link to board list on front page 2015-10-19 09:26:38 -04:00
jeff
4698f7a118 try fixing backlinks 2015-10-19 09:20:30 -04:00
jeff
5e60d20222 fuggg 2015-10-19 09:16:07 -04:00
jeff
6cbc367630 try fixing nnptchan.js 2015-10-19 09:13:28 -04:00
jeff
af85eae429 ammend nnptchan.js to use old style shorthashes 2015-10-19 09:12:32 -04:00
jeff
5420346b36 add board list template 2015-10-19 08:42:27 -04:00
jeff
e11978a0d9 add link to peering 2015-10-16 14:19:44 -04:00
jeff
d94813ee36 add_key 2015-10-16 14:17:16 -04:00
jeff
1aa4f81ae7 wrong link 2015-10-16 14:14:42 -04:00
jeff
270e72c8eb forgot link 2015-10-16 14:13:59 -04:00
jeff
0d1c42b086 fix up docs 2015-10-16 14:11:08 -04:00
jeff
105b314ee7 add link to next step in build.md 2015-10-16 13:56:59 -04:00
jeff
7dfc1e3418 fix docs 2015-10-16 13:47:33 -04:00
jeff
d5b45cb58e fix docs 2015-10-16 13:42:55 -04:00
jeff
a9ea094144 apply fix for json parse error 2015-10-14 13:48:03 -04:00
jeff
f1037d888d change to use overchan.archive.* 2015-10-14 13:46:17 -04:00
jeff
2a9b1f3eac fix 404 errors 2015-10-14 13:19:47 -04:00
jeff
bf351294b1 add archive script 2015-10-14 12:57:02 -04:00
jeff
f93256e0d8 fix markup to not suck as bad 2015-10-14 09:05:32 -04:00
jeff
c1ecf14258 change frontend to message id in post template 2015-10-14 09:01:47 -04:00
jeff
80e12fe0f3 add todo list 2015-10-10 10:22:00 -04:00
jeff
f6400b3cb5 i suck at css 2015-10-08 11:55:58 -04:00
jeff
04126b743c fak 2015-10-08 11:49:30 -04:00
jeff
f7211600f8 Merge branch 'master' of ssh://github.com/majestrate/nntpchan 2015-10-08 11:42:16 -04:00
jeff
25901e3d44 add references to user.css in all templates 2015-10-08 11:42:10 -04:00
Jeff
97ec36feaa Merge pull request #15 from 4cdn/patch-2
typos + non-base32 onion fix
2015-10-08 06:46:25 -04:00
4cdn
c5f17cf048 typos + non-base32 onion fix 2015-10-07 21:35:42 -04:00
Jeff
0b7b248ea1 Merge pull request #14 from MrBrass/master
This one's been bugging me for way too long
2015-10-07 20:54:26 -04:00
MrBrass
2f381e7052 This one's been bugging me for way too long 2015-10-07 19:21:54 -04:00
Jeff
f006b61c4e Merge pull request #13 from MrBrass/master
typo, no clocks here
2015-10-07 19:10:27 -04:00
MrBrass
3a13943d49 typo, no clocks here 2015-10-07 19:08:06 -04:00
Jeff
ab15a2ff33 Merge pull request #12 from MrBrass/master
Added feeds.ini and peering documentation
2015-10-07 19:04:01 -04:00
MrBrass
af582eb30b Added feeds.ini and peering documentation 2015-10-07 18:55:54 -04:00
jeff
471377ff2e remove instructions to use tags as the existing tags are outdated 2015-10-07 14:07:32 -04:00
jeff
3c4e319f06 add base files for documentation 2015-10-07 14:04:50 -04:00
Jeff
7845131544 Merge pull request #11 from 4cdn/patch-1
you didnt even do it right
2015-10-05 18:05:50 -04:00
4cdn
91971f2f3e you didnt even do it right 2015-10-05 16:25:22 -04:00
Jeff
072e36915a Merge pull request #8 from majestrate/dank
Dank
2015-10-04 06:55:35 -04:00
jeff
758a2c6bbb newboard.js prepends 'overchan.' if it's not present in the name 2015-10-04 06:38:17 -04:00
jeff
fc23bea021 Merge branch 'master' into dank 2015-10-04 06:34:12 -04:00
jeff
b3f104a80a update faq 2015-10-04 06:34:01 -04:00
jeff
e88c8f78ba newboard.js prepends 'overchan.' if it's not present in the name 2015-10-04 06:32:10 -04:00
jeff
d249d373c1 Merge branch 'master' into dank 2015-10-03 22:07:37 -04:00
jeff
8608d222c3 add link to /new/ 2015-10-03 22:07:19 -04:00
jeff
fcca345ba1 fix nginx config 2015-10-03 10:31:32 -04:00
jeff
bc81c8e251 add example nginx config, probably works 2015-10-03 10:14:25 -04:00
jeff
ccbdd33b93 Merge branch 'master' into dank
Conflicts:
	contrib/static/site.css
2015-10-02 15:53:45 -04:00
jeff
7727fc76f8 add message field 2015-10-02 15:46:52 -04:00
jeff
bb676336db fix 2015-10-02 15:45:22 -04:00
jeff
6194db1941 Merge branch 'master' into devel
Conflicts:
	contrib/static/site.css
2015-10-02 15:41:44 -04:00
jeff
229ef83e35 add initial newboard stuff 2015-10-02 15:38:59 -04:00
jeff
12e887316a remove dank maymz 2015-10-02 12:04:49 -04:00
jeff
823af74633 Merge branch 'master' into dank 2015-10-02 11:02:37 -04:00
jeff
441be15845 add pubkey.* admin functions 2015-10-02 11:00:26 -04:00
jeff
95f425c31d Merge branch 'master' into dank 2015-10-01 14:29:12 -04:00
jeff
2366781282 Merge branch 'devel'
Conflicts:
	contrib/templates/default/post.mustache
2015-10-01 14:28:36 -04:00
jeff
69adbaca5a fix irc link 2015-10-01 14:27:46 -04:00
jeff
dd2f916aed wrong placement again 2015-10-01 14:02:45 -04:00
jeff
ef71260653 wrong placement of icons 2015-10-01 14:02:30 -04:00
jeff
0e0a9c3da9 wrong placement again 2015-10-01 14:01:54 -04:00
jeff
cdc405f29e wrong placement of icons 2015-10-01 14:00:07 -04:00
jeff
1a51354621 Merge branch 'devel' into dank
Conflicts:
	contrib/templates/default/post.mustache
2015-10-01 13:56:09 -04:00
jeff
ac3f0eab94 add css and images for origins 2015-10-01 13:55:17 -04:00
jeff
c5605a4412 add post origin awareness 2015-10-01 13:51:01 -04:00
jeff
4e31910ed6 add background image again 2015-10-01 09:42:49 -04:00
jeff
3b1d09072c change id so that backlinks work 2015-09-30 17:39:56 -04:00
jeff
7f56d35762 remove memes 2015-09-23 20:08:42 -04:00
jeff
3360eaf924 add css rule 2015-09-23 18:54:26 -04:00
jeff
51041e2dc9 case matters for real 2015-09-23 09:07:53 -04:00
jeff
6e20cb270e case matters 2015-09-23 09:07:25 -04:00
jeff
6019d70382 ammend mod panel js more 2015-09-23 09:06:44 -04:00
jeff
cec6f7cef5 ammend mod panel js 2015-09-23 09:04:37 -04:00
jeff
40b7e0a88b fix js 2015-09-23 08:59:56 -04:00
jeff
b595024585 ammend mod panel 2015-09-23 08:59:02 -04:00
jeff
00fbc305be add more actions to mod panel 2015-09-23 08:54:49 -04:00
jeff
5e3f2eea03 try using 1 thread for regenerating thumbnails 2015-09-22 12:41:10 -04:00
jeff
7f721eefea fix mod panel a bit 2015-09-22 10:34:38 -04:00
jeff
866196e810 add more info in mod panel, add admin action to rethumb 2015-09-22 10:33:01 -04:00
jeff
8c18b4405d make captcha image background not dark 2015-09-22 07:28:26 -04:00
jeff
578d9f44b3 add regen all threads button 2015-09-20 19:33:31 -04:00
Jeff
ab38445555 Merge pull request #4 from 4cdn/master
user interface changes
2015-09-19 19:39:09 -04:00
4cdn
98cf765690 Update README.md 2015-09-19 19:32:15 -04:00
4cdn
d742af18b5 removing reliance on external file hosting 2015-09-19 19:31:03 -04:00
4cdn
74a1c044f0 removing reliance on external file hosting 2015-09-19 19:30:05 -04:00
4cdn
adb3e54212 new file: contrib/static/fieri.png 2015-09-19 23:28:02 +00:00
4cdn
1cc4d4e858 new file: contrib/static/about.mp3 2015-09-19 23:21:45 +00:00
4cdn
ec8db8121f Update README.md 2015-09-19 16:24:09 -04:00
4cdn
9cb8998302 faq page more entertaining
encourages users to read completely
2015-09-19 16:22:37 -04:00
4cdn
2f8fd2f2b5 improved visual aesthetics 2015-09-19 16:21:22 -04:00
jeff
790c61cfdb ammend templates to use stylesheets 2015-09-19 13:54:10 -04:00
jeff
7b3ec70a80 css tweak 2015-09-19 13:50:19 -04:00
jeff
fcbae8cea1 captcha background consistance 2015-09-19 13:45:49 -04:00
jeff
569727cc96 css tweak 2015-09-19 13:41:00 -04:00
jeff
f7fc61d493 css tweak 2015-09-19 13:39:41 -04:00
jeff
8cbf1f217d css tweak 2015-09-19 13:37:57 -04:00
jeff
458232d402 css tweak 2015-09-19 13:36:33 -04:00
jeff
fcfd010e5c css tweak 2015-09-19 13:34:46 -04:00
jeff
dca5ee7561 css tweak 2015-09-19 13:33:26 -04:00
jeff
108f05da32 css tweak 2015-09-19 13:33:00 -04:00
jeff
a515ba9d1f css tweak 2015-09-19 13:29:25 -04:00
jeff
8611e2e768 css tweak 2015-09-19 13:28:48 -04:00
jeff
20dd0c215e css tweaks 2015-09-19 13:28:20 -04:00
jeff
c91c8c08b1 change bg.jpg 2015-09-19 13:27:44 -04:00
jeff
9321a65f1c css tweak 2015-09-19 13:25:32 -04:00
jeff
b2a71e1877 change background 2015-09-19 13:22:10 -04:00
jeff
045e3140ad css tweak 2015-09-19 13:18:34 -04:00
jeff
d6f073943e css tweaks 2015-09-19 13:17:30 -04:00
jeff
47f884ce98 css tweaks 2015-09-19 13:16:51 -04:00
jeff
9d815479b2 add background image 2015-09-19 13:15:54 -04:00
jeff
2aa2405ba7 css tweaks 2015-09-19 13:03:41 -04:00
jeff
40d6cf77ad use correct parameter in admin command 2015-09-19 09:02:08 -04:00
jeff
e70c4ed84e syntax error 2015-09-19 08:58:33 -04:00
jeff
1c61de8880 add admin stuff to mod panel 2015-09-19 08:54:54 -04:00
jeff
8d146ed6cd change background gradient 2015-09-19 07:39:36 -04:00
jeff
9a807bbebf do not use red 2015-09-17 16:52:28 -04:00
jeff
61fc6d076f make dark 2015-09-17 16:50:32 -04:00
jeff
5a2500dffc make dark 2015-09-17 16:46:21 -04:00
jeff
021721d21e ammend build docs 2015-09-08 22:32:28 -04:00
jeff
2304d3d8fa css tweaks 2015-09-08 22:30:41 -04:00
jeff
c340d215e0 css tweaks 2015-09-08 22:29:26 -04:00
jeff
9e0029772c css tweaks 2015-09-08 22:27:29 -04:00
jeff
1663abcbec css tweaks 2015-09-08 22:26:07 -04:00
jeff
b58e582f0a css tweaks 2015-09-08 22:20:20 -04:00
jeff
1cfa104e4c ammend css 2015-09-08 22:04:39 -04:00
jeff
dc06baba37 fix templates 2015-09-05 15:36:36 -04:00
jeff
838bbc20cd add reply link to posts 2015-09-05 15:29:14 -04:00
jeff
487e392d76 fix thumbnailer 2015-09-05 11:05:32 -04:00
jeff
90276293e1 change thumbs.sh tool to use new thumbnailing 2015-09-05 11:03:04 -04:00
jeff
8411568530 make it so that we don't error when we have no postform, i.e. ukko 2015-09-04 17:20:02 -04:00
jeff
de51b912ff have ukko load nntpchan.js 2015-09-04 17:18:36 -04:00
jeff
8b206740f8 forgot a brace 2015-09-04 17:16:43 -04:00
jeff
be7e510519 try fixing backlinks 2015-09-04 17:14:05 -04:00
jeff
abefe50eb6 make post numbers insert backlink on click 2015-09-04 17:09:43 -04:00
jeff
fb06097557 resolve conflict 2015-09-04 16:51:19 -04:00
jeff
7ba0e728af truncate posts and threads 2015-09-04 16:47:52 -04:00
jeff
f9ea948071 psy tag 2015-08-31 16:58:30 -04:00
jeff
a2fd94a83e add spoiler css 2015-08-31 16:41:25 -04:00
jeff
fd1193f73a add redtext css rules 2015-08-31 16:14:32 -04:00
Jeff
64cd178b2a Merge pull request #1 from Erkan-Yilmaz/patch-1
change 1 word
2015-08-31 15:46:31 -04:00
Erkan Yilmaz
4b56272fdd change 1 word
to: cryptographically
2015-08-31 18:25:45 +02:00
49 changed files with 1510 additions and 297 deletions

View File

@@ -1,29 +1,28 @@
# NNTPChan #
NNTPChan (previously known as overchan) is a decentralized imageboard that uses nntp to synchronize content between many different servers. It utilizes cryptograpghicly signed posts to perform optional/opt-in decentralized moderation.
NNTPChan (previously known as overchan) is a decentralized imageboard that uses nntp to synchronize content between many different servers. It utilizes cryptographically signed posts to perform optional/opt-in decentralized moderation.
This repository contains resources used by the core daemon which is located [here](https://github.com/majestrate/srndv2) along with general documentation, [here](doc/)
## getting started ##
After you [built and installed the daemon](doc/build.md) and [set up your database](doc/database.md), clone this repository and start up the daemon
Get the dependancies
# clone it
git clone https://github.com/majestrate/nntpchan ~/nntpchan
# get the latest stable release
cd ~/nntpchan/
git checkout tags/0.2.1
sudo apt-get update
sudo apt-get --no-install-recommends install imagemagick libsodium-dev ffmpegthumbnailer sox build-essential git golang ca-certificates
# set up the workspace
srndv2 setup
Check out this repo and build it
# run the daemon
srndv2 run
git clone https://github.com/majestrate/nntpchan
cd nntpchan
./build.sh
Now configure the database. [Next](doc/database.md)
Then open http://127.0.0.1:18000/ukko.html in your browser.
---
*PLEASE* report any bugs you find while setting up or building [(here)](https://github.com/majestrate/nntpchan/issues) so that the problems get fixed (^:
*PLEASE* report any bugs you find while setting up or building [(here)](https://github.com/majestrate/nntpchan/issues) so that the problems get fixed :^)
For peering requests, questions or support find me on [rizon](https://qchat.rizon.net/?channels=#nntpchan) as \__uguu\__

6
TODO.md Normal file
View File

@@ -0,0 +1,6 @@
## TODO ##
* extra stylesheets
* alternative templates
* javascript free mod panel
* liveui

8
build.sh Executable file
View File

@@ -0,0 +1,8 @@
#!/usr/bin/env bash
set -e
root=$(readlink -e $(dirname $0))
cd $root
export GOPATH=$root/go
mkdir -p $GOPATH
go get -u github.com/majestrate/srndv2
cp -a $GOPATH/bin/srndv2 $root

View File

@@ -0,0 +1,11 @@
# using srndv2 behind nginx with a prefix
# make sure to set prefix=/nntpchan/ for section frontend in srnd.ini
server {
listen 80;
location /nntpchan/(.*) {
client_max_body_size 50M;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_pass http://[::1]:18000/$1;
}
}

View File

@@ -0,0 +1,76 @@
Date: October 2015.
Getting the srndv2 tool
I am using debian, you should be able to use most any linux distro for this. Known to work are: debian, arch linux, <TODO: add more>.
Most commands should be done as a normal user, but some special commands need to be done as root. I find it useful to have two terminals open. I'll denote normal user level commands with '$' and root command with '#'.
Some dependencies you will need to install (as root) are:
# apt-get install build-essential golang git
# apt-get install libsodium-dev ffmpegthumbnailer
# apt-get install imagemagick ffmpegthumbnailer sox
The source code is in these two repos:
* https://github.com/majestrate/nntpchan
* https://github.com/majestrate/srndv2
set up your GOPATH (notes on that here: https://golang.org/doc/code.html#GOPATH ) and then install and build it:
$ go get -u github.com/majestrate/srndv2
If that command didn't work read the errors and check if you lacked any dependencies.
Now you have the srndv2 tool which you can run, but it will not work yet: You need to step up an SQL database first.
--------------
Setting up an SQL database
* https://wiki.postgresql.org/wiki/Detailed_installation_guides
Install postgresql.
# apt-get install postgresql postgresql-client
Create a postgresql user called 'srnd' and a database 'srnd':
# su postgres
$ whoami
postgres
$ psql -f nntpchan/nntp.psql
TODO: Get correct filename here.
Test if you can log in to that SQL user this way:
$ psql -d srnd -U srnd
If there is an issue with that try the following from the debian wiki:
------------
edit pg_hba.conf in /etc/postgresql/X.Y/main/pg_hba.conf
local all all trust # replace ident or peer with trust
reload postgresql
# /etc/init.d/postgresql reload
------------
hit Contol-D to get back your root terminal after doing this.
Once SQL setup is successful..
Now as your regular user that installed the srndv2 tool, you should be able to set up srndv2
First clone nntpchan and cd into it, then ask the srndv2 tool to setup your node:
$ git clone https://github.com/majestrate/nntpchan.git
$ cd nntpchann
ntpchan/$ srndv2 setup
ntpchan/$ srndv2 tool keygen

BIN
contrib/static/about.mp3 Normal file

Binary file not shown.

BIN
contrib/static/bg.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 550 B

BIN
contrib/static/clearnet.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 846 B

View File

@@ -1,7 +1,7 @@
<html>
<head>
<link rel="stylesheet" href="site.css"></link>
<title> NNTPChan Frequently Asked Questions</title>
<link rel="stylesheet" href="site.css" />
<title> NNTPChan Frequently Asked Questions </title>
</head>
<body>
<h2>NNTPChan faq </h2>
@@ -27,10 +27,19 @@
<div>Question: How can I remove content from nntpchan completely? </div>
<div>‾\(._.)/‾ I don't know. You probably can't unless every server agrees to remove the content, even then, nothing prevents someone from reposting it. You can't delete what you post on the internet.</div>
</p>
<p>
<div>Question: Do you allow child porn? </div>
<div>No, fuck off and die in a fire. All infringing posts are nuked.</div>
</p>
<hr />
<p>
<div>Question: Do you allow XYZ content? </div>
<div>If it violates USA Law or causes problems with my host, no. Otherwise, yes. <b>All posts on this site are the responsibility of the individual poster and not the administration of this server</b>.</div>
<div>If it violates USA Law or causes problems with my host, no. Otherwise, probably.</div>
</p>
<hr />
<p>
<div>Question: Someone posted something I don't like but it's not illegal</div>
<div>That is not my problem. All posts on this site are the responsibility of the individual poster and not the administration of this server</div>
</p>
<hr />
<p>
@@ -39,9 +48,13 @@
</p>
<hr />
<p>
<div>Please send any questions to ampernand [|at\] gmail {dot} com with subject starting with "nntpchan question" </div>
<div>Please send any gripes/questions/inqueries/suggestions/complaints to ampernand [|at\] gmail {dot} com with subject starting with "nntpchan question" </div>
</p>
<hr />
</div>
<audio autoplay="autoplay" loop="loop">
<source src="about.mp3" type="audio/mpeg">
<embed src="about.mp3">
</audio>
</body>
</html>

BIN
contrib/static/i2p.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

View File

@@ -42,6 +42,53 @@ function nntpchan_unban() {
})
}
function get_board_target() {
var e = document.getElementById("nntpchan_board_target");
return e.value;
}
function get_key_target() {
var e = document.getElementById("nntpchan_key_target");
return e.value;
}
function nntpchan_key_del() {
nntpchan_admin("pubkey.del", {
pubkey: get_key_target()
});
}
function nntpchan_key_add() {
nntpchan_admin("pubkey.add", {
pubkey: get_key_target()
});
}
function nntpchan_admin_board(method) {
nntpchan_admin(method, {
newsgroup: get_board_target()
})
}
function nntpchan_admin(method, param) {
nntpchan_mod({
name:"admin",
parser: function(target) {
return method;
},
handle: function(j) {
if (j.result) {
return document.createTextNode(j.result);
} else {
return "nothing happened?";
}
},
method: ( param && "POST" ) || "GET",
data: param
})
}
// handle delete command
function nntpchan_delete() {
nntpchan_mod({
@@ -127,8 +174,14 @@ function nntpchan_mod(mod_action) {
}
if (mod_action.name) {
var url = mod_action.name + "/" + target;
ajax.open("GET", url);
ajax.send();
ajax.open(mod_action.method || "GET", url);
var data = mod_action.data;
if (data) {
ajax.setRequestHeader("Content-type","text/json");
ajax.send(JSON.stringify(data));
} else {
ajax.send();
}
} else {
alert("mod action has no name");
}

View File

@@ -0,0 +1,10 @@
function createBoard() {
var form = document.getElementById("postform");
var e = document.getElementById("boardname");
var board = e.value;
if ( ! board.startsWith("overchan.") ) {
board = "overchan." + board;
}
form.action = form.action + board;
form.submit();
}

View File

@@ -0,0 +1,14 @@
//
// nntpchan.js -- frontend ui niceness
//
// insert a backlink for a post given its short hash
function nntpchan_backlink(shorthash)
{
var elem = document.getElementById("postform_message");
if ( elem )
{
elem.value += ">>" + shorthash.substr(0,10) + "\n";
}
}

View File

@@ -1,20 +1,12 @@
.thread {
margin-right: 20px;
margin-bottom: 1em;
display: inline-block;
word-wrap: break-word;
width: 100%;
}
.frontend , .subject {
color: #0f0d2d;
color: #928BFF;
}
.name {
color: #117743;
}
.name , .subject {
font-weight: bold;
}
@@ -23,7 +15,6 @@
text-align: center;
}
input {
width: 70%;
}
@@ -44,8 +35,39 @@ textarea {
padding: 10px 10px;
}
.reply, th, .ukko_thread_header {
background: #d6daf0;
pre {
white-space: pre-wrap;
background: #3f3f3f;
color: #d17600;
display: inline-block;
overflow-wrap: break-word;
word-wrap: break-word;
}
td {
background-color: dimgrey;
}
.board_td {
position: relative; left: 2px;
}
.posts_td {
position: relative; left: -2px;
}
#overview_graph {
position: relative;
top: 2px;
background: dimgrey;
}
.reply, .ukko_thread_header {
background: #202331;
}
legend {
/* background-color: #525252; */
}
hr {
@@ -55,17 +77,16 @@ hr {
border-style: solid none none;
}
a:hover , a:visited:hover {
color: #f13333;
}
a {
color: blue;
color: #0C2FF3;
}
a:visited {
color: #414383;
color: #5E00A0;
}
.navbar {
@@ -76,9 +97,8 @@ a:visited {
margin-top: 0px;
z-index: 20;
box-shadow: 0px 1px 20px rgba(0, 0, 0, 0.15);
background: #CFD8EF;
background: #202331;
color: #616383;
}
.navbar-sep {
@@ -96,13 +116,23 @@ a:visited {
}
th {
background: #4DA6BD;
font-size: 10pt;
padding-left: 10px;
padding-right: 15px;
}
body {
background: linear-gradient(to top, #eef2ff, #eaf1ff) repeat scroll;
input, textarea {
color: whitesmoke;
background: #2d2d2d;
border-color: #4D28CA;
border-radius: 3px;
}
html {
color: #ededed;
background: black;
height: 100%;
font-family: arial,helvetica,sans-serif;
font-size: 10pt;
margin: 0 4px;
@@ -118,7 +148,6 @@ body {
.frontend {
margin-top: 0px;
background: #e0f0f0;
display: inline-block;
}
@@ -127,21 +156,59 @@ body {
margin-bottom: 10px;
}
.post, .post_body {
.post {
display: inline;
margin-bottom: 5px;
}
.post_body > p {
margin: 2px;
}
.tripcode {
color: #de04ef;
}
@keyframes psych
{
0% {background-color: red; color: blue; }
10% {background-color: yellow; color: red; }
20% {background-color: blue; color: green; }
30% {background-color: green; color: yellow; }
40% {background-color: red; color: blue; }
50% {background-color: yellow; color: green; }
60% {background-color: blue; color: yellow; }
70% {background-color: green; color: blue; }
80% {background-color: red; color: green; }
90% {background-color: yellow; color: red; }
95% {background-color: blue; color: yellow; }
100% {background-color: green; color: white; }
}
.psy {
animation: psych 2s linear infinite;
display: inline-block;
}
.memearrows {
color: green;
color: #29D029;
}
.redtext {
color: #d50505;
font-weight: bold;
}
.spoiler {
display: inline-block;
}
.spoiler > p {
background: black;
color: black;
}
.spoiler:hover > p {
background: black;
color: white;
}
.intro {
@@ -160,23 +227,97 @@ body {
max-height: 200px;
}
pre > p {
margin: 0px 0px;
}
.reply , .post_body > pre , .ukko_thread_header {
.reply, .ukko_thread_header , pre {
padding: 7px 7px;
border-radius: 5px;
box-shadow: 1px 1px 3px black;
}
.post_body > pre {
background: #3f3f3f;
color: #d17600;
.post_body > p {
margin: 0px 0px;
}
.post_body {
display: inline;
}
.post {
display: inline-block;
width: 80%;
}
#postform_attachment {
max-width: 330px;
}
#faq > div {
margin-left: 20%;
width: 50%;
padding: 10px;
}
}
#captcha_img {
background: #4DA6BD;
}
figure {
float: left;
margin: 1ex;
}
figure img {
max-width:256px;
max-height:128px;
max-width:100%;
}
fieldset {
overflow: auto;
border-radius: 5px 0px 5px 0px;
}
fieldset > img {
float: right;
}
.thread {
float: left;
width: 90%;
padding-left: 10px;
margin-top: 10px;
margin-bottom: 10px;
background-color: #252525;
}
.replybar {
float: left;
position: fixed;
top: 2ex;
right: 0;
width: 34%
}
@media (max-width: 100ex) {
.replybar, .thread {
width: 100%;
position: static;
}
}
.hide-reply:checked ~ div {
width: 100%;
position: static;
}
textarea#reply-text {
width: 100%;
resize: vertical;
}
.hide-reply {
float: right;
position: fixed;
top: 0;
right: 0;
}
hr {
padding-bottom: 20px;
}

BIN
contrib/static/tor.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

View File

@@ -0,0 +1,3 @@
/*
put your custom stylesheet here
*/

View File

@@ -14,7 +14,10 @@
<html>
<head>
<meta charset="utf-8" />
<link rel="stylesheet" href="{{board.Prefix}}static/site.css"></link>
<meta name="viewport" content="initial-scale=1" />
<link rel="stylesheet" href="{{board.Prefix}}static/site.css" />
<link rel="stylesheet" href="{{board.Prefix}}static/user.css" />
<script type="text/javascript" src="{{board.Prefix}}static/nntpchan.js"></script>
<title>{{board.Board}}</title>
</head>
<body>
@@ -38,8 +41,6 @@
<br />
{{/Truncate.Replies}}
</div>
<br/>
<hr/>
{{/board.Threads}}
</div>
</body>

View File

@@ -0,0 +1,49 @@
{{!
boardlist.mustache -- full list of every board
template parameters:
- graph ( a list of 4 string tuples: (board, posts_per_hour, posts_per_day, total_posts) )
- frontend ( the name of the frontend )
- prefix ( the site's prefix )
}}
<html>
<head>
<link rel="stylesheet" href="{{prefix}}static/site.css"></link>
<link rel="stylesheet" href="{{prefix}}static/user.css"></link>
<title> {{frontend}} board list </title>
</head>
<body>
<center>
<div class="index-outer">
<div class="index-inner">
<table id="board_graph">
<tbody>
<tr>
<th> Board </th>
<th> Post per Hour </th>
<th> Post per Day </th>
<th> Total </th>
</tr>
{{# graph}}
<tr>
<td>
<a href="{{prefix}}{{Board}}-0.html">{{Board}}</a>
</td>
<td>
{{Hour}}
</td>
<td>
{{Day}}
</td>
<td>
{{All}}
</td>
</tr>
{{/ graph}}
</tbody>
</table>
</div>
</div>
</center>
</body>
</html>

View File

@@ -1,7 +1,9 @@
{{!
frontpage.mustache -- template for index.html
template parameters:
- graph ( a list of 4 string tuples: (board, posts_per_hour, posts_per_day, total_posts) )
- boardgraph ( a boardPageRows instance, see srnd/model.go )
- postgraph ( a postsGraph instance , see srnd/model.go )
- overview ( an overviewModel instance, see srnd/model.go )
- totalposts ( the number of total posts we have ever seen )
- frontend ( the name of the frontend )
- prefix ( the site's prefix )
@@ -9,7 +11,8 @@
<html>
<head>
<link rel="stylesheet" href="{{prefix}}static/site.css"></link>
<link rel="stylesheet" href="{{prefix}}static/site.css" />
<link rel="stylesheet" href="{{prefix}}static/user.css" />
<title> {{frontend}} on nntpchan </title>
</head>
<body>
@@ -19,39 +22,54 @@
<h1> {{frontend}} on nntpchan </h1>
<h2>View the <a href="ukko.html">overboard</a></h2>
<h3>Read the <a href="{{prefix}}static/faq.html">FAQ</a></h3>
<h3>Join the <a href="https://i2p.rocks/irc/?channels=overchan&nick=nameless">IRC</a></h3>
<h3>Join the IRC on <a href="https://qchat.rizon.net/?channels=#nntpchan">rizon</a> or <a href="irc://127.0.0.1:6668/overchan">irc2p</a></h3>
<h3>Lurk on <a href="irc://allyour4nert7pkh.onion/overchan">URC</a></h3>
<h3>Check out the <a href="{{prefix}}boards.html">board list</a></h3>
<h3>Fork on github: <a href="https://github.com/majestrate/nntpchan/">frontend</a> and <a href="https://github.com/majestrate/srndv2/">core</a></h3>
<h4>We've Had {{totalposts}} Posts Since August 01 2015 </h4>
</div>
<div class="index-inner">
<table id="board_graph">
<table>
<tbody>
<tr>
<th> Board </th>
<th> Post per Hour </th>
<th> Post per Day </th>
<th> Total </th>
</tr>
{{# graph}}
<tr>
<td>
<a href="{{prefix}}{{Board}}-0.html">{{Board}}</a>
<td class="posts_td">
{{{postsgraph.Render}}}
</td>
<td>
{{Hour}}
</td>
<td>
{{Day}}
</td>
<td>
{{All}}
<td class="board_td">
{{! todo: move boardgraph into its own file like postsgraph }}
<table id="board_graph">
<tbody>
<tr>
<th> Board </th>
<th> Posts this Hour </th>
<th> Posts Today </th>
<th> Total </th>
</tr>
{{# boardgraph}}
<tr>
<td>
<a href="{{prefix}}{{Board}}-0.html">{{Board}}</a>
</td>
<td>
{{Hour}}
</td>
<td>
{{Day}}
</td>
<td>
{{All}}
</td>
</tr>
{{/ boardgraph}}
</tbody>
</table>
</td>
</tr>
{{/ graph}}
</tbody>
</table>
{{{overview.Render}}}
</div>
</div>
</center>
</body>
</html>
</html>

View File

@@ -0,0 +1,36 @@
{{!
graph_history.mustache
template parameters:
- history ( a list of PostEntry instances, see srnd/model.go )
}}
<html>
<head>
<meta charset="utf-8"></meta>
<link rel="stylesheet" href="{{prefix}}static/site.css" />
<link rel="stylesheet" href="{{prefix}}static/user.css" />
<title> Post History</title>
</head>
<body>
<td>
<table id="history_graph">
<thead>
<tr>
<th>Month</th>
<th>Posts</th>
<th></th>
</tr>
</thead>
<tbody>
{{#history.Scale}}
<tr>
<td>{{Date}}</td>
<td class="history_num">{{Num}}</td>
<td>{{OvercockGraph}}</td>
</tr>
{{/history.Scale}}
</tbody>
</table>
</td>
</body>
</html>

View File

@@ -9,7 +9,8 @@
<html>
<head>
<meta charset="utf-8"></meta>
<link rel="stylesheet" href="{{prefix}}static/site.css"></link>
<link rel="stylesheet" href="{{prefix}}static/site.css" />
<link rel="stylesheet" href="{{prefix}}static/user.css" />
<title> here is a new tripcode </title>
</head>
<body>
@@ -17,4 +18,4 @@
<div id="secret_key">secret: {{secret}}</div><div id="public_key">public: {{public}}</div><div>tripcode: <span class="tripcode" id="capcode_key">{{{tripcode}}}</span></div>
</pre>
</body>
</html>
</html>

View File

@@ -1,6 +1,7 @@
<html>
<head>
<link ref="stylesheet" href="{{prefix}}static/site.css"></link>
<link rel="stylesheet" href="{{prefix}}static/site.css" />
<link rel="stylesheet" href="{{prefix}}static/user.css" />
<title>login</title>
</head>
<body>

View File

@@ -4,11 +4,12 @@
- prefix ( the site prefix )
- mod_prefix ( the prefix to the mod panel, could be something like https://mod.site.tld/ or /mod/ )
- message ( the message returned from the login attempt )
- fail ( present if the login failed )
- fail ( present if the login failed ) // not yet added
}}
<html>
<head>
<link ref="stylesheet" href="{{prefix}}static/site.css"></link>
<link rel="stylesheet" href="{{prefix}}static/site.css" />
<link rel="stylesheet" href="{{prefix}}static/user.css" />
<meta http-equiv="refresh" content="1; {{mod_prefix}}"></meta>
<title>login</title>
</head>

View File

@@ -6,7 +6,8 @@
}}
<html>
<head>
<link rel="stylesheet" href="{{prefix}}static/site.css"></link>
<link rel="stylesheet" href="{{prefix}}static/site.css" />
<link rel="stylesheet" href="{{prefix}}static/user.css" />
<!-- yes it uses js -->
<script type="text/javascript" src="{{prefix}}static/mod.js"></script>
<title> nntpchan mod page </title>
@@ -25,6 +26,56 @@
<button onclick="nntpchan_unban()">unban (ip)</button>
</div>
</div>
<hr />
<div>
<div> key actions </div>
<div>
<label for="nntpchan_board_target">pubkey:</label>
<input type="text" id="nntpchan_key_target" />
</div>
<div>
<button onclick="nntpchan_key_add()">add key</button>
<button onclick="nntpchan_key_del()">remove key</button>
</div>
</div>
<hr />
<div>
<div> board actions </div>
<div>
<label for="nntpchan_board_target">board name:</label>
<input type="text" id="nntpchan_board_target" />
</div>
<div>
<button onclick="nntpchan_admin_board('frontend.add')">add board</button>
</div>
<div>
<button onclick="nntpchan_admin_board('frontend.regen')">regenerate</button>
</div>
<div>
<button onclick="nntpchan_admin_board('frontend.ban')">ban</button>
<button onclick="nntpchan_admin_board('frontend.unban')">unban</button>
</div>
<div>
<button onclick="nntpchan_admin_board('frontend.nuke')">nuke</button>
</div>
</div>
<hr />
<div>
<div>
lightweight actions
</div>
<div>
<button onclick="nntpchan_admin('template.reload')">reload all templates</button>
</div>
</div>
<hr />
<div>
<label>very load heavy actions, use with care</label>
<div>
<button onclick="nntpchan_admin('frontend.regen')">regenerate all pages</button>
<button onclick="nntpchan_admin('thumbnail.regen')">regenerate all thumbnails</button>
</div>
</div>
<div id="nntpchan_mod_result"></div>
<noscript>
<b>enable js to use the mod panel kthx</b>

View File

@@ -0,0 +1,56 @@
<html>
<head>
<title>create new board</title>
<link rel="stylesheet" href="{{prefix}}static/site.css" />
<link rel="stylesheet" href="{{prefix}}static/user.css" />
<script type="text/javascript" src="{{prefix}}static/newboard.js">
</script>
</head>
<body>
<p>make your first post</p>
<hr />
<form action="{{prefix}}post/" enctype="multipart/form-data" name="post" method="post" id="postform" >
<div id="postform-outer">
<div id="postform-inner">
<table class="postform">
<tbody>
<tr>
<th>
Board Name
</th>
<td>
<input type="text" name="name" value="" id="boardname" />
<button onclick="createBoard()">Create Board</button>
</td>
</tr>
<tr>
<th>
Comment
</th>
<td>
<textarea id="postform_message" name="message" cols=40 rows=5></textarea>
</td>
</tr>
<tr>
<th>
Captcha
</th>
<td>
<img id="captcha_img" src="{{prefix}}captcha/img" alt="captcha" />
</td>
</tr>
<tr>
<th>
Solution
</th>
<td>
<input type="text" name="captcha" />
</td>
</tr>
</tbody>
</table>
</div>
</div>
</form>
</body>
</html>

View File

@@ -0,0 +1,25 @@
{{! overview.mustache
paramters:
- overview (list of PostModels in order of last posted)
}}
<table id="overview_graph">
<thead>
<tr>
<th>Newsgroup</th>
<th>Posted</th>
<th>Subject</th>
</tr>
</thead>
<tbody>
{{#overview}}
<tr>
<td><a href="{{Prefix}}{{Board}}-0.html">{{Board}}</td>
<td>{{Date}}</td>
<td><a href="{{PostURL}}">{{Truncate.Subject}}</a></td>
</tr>
{{/overview}}
</tbody>
</table>

View File

@@ -1,43 +1,26 @@
<div class="{{{CSSClass}}}" id="post_{{PostHash}}">
<p class="intro">
<label for="delete_{{PostHash}}">
<span class="frontend">
[[ {{Frontend}} ]]
</span>
<span class="subject">
{{Subject}}
</span>
<span class="name">
{{#Sage}}
<a href="mailto:sage">
{{Name}}
</a>
{{/Sage}}
{{^Sage}}
{{Name}}
{{/Sage}}
</span>
<span class="postdate">
{{Date}}
</span>
</label>
<a href="{{PostURL}}" onclick="">No. {{ShortHash}}</a>
{{#OP}}
<a href="{{PostURL}}">[reply]</a>
{{/OP}}
<span class="tripcode">{{{Pubkey}}}</span>
</p>
<div class="files">
{{#Attachments}}
<div class="file">
<p class="file_info">
<span>File: {{Filename}}</span>
</p>
<a target="_blank" class="file-link" href="{{Source}}" title="{{Filename}}">
<img class="file-thumbnail" src="{{Thumbnail}}" alt="{{Filename}}" />
</a>
</div>
{{/Attachments}}
</div>
<div class="post_body">{{{RenderBody}}}</div>
</div>
<fieldset>
{{#IsI2P}}
<img src="{{Prefix}}static/i2p.png" title="post from i2p" />
{{/IsI2P}}
{{#IsTor}}
<img src="{{Prefix}}static/tor.png" title="post from tor" />
{{/IsTor}}
{{#IsClearnet}}
<img src="{{Prefix}}static/clearnet.png" title="post from clearnet" />
{{/IsClearnet}}
<legend>
<span class="subject">{{Subject}}</span> <span class="name">{{Name}}</span> {{Date}}
No. <a onclick="nntpchan_backlink('{{ShortHash}}');" title="{{MessageID}}">{{ShortHash}}</a>
<a href="{{PostURL}}">[reply]</a> <span class="tripcode">{{{Pubkey}}}</span><br />
</legend>
{{#Attachments}}
<figure>
<figcaption>
<a target="_blank" href="{{Source}}" title="{{Filename}}"><img src="{{Thumbnail}}" alt="{{Filename}}" /></a>
</figcaption>
</figure>
{{/Attachments}}
<label class="post_body">
{{{RenderBody}}}
</label>
</fieldset>

View File

@@ -1,4 +1,7 @@
<html>
<meta charset="utf-8" />
<link rel="stylesheet" href="{{prefix}}static/site.css" />
<link rel="stylesheet" href="{{prefix}}static/user.css" />
<meta http-equiv="refresh" content="1; {{redirect_url}}" />
<body>
<p>post failed: {{reason}}</p>

View File

@@ -0,0 +1,48 @@
<html>
<head>
<title> try again </title>
<meta charset="utf-8" />
<link rel="stylesheet" href="{{prefix}}static/site.css" />
<link rel="stylesheet" href="{{prefix}}static/user.css" />
</head>
<body>
<form enctype="multipart/form-data" name="post" method="post">
{{#attachment}}
<input type="hidden" name="attachment_data" value="{{attachment}}" />
<input type="hidden" name="attachment_filename" value="{{attachment_filename}}" />
<input type="hidden" name="attachment_mime" value="{{attachment_type}}" />
{{/attachment}}
<input type="hidden" name="reference" value="{{reference}}" />
<input type="hidden" name="name" value="{{name}}" />
<input type="hidden" name="subject" value="{{subject}}" />
<input type="hidden" name="captcha_id" value="{{captcha_id}}" />
<input type="hidden" name="message" value="{{message}}" />
<div id="postform-outer">
<div id="postform-inner">
<div>{{fail_message}}</div>
<table class="postform">
<tbody>
<tr>
<th>
Captcha
</th>
<td>
<img id="captcha_img" src="{{prefix}}captcha/{{captcha_id}}.png" alt="captcha" />
</td>
</tr>
<tr>
<th>
Solution
</th>
<td>
<input type="text" name="captcha" />
<input type="submit" value="Post" class="button" />
</td>
</tr>
</tbody>
</table>
</div>
</div>
</form>
</body>
</html>

View File

@@ -5,6 +5,9 @@
- message_id ( the value of the Message-ID header in the post we made, the truncated sha1 of this is the >>posthash )
}}
<html>
<meta charset="utf-8" />
<link rel="stylesheet" href="{{prefix}}static/site.css" />
<link rel="stylesheet" href="{{prefix}}static/user.css" />
<meta http-equiv="refresh" content="2; {{redirect_url}}" />
<body>
<pre>posted as {{message_id}}</pre>

View File

@@ -34,7 +34,7 @@
Comment
</th>
<td>
<textarea type="text" name="message" cols=40 rows=5></textarea>
<textarea id="postform_message" name="message" cols=40 rows=5></textarea>
</td>
</tr>
<tr>
@@ -42,7 +42,15 @@
File
</th>
<td>
<input type="file" name="attachment" />
<input id="postform_attachment" type="file" name="attachment" />
</td>
</tr>
<tr>
<th>
Get Dubs
</th>
<td>
<input type="checkbox" name="dubs" />
</td>
</tr>
<tr>
@@ -66,4 +74,4 @@
</div>
</div>
</form>

View File

@@ -1,33 +0,0 @@
<div class="thread_reply" id="post_{{PostHash}}">
<p class="intro">
<label for="delete_{{PostHash}}">
<span class="subject">
{{Subject}}
</span>
<span class="name">
{{#Sage}}
<a href="mailto:sage">
{{Name}}
</a>
{{/Sage}}
{{^Sage}}
{{Name}}
{{/Sage}}
</span>
<time
</label>
<a href="{{PostURL}}" onclick="">
No. {{PostHash}}
</a>
</p>
<div class="files">
{{#Image}}
<a class="file" href="{{Source}}">
<img class="file-thumbnail" src="{{Thumbnail}}" />
</a>
{{/Image}}
</div>
<div class="thread_reply_body">
{{{RenderBody}}}
</div>
</div>

View File

@@ -0,0 +1,25 @@
{{!
posts graph.mustache -- post frequence graph
parameters:
* graph - a postsGraph instance (see srnd/model.go)
}}
<table id="posts_graph">
<thead>
<tr>
<th>Day</th>
<th>Posts</th>
<th></th>
</tr>
</thead>
<tbody>
{{#graph.Scale}}
<tr>
<td>{{Day}}</td>
<td>{{Num}}</td>
<td>{{OvercockGraph}}</td>
</tr>
{{/graph.Scale}}
</tbody>
</table>

View File

@@ -14,7 +14,10 @@
<html>
<head>
<meta charset="utf-8" />
<link rel="stylesheet" href="{{thread.Prefix}}static/site.css"></link>
<meta name="viewport" content="initial-scale=1" />
<link rel="stylesheet" href="{{thread.Prefix}}static/site.css" />
<link rel="stylesheet" href="{{thread.Prefix}}static/user.css" />
<script type="text/javascript" src="{{thread.Prefix}}static/nntpchan.js"></script>
<title> {{thread.OP.Subject}} </title>
</head>
<body>
@@ -38,6 +41,5 @@
{{/ thread.Replies}}
</div>
<br/>
<hr/>
</body>
</html>

View File

@@ -8,27 +8,27 @@
<head>
<title> ukko / overboard </title>
<meta charset="utf-8" />
<link rel="stylesheet" href="{{prefix}}static/site.css"></link>
</head>
<link rel="stylesheet" href="{{prefix}}static/site.css" />
<link rel="stylesheet" href="{{prefix}}static/user.css" />
<script type="text/javascript" src="{{prefix}}static/nntpchan.js"></script>
</head>
<body>
<div id="ukko-topbar">
<a href="{{prefix}}">Front Page</a>
</div>
<div id="ukko_threads" class="threads_container">
<div id="ukko_threads">
{{#threads}}
<!--
<div class="ukko_thread_header">
<p> Posted on <a href="{{{BoardURL}}}"><span class="ukko_boardname">{{OP.Board}}</span></a></p>
</div>
-->
<div class="thread" id="thread_{{OP.PostHash}}">
<div clsss="thread_header">
</div>
{{{OP.RenderPost}}}
{{{OP.Truncate.RenderPost}}}
{{#Truncate.Replies}}
{{{Truncate.RenderPost}}}
<br />
{{/Truncate.Replies}}
</div>
<hr/>
{{/threads}}
</div>
</body>

View File

@@ -0,0 +1,148 @@
#!/usr/bin/env python3.4
import requests
from bs4 import BeautifulSoup as BS
import datetime
import io
import nntplib
import time
import urllib.parse
class Article:
"""
an nntp article
"""
timeFormat = '%a, %d %b %Y %H:%M:%S +0000'
def __init__(self, j, board, site):
"""
construct article
:param j: json object
"""
self.j = j
self.board = board
self.site = site
self.messageID = self.genMessageID(j['no'])
self.attachments = list()
def formatDate(self):
return datetime.datetime.utcfromtimestamp(self.j['time']).strftime(self.timeFormat)
def message(self):
m = ''
# for each line
for p in BS(self.j['com']).find_all('p'):
# clean it
m += p.text
m += '\n'
if len(m.rstrip('\n')) > 0:
return m
def subject(self):
if 'subject' in self.j:
return self.j['subject']
def name(self):
return self.j['name']
def group(self):
return 'overchan.archive.{}.{}'.format(self.site, self.board)
def genMessageID(self, no):
return '<{}.{}@{}>'.format(self.board, no, self.site)
def header(self):
hdr = ("Subject: {}\n"+\
"From: {} <archiver@srndv2.tools>\n"+\
"Date: {}\n"+\
"Newsgroups: {}\n"+\
"Message-ID: {}\n"+\
"Path: {}\n").format(self.subject(), self.name(), self.formatDate(), self.group(), self.messageID, self.site)
if self.j['resto'] > 0:
hdr += "References: {}\n".format(self.genMessageID(self.j['resto']))
return hdr
def bodyPlain(self):
msg = self.message()
if msg:
return "{}\n{}".format(self.header(), msg)
def bodyMultipart(self):
pass
def body(self):
if len(self.attachments) > 0:
return self.bodyMultipart()
else:
return self.bodyPlain()
class Poster:
def __init__(self, host, port):
self.host, self.port = host, port
def post(self, articles):
"""
post 1 or more articles
"""
if isinstance(articles, Article):
return self.post([articles])
else:
n = nntplib.NNTP(self.host, self.port)
for article in articles:
body = article.body()
if body:
print("posting {}".format(article.messageID))
try:
body = io.BytesIO(body.encode('utf-8'))
n.ihave(article.messageID, body)
except Exception as e:
print('failed: {}'.format(e))
n.quit()
def url_parse(url):
return urllib.parse.urlparse(url)
class Getter:
def __init__(self, url):
self.url = url
self.site = url_parse(url).hostname
self.board = url_parse(url).path.split('/')[1]
def get(self):
"""
yield a bunch of articles
"""
r = requests.get(self.url)
if r.status_code == 200:
try:
j = r.json()
except:
pass
else:
for t in j['threads']:
posts = t['posts']
for post in posts:
yield Article(post, self.board, self.site)
def main():
import argparse
ap = argparse.ArgumentParser()
ap.add_argument('--server', type=str, required=True)
ap.add_argument('--port', type=int, required=True)
ap.add_argument('--board', type=str, required=True)
args = ap.parse_args()
poster = Poster(args.server, args.port)
for n in range(10):
getter = Getter('https://8ch.net/{}/{}.json'.format(args.board, n))
poster.post(getter.get())
if __name__ == "__main__":
main()

10
contrib/tools/keys/keys.sh Executable file
View File

@@ -0,0 +1,10 @@
#!/bin/bash
#
# script to make sql file for inserting all "currently trusted" keys
#
root=$(readlink -e $(dirname $0))
touch $root/keys.sql
for key in $(cat $root/keys.txt) ; do
echo "insert into modprivs(pubkey, newsgroup, permission) values('$key', 'overchan', 'all');" >> keys.sql ;
done

View File

@@ -0,0 +1,10 @@
insert into modprivs(pubkey, newsgroup, permission) values('039a876792db66966241e63140e7df79df488033360064b67d890635814e925e', 'overchan', 'all');
insert into modprivs(pubkey, newsgroup, permission) values('286650cac49fc540507a2b6593fa7aba7c5101e4314b6e5cfee1e64810a85bb7', 'overchan', 'all');
insert into modprivs(pubkey, newsgroup, permission) values('c85aed0939fa1677bf9f354d8ac3dc9b1132cabea22b152247fa59cfc3d42d4f', 'overchan', 'all');
insert into modprivs(pubkey, newsgroup, permission) values('fcd5fdffdb742a696a6d4df3a06d5c180aa523f2900b13fe893556832a1171f4', 'overchan', 'all');
insert into modprivs(pubkey, newsgroup, permission) values('7227245429c46262baabfc3ce8e27b584b22262ad5c074bac4f05e0c7e2d9106', 'overchan', 'all');
insert into modprivs(pubkey, newsgroup, permission) values('0c701740b6f6e799fb08354150265e19553535d2bd168f55067134d4a61449ac', 'overchan', 'all');
insert into modprivs(pubkey, newsgroup, permission) values('ce39e0ea3c056e02e086063296c12fd36b8bf9530ab694bc645b48684004f946', 'overchan', 'all');
insert into modprivs(pubkey, newsgroup, permission) values('d03da6ab445729f5f38f478fbefc5226bb1d58393a3b5a6852ec89c3ababc314', 'overchan', 'all');
insert into modprivs(pubkey, newsgroup, permission) values('ce39e0ea3c056e02e086063296c12fd36b8bf9530ab694bc645b48684004f946', 'overchan', 'all');
insert into modprivs(pubkey, newsgroup, permission) values('6440e2e383a802f2d487c71d2018b9dc53529e5d234e668c156aec97dae8fe6b', 'overchan', 'all');

View File

@@ -0,0 +1,10 @@
039a876792db66966241e63140e7df79df488033360064b67d890635814e925e
286650cac49fc540507a2b6593fa7aba7c5101e4314b6e5cfee1e64810a85bb7
c85aed0939fa1677bf9f354d8ac3dc9b1132cabea22b152247fa59cfc3d42d4f
fcd5fdffdb742a696a6d4df3a06d5c180aa523f2900b13fe893556832a1171f4
7227245429c46262baabfc3ce8e27b584b22262ad5c074bac4f05e0c7e2d9106
0c701740b6f6e799fb08354150265e19553535d2bd168f55067134d4a61449ac
ce39e0ea3c056e02e086063296c12fd36b8bf9530ab694bc645b48684004f946
d03da6ab445729f5f38f478fbefc5226bb1d58393a3b5a6852ec89c3ababc314
ce39e0ea3c056e02e086063296c12fd36b8bf9530ab694bc645b48684004f946
6440e2e383a802f2d487c71d2018b9dc53529e5d234e668c156aec97dae8fe6b

View File

@@ -1,23 +0,0 @@
#!/usr/bin/env bash
#
# shell script for regenerating thumbnails
#
if [ "$1" == "" ] ; then
echo "usage: $0 webroot_dir"
else
cd $1
echo "regenerate missing thumbs in $(pwd)"
find img/ \
-type f \
-regextype posix-extended \
-iregex '.*\.(png|jpg|gif)$' \
-not -execdir test -f '../thm/{}' \; \
-exec echo 'generating missing thumb for {}' \; \
-exec mogrify \
-define jpeg:size=500x500 \
-thumbnail '250>x250>' \
-path thm/ \
-strip \
'{}' \;
fi

View File

@@ -4,53 +4,25 @@
## requirements ##
* linux or freebsd
* go 1.4 or higher
* go 1.3 or higher
* libsodium 1.0 or higher
* imagemagick
* RabbitMQ
* ffmpegthumbnailer
* sox
## debian ##
Debian Jessie has go 1.3, we need 1.4 or higher to build the nntpchan daemon so let's do that first, assumes 64bit linux:
#
# --->> DO NOT RUN AS ROOT <<---
# (you probably will break stuff really bad if you do)
#
Get the dependancies
# make directory for go's packages
mkdir -p $HOME/go
# set up a directory for our go distribution
mkdir -p $HOME/local
cd $HOME/local
# obtain and unpack go binary distribution
wget https://storage.googleapis.com/golang/go1.4.2.linux-amd64.tar.gz -O go-stable.tar.gz
tar -xzvf go-stable.tar.gz
# set up environmental variables for go
export GOROOT=$HOME/local/go
export GOPATH=$HOME/go
export PATH=$GOROOT/bin:$GOPATH/bin:$PATH
# put environmental variables in bash_alises for later
echo 'export GOROOT=$HOME/local/go' >> $HOME/.bash_aliases
echo 'export GOPATH=$HOME/go' >> $HOME/.bash_aliases
echo 'export PATH=$GOROOT/bin:$GOPATH/bin:$PATH' >> $HOME/.bash_aliases
sudo apt-get update
sudo apt-get --no-install-recommends install imagemagick libsodium-dev ffmpegthumbnailer sox build-essential git golang ca-certificates
We'll also need to install some dependancies that come with debian:
Check out the repo and build it
# as root
apt update
apt install imagemagick libsodium-dev
Now build the daemon:
go get github.com/majestrate/srndv2
go install github.com/majestrate/srndv2
It will create an executable at $GOPATH/bin/srndv2 which is already in our $PATH so it can be run by typing ``srndv2``
git clone https://github.com/majestrate/nntpchan
cd nntpchan
./build.sh
Now configure the database. [next](database.md)

9
doc/configuration.md Normal file
View File

@@ -0,0 +1,9 @@
# Configuration #
In nntpchan's stack there are currently 2 configuration files.
All config files are auto generated with sane defaults if the files are not present.
[feeds.ini](feeds.md) is for all your nntp outfeeds
[srnd.ini](srnd.md) is for the core daemon

View File

@@ -1,9 +1,8 @@
Postgres on Debian:
Postgres on Debian (as root)
# install
apt-get install postgresql postgresql-client
# install as root
apt-get install --no-install-recommends postgresql postgresql-client
Setting up postgres (as root)
@@ -11,13 +10,19 @@ Setting up postgres (as root)
# become postgres user
su postgres
# spawn postgres admin shell
psql
psql
You'll get a prompt, enter the following:
CREATE ROLE srnduser WITH LOGIN PASSWORD 'srndpassword';
CREATE DATABASE srnd WITH ENCODING 'UTF8' OWNER srnduser;
CREATE ROLE srnd WITH LOGIN PASSWORD 'srnd';
CREATE DATABASE srnd WITH ENCODING 'UTF8' OWNER srnd;
\q
Change the username and password as desired.
For demo purposes we'll use these credentials.
These are default values, please change them later.
## important
these credentials assume you are going to run using a user called `srnd`, if your username you plan to run the daemon as is different please change `srnd` to your username.
Now run it, [next](running.md)

135
doc/feeds.md Normal file
View File

@@ -0,0 +1,135 @@
# feeds.ini #
## Peering ##
In order to actually be distributed, you need another person to sync posts with, otherwise what's the point right?
Right now peering information is private, there is no link level authentication (yet) so everything is done via either a vpn tunnel or a tor hidden service.
### Peering over tor ###
Install tor
apt-get install tor
Make a tor hidden service point from outside port 119 to port 1199
Add to /etc/tor/torrc:
HiddenServiceDir /var/lib/tor/nntp_feed
HiddenServicePort 119 127.0.0.1:1199
restart/reload tor then
cat /var/lib/tor/nntp_feed/hostname
This is your in feed address
Then to peer with someone over tor add this to you feeds.ini
[feed-ourpeer.onion]
host=PeersOnionAddress.onion
port=119
proxy-type=socks4a
proxy-host=127.0.0.1
proxy-port=9050
[ourpeer.onion]
overchan=1
ctl=1
### Peering over cjdns ###
Set up cjdns, read more [here](https://github.com/cjdelisle/cjdns/blob/master/doc/configure.md#connection-interfaces)
git clone https://github.com/cjdelisle/cjdns
cd cjdns && ./do
./cjdroute --genconf >> cjdroute.conf
./cjdroute < cjdroute.conf
Get your ipv6 address for cjdns
ip addr show tun0
Edit srnd.ini to bind nntp on that ipv6 address, make sure to use the square braces `[` and `]`
[nntp]
...
bind=[xxxx:xxxx:xxxx:xxx:xx....]:1199
Say you have 2 friends at fc33:3:3::aadd and fc03:9f:123::a3df.
Add to feeds.ini the following:
[feed-bob]
host=[fc33:3:3::aadd]
port=1199
proxy-type=none
[bob]
overchan=1
ctl=1
[feed-charlie]
host=[fc03:9f:123::a3df]
port=1199
proxy-type=none
[charlie]
overchan=1
ctl=1
## Options ##
#### You need one connection and one settings block for each connection ####
Here is an example entry in feeds.ini
[feed-them.onion]
host=aabbccddeeff2233.onion
port=119
proxy-type=socks4a
proxy-host=127.0.0.1
proxy-port=9050
[them.onion]
overchan=1
ano.paste=0
ctl=1
But what does it mean?
[feed-them.onion]
Connection settings for a peer
host=aabbccddeeff2233.onion
port=119
proxy-type=socks4a
proxy-host=127.0.0.1
proxy-port=9050
Proxy settings, straight forward. Supported proxy types are `socks4a` and `none`
[them.onion]
nntp synchronization settings
overchan=1
Sync all boards, use
overchan.bad=0
to prevent certain boards from syncing with certain peers. It can be used to keep bad boards out or keep exclusive boards in
ano.paste=0
This WILL be the nntpchan pastebin, but it's not implimented yet
ctl=1
Allows you to recieve moderation notifications from other boards, it's also used for decentralized moderation

View File

@@ -1,52 +0,0 @@
## peering with other nodes ##
In order to actually be distributed, you need another person to sync posts with, otherwise what's the point right?
Right now peering information is private, there is no link level authenticatio (yet) so everything is done via either a vpn tunnel or a tor hidden service.
### Peering via cjdns vpn tunnel ###
Set up cjdns, read more [here](https://github.com/cjdelisle/cjdns/blob/master/doc/configure.md#connection-interfaces)
git clone https://github.com/cjdelisle/cjdns
cd cjdns && ./do
./cjdroute --genconf >> cjdroute.conf
./cjdroute < cjdroute.conf
Get your ipv6 address for cjdns
ip addr show tun0
Edit srnd.ini to bind nntp on that ipv6 address, make sure to use the square brances `[` and `]`
[nntp]
...
bind=[xxxx:xxxx:xxxx:xxx:xx....]:1199
say you have 2 friends at fc33:3:3::aadd and fc03:9f:123::a3df. right now feeds.ini can't take raw ipv6 addresses so add them to `/etc/hosts`
# add these lines to /etc/hosts
fc33:3:3::aadd bob
fc03:9f:123::a3df charlie
then add to feeds.ini the following:
[feed-bob]
proxy-type=none
[bob]
overchan.*=1
ctl=1
[feed-charlie]
proxy-type=none
[charlie]
overchan.*=1
ctl=1
then restart srndv2
**TODO:** firewalling

335
doc/protocol.md Normal file
View File

@@ -0,0 +1,335 @@
Overchan is a newsgroup meant to be served on web frontends in an effort to create a decentralized imageboard. Moderation takes place on each frontend itself. Message and image transport is using MIME multipart messages and Base64 as encoding for Images. All messages need to be valid NNTP messages, the transport of messages need to follow NNTP specifications. It is possible to use an existing NNTP daemon like INN or to implement the NNTP sync part as well.
# Sync Protocol (NNTP)
## Article Format
### Monopart
Message without images can be sent without delimiting the message.
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
From: anonymous <foo@bar.ano>
Date: Thu, 02 May 2013 12:16:44 +0000
Message-ID: <pmc8xpmgyf2@foo.bar>
Newsgroups: overchan.test
Subject: none
References: <referenced message-id>
Path: hschan.ano
X-Sage: optional
some visible message text
### Multipart
This is necessary for posting files.
Mime-Version: 1.0
Content-Type: multipart/mixed; boundary="abcdEFGH-1234"
From: anonymous <foo@bar.ano>
Date: Thu, 02 May 2013 12:16:44 +0000
Message-ID: <pmc8xpmgyf2@foo.bar>
Newsgroups: overchan.test
Subject: none
References: <referenced message-id>
Path: hschan.ano
X-Sage: optional
This is a multi-part message in MIME format.
--abcdEFGH-1234
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
some visible message text
--abcdEFGH-1234
Content-Type: image/jpeg; name="RosenFessel_LM_030-lg.jpg"
Content-Transfer-Encoding: base64
Content-Disposition: attachment; filename="RosenFessel_LM_030-lg.jpg"
/9j/4AAQSkZJRgABAQAAAQABAAD//gA8Q1JFQVRPUjogZ2QtanBlZyB2MS4wICh1c2luZyBJ
SkcgSlBFRyB2NjIpLCBxdWFsaXR5ID0gMTAwCv/bAEMAAQEBAQEBAQEBAQEBAQEBAQEBAQEB
[..]
e3ykVkO1lOwlSMkfvDngbSOmRuqaDQo2Kqi5yUwfKPXkk8kAjIA5B4wPUVi8TKblJ1Oy969r
ea8+nXc6I4WnFLROMVZRai1L4bK+vdfM/9k=
--abcdEFGH-1234-
Content-Type boundary="$IDENTIFIER"
Where ``$identifier`` should be a rather long random string (at least 0-9, a-z, A-Z, - are allowed). The ``$identifier`` should not occur in the message text itself, so it usually begins with multiple - characters because these will never occur in base64. The content type ``multipart/mixed`` allows to have different parts inside a message body. The first part would be the actual message, the second part could be a Base64 encoded picture. See also: MIME
In ~~2013~~ 2015 we can send UTF-8 messages, although this is not part of the old testament.
### Date
It is recommend to use ``UTC (+0000)`` as timezone for new messages. If a received message is not already in UTC, the date may be converted to UTC for display purposes.
### Message-ID: (see RFC 3977)
"A message-id MUST begin with "<", end with ">", and MUST NOT contain the latter except at the end."
"A message-id MUST be between 3 and 250 octets in length."
"A message-id MUST NOT contain octets other than printable US-ASCII characters."
a possible valid message-id could be in the format <{random}{timestamp}@${frontend}> where:
${random} == a random 10 char ascii value
${timestamp} == the current unix_timestamp
${frontend} == web.hschan.ano
Which would result in ``jbUdn73KxN1369733675@web.hschan.ano`` This format makes it easier to block massive spam/inapropiate content based on the frontend and a timespan.
### References
If reference is not given or empty, the message is considered an original (root) post.
### X-Sage
If ``X-Sage`` is given, the message shall not bump the corresponding thread.
## Transport Format
NNTP requires line endings with ``\r\n``
### Sending
if a line in the message body starts with `.` in needs another `.` prepended. the last line must be a single `.\r\n`
### Receiving:
If a line in the message body starts with `.` but is not `.\r\n` the `.` needs to be removed.
# Frontend
## Postnumbers
The first ten characters of a sha1sum of field message-id. The probability for a unique post number (at time of generation) on a board with a maximum of 30k messages is:
(1-(1/16^10))^30000 = 0.99999997271515937221
In case of several message forgers exhaust obscure post numbers, it will become much more likely for a quote to be 'shadowed'.
There was a hash collision on October 13 2015, the post hash has been bumped from 10 to 18 bytes.
### Quotes
Quotes reference postnumbers and work across all boards on overchan. The comment field may contain serveral lines such as:
\>>postnumber
to quote someone.
Valid quotes match this regex: `>+ ?[0-9a-f]+`
#### Optional
* Resolve quotes to corresponding articles and append them to references - this will aid newsreaders.
* Parse message IDs as quotes
## Implementations
Because of the decentralized nature of Overchan, many different entry points to using the service can exist. In the following we discuss different implementations all serving from the newsgroup 'overchan'.
### negromancy.ano
negromancy.ano uses `breaking-news`, a web frontend compiler for imageboards, pastebins, etc.
`breaking-news` consists of an Happstack application and a daemon that will generate static html from NNTP files. It depends on InterNetNews (INN) and a load balancer that can distinguish between POST and GET, preferably nginx. Furthermore it relies on imagemagick (mogrify) for generation of thumbnails. Hchloride are bindings to libsodium in haskell that breaking-news uses for singing messages.
It utilizes blaze-html for fast Html templating and happstack-lite for serving POST requests.
You can visit http://boards.negromancy.ano/
for browsing the imageboard.
#### GET request
nginx will serve a static html from dir.
#### POST request
nginx will reverse to the happstack web application which generates and sends a NNTP message to a local INN daemon. INNd will place the new article in dir and feed it to its configured peers. Pictures are encoded in base64 or base91a. Root posting will not work without attaching an image.
#### Generation of Html
The daemon will poll for new articles in dir. If new files are found, it generates 10 main pages ranging from 0.html to 9.html and a html each for any altered threads. For each new article the corresponding thread, starting with the original post, will be bumped to the first page (0.html). For new posts, corresponding pictures are created and 'thumbnailed' through mogrify.
### overchan.sfor.ano
overchan.sfor.ano uses SRNd, a complete NNTP server implemented in Python.
It provides a plugin interface (among other hook possibilities) which loads plug-in overchan and postman. Plug-in overchan is notified about new messages in `overchan.*` and creates static HTML files. Plug-in postman receives new messages via HTTP POST request and adds those messages to SRNd where they are send to configured outfeeds. It depends on a reverse proxy like nginx which delivers generated HTML files and proxies POST requests back to postman.
You can visit http://overchan.sfor.ano
for browsing the imageboard and ``git clone git://git.sfor.ano/SRNd.git`` for source.
#### GET request
nginx will serve a static html or image from dir.
#### POST request
nginx will proxy to postman which generates and delivers a NNTP message to SRNd which then will notify overchan plugin about the new message and also deliver it to its configured NNTP peers (which can run SRNd or another NNTPd software like INN). Pictures are encoded in base64.
#### Generation of Html
Plugin overchan is notified by SRNd about new articles and (re)generates `thread-$id.html` and its parent board with up to 10 root posts for each site. For each new article without `X-sage` header the corresponding thread will be bumped to the first page. For new posts, corresponding pictures are created and thumbnailed.
### NNTP News reader applications
Through the use of the standard MIME format, news reader applications like Mozilla Thunderbird can also read and post directly to the chan newsserver. Each chan will appear as a root post, while additional posts will appear as replies directly to the root post.
News readers have some features the chan software may not have: multiple attachments, non-image attachments, subject, posts referencing non-root posts, HTML text.
Open question: how should this be handled by the chan software for viewing?
# Extensions
## Control suggestion
A control suggestion is a single message containing lines with commands, message-ID and extra information separated by spaces.
### Commands
sticky: sticky this thread
delete-x-all: delete all attachments from this article
delete: delete the whole article
### Format
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
From: anonymous <foo@bar.ano>
Date: Thu, 02 May 2013 12:16:44 +0000
Message-ID: <h2cykk1lwlmuqao2qiy@foo.bar>
Newsgroups: ctl
Subject: none
Path: censorship.fleet
X-Sage: optional
delete-x-all <message-ID>
delete <message-ID>
delete <message-ID>
Messages to control are separated by at least one line break.
### Examples
Delete all attachments from message with ID ``message-ID``
delete-x-all <message-ID>
Please sticky thread with OP ``message-ID`` till UNIX timestamp ``1380000000``
sticky <message-ID> unix_timestamp 1380000000
### Convention
We send control suggestions to newsgroup ``ctl``. Full deletion of a root post results in removal of corresponding thread.
### Signatures
As users give their secret key to the frontend they expect every form field to be verified on all ends. This includes the comment field and headers. In the following we suggest a protocol to sign optional headers.
We sign a SHA512 hash of the message body using primitive Ed25519 as defined by SUPERCOP and libsodium. Therefore this system does not inherit any collision resilience from Ed25519, a hash collision is a signature collision.
Signing M vs. Signing H(M)
method space time
S(M) O(n) O(n)
S(H(M)) O(1) O(n)
S: Sign
H: Hash
M: Message
Input for block based hashing algorithms like SHA-512 can be streamed, only keeping a fixed blocked size in memory instead of all blocks. In case of SHA-512 these message blocks are 1024 bit and the hash to sign 512 bit. Optimized ``S(H(M))`` implementations require a constant amount memory as opposed to a linear requirement in ``S(M)``.
### Format for signing messages (RFC 822)
Outer headers start with ``Content-Type: message/rfc822`` when there are signed headers or at least an attachment,
which requires ``Content-Type: multipart/mixed`` to be signed as well as an inner header.
Otherwise you can use ``Content-Type: text/plain``, in which case you just sign the body.
Outer headers include ``X-pubkey-ed25519`` and ``X-signature-ed25519-sha512``, inner headers need verification.
``X-pubkey-ed25519`` is 64 characters long, 32 byte public key in base 16: ``Base16(PK)``
``X-signature-ed25519-sha512`` is 128 characters long, 64 byte signature in base 16: ``Base16(S(SK,H(M)))``
The signed message equals body of the outer message. It begins at first inner header (in this example ``Content-Type: text/plain``) and includes the inner body. Lines are separated by ``<CRLF>``.
Please include a ``Content-Type`` header in the inner message as suggested by RFC822.
Symbol Function
Base16 function that will take an arbitrary amount of octets and encode them to Base 16 with character set "0123456789abcdef"
SK 64 bytes secret key
PK 32 bytes public key, can be generated from signSeedKeypair(take32(SK))
M message body
H function that will hash an arbitrary amount of octets using SHA-512, returning 64 bytes
S(SK,M) function that will sign an arbitrary amount of octets M using Ed25519 with secret key SK, returning only the first 64 bytes
take32 function that takes any amount of binary data and returns the first 32 bytes
#### Example
Content-Type: message/rfc822; charset=UTF-8
Content-Transfer-Encoding: 8bit
From: anonymous <foo@bar.ano>
Date: Thu, 02 May 2013 12:16:44 +0000
Message-ID: <h2cykk1lwlmuqao2qiy@foo.bar>
Newsgroups: ctl
Subject: none
Path: censorship.fleet
X-pubkey-ed25519: 37c16fa40c2bade813b53b65107a064d02becfa5635acf3241003a61cb137ea3
X-signature-ed25519-sha512: a850ccd788d71ed19de8dfa061b9f1f4f506810a01ed1391433e893a3e6305b4944168760d97f2517bcfe786aef1ccfc34fb7bb1b77531 82aebf2bdd0303150f
Content-Type: text/plain; charset=UTF-8
Date: Thu, 02 May 2013 12:16:44 +0000
delete-x-all <message-ID>
delete <message-ID>
delete <message-ID
In this example header Date needs verification, too.
The following part is signed:
Content-Type: text/plain; charset=UTF-8
Date: Thu, 02 May 2013 12:16:44 +0000
delete-x-all <message-ID>
delete <message-ID>
delete <message-ID
Above example in octets:
Content-Type: text/plain; charset=UTF-8\\r\\nDate: Thu, 02 May 2013 12:16:44 +0000\\r\\n\\r\\ndelete-x-all <message-ID>\\r\\ndelete <message-ID>\\r\\n\\r\\ndelete <message-ID>
# Glossary
## chan specific
### root post
original post
### OP
original post
### thread
a collection of messages starting with the original post followed by messages referencing it ordered by date
### bump
newest post will be shown first with corresponding thread
### sticky
thread is temporarily 'bumped' by the frontend and sticks there regardless of newer posts

39
doc/running.md Normal file
View File

@@ -0,0 +1,39 @@
## Running
After you have [built the daemon](build.md) and [configured the database](database.md) you can run the daemon.
check out the nntpchan repo and build the daemon if you already haven't
git clone https://github.com/majestrate/nntpchan
cd nntpchan
./build.sh
set up the daemon:
./srndv2 setup
generate admin keys, don't loose them.
./srndv2 tool keygen
add yourself as admin by adding your ``public key`` to the ``frontend`` section of ``srnd.ini``
...
[frontend]
enable=1
admin_key=yourpublickeygoeshere
... # leave the rest of the config values alone for now
run it:
./srndv2 run
Now open the browser up to http://127.0.0.1:18000/
To access the mod panel go to the [mod panel](http://127.0.0.1:18000/mod/) and use your ``private key`` to log in
Now read about [peering](feeds.md)

3
doc/srnd.md Normal file
View File

@@ -0,0 +1,3 @@
# srnd.ini
todo: document this file