Archived
1
0
Conflicts:
	build-js.sh
	build.sh
This commit is contained in:
Jan Verbeek 2016-10-08 14:29:46 +02:00
commit 9e9a1efe06
41 changed files with 2271 additions and 167 deletions

1
.gitignore vendored
View File

@ -35,6 +35,7 @@ vendor
# generated js
contrib/static/nntpchan.js
contrib/static/js/nntpchan.js
contrib/static/miner-js.js
#docs trash

View File

@ -3,11 +3,11 @@ NNTPChan
**NNTPChan** (previously known as overchan) is a decentralized imageboard that uses the [NNTP protocol](https://en.wikipedia.org/wiki/Network_News_Transfer_Protocol) (network-news transfer protocol) 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 on [GitHub](https://github.com/majestrate/srndv2) (for now) along with general documentation, [here](doc/)
This repository contains resources used by the core daemon which is located on [GitHub](https://github.com/majestrate/srndv2) (for now) along with general documentation, [here](doc/).
##Getting started
[This](doc) is a step-by-step guide for getting up-and-running with NNTPChan as well as documentation for developers wwho want to either work on NNTPChan directly or use NNTPChan in their aplications with the API.
[This](doc) is a step-by-step guide for getting up-and-running with NNTPChan as well as documentation for developers who want to either work on NNTPChan directly or use NNTPChan in their aplications with the API.
##Bugs and issues
@ -27,6 +27,15 @@ Tor node list:
2. [chan](http://ev7fnjzjdbtu3miq.onion/)
3. [oniichan](http://sfw.oniichanylo2tsi4.onion/)
##Clients
NNTP (confirmed working):
* Thunderbird
Web:
* [Yukko](https://github.com/faissaloo/Yukko): ncurses based nntpchan web ui reader
##Support

View File

@ -15,22 +15,11 @@ if [ ! -f "$GOPATH/bin/minify" ]; then
echo "set up minifiy"
go get -v github.com/tdewolff/minify/cmd/minify
fi
if [ ! -f "$GOPATH/bin/gopherjs" ]; then
echo "set up gopherjs"
go get -v -u github.com/gopherjs/gopherjs
fi
# build cuckoo miner
echo "Building cuckoo miner"
go get -v -u github.com/ZiRo-/cuckgo/miner_js
"$GOPATH/bin/gopherjs" -m -v build github.com/ZiRo-/cuckgo/miner_js
mv ./miner_js.js ./contrib/static/miner-js.js
rm ./miner_js.js.map
outfile=$PWD/contrib/static/nntpchan.js
lint() {
if [ "x$(which jslint)" == "x" ] ; then
if [ "$(which jslint)" == "" ] ; then
# no jslint
true
else
@ -42,8 +31,9 @@ lint() {
mini() {
echo "minify $1"
echo "" >> $2
echo "/* local file: $1 */" >> $2
echo "/* begin $1 */" >> $2
"$GOPATH/bin/minify" --mime=text/javascript >> $2 < $1
echo "/* end $1 */" >> $2
}
# do linting too
@ -54,7 +44,19 @@ if [ "x$1" == "xlint" ] ; then
done
fi
echo -e "//For source code and license information please check https://github.com/majestrate/nntpchan \n" > $outfile
rm -f "$outfile"
echo '/*' >> $outfile
echo ' * For source code and license information please check https://github.com/majestrate/nntpchan' >> $outfile
brandingfile=./contrib/branding.txt
if [ -e "$brandingfile" ] ; then
echo ' *' >> $outfile
while read line; do
echo -n ' * ' >> $outfile;
echo $line >> $outfile;
done < $brandingfile;
fi
echo ' */' >> $outfile
if [ -e ./contrib/js/contrib/*.js ] ; then
for f in ./contrib/js/contrib/*.js ; do
@ -62,10 +64,16 @@ if [ -e ./contrib/js/contrib/*.js ] ; then
done
fi
mini ./contrib/js/main.js_ "$outfile"
mini ./contrib/js/entry.js "$outfile"
# local js
for f in ./contrib/js/*.js ; do
for f in ./contrib/js/nntpchan/*.js ; do
mini "$f" "$outfile"
done
# vendor js
for f in ./contrib/js/vendor/*.js ; do
mini "$f" "$outfile"
done
echo "ok"

View File

@ -1,7 +1,7 @@
#!/usr/bin/env bash
root=$(readlink -e "$(dirname "$0")")
set -e
if [ "x" == "x$root" ] ; then
if [ "" == "$root" ] ; then
root=$PWD/${0##*}
fi
cd "$root"
@ -24,9 +24,13 @@ rev="QmPAqM7anxdr1ngPmJz9J9AAxDLinDz2Eh9aAzLF9T7LNa"
ipfs="no"
rebuildjs="yes"
_next=""
unstable="no"
# check for build flags
for arg in "$@" ; do
case $arg in
"--unstable")
unstable="yes"
;;
"--no-js")
rebuildjs="no"
;;
@ -52,13 +56,13 @@ for arg in "$@" ; do
esac
done
if [ "x$rev" == "x" ] ; then
if [ "$rev" == "" ] ; then
echo "revision not specified"
exit 1
fi
cd "$root"
if [ "x$rebuildjs" == "xyes" ] ; then
if [ "$rebuildjs" == "yes" ] ; then
echo "rebuilding generated js..."
./build-js.sh
fi
@ -66,7 +70,7 @@ unset GOPATH
export GOPATH=$PWD/go
mkdir -p "$GOPATH"
if [ "x$ipfs" == "xyes" ] ; then
if [ "$ipfs" == "yes" ] ; then
if [ ! -e "$GOPATH/bin/gx" ] ; then
echo "obtaining gx"
go get -u -v github.com/whyrusleeping/gx
@ -83,10 +87,17 @@ if [ "x$ipfs" == "xyes" ] ; then
go get -d -v
go build -v .
mv nntpchan srndv2
echo -e "Built\n"
echo "Now configure NNTPChan with ./srndv2 setup"
else
go get -u -v github.com/majestrate/srndv2
cp "$GOPATH/bin/srndv2" "$root"
if [ "$unstable" == "yes" ] ; then
go get -u -v github.com/majestrate/srndv2/cmd/nntpchan
cp "$GOPATH/bin/nntpchan" "$root"
echo "built unstable, if you don't know what to do, run without --unstable"
else
go get -u -v github.com/majestrate/srndv2
cp "$GOPATH/bin/srndv2" "$root"
echo -e "Built\n"
echo "Now configure NNTPChan with ./srndv2 setup"
fi
fi
echo -e "Built\n"
echo "Now configure NNTPChan with ./srndv2 setup"

View File

@ -0,0 +1,89 @@
<?php
function gennntp($headers, $files) {
if (count($files) == 0) {
}
else if (count($files) == 1 && $files[0]['type'] == 'text/plain') {
$content = $files[0]['text'] . "\r\n";
$headers['Content-Type'] = "text/plain; charset=UTF-8";
}
else {
$boundary = sha1($headers['Message-Id']);
$content = "";
$headers['Content-Type'] = "multipart/mixed; boundary=$boundary";
foreach ($files as $file) {
$content .= "--$boundary\r\n";
if (isset($file['name'])) {
$file['name'] = preg_replace('/[\r\n\0"]/', '', $file['name']);
$content .= "Content-Disposition: form-data; filename=\"$file[name]\"; name=\"attachment\"\r\n";
}
$type = explode('/', $file['type'])[0];
if ($type == 'text') {
$file['type'] .= '; charset=UTF-8';
}
$content .= "Content-Type: $file[type]\r\n";
if ($type != 'text' && $type != 'message') {
$file['text'] = base64_encode($file['text']);
$content .= "Content-Transfer-Encoding: base64\r\n";
}
$content .= "\r\n";
$content .= $file['text'];
$content .= "\r\n";
}
$content .= "--$boundary--\r\n";
}
//$headers['Content-Length'] = strlen($content);
$headers['Mime-Version'] = '1.0';
$headers['Date'] = date('r', $headers['Date']);
$out = "";
foreach ($headers as $id => $val) {
$val = str_replace("\n", "\n\t", $val);
$out .= "$id: $val\r\n";
}
$out .= "\r\n";
$out .= $content;
return $out;
}
function shoveitup($msg, $id) {
$s = fsockopen("tcp://localhost:1119");
fgets($s);
fputs($s, "MODE STREAM\r\n");
fgets($s);
fputs($s, "TAKETHIS $id\r\n");
fputs($s, $msg);
fputs($s, "\r\n.\r\n");
fgets($s);
fclose($s);
}
$time = time();
echo "\n@@@@ Thread:\n";
echo $m0 = gennntp(["From" => "czaks <marcin@6irc.net>", "Message-Id" => "<1234.0000.".$time."@example.vichan.net>", "Newsgroups" => "overchan.test", "Date" => time(), "Subject" => "None"],
[['type' => 'text/plain', 'text' => "THIS IS A NEW TEST THREAD"]]);
echo "\n@@@@ Single msg:\n";
echo $m1 = gennntp(["From" => "czaks <marcin@6irc.net>", "Message-Id" => "<1234.1234.".$time."@example.vichan.net>", "Newsgroups" => "overchan.test", "Date" => time(), "Subject" => "None", "References" => "<1234.0000.".$time."@example.vichan.net>"],
[['type' => 'text/plain', 'text' => "hello world, with no image :("]]);
echo "\n@@@@ Single msg and pseudoimage:\n";
echo $m2 = gennntp(["From" => "czaks <marcin@6irc.net>", "Message-Id" => "<1234.2137.".$time."@example.vichan.net>", "Newsgroups" => "overchan.test", "Date" => time(), "Subject" => "None", "References" => "<1234.0000.".$time."@example.vichan.net>"],
[['type' => 'text/plain', 'text' => "hello world, now with an image!"],
['type' => 'image/gif', 'text' => base64_decode("R0lGODlhAQABAIAAAAUEBAAAACwAAAAAAQABAAACAkQBADs="), 'name' => "urgif.gif"]]);
echo "\n@@@@ Single msg and two pseudoimages:\n";
echo $m3 = gennntp(["From" => "czaks <marcin@6irc.net>", "Message-Id" => "<1234.1488.".$time."@example.vichan.net>", "Newsgroups" => "overchan.test", "Date" => time(), "Subject" => "None", "References" => "<1234.0000.".$time."@example.vichan.net>"],
[['type' => 'text/plain', 'text' => "hello world, now WITH TWO IMAGES!!!"],
['type' => 'image/gif', 'text' => base64_decode("R0lGODlhAQABAIAAAAUEBAAAACwAAAAAAQABAAACAkQBADs="), 'name' => "urgif.gif"],
['type' => 'image/gif', 'text' => base64_decode("R0lGODlhAQABAIAAAAUEBAAAACwAAAAAAQABAAACAkQBADs="), 'name' => "urgif2.gif"]]);
shoveitup($m0, "<1234.0000.".$time."@example.vichan.net>");
sleep(1);
shoveitup($m1, "<1234.1234.".$time."@example.vichan.net>");
sleep(1);
shoveitup($m2, "<1234.2137.".$time."@example.vichan.net>");
shoveitup($m3, "<1234.2131.".$time."@example.vichan.net>");

View File

@ -0,0 +1 @@
3rd party javascript

View File

@ -1,4 +1,4 @@
var banner_count = 3;
var banner_count = 5;
// inject a banner into an element
function nntpchan_inject_banners(elem, prefix) {

View File

@ -0,0 +1,206 @@
/** hidepost.js -- hides posts from page given $things */
function get_hidden_posts() {
var st = get_storage();
var prefix = "nntpchan_hide_post_";
return {
all : function() {
var msgids = [];
for ( var k in st) {
if (k.indexOf(prefix) == 0) {
var m = k.substring(prefix.length);
msgids.push(m);
}
}
return msgids;
},
add : function (msg) {
st[prefix+msg] = "post";
},
del : function (msg) {
st.removeItem(prefix+msg);
}
}
}
// is a post elem an OP?
function postIsOP(elem) {
var ds = elem.dataset;
return ds && ds.rootmsgid == ds.msgid ;
}
function _hide_elem(elem, fade) {
if(!fade) {
if (elem.style) {
elem.style.display = "none";
} else {
elem.style = {display: "none" };
}
elem.dataset.userhide = "yes";
} else {
$(elem).fadeOut(400, function() {
_hide_elem(elem);
});
}
}
function _unhide_elem(elem) {
$(elem).fadeIn();
elem.dataset.userhide = "no";
}
// return true if element is hidden
function _elemIsHidden(elem) {
return elem.dataset && elem.dataset.userhide == "yes";
}
// hide a post
function hidepost(elem, nofade) {
console.log("hidepost("+elem.dataset.msgid+")");
var posts = get_hidden_posts();
if (posts) {
// add to persitant hide
posts.add(elem.dataset.msgidhash);
}
if(postIsOP(elem)) {
// hide thread it's an OP
var thread = document.getElementById("thread_"+elem.dataset.rootmsgidhash);
if (thread) {
var e = thread.getElementsByClassName("post");
for ( var idx = 0; idx < e.length ; idx ++ ) {
if (e[idx].dataset.msgid == elem.dataset.msgid) continue; // don't apply
hidepost(e[idx]);
}
}
}
// hide attachments and post body
var es = elem.getElementsByClassName("attachments");
for (var idx = 0; idx < es.length ; idx ++ ) {
_hide_elem(es[idx], !nofade);
}
es = elem.getElementsByClassName("post_body");
for (var idx = 0; idx < es.length ; idx ++ ) {
_hide_elem(es[idx], !nofade);
}
es = elem.getElementsByClassName("postheader");
for (var idx = 0; idx < es.length ; idx ++ ) {
_hide_elem(es[idx], !nofade);
}
elem.dataset.userhide = "yes";
elem.setHideLabel("[show]");
}
// unhide a post
function unhidepost(elem) {
console.log("unhidepost("+elem.dataset.msgid+")");
var posts = get_hidden_posts();
if (posts) {
// remove from persiting hide
posts.del(elem.dataset.msgidhash);
}
if(postIsOP(elem)) {
var thread = document.getElementById("thread_"+elem.dataset.rootmsgidhash);
if(thread) {
var e = thread.getElementsByClassName("post");
for ( var idx = 0; idx < e.length ; idx ++ ) {
if(e[idx].dataset.msgid == elem.dataset.msgid) continue;
unhidepost(e[idx]);
}
}
}
// unhide attachments and post body
var es = elem.getElementsByClassName("attachments");
for (var idx = 0; idx < es.length ; idx ++ ) {
_unhide_elem(es[idx]);
}
es = elem.getElementsByClassName("post_body");
for (var idx = 0; idx < es.length ; idx ++ ) {
_unhide_elem(es[idx]);
}
es = elem.getElementsByClassName("postheader");
for (var idx = 0; idx < es.length ; idx ++ ) {
_unhide_elem(es[idx]);
}
elem.dataset.userhide = "no";
elem.setHideLabel("[hide]");
}
// hide a post given a callback that checks each post
function hideposts(check_func) {
var es = document.getElementsByClassName("post");
for ( var idx = 0; idx < es.length ; idx ++ ) {
var elem = es[idx];
if(check_func && elem && check_func(elem)) {
hidepost(elem);
}
}
}
// unhide all posts given callback
// if callback is null unhide all
function unhideall(check_func) {
var es = document.getElementsByClassName("post");
for (var idx=0 ; idx < es.length; idx ++ ) {
var elem = es[idx];
if(!check_func) { unhide(elem); }
else if(check_func(elem)) { unhide(elem); }
}
}
// inject posthide into page
onready(function() {
var posts = document.getElementsByClassName("post");
for (var idx = 0 ; idx < posts.length; idx++ ) {
console.log("inject hide: "+posts[idx].dataset.msgid);
var inject = function (elem) {
var hider = document.createElement("a");
hider.setAttribute("class", "hider");
elem.setHideLabel = function (txt) {
var e_hider = hider;
e_hider.innerHTML = txt;
}
elem.hidepost = function() {
var e_self = elem;
var e_hider = hider;
hidepost(e_self);
}
elem.unhidepost = function() {
var e_self = elem;
var e_hider = hider;
unhidepost(e_self);
}
elem.isHiding = function() {
var e_self = elem;
return _elemIsHidden(e_self);
}
hider.appendChild(document.createTextNode("[hide]"));
hider.onclick = function() {
var e_self = elem;
if(e_self.isHiding()) {
e_self.unhidepost();
} else {
e_self.hidepost();
}
}
elem.appendChild(hider);
};
inject(posts[idx]);
}
// apply persiting hidden posts
var posts = get_hidden_posts();
if(posts) {
var all = posts.all();
for ( var idx = 0 ; idx < all.length; idx ++ ) {
var id = all[idx];
var elem = document.getElementById(id);
if(elem)
hidepost(elem, true);
}
}
});

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1 @@
main nntpchan javascript files

View File

@ -352,6 +352,8 @@ function inject_hover_for_element(elem) {
}
function init(prefix) {
// because no one cares about this feature :|
return;
// inject posthover ...
inject_hover_for_element(document);
if ( /\.html$/.test(document.location.pathname) && ! (/ukko/.test(document.location.pathname)) ) {

View File

@ -2,6 +2,7 @@ var easiness = 55.0;
var miner_threads = 4;
var randoffs = 64;
/*
onready(function(){
document.getElementById("start_miner").onclick = function() {
var btn = document.getElementById("start_miner");
@ -61,3 +62,5 @@ onready(function(){
function miner_cb(s) {
document.getElementById("miner_result").value = s;
}
*/

View File

@ -0,0 +1,2 @@
this directory holds unused javascript files for nntpchan
don't delete files move them here

2
contrib/js/readme.md Normal file
View File

@ -0,0 +1,2 @@
javascript files for nntpchan

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.8 KiB

After

Width:  |  Height:  |  Size: 45 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 66 KiB

After

Width:  |  Height:  |  Size: 59 KiB

BIN
contrib/static/banner_3.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 62 KiB

BIN
contrib/static/banner_4.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

View File

@ -2,15 +2,14 @@
bloodgod theme css override
*/
/**
bloodgod theme css override
*/
body {
color: #666;
background: #111;
}
.post_body > pre {
color: #666;
}
input, textarea, button, input[type="text"], input[type="password"],
input[type="checkbox"], input[type="file"], input[type="submit"],
@ -25,7 +24,7 @@ input[type="button"] {
color: black;
}
#captcha_img, pre {
#captcha_img {
background: #D80000;
}
@ -110,4 +109,4 @@ table thead th {
.origin > img , .not_found > img {
-webkit-filter: invert(1);
filter: invert(1);
}
}

View File

@ -16,6 +16,23 @@ body {
background: #FBFFC9;
}
.navbar, table, thead, th, table, pre {
#postform_container {
background-color: rgba(0,0,0,0);
}
.post:target {
background-color: #ffda9b;
box-shadow: 0px 0px 5px 1px;
}
img#nntpchan_banner {
box-shadow: 0px 0px 10px 0px #FFECBE;
}
#postform_inner {
box-shadow: 0px 1px 5px 1px;
}
.navbar, table, thead, th, table, pre, .op {
background: #FFECBE;
}

249
contrib/static/livechan.css Normal file
View File

@ -0,0 +1,249 @@
input {
-moz-border-radius: 0px;
-webkit-border-radius: 0px;
border-radius: 0px;
}
.livechan_captcha_input {
color: black;
}
textarea, select {
-moz-border-radius: 0px;
-webkit-border-radius: 0px;
border-radius: 0px;
}
.livechan_chat_input {
padding: 0;
margin: 0;
position: fixed;
width: 100%;
bottom: 0;
left: 0;
right: 0;
background: #d6daf0;
}
.livechan_chat_input_name, .livechan_chat_input_convo {
padding: 0;
padding-left: none;
margin: 0;
width: 80%;
color: black;
}
.livechan_chat_input_left {
width: 19%;
}
.livechan_chat_input_message_div {
padding:0;
margin:0;
position: absolute;
width: 70%;
left: 20%;
top: 3px;
bottom: 0;
}
.livechan_chat_input_message {
padding: 0;
margin: 0;
border:none;
height: 100%;
width: 100%;
resize: none;
}
.livechan_chat_input_submit {
position: absolute;
width: 8%;
top: 3px;
right: 1px;
bottom: 0;
border: none;
color: black;
}
.livechan_chat_output {
position: fixed;
top: 20px;
left: 0;
right: 0;
bottom: 60px;
overflow: auto;
width: 89%;
-webkit-overflow-scrolling: touch;
}
.livechan_chat_output_chat {
max-height: 200px;
overflow: hidden;
}
.livechan_chat_output_date {
margin: 0 4px;
}
.livechan_chat_output_count:hover {
cursor: pointer;
}
.livechan_chat_capcode {
margin: 0 4px;
font-style: italic;
font-weight: lighter;
}
.livechan_image_thumb {
max-width: 300px;
max-height: 200px;
float: left;
margin: 10px;
}
.livechan_captcha {
left: 0px;
top: 0px;
bottom: 0px;
right: 0px;
position: fixed;
opacity: 0.9;
}
.livechan_captcha_inner {
padding: 200px;
}
.livechan_captcha_image {
}
.livechan_captcha_input {
float: down;
}
.livechan_spoiler {
color: black;
background: black;
}
.livechan_chat_output_chat {
background: #d6daf0;
}
.livechan_spoiler:hover {
color: white;
}
.livechan_convo_label {
padding: 5px;
}
.livechan_convobar_root {
position: fixed;
top: 20px;
right: 0;
width: 10%;
}
.livechan_convobar_item {
padding: 5px;
margin: 5px;
background: #d6daf0;
}
.livechan_navbar {
z-index: 3;
position: fixed;
top: 0;
width: 100%;
height: 20px;
}
.livechan_navbar_mod_indicator_inactive, .livechan_navbar_mod_indicator_active, .livechan_navbar_status, .livechan_navbar_channel_label {
padding-left: 10px;
padding-right: 10px;
background: #d6daf0;
}
.hover {
position: relative;
padding: 1px;
left: -1000px
border: 1px dashed black;
visibility: hidden;
}
.hover > img {
position: fixed;
top: 0%;
right: 0;
max-width: 75%;
max-height: 75%;
visibility: visible;
}
.livechan_captcha, .livechan_convobar_root, #chat {
background: #EEF2FF;
}
.livechan_chat_output_chat {
font-family: monospace;
margin: 4px;
padding: 4px;
}
.livechan_chat_output_name {
font-weight: bold;
color: green;
}
.livechan_chat_output_count:hover {
color: red;
}
.livechan_greentext {
color: #789922;
}
.livechan_boldtext {
font-weight: bold;
}
.livechan_internallink , a {
color: blue;
}
.livechan_internallink:hover , a {
color: red;
cursor: pointer;
}
.livechan_chat_selected {
background: blue;
}
.livechan_navbar_mod_indicator_active {
background: #4a4ad4;
color: #34d434;
}
.livechan_navbar_mod_indicator_admin {
background: #4a4ad4;
color: red;
}
.livechan_navbar_mod_indicator_inactive {
color: #aaaaaa;
background: #EEF2FF;
}
.livechan_redtext {
color: #af0a0f;
font-weight: bold;
}

View File

@ -89,17 +89,22 @@ textarea {
max-height: 2.4em;
}
.post_body > pre {
font-size: 10pt;
font-weight: unset;
}
pre {
white-space: pre-wrap;
align: center;
font-size: 13pt;
background: #98E;
font-size: 12pt;
color: black;
display: inline-block;
overflow-wrap: break-word;
word-wrap: break-word;
font-weight: bold;
padding: 20px 20px 20px 20px;
font-family: sans;
margin-left: auto;
margin-right: auto;
@ -318,26 +323,46 @@ input, textarea {
.frontend {
margin-top: 0px;
display: inline-block;
margin-right: 5px;
}
.op , .reply {
float: left;
clear: both;
}
.op {
margin-top: 5px;
margin-bottom: 1px;
float: left;
clear: both;
}
.post:target {
background-color: #A99AFF;
}
.postreply {
float: right;
}
.post {
max-width: 75%;
margin-bottom: 5px;
background-color: #D6DAF0;
border: 1px solid #B7C5D9;
border-left: none;
border-top: none;
display: table;
padding: 2px;
margin: 2px;
display: inline-block;
float: left;
clear: both;
min-width: 500px;
}
.postheader {
width: 100%;
padding-top: 3px;
padding-right: 5px
}
@ -435,10 +460,6 @@ input, textarea {
padding-bottom: 0px;
}
.post {
display: inline-block;
}
.pagelist {
display: inline-block;
overflow: hidden;
@ -545,8 +566,20 @@ textarea#reply-text {
}
.thread {
padding-left: 10%;
padding-left: 10px;
padding-top: 10px;
padding-bottom: 10px;
width: 80%;
}
}
.hider {
float: right;
}
@keyframes rotate {
0% { transform:rotate(0deg); }
25% { transform:rotate(-1deg); }
50% { transform:rotate(0deg); }
75% { transform:rotate(1deg); }
}

View File

@ -9,6 +9,12 @@ body
padding-right: 4px;
}
.post_body > pre {
color: #DADADA;
text-align: left;
}
main,
aside,
section
@ -336,6 +342,12 @@ textarea
margin-bottom: 1px;
float: left;
clear: both;
background-color: #0f0f0f;
border-color: #242424;
}
pre {
background-color: #0f0f0f;
}
.post
@ -621,4 +633,17 @@ hr
{
border: 1px solid #535353;
height: 1px
}
}
img#nntpchan_banner {
box-shadow: 0px 0px 10px 0px;
}
#postform_container {
background-color: rgba(0, 0, 0, 0);
}
.post:target {
background-color: #2c2d3e;
box-shadow: 0px 0px 10px 2px;
}

View File

@ -16,66 +16,64 @@
<script src="{{prefix}}static/nntpchan.js" type="text/javascript"></script>
<title> {{frontend}} on nntpchan </title>
</head>
<body onload="main()">
<body>
{{{navbar}}}
<center>
<div class="index-outer">
<div class="index-inner">
<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 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 id="nntpchan_banner">
</div>
<div class="index-inner">
<table>
<tbody>
<tr>
<td class="posts_td">
{{{postsgraph}}}
</td>
<td class="board_td">
{{! todo: move boardgraph into its own file like postsgraph }}
<table id="board_graph">
<thead>
<tr>
<th> {{#i18n.Translations}}{{board_label}}{{/i18n.Translations}} </th>
<th> {{#i18n.Translations}}{{posts_hour}}{{/i18n.Translations}} </th>
<th> {{#i18n.Translations}}{{posts_today}}{{/i18n.Translations}} </th>
<th> {{#i18n.Translations}}{{total}}{{/i18n.Translations}} </th>
</tr>
</thead>
<tbody>
{{# boardgraph}}
<div class="index-outer">
<div id="nntpchan_banner">
</div>
<div class="index-inner">
<div>{{frontend}} on nntpchan</div>
<div>View the <a href="{{prefix}}ukko.html">overboard</a></div>
<div>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></div>
<div>Check out the <a href="{{prefix}}boards.html">board list</a></div>
<div>Fork on github: <a href="https://github.com/majestrate/nntpchan/">frontend</a> and <a href="https://github.com/majestrate/srndv2/">core</a></div>
<div>We've Had {{totalposts}} Posts Since August 01 2015 </div>
</div>
<div class="index-inner">
<table>
<tbody>
<tr>
<td class="posts_td">
{{{postsgraph}}}
</td>
<td class="board_td">
{{! todo: move boardgraph into its own file like postsgraph }}
<table id="board_graph">
<thead>
<tr>
<td>
<a href="{{prefix}}{{Board}}-0.html">{{Board}}</a>
</td>
<td>
{{Hour}}
</td>
<td>
{{Day}}
</td>
<td>
{{All}}
</td>
<th> {{#i18n.Translations}}{{board_label}}{{/i18n.Translations}} </th>
<th> {{#i18n.Translations}}{{posts_hour}}{{/i18n.Translations}} </th>
<th> {{#i18n.Translations}}{{posts_today}}{{/i18n.Translations}} </th>
<th> {{#i18n.Translations}}{{total}}{{/i18n.Translations}} </th>
</tr>
{{/ boardgraph}}
</tbody>
</table>
</td>
</tr>
</tbody>
</table>
{{{overview}}}
</thead>
<tbody>
{{# 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>
</tbody>
</table>
{{{overview}}}
</div>
</div>
</div>
</center>
<script type="text/javascript">
var e = document.getElementById("nntpchan_banner");
@ -83,8 +81,8 @@
</script>
<hr/>
<footer>
<p class="legal">All posts on this site are the responsibility of the individual poster and not the administration, pursuant to 47 U.S.C. § 230.</p>
<p class="legal">To make a DMCA request or report illegal content, please contact the administration</p>
<p class="legal">All posts on this site are the responsibility of the individual poster and not the administration, pursuant to 47 U.S.C. § 230.</p>
<p class="legal">To make a DMCA request or report illegal content, please contact the administration</p>
</footer>
</body>
</html>

View File

@ -8,34 +8,25 @@
<head>
<title> {{#i18n.Translations}}{{overboard_title}}{{/i18n.Translations}} </title>
<meta charset="utf-8" />
<link rel="stylesheet" href="{{prefix}}static/site.css" />
<meta name="viewport" content="initial-scale = 1.0,maximum-scale = 1.0" />
<link rel="stylesheet" href="{{prefix}}static/livechan.css" />
<link id="current_theme" rel="stylesheet" href="{{prefix}}static/user.css" />
<style type="text/css" id="convo_filter">
</style>
<script type="text/javascript" src="{{prefix}}static/nntpchan.js"></script>
</head>
<body>
<center>
<div id="nntpchan_banner">
</div>
</center>
<!-- begin navbar -->
{{{navbar}}}
<!-- end navbar -->
<div id="livechan">
</div>
<noscript>you need js for livechan mode</noscript>
<script type="text/javascript" >
var prefix = "{{prefix}}";
var e = document.getElementById("nntpchan_banner");
nntpchan_inject_banners(e, prefix);
init(prefix);
e = document.getElementById("livechan");
if (e) {
inject_livechan_widget(prefix, e);
var e = document.createElement("div");
e.setAttribute("id", "chat");
e.setAttribute("style", "position:fixed;left:0;right:0;top:0;bottom:0;width:100%;height:100%;");
document.body.appendChild(e);
var board = "";
if (location.hash != "" ) {
board = location.hash.substr(1);
}
new Chat(e, board, { prefix : "{{prefix}}" });
</script>
<hr/>
<footer>
<p class="legal">All posts on this site are the responsibility of the individual poster and not the administration, pursuant to 47 U.S.C. § 230.</p>
<p class="legal">To make a DMCA request or report illegal content, please contact the administration</p>
</footer>
</body>
</html>

View File

@ -1,4 +1,23 @@
<div id="{{post.PostHash}}" class="{{post.CSSClass}}">
<div id="{{post.PostHash}}" class="{{post.CSSClass}}"
data-frontend="{{post.Frontend}}"
data-newsgroup="{{post.Board}}"
data-msgid="{{post.MessageID}}"
data-msgidhash="{{post.PostHash}}"
data-rootmsgid="{{post.Reference}}"
data-rootmsgidhash="{{post.ReferenceHash}}"
{{#post.Sage}}
data-sage="1"
{{/post.Sage}}
{{#post.IsI2P}}
data-origin="i2p"
{{/post.IsI2P}}
{{#post.IsTor}}
data-origin="tor"
{{/post.IsTor}}
{{#post.IsClearnet}}
data-origin="clearnet"
{{/post.IsClearnet}}
data-posturl="{{post.PostURL}}">
<legend class="postheader">
<span class="origin">
{{#post.IsI2P}}
@ -10,17 +29,28 @@
{{#post.IsClearnet}}
<img src="{{post.Prefix}}static/clearnet.png" title="{{#i18n.Translations}}{{from_clearnet}}{{/i18n.Translations}}" />
{{/post.IsClearnet}}
</span>
<span class="subject">{{post.Subject}}</span>
<span class="name">{{post.Name}}</span>
<time datetime="{{post.DateRFC}}">{{post.Date}}</time>
<a href="#" class="postnol">No.</a><a class="postno" onclick="nntpchan_reply(this, '{{post.ShortHash}}');" title="{{post.MessageID}}" root="{{post.Reference}}" boardname="{{post.Board}}">{{post.ShortHash}}</a>
<a href="{{post.PostURL}}">[{{#i18n.Translations}}{{reply_label}}{{/i18n.Translations}}]</a>
<span class="tripcode">{{{post.Pubkey}}}</span>
</span>
<div class="postreply">
<a class="postno" onclick="nntpchan_reply(this, '{{post.ShortHash}}');" root="{{post.Reference}}" boardname="{{post.Board}}">&gt;&gt;{{post.ShortHash}}</a>
<a href="{{post.PostURL}}">[{{#i18n.Translations}}{{reply_label}}{{/i18n.Translations}}]</a>
</div>
<div>
Subject: <span class="subject">{{post.Subject}}</span>
</div>
<div>
Name: <span class="name">{{post.Name}}</span><span clas="tripcode">{{{post.Pubkey}}}</span>
</div>
<div>
MessageID: <span class="msgid">{{post.MessageID}}</span>
</div>
<div>
Date: <time datetime="{{post.DateRFC}}">{{post.Date}}</time>
</div>
</legend>
<hr>
<div class="attachments">
{{#post.Attachments}}
<figure>
<figure data-sha512="{{Hash}}">
<figcaption>
<a class="download_link" href="{{Source}}" download="{{Filename}}">{{#i18n.Translations}}{{download_prompt}}{{/i18n.Translations}}</a>
<a class="file" href="{{Source}}" title="{{Filename}}" target="_blank"><img src="{{Thumbnail}}" alt="{{Filename}}" class="thumbnail"/></a>
@ -30,6 +60,7 @@
{{/post.Attachments}}
</div>
<div class="post_body">
{{{post.RenderBody}}}
</div>
<pre>{{{post.RenderBody}}}</pre>
</div>
<hr>
</div>

View File

@ -77,14 +77,14 @@
<input type="text" name="captcha" autocomplete="off" id="captcha_solution" />
</td>
</tr>
<tr>
<!-- <tr>
<th>
{{#i18n.Translations}}{{cuckoo_pow}}{{/i18n.Translations}}
</th>
<td>
<input type="text" name="pow" autocomplete="off" id="miner_result" /><input id="start_miner" class="button" type="button" value="{{#i18n.Translations}}{{start_mining}}{{/i18n.Translations}}"/>
</td>
</tr>
</tr> -->
</tbody>
</table>
</div>

View File

@ -23,7 +23,7 @@
<!-- end navbar -->
<div class="board_header"> {{#i18n.Translations}}{{overboard_title}}{{/i18n.Translations}} </div>
<div id="ukko_threads">
<pre><a href="#" onclick="ukko_livechan('{{prefix}}')">livechan</a></pre>
<pre><a href="{{prefix}}livechan/">livechan</a></pre>
{{#threads}}
<div class="thread" id="thread_{{OP.PostHash}}">
<div class="ukko_thread_header">

View File

@ -1,5 +1,6 @@
NNTPChan Documentation
======================
**WARNING: Caching with redis was deprecated in [commit 96de42](https://github.com/majestrate/srndv2/commit/96de42bf5d689a54d27871c9f8bc4ef3d0cdbefc). Any reference to redis as a cache should be ignored. You should instead use null cache.**
Hey, welcome to the documentation. This will help you use and develop with NNTPChan.
@ -9,7 +10,7 @@ Hey, welcome to the documentation. This will help you use and develop with NNTPC
2. [Setting up NNTPChan](setting-up.md) - Configuring the node
3. [Running NNTPChan](running.md) - Running the node for the first time
4. [Managing your NNTPChan node with the CLI](cli.md) - Manage many aspects of your node via the command-line interface
5. [Configuring your news reader for NNTPChan](extras/configure-newsreader.md) - Setup **Mozilla Thunderbird** or **Pan** to send and receive articles from your node.
5. [Configuring your news reader for NNTPChan](extras/configure-newsreader.md) - Setup **Mozilla Thunderbird** or **Pan** to send and receive articles from your NNTPChan node of choice.
##Developer related

View File

@ -8,7 +8,7 @@ This document will help you build the NNTPChan software from the source code.
NNTPChan can run on the following operating systems:
* Linux
* Instructions are available for Debian and Trisquel.
* Instructions are available for Debian and [Trisquel](#trisquel-instructions-wip).
* FreeBSD
Dependancies:

View File

@ -4,23 +4,10 @@ Configuring Postgres database
These are instructions for setting up NNTPChan with Postgres as the data-storage system.
##Configuring Postgres
A user with sufficient privileges to run su is required (hint: you can use root). This command switches to the Postgres user, creates a Postgres role called `srnd`, and prompts for a password. For illustrative purposes, we will use `srnd` as the password.
Setting up postgres (as root):
# become postgres user
su postgres
# spawn postgres admin shell
psql
You'll get a prompt, enter the following:
CREATE ROLE srnd WITH LOGIN PASSWORD 'srnd';
CREATE DATABASE srnd WITH ENCODING 'UTF8' OWNER srnd;
\q
For demo purposes we'll use these credentials.
These are default values, please change them later.
# su - postgres -c "createuser --pwprompt --createdb --encrypted srnd"
###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.
It's easiest to connect to Postgres using role-based authentication. In this case, our Linux user `srnd` matches up with our Postgres role `srnd`, so role-based authentication can take place. If you're running SRNDv2 as a different user (e.g. `nntpchan`), you will need to create a role that matches that user using the command above.

View File

@ -16,6 +16,7 @@ allow_attachments=1
require_tls=1
anon_nntp=0
feeds=/etc/nntpchan/feeds.d
archive=0
[pprof]
enable=0
@ -82,17 +83,19 @@ This is where you put the address and port that you would like the NNTP server t
####sync_on_start
* When this is set to `1` your NNTP server will sync articles with its peers on startup.
* When this is set to `0` then no syncing will take place on statup.
* When this is set to `0` then no syncing will take place on startup.
####allow_anon
* When this is set to `1` bluh.
* When this is set to `0` bluh.
* When this is set to `1`, posts made from anonymizing networks will be synced from peers.
* When this is set to `0`, posts made from anonymizing networks will not be synced from peers.
####allow_anon_attachments
* When this is set to `1` bluh.
* When this is set to `0` bluh.
* When this is set to `1`, attachments posted from anonymizing networks will be syncdd from peers.
* When this is set to `0`, attachments posted from anonymizing networks will not be synced from peers.
Nodes with `allow_anon_attachments` disabled will not receive threads with images posted from anonymizing networks. Likewise, the thread replies will not sync. In the case where an anonymized user posts an image reply and the node has `allow_anon_attachments` disabled, text posts without attachments replying to the non-synced image post will appear to be "ghosted".
####allow_attachments
@ -112,6 +115,9 @@ This is where you put the address and port that you would like the NNTP server t
####feeds
* Feeds configurations can optionally be stored in a directory of your choosing (the default is `feeds.d` in the working directory). Any ini files located in this directory will be loaded.
####archive
* When this is set to `1`, the daemon will never expire posts.
* When this is set to `0`, the daemon will delete old posts. FIXME: under what conditions?
##`[pprof]`
@ -129,8 +135,8 @@ All pprof-related settings.
##`[frontend]`
#####minimize_html
* `0`: do not minimize HTML
* `1`: minimize HTML
* `0`: Do not minimize HTML
* `1`: Minimize HTML
##Placing configuration elsewhere