How about a contest who fixes the most plugins then?

Best posts made by rbeer
-
RE: Plugin & Theme contest 2015 ideas
-
[nodebb-plugin-smoothshorts] Short URLs built in...
.. well, almost. It's a plugin, after all.
npm install nodebb-plugin-smoothshorts
Features
(README.md)
Once a user opens the browser's context menu upon a topic link, the href value of that link gets replaced with its assigned hash:
This also works on posts (theme-persona; couldn't find post links in theme-lavender).
The now copied address is one of the formhttps://yourNodeBB.org/ss/HASH
. Visiting it will set some logic in motion, finding the associated post or topic and redirecting accordingly:
The original address is restored on any next
mousedown
event. This way, even if the just hashed and copied link is clicked, the user will be visiting that original, since the event is processed before the browser attempts to follow the link. (Tested in FireFox 38.05 and Chrome 43.0; please let me know if your browser doesn't work!)Changelog
0.1.0
- Added ACP page.
- Settings
- Create missing hashs topics/posts.
- Added modifier key (ctrl, alt or shift) to replace urls.
- Added ability to change domain for short urls.
(https://prettylongdomain.org/topic/2/slug/ -> https://short.org/ss/hash)
- Added ACP page.
-
[nodebb-plugin-expiring-uploads] Hide and expire users uploads
(Hopefully) As requested by @chrismccoy
Thanks for the idea!nodebb-plugin-expiring-uploads
Hide and expire users uploads.
The name actually only tells half the story. This plugin lets you:
-
Hide uploads of definable filetypes behind a hash/timestamp/filename combination. Uploads are not stored in the standard path (public/uploads). This ensures, that even when the filename is known, it's pretty hard to guess its location.
-
Set an expiration time(range) for those hash/timestamp/filename urls. Every setting > 0 will have uploads handled by this plugin expire.
PLEASE NOTE: Expiration is calculated at request time. If you uploaded a file 7 days ago and now decide to lower the expiration time from 10 to 5 days, this file will be treated as expired.
Installation
-
npm install nodebb-plugin-expiring-uploads
-
Activate the plugin in the ACP.
-
Adjust the settings! Standard expiration time is 0 = uploads never expire.
-
-
RE: Download Token - bounty offered
@chrismccoy
Is this, more or less, what you are looking for?
Please consider this an early alpha preview, that will most definetly clutter the * peep * out of your log.npm i nodebb-plugin-expiring-uploads
I've taken the liberty to replace the md5- with xx-hashs. MD5 is outdated since years and quite verbose (aa1469dd64687462ee30378e14d34105 vs. 6edebbb6).
The outcoming url is of the form:
ht*p://nodebb/uploads/xxhash/CreationTimestamp-in-hex/filename.ext
e.g.ht*p://lsw.local/uploads/705bab4a/14e6b6e49dc/droid-sans-mono.zip
The seed of xxhash is the first part (up to the first
-
) of your nodeBB's secret (config.json).On the HDD, files are stored in
/nodeBB/expiring_uploads/
as opposed to/nodeBB/public/uploads/files/
, since everything in/public/
could be guessed, as all of its contents seem to be blindly exposed to the clients. Please note, that my lazily hardcoding the/
could make this plugin fail on Windows. I'll change that, or at least check whether the NodeBB core takes care of it.The created links are routed, but you can't actually download the file, yet.
The plugin hook (filter:uploadFile) is pretty needy - or powerful; depending on your point of view. Anyway, it breaks out of (returns from) the core function, handling uploads, as early as it can get. Meaning, that the plugin has to handle everything like allowed filetypes, -sizes and such. I assume, that you e.g. don't want to have uploaded pictures expire. It's in there, but only rudimentarily, for now. That's why I haven't started the ACP part of it, yet.
In the end the plugin will surely have an option to choose, but for starters: What's your preference, the least setup effort for you? Would you rather define filetypes which should be expiring or those who should not?
Another aproach would be to add a second "Expiring Upload" button to the composer. This way the built-in button would follow the general setup (e.g. allowed filetypes images) and the added button would only accept .zip, .gz, .pdf, what have you. -
RE: Need further help with developing first plugin
baris said:
Don't give up so easily
Yes! Yes! Yes!
JavaScript is a prototypal language, which makes it a bit confusing, but very powerful. You can structure your programs in various ways. I'm only gonna go into how it's (mostly) done in nodeJS:
Although you define objects with members, it is uncommon to actually create instances of those objects. JS has a
new
keyword that allows you to do that, but there it gets messy withthis
and what it means. Sometimesthis
points to an object, sometimes a function - it all depends on where you use it and who called what. You should read up on 'function scope' and 'closure', in case you're interested. I myself still like to use it. But anyway, most code you will encounter treats objects asstatic
. Also, function parameters are passedby value
rather thanby reference
(you may know this from C as passing a variable vs. passing a pointer). Let's have a look:var aNumberVariable = 50; myMethod = function(functionsNumberVariable) { functionsNumberVariable = 100; console.log(functionsNumberVariable); }; myMethod(aNumberVariable); console.log(aNumberVariable);
When you execute this snippet, the output will read
100
and then50
.Your browser's console is awesome for fiddling! I use chrome.
Here you can see, that
aNumberVariable
is assigned50
,myMethod
defined and then called. The parameter is passed to the function, where only its value is received, and put into a newly created variablefunctionsNumberVariable
. This then is set to 100 and written to the console. The function call (myMethod()
) is done synchronously, so everything following 'waits' for the function to finish/return. It does so with no value (akaundefined
), but the console ignores that. Then the last line is executed, showing thataNumberVariable
's value is still 50. (The showingundefined
in the picture is actually not from anywhere in my code. I think that is the result of a function, the console's VM wraps your statements in. Once again the scope thingy.)But this also means, that once
myMethod
is through doing its thing, you have no way to accessfunctionsNumberVariable
anymore (before mentioned closure or function scope). Even worse, it's a candidate to be gobbled up by the garbage collector in one of its next runs. Now, you could, of course, easily just return its value, but this is where nodeJS's magic of asynchronicity gets in between.Everything below would have to wait for your function to return, so a read from a database or from a network resource could easily block your process for a lengthy amount of time - not so good.
Fortunately, JavaScript is capable of passing functions as parameters.. This - we're almost there - is the callback (in our case here; you can do heaps of other neat things with it). You basically pass the next step in your chain of processing as this function, passing it the values which you otherwise would have returned. I fail to come up with a quick and easy code example to run, right now. So I'll draw it in a diagram:
At this point you'd be perfectly right to say: "Well, nice story. But there's also an invisible return inqueryDatabase
which the program has to wait for.". Yes, it is. That's why I painted its declaration yellowish. Your JavaScript runs also in nodeJS on a single thread, but under the hood, when V8 (JS engine) passes such calls to the I/O layer it utilises multi-threading. This game of passing callbacks is played along the chain, until V8 'queries' some system I/O function. There it is split off into another thread, from where (on the return path, if you will) the callbacks are called one after another. The actual functionsreturn
s are done as soon V8 has branched off this new thread. I'm not 100% sure about this last part, though. I urge everyone who knows more about this to correct me!By the way: Every function comes with several 'invisible' variables set. One of which is
arguments
. That's an array of all parameters passed to the function. Disregarding the declarations (function(var1, var2)) you did. So even when you define your function asmyMethod = function()
,arguments
is available and filled with everything that has been passed in the call. Great for exploring!
-
RE: Retrieve setting value from the client side
I'm not sure if I understood you correctly, but I think you want to use the PluginSocket (socket.io) for this:
Server:
https://github.com/rbeer/nodebb-plugin-smoothshorts/blob/master/smoothshorts_be.js#L60-L67
Client:
https://github.com/rbeer/nodebb-plugin-smoothshorts/blob/master/static%2Flib%2Fsmoothshorts_fe.js#L21-L24 -
RE: NodeBB development environment (IDE - Tools - Configs etc)
@BDHarrington7
Use pgrep/pkill!kill -s USR1 $(fgrep -f "app.js")
or even shorter with pkill
pkill -USR1 -f "app.js"
Substitute
-USR1
with-SIGHUP
and you got yourself a quick and easy build-tool command to restart NodeBB, when changing files.
(I'm using SublimeText / Atom) -
RE: Harm from the files?
Well, in terms of losing your userbase one after another, once they figure out that your site allows people to spread their malware, of course.
Seriously though:
As long as you don't explicitly execute uploaded files on you server, I don't think so. Haven't seen any code that does it automatically. But then again: Never say never. There's always a chance that someone figures a way to do it.
Apart from that always present risk, I'd give it a "No, it can not."Furthermore, this depends on which OS you are running your site on. Linux systems are somewhat safe due to the simple fact, that there just is little malware for that OS. More importantly is it a matter of proper configuration. In server-land (Linux/Windows alike, though Linux again clearly has the advantage) you should always have your deamons (services) run with their own user. Giving them only the priviliges (access to files, network interfaces, what not...) they really need to do their thing. This way, worst case, your site itself would be harmed, but without having your whole machine compromised, so replaying a backup would solve the problem rather easily.
-
RE: [nodebb-plugin-smoothshorts] Short URLs built in...
0.1.0 is here!
Added ACP page, hashing old topics/posts and different domain for short urls.
As well as the ability to use a modifier key for replacing urls. I highly suggest to use this feature, since the context menu offers more options than just copying links.Here's a preview of the ACP page:
-
RE: Wikipedia
(Read this with an open mind! Some of you seem confused. One way or the other: mistakes have been made. I'm merely sharing my best guesses on why the article got deleted.)
First off: This guy's points are all valid.
In my opinion, it's not so much about NodeBB not being popular; although the discussion revolved around that. Quite honestly, I wouldn't approve of the article in question myself. Is there a way to get the text back? Did anyone save it? I'd like to give some examples, but can't, now that it is deleted.
Anyhow. Back when I read it, my overall impression was more like reading an ad than a wikipedia article. Please keep in mind that wikipedia aims to be an encyclopedia. In that, there just isn't room for "We want to", "We plan to" and anything of that sort.
- "modern platform that will hopefully help shape forums of the future", for example, is a claim, not a fact. If it was true, this sentence would read something like: "platform that has pioneered the shift from php to javascript driven bulletin boards". Let alone the word "modern" isn't timeless, therefore not suitable for an encyclopedia entry.
- "will soon allow integration with services such as WrapBootstrap" - Well, that's fine. But is it a fact? No, it's not. It's again just a claim of what will be. I am not that familiar with wikipedia articles, but I feel that there's also no justification for forseeing the future in those kinds of reads.
Then there's the (inferable) intention in this very topic - which the deleter refers to:
Phrases like "Thats the most important page to be on" make me think: Why is it important? I mean, the strive for gaining popularity can too easily be infered.Last, but certainly not least, maybe the biggest mistake was to call for action. The very first post in this thread acknowledges the fact that you can't write an article about yourself, but simply delegates the task at the same time. Actively asking one of your users at least implies that the article is (again) written by NodeBB itself. I think this is also where this notability claim might be based on. Try to see it as you having given the job to an amateur (no offense) agency. It's not like someone stumbled upon NodeBB and went: "Hey, that's nice. I'll write a wikipedia article about it."
I admit, those are minute details, but they still are there. And I am actually pretty relieved that wikipedia authors think in and act upon those details. It's an encyclopedia! It has to be unbiased, neutral and almost painfully correct.
P.S.
Putting myself in that guys shoes, I'd be pretty pissed too, if someone was to accuse me of "fanboyism".
Latest posts made by rbeer
-
RE: Errors while installing new 0.9.0 to new CentOS 7 VM
@JaredBusch said:
A quick
firewall-cmd --zone=public --add-port=4567/tcp --permanent
andfirewall-cmd --reload
later
And there we go.
Thanks @rbeer for the information about nodejs versions. I did not see the indicator that you did obviously.
Very nice! Glad to see it working now.
And, don't you worry! I was tearing my hair out for about an hour, when I stumbled upon that error some weeks ago. -
RE: Thoughts on securing your NodeBB installation
@xen
Binding a port through your ssh connection is actually quite simple.
(The following assumes that you are using the OpenSSH client on GNU/Linux)tl;dr:
https://youtu.be/vC7Smc67gPg- Start the SSH client with
ssh user@remotehost.com -L 7000:localhost:6379
So basically like you would normally do, appending-L ...
with the syntax:- local_port:interface_on_remote:remote_port (ssh manpage)
- You should have an interactive session to your remote, prompt and all or whatever your setup resolves into when logging in over SSH. Again, business as usual is expected here.
- Now comes the good part: Since you tunneled your local port
7000
to the remoteslocalhost
interface on (redis-) port6379
, you can create a new connection in Redis Desktop Manager, ignoring the SSH tab in the "New Connection" dialog and simply connecting to localhost:7000.
- Start the SSH client with
-
RE: Errors while installing new 0.9.0 to new CentOS 7 VM
That might be true. I am not familiar with CentOS and its package management.
Replacing the install instructions in question with nodesource (https://github.com/nodesource/distributions/tree/master/), might be a good idea. I know e.g. that Debian also has 0.10.x in its repos.
-
RE: Errors while installing new 0.9.0 to new CentOS 7 VM
All your logs and screenshots show a nodejs version 0.10.x. That's heavily outdated. Which manifests itself fataly in
../node_modules/nan/nan.h:328:47: error: βREPLACE_INVALID_UTF8β is not a member of βv8::Stringβ static const unsigned kReplaceInvalidUtf8 = v8::String::REPLACE_INVALID_UTF8;
i.e. a module, that needs compilation, can't find a member (
REPLACE_INVALID_UTF8
) of theString
class inv8
. It must have been introduced later. Upgrading to 0.12.x at least should solve this problem. -
RE: How to export from Redis to MongoDB? (My database got wiped)
@rbeer said:
I'm curious about the contents of two files:
- /var/log/redis/redis-server.log
- /path/to/nodebb/log/nodebb.log
-
RE: How to export from Redis to MongoDB? (My database got wiped)
Hi @Pilvinen
I hope you didn't
purge
redis, already. That could have deleted the log file, as well.I'm curious about the contents of two files:
- /var/log/redis/redis-server.log
- /path/to/nodebb/log/nodebb.log
Like all the others, I suspect redis itself to be the source of failure here. NodeBB uses the DB's
flush
(wipe all data) only in its tests; even there on a test-databse you'd have to set up explicitly. -
RE: Do we care about number of views?
Views shouldn't be used for measuring popularity, whatsoever. At least as it is now. You can keep spamming the refresh button or even write a tiny script to request a topic. There is really no checks in place. It is too easily manipulated.
If that was changed to #views/#users, then it might become a good tool for measuring e.g. how many users have been reached with an announcement topic.
-
RE: Trouble with script embedding in a widget.
I don't know, sorry.
Actually, because I don't know anything about IE, at all. When FF gained users and Chrome came into play, I decided to abandon IE all together. Now, I know this looks like a stupid move, but around the same time also mobile devices gained market shares. Forseeing that those would be the future anyway, I diverted my focus onto them rather any longer hassling with IE. -
RE: Trouble with script embedding in a widget.
@yariplus
Great idea to do this with an iframe.@Tanguy-Bodin-Hullin
The important factor to this problem is that DOM parsing/building is designed as a one-way street. The browser processes your HTML from top to bottom. To add/delete it uses a pointer, which is always at a specific point in the DOM at a time. The problem with asynchronously loaded scripts and document.write() is, that document.write() tries to put the content wherever the pointer is right now. It has no information itself where to put the content.
In this quick example I put the pointer at the end of the page, when the script tries to execute document.write(). That's not always the case! The async loading can finish whenever, meaning that, worst case, document.write() would slap its content just somewhere on your page, leading to obvious fails. That's why the browser warns and refuses to execute document.write() at all. A way better solution than having your content appear at a different place every time you refresh the page, depending on how long the async loading took. Imagine to have to debug something like that.The <iframe> solution works, because <iframe>s are actually their own DOM inside the DOM, including the parsing process. I can remember how we used to avoid <iframe>s; things like that brought them back into the good parts of HTML.