Merge branch 'master' into add_categories

This commit is contained in:
Joey Yakimowich-Payne 2020-02-14 09:48:08 -07:00
commit fac828b1e9
13 changed files with 72 additions and 51 deletions

View file

@ -9,7 +9,7 @@ cache:
- "$HOME/.choosenim"
addons:
firefox: "60.0.1"
firefox: "73.0"
before_install:
- sudo apt-get -qq update
@ -26,13 +26,13 @@ before_install:
- sudo make -j5 install
- cd ..
- wget https://github.com/mozilla/geckodriver/releases/download/v0.20.1/geckodriver-v0.20.1-linux64.tar.gz
- wget https://github.com/mozilla/geckodriver/releases/download/v0.26.0/geckodriver-v0.26.0-linux64.tar.gz
- mkdir geckodriver
- tar -xzf geckodriver-v0.20.1-linux64.tar.gz -C geckodriver
- tar -xzf geckodriver-v0.26.0-linux64.tar.gz -C geckodriver
- export PATH=$PATH:$PWD/geckodriver
install:
- export CHOOSENIM_CHOOSE_VERSION="#f92d61b1f4e193bd"
- export CHOOSENIM_CHOOSE_VERSION="stable"
- |
curl https://nim-lang.org/choosenim/init.sh -sSf > init.sh
sh init.sh -y
@ -41,4 +41,5 @@ install:
script:
- export MOZ_HEADLESS=1
- nimble -y install
- nimble -y test

View file

@ -1,5 +1,5 @@
# Package
version = "2.1.0"
version = "2.0.2"
author = "Dominik Picheta"
description = "The Nim forum"
license = "MIT"
@ -12,16 +12,16 @@ skipExt = @["nim"]
# Dependencies
requires "nim >= 0.18.1"
requires "jester#22f8240"
requires "nim >= 1.0.6"
requires "jester#d8a03aa"
requires "bcrypt#head"
requires "hmac#9c61ebe2fd134cf97"
requires "recaptcha 1.0.2"
requires "recaptcha#d06488e"
requires "sass#649e0701fa5c"
requires "karax#c8c7b13"
requires "karax#f6bda9a"
requires "webdriver#20f3c1b"
requires "webdriver#c2fee57"
# Tasks
@ -36,7 +36,7 @@ task frontend, "Builds the necessary JS frontend (with CSS)":
exec "nimble c -r src/buildcss"
exec "nimble js -d:release src/frontend/forum.nim"
mkDir "public/js"
cpFile "src/frontend/nimcache/forum.js", "public/js/forum.js"
cpFile "src/frontend/forum.js", "public/js/forum.js"
task minify, "Minifies the JS using Google's closure compiler":
exec "closure-compiler public/js/forum.js --js_output_file public/js/forum.js.opt"

View file

@ -269,6 +269,13 @@ $threads-meta-color: #545d70;
}
// Hide all the avatars but the first on small screens.
@media screen and (max-width: 600px) {
#threads-list a:not(:first-child) > .avatar {
display: none;
}
}
.posts, .about {
@extend .grid-md;
@extend .container;

View file

@ -100,7 +100,7 @@ You should then create a symlink to this file inside ``/etc/nginx/sites-enabled/
ln -s /etc/nginx/sites-available/<forum.hostname.com> /etc/nginx/sites-enabled/<forum.hostname.com>
```
Then restart nginx by running ``sudo systemctl restart nginx``.
Then reload nginx configuration by running ``sudo nginx -s reload``.
### Supervisor

View file

@ -457,13 +457,21 @@ proc executeReply(c: TForumData, threadId: int, content: string,
if isLocked == "1":
raise newForumError("Cannot reply to a locked thread.")
let retID = insertID(
db,
crud(crCreate, "post", "author", "ip", "content", "thread", "replyingTo"),
c.userId, c.req.ip, content, $threadId,
if replyingTo.isSome(): $replyingTo.get()
else: ""
)
var retID: int64
if replyingTo.isSome():
retID = insertID(
db,
crud(crCreate, "post", "author", "ip", "content", "thread", "replyingTo"),
c.userId, c.req.ip, content, $threadId, $replyingTo.get()
)
else:
retID = insertID(
db,
crud(crCreate, "post", "author", "ip", "content", "thread"),
c.userId, c.req.ip, content, $threadId
)
discard tryExec(
db,
crud(crCreate, "post_fts", "id", "content"),
@ -621,7 +629,7 @@ proc executeRegister(c: TForumData, name, pass, antibot, userIp,
raise newForumError("Invalid username", @["username"])
if getValue(
db,
sql"select name from person where name = ? and isDeleted = 0",
sql"select name from person where name = ? collate nocase and isDeleted = 0",
name
).len > 0:
raise newForumError("Username already exists", @["username"])
@ -1123,7 +1131,8 @@ routes:
except EParseError:
let err = PostError(
errorFields: @[],
message: getCurrentExceptionMsg()
message: "Message needs to be valid RST! Error: " &
getCurrentExceptionMsg()
)
resp Http400, $(%err), "application/json"

View file

@ -25,7 +25,7 @@ proc getInt64*(s: string, default = 0): int64 =
when defined(js):
include karax/prelude
import karax / [kdom]
import karax / [kdom, kajax]
from dom import nil
@ -87,16 +87,10 @@ when defined(js):
navigateTo(url)
type
FormData* = ref object
proc newFormData*(): FormData
{.importcpp: "new FormData()", constructor.}
proc newFormData*(form: dom.Element): FormData
{.importcpp: "new FormData(@)", constructor.}
proc get*(form: FormData, key: cstring): cstring
{.importcpp: "#.get(@)".}
proc append*(form: FormData, key, val: cstring)
{.importcpp: "#.append(@)".}
proc renderProfileUrl*(username: string): string =
makeUri(fmt"/profile/{username}")

View file

@ -1,6 +1,6 @@
when defined(js):
import sugar, httpcore, options, json
import dom except Event
import dom except Event, KeyboardEvent
include karax/prelude
import karax / [kajax, kdom]

View file

@ -26,7 +26,7 @@ when defined(js):
proc performScroll() =
let replyBox = dom.document.getElementById("reply-box")
replyBox.scrollIntoView(false)
replyBox.scrollIntoView()
proc show*(state: ReplyBox) =
# Scroll to the reply box.

View file

@ -1,6 +1,6 @@
when defined(js):
import sugar, httpcore, options, json
import dom except Event
import dom except Event, KeyboardEvent
include karax/prelude
import karax / [kajax, kdom]

View file

@ -10,11 +10,6 @@ let
import frontend/[karaxutils, error]
export parseInt
proc `%`*[T](opt: Option[T]): JsonNode =
## Generic constructor for JSON data. Creates a new ``JNull JsonNode``
## if ``opt`` is empty, otherwise it delegates to the underlying value.
if opt.isSome: %opt.get else: newJNull()
type
Config* = object
smtpAddress*: string
@ -56,7 +51,7 @@ proc loadConfig*(filename = getCurrentDir() / "forum.json"): Config =
smtpPassword: "", mlistAddress: "")
let root = parseFile(filename)
result.smtpAddress = root{"smtpAddress"}.getStr("")
result.smtpPort = root{"smtpPort"}.getNum(25).int
result.smtpPort = root{"smtpPort"}.getInt(25)
result.smtpUser = root{"smtpUser"}.getStr("")
result.smtpPassword = root{"smtpPassword"}.getStr("")
result.smtpFromAddr = root{"smtpFromAddr"}.getStr("")
@ -69,7 +64,7 @@ proc loadConfig*(filename = getCurrentDir() / "forum.json"): Config =
result.name = root["name"].getStr()
result.title = root["title"].getStr()
result.ga = root{"ga"}.getStr()
result.port = root{"port"}.getNum(5000).int
result.port = root{"port"}.getInt(5000)
proc processGT(n: XmlNode, tag: string): (int, XmlNode, string) =
result = (0, newElement(tag), tag)

View file

@ -115,7 +115,7 @@ proc login*(session: Session, user, password: string) =
checkText "#profile-btn #profile-name", user
click "#profile-btn"
proc register*(session: Session, user, password: string) =
proc register*(session: Session, user, password: string, verify = true) =
with session:
click "#signup-btn"
@ -130,11 +130,13 @@ proc register*(session: Session, user, password: string) =
click "#signup-modal .create-account-btn"
wait()
# Verify that the user menu has been initialised properly.
click "#profile-btn"
checkText "#profile-btn #profile-name", user
# close menu
click "#profile-btn"
if verify:
with session:
# Verify that the user menu has been initialised properly.
click "#profile-btn"
checkText "#profile-btn #profile-name", user
# close menu
click "#profile-btn"
proc createThread*(session: Session, title, content: string) =
with session:

View file

@ -30,5 +30,18 @@ proc test*(session: Session, baseUrl: string) =
test "can register":
with session:
register("test", "test")
logout()
session.logout()
test "can't register same username with different case":
with session:
register "test1", "test1", verify = false
logout()
navigate baseUrl
wait()
register "TEst1", "test1", verify = false
ensureExists "#signup-form .has-error"
navigate baseUrl
wait()