Skip to content

Instantly share code, notes, and snippets.

@xmonader
Last active December 19, 2023 12:08
Show Gist options
  • Star 4 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save xmonader/d41a5c9f917eadb90d3025e7b7e748dd to your computer and use it in GitHub Desktop.
Save xmonader/d41a5c9f917eadb90d3025e7b7e748dd to your computer and use it in GitHub Desktop.
urlshort.nim
# nimshorturl
# Copyright xmonader
# nim url shortening service
import jester, asyncdispatch, htmlgen, json, os, strutils, strformat, db_sqlite
# hostname can be something configurable "http://ni.m:5000"
let hostname = "localhost:5000"
var theDb : DbConn
if not fileExists("/tmp/mytest.db"):
theDb = open("/tmp/mytest.db", "", "", "")
theDb.exec(sql("""create table urls (
id INTEGER PRIMARY KEY,
url VARCHAR(255) NOT NULL
)"""
))
else:
theDb = open("/tmp/mytest.db", "", "", "")
routes:
get "/home":
var htmlout = """
<html>
<title>NIM SHORT</title>
<head>
<script
src="https://code.jquery.com/jquery-3.3.1.min.js"
integrity="sha256-FgpCb/KJQlLNfOu91ta32o/NMZxltwRo8QtmkMRdAu8="
crossorigin="anonymous"></script>
<script>
function postData(url, data) {
// Default options are marked with *
return fetch(url, {
body: JSON.stringify(data), // must match 'Content-Type' header
cache: 'no-cache', // *default, no-cache, reload, force-cache, only-if-cached
credentials: 'same-origin', // include, same-origin, *omit
headers: {
'user-agent': 'Mozilla/4.0 MDN Example',
'content-type': 'application/json'
},
method: 'POST', // *GET, POST, PUT, DELETE, etc.
mode: 'cors', // no-cors, cors, *same-origin
redirect: 'follow', // manual, *follow, error
referrer: 'no-referrer', // *client, no-referrer
})
.then(resp => resp.json())
}
$(document).ready(function() {
$('#btnsubmit').on('click', function(e){
e.preventDefault();
postData('/shorten', {url: $("#url").val()})
.then( data => {
let id = data["id"]
$("#output").html(`<a href="%%hostname/${id}">Shortlink: ${id}</a>`);
});
});
});
</script>
</head>
<body>
<div>
<form>
<label>URL</label>
<input type="url" name="url" id="url" />
<button id="btnsubmit" type="button">SHORT!</button
</form>
</div>
<div id="output">
</div>
</body>
</html>
"""
htmlout = htmlout.replace("%%hostname", hostname)
resp htmlout
post "/shorten":
let url = parseJson(request.body).getOrDefault("url").getStr()
if not url.isNilOrEmpty():
var id = theDb.getValue(sql"SELECT id FROM urls WHERE url=?", url)
echo "ID: " & $id
if id.isNilOrEmpty():
id = $theDb.tryInsertId(sql"INSERT INTO urls (url) VALUES (?)", url)
var jsonResp = $(%*{"id": id})
echo "RESP JSON: ", jsonResp
resp Http200, jsonResp
else:
resp Http400, "please specify url in the posted data."
get "/@Id":
let url = theDb.getValue(sql"SELECT url FROM urls WHERE id=?", @"Id")
if url.isNilOrEmpty():
resp Http404, "Don't know that url"
else:
redirect url
runForever()
theDb.close()
@symgryph
Copy link

I got farther, but now I get: (if this is annoying just tel me and I'll stop)
Users/tmunn/src/nim/shorturl/test.nim(9, 15) Error: type mismatch: got <string, typeof(nil), typeof(nil), typeof(nil)>
but expected one of:
proc open(filename: string; mode: FileMode = fmRead; bufSize: int = -1): File
first type mismatch at position: 2
required type for mode: FileMode
but expression 'nil' is of type: typeof(nil)
proc open(connection, user, password, database: string): DbConn
first type mismatch at position: 2
required type for user: string
but expression 'nil' is of type: typeof(nil)
4 other mismatching symbols have been suppressed; compile with --showAllMismatches:on to see them

expression: open("/Users/tmunn/mytest.db", nil, nil, nil)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment