diff --git a/src/main.v b/src/main.v index 9d9e541..ca35c9d 100644 --- a/src/main.v +++ b/src/main.v @@ -5,7 +5,6 @@ import os import log import io import pkg -import archive import repo const port = 8000 @@ -110,7 +109,5 @@ fn main() { return } // println(info) - println(res.info) - print(res.files) - println(res.info.to_desc()) + print(res) } diff --git a/src/pkg.v b/src/pkg.v index cd1f2a6..bcd2724 100644 --- a/src/pkg.v +++ b/src/pkg.v @@ -89,6 +89,7 @@ mut: checkdepends []string } +// parse_pkg_info_string parses a PkgInfo object from a string fn parse_pkg_info_string(pkg_info_str &string) ?PkgInfo { mut pkg_info := PkgInfo{} @@ -140,7 +141,7 @@ fn parse_pkg_info_string(pkg_info_str &string) ?PkgInfo { return pkg_info } -// Extracts the file list & .PKGINFO contents from an archive +// read_pkg extracts the file list & .PKGINFO contents from an archive // NOTE: this command currently only supports zstd-compressed tarballs pub fn read_pkg(pkg_path string) ?Pkg { if !os.is_file(pkg_path) { @@ -166,9 +167,9 @@ pub fn read_pkg(pkg_path string) ?Pkg { return error('Failed to open package.') } - // We iterate over every header in search of the .PKGINFO one mut buf := voidptr(0) mut files := []string{} + for C.archive_read_next_header(a, &entry) == C.ARCHIVE_OK { pathname := C.archive_entry_pathname(entry) @@ -198,7 +199,7 @@ pub fn read_pkg(pkg_path string) ?Pkg { } } -// Represent a PkgInfo struct as a desc file +// to_desc returns a desc file valid string representation pub fn (p &PkgInfo) to_desc() string { // TODO calculate md5 & sha256 instead of believing the file mut desc := '' diff --git a/src/repo.v b/src/repo.v index ae76cc9..f3ebfd4 100644 --- a/src/repo.v +++ b/src/repo.v @@ -1,7 +1,6 @@ module repo import os -import archive const pkgs_subpath = 'pkgs' @@ -22,35 +21,37 @@ pub: pkg_dir string [required] } -// Returns whether the repository contains the given package. +// contains returns whether the repository contains the given package. pub fn (r &Repo) contains(pkg string) bool { return os.exists(os.join_path(r.repo_dir, 'files', pkg)) } -// Adds the given package to the repo. If false, the package was already +// add adds the given package to the repo. If false, the package was already // present in the repository. pub fn (r &Repo) add(pkg string) ?bool { return false } -// Re-generate the db & files archives. +// generate re-generates the db & files archives. fn (r &Repo) genenerate() ? { } -// Returns path to the given package, prepended with the repo's path. +// pkg_path returns path to the given package, prepended with the repo's path. pub fn (r &Repo) pkg_path(pkg string) string { return os.join_path_single(r.pkg_dir, pkg) } +// exists checks whether a package file exists pub fn (r &Repo) exists(pkg string) bool { return os.exists(r.pkg_path(pkg)) } -// Returns the full path to the database file +// db_path returns the full path to the database file pub fn (r &Repo) db_path() string { return os.join_path_single(r.repo_dir, 'repo.tar.gz') } +// add_package adds a package to the repository pub fn (r &Repo) add_package(pkg_path string) ? { mut res := os.Result{} diff --git a/src/routes.v b/src/routes.v index c7df286..101e1c5 100644 --- a/src/routes.v +++ b/src/routes.v @@ -7,6 +7,7 @@ import time const prefixes = ['B', 'KB', 'MB', 'GB'] +// pretty_bytes converts a byte count to human-readable version fn pretty_bytes(bytes int) string { mut i := 0 mut n := f32(bytes) @@ -23,6 +24,7 @@ fn is_pkg_name(s string) bool { return s.contains('.pkg') } +// get_root handles a GET request for a file on the root ['/:filename'; get] fn (mut app App) get_root(filename string) web.Result { mut full_path := '' @@ -88,6 +90,7 @@ fn (mut app App) get_root(filename string) web.Result { // return app.text('Package added successfully.') // } +// add_package PUT a new package to the server ['/add'; put] pub fn (mut app App) add_package() web.Result { return app.text('') diff --git a/src/web/logging.v b/src/web/logging.v index 66426f2..fc697ff 100644 --- a/src/web/logging.v +++ b/src/web/logging.v @@ -2,28 +2,34 @@ module web import log +// log reate a log message with the given level pub fn (mut ctx Context) log(msg &string, level log.Level) { lock ctx.logger { ctx.logger.send_output(msg, level) } } +// lfatal create a log message with the fatal level pub fn (mut ctx Context) lfatal(msg &string) { ctx.log(msg, log.Level.fatal) } +// lerror create a log message with the error level pub fn (mut ctx Context) lerror(msg &string) { ctx.log(msg, log.Level.error) } +// lwarn create a log message with the warn level pub fn (mut ctx Context) lwarn(msg &string) { ctx.log(msg, log.Level.warn) } +// linfo create a log message with the info level pub fn (mut ctx Context) linfo(msg &string) { ctx.log(msg, log.Level.info) } +// ldebug create a log message with the debug level pub fn (mut ctx Context) ldebug(msg &string) { ctx.log(msg, log.Level.debug) } diff --git a/src/web/web.v b/src/web/web.v index 404bd08..2db8f18 100644 --- a/src/web/web.v +++ b/src/web/web.v @@ -187,14 +187,14 @@ struct Route { } // Defining this method is optional. -// This method called at server start. +// init_server is called at server start. // You can use it for initializing globals. pub fn (ctx Context) init_server() { eprintln('init_server() has been deprecated, please init your web app in `fn main()`') } // Defining this method is optional. -// This method called before every request (aka middleware). +// before_request is called before every request (aka middleware). // Probably you can use it for check user session cookie or add header. pub fn (ctx Context) before_request() {} @@ -206,7 +206,7 @@ pub struct Cookie { http_only bool } -// web intern function +// send_response_to_client sends a response to the client [manualfree] pub fn (mut ctx Context) send_response_to_client(mimetype string, res string) bool { if ctx.done { @@ -230,33 +230,33 @@ pub fn (mut ctx Context) send_response_to_client(mimetype string, res string) bo return true } -// Response HTTP_OK with s as payload with content-type `text/html` +// html HTTP_OK with s as payload with content-type `text/html` pub fn (mut ctx Context) html(s string) Result { ctx.send_response_to_client('text/html', s) return Result{} } -// Response HTTP_OK with s as payload with content-type `text/plain` +// text HTTP_OK with s as payload with content-type `text/plain` pub fn (mut ctx Context) text(s string) Result { ctx.send_response_to_client('text/plain', s) return Result{} } -// Response HTTP_OK with json_s as payload with content-type `application/json` +// json HTTP_OK with json_s as payload with content-type `application/json` pub fn (mut ctx Context) json(j T) Result { json_s := json.encode(j) ctx.send_response_to_client('application/json', json_s) return Result{} } -// Response HTTP_OK with a pretty-printed JSON result +// json_pretty Response HTTP_OK with a pretty-printed JSON result pub fn (mut ctx Context) json_pretty(j T) Result { json_s := json.encode_pretty(j) ctx.send_response_to_client('application/json', json_s) return Result{} } -// Response HTTP_OK with file as payload +// file Response HTTP_OK with file as payload // This function manually implements responses because it needs to stream the file contents pub fn (mut ctx Context) file(f_path string) Result { if ctx.done { @@ -329,13 +329,13 @@ pub fn (mut ctx Context) file(f_path string) Result { return Result{} } -// Response HTTP_OK with s as payload +// ok Response HTTP_OK with s as payload pub fn (mut ctx Context) ok(s string) Result { ctx.send_response_to_client(ctx.content_type, s) return Result{} } -// Response a server error +// server_error Response a server error pub fn (mut ctx Context) server_error(ecode int) Result { $if debug { eprintln('> ctx.server_error ecode: $ecode') @@ -347,7 +347,7 @@ pub fn (mut ctx Context) server_error(ecode int) Result { return Result{} } -// Redirect to an url +// redirect Redirect to an url pub fn (mut ctx Context) redirect(url string) Result { if ctx.done { return Result{} @@ -360,7 +360,7 @@ pub fn (mut ctx Context) redirect(url string) Result { return Result{} } -// Send an not_found response +// not_found Send an not_found response pub fn (mut ctx Context) not_found() Result { if ctx.done { return Result{} @@ -370,7 +370,7 @@ pub fn (mut ctx Context) not_found() Result { return Result{} } -// Sets a cookie +// set_cookie Sets a cookie pub fn (mut ctx Context) set_cookie(cookie Cookie) { mut cookie_data := []string{} mut secure := if cookie.secure { 'Secure;' } else { '' } @@ -383,17 +383,17 @@ pub fn (mut ctx Context) set_cookie(cookie Cookie) { ctx.add_header('Set-Cookie', '$cookie.name=$cookie.value; $data') } -// Sets the response content type +// set_content_type Sets the response content type pub fn (mut ctx Context) set_content_type(typ string) { ctx.content_type = typ } -// Sets a cookie with a `expire_data` +// set_cookie_with_expire_date Sets a cookie with a `expire_data` pub fn (mut ctx Context) set_cookie_with_expire_date(key string, val string, expire_date time.Time) { ctx.add_header('Set-Cookie', '$key=$val; Secure; HttpOnly; expires=$expire_date.utc_string()') } -// Gets a cookie by a key +// get_cookie Gets a cookie by a key pub fn (ctx &Context) get_cookie(key string) ?string { // TODO refactor mut cookie_header := ctx.get_header('cookie') if cookie_header == '' { @@ -413,7 +413,7 @@ pub fn (ctx &Context) get_cookie(key string) ?string { // TODO refactor return error('Cookie not found') } -// Sets the response status +// set_status Sets the response status pub fn (mut ctx Context) set_status(code int, desc string) { if code < 100 || code > 599 { ctx.status = '500 Internal Server Error' @@ -422,12 +422,12 @@ pub fn (mut ctx Context) set_status(code int, desc string) { } } -// Adds an header to the response with key and val +// add_header Adds an header to the response with key and val pub fn (mut ctx Context) add_header(key string, val string) { ctx.header.add_custom(key, val) or {} } -// Returns the header data from the key +// get_header Returns the header data from the key pub fn (ctx &Context) get_header(key string) string { return ctx.req.header.get_custom(key) or { '' } } @@ -436,7 +436,7 @@ interface DbInterface { db voidptr } -// run_app +// run runs the app [manualfree] pub fn run(global_app &T, port int) { mut l := net.listen_tcp(.ip6, ':$port') or { panic('failed to listen $err.code $err') } @@ -478,6 +478,7 @@ pub fn run(global_app &T, port int) { } } +// handle_conn handles a connection [manualfree] fn handle_conn(mut conn net.TcpConn, mut app T, routes map[string]Route) { conn.set_read_timeout(30 * time.second) @@ -615,6 +616,7 @@ fn handle_conn(mut conn net.TcpConn, mut app T, routes map[string]Route) { conn.write(web.http_404.bytes()) or {} } +// route_matches returns wether a route matches fn route_matches(url_words []string, route_words []string) ?[]string { // URL path should be at least as long as the route path // except for the catchall route (`/:path...`) @@ -657,7 +659,7 @@ fn route_matches(url_words []string, route_words []string) ?[]string { return params } -// check if request is for a static file and serves it +// serve_if_static checks if request is for a static file and serves it // returns true if we served a static file, false otherwise [manualfree] fn serve_if_static(mut app T, url urllib.URL) bool { @@ -676,6 +678,7 @@ fn serve_if_static(mut app T, url urllib.URL) bool { return true } +// scan_static_directory makes a static route for each file in a directory fn (mut ctx Context) scan_static_directory(directory_path string, mount_path string) { files := os.ls(directory_path) or { panic(err) } if files.len > 0 { @@ -695,7 +698,7 @@ fn (mut ctx Context) scan_static_directory(directory_path string, mount_path str } } -// Handles a directory static +// handle_static Handles a directory static // If `root` is set the mount path for the dir will be in '/' pub fn (mut ctx Context) handle_static(directory_path string, root bool) bool { if ctx.done || !os.exists(directory_path) { @@ -724,7 +727,7 @@ pub fn (mut ctx Context) mount_static_folder_at(directory_path string, mount_pat return true } -// Serves a file static +// serve_static Serves a file static // `url` is the access path on the site, `file_path` is the real path to the file, `mime_type` is the file type pub fn (mut ctx Context) serve_static(url string, file_path string) { ctx.static_files[url] = file_path @@ -733,7 +736,7 @@ pub fn (mut ctx Context) serve_static(url string, file_path string) { ctx.static_mime_types[url] = web.mime_types[ext] } -// Returns the ip address from the current user +// ip Returns the ip address from the current user pub fn (ctx &Context) ip() string { mut ip := ctx.req.header.get(.x_forwarded_for) or { '' } if ip == '' { @@ -749,22 +752,23 @@ pub fn (ctx &Context) ip() string { return ip } -// Set s to the form error +// error Set s to the form error pub fn (mut ctx Context) error(s string) { println('web error: $s') ctx.form_error = s } -// Returns an empty result +// not_found Returns an empty result pub fn not_found() Result { return Result{} } +// send_string fn send_string(mut conn net.TcpConn, s string) ? { conn.write(s.bytes()) ? } -// Do not delete. +// filter Do not delete. // It used by `vlib/v/gen/c/str_intp.v:130` for string interpolation inside web templates // TODO: move it to template render fn filter(s string) string {