├── .gitignore
├── CREDITS.txt
├── LICENSE.txt
├── README.md
├── bin
├── autowire.lua
└── unix
│ ├── build.lua
│ ├── octopus.service
│ ├── server.sh
│ └── ssl_certificate
│ ├── server.crt
│ └── server.key
└── extensions
├── baseline
├── config.lua
├── src
│ ├── BaselineHtmlTemplate.lua
│ └── widget
│ │ ├── nav.css
│ │ ├── popup
│ │ ├── InfoPopup.js
│ │ ├── OneFieldPopup.js
│ │ ├── Popup.css
│ │ ├── Popup.js
│ │ ├── QuestionPopup.js
│ │ ├── ThreeFieldsPopup.js
│ │ └── TwoFieldsPopup.js
│ │ └── style.css
└── static
│ ├── css
│ └── font-awesome.min.css
│ ├── fonts
│ ├── FontAwesome.otf
│ ├── fontawesome-webfont.eot
│ ├── fontawesome-webfont.svg
│ ├── fontawesome-webfont.ttf
│ ├── fontawesome-webfont.woff
│ └── fontawesome-webfont.woff2
│ └── js
│ ├── diff_match_patch.js
│ ├── difflib.js
│ ├── diffview.css
│ ├── diffview.js
│ ├── html5shiv.js
│ ├── init-baseline.js
│ ├── init-shop.js
│ ├── jquery.min.js
│ ├── jquery.pretty-text-diff.js
│ ├── skel-layers.min.js
│ ├── skel.css
│ └── skel.min.js
├── config.lua
├── core
├── config.lua
└── src
│ ├── builder.lua
│ ├── cookie.lua
│ ├── crypto.lua
│ ├── database.lua
│ ├── date.lua
│ ├── eval.lua
│ ├── exception.lua
│ ├── exit.lua
│ ├── fileutil.lua
│ ├── http.lua
│ ├── http_headers.lua
│ ├── js
│ ├── parse.js
│ └── widget.js
│ ├── json.lua
│ ├── param.lua
│ ├── parse.lua
│ ├── persistence.lua
│ ├── resty
│ ├── README.md
│ ├── md5.lua
│ ├── mysql.lua
│ ├── resty.sh
│ ├── rsa.lua
│ ├── sha.lua
│ ├── sha1.lua
│ └── sha256.lua
│ ├── rocky
│ ├── README.md
│ ├── certificate.lua
│ ├── crypto.lua
│ ├── luaorm.lua
│ ├── ngx.lua
│ ├── ngxssl.lua
│ ├── postgresql.lua
│ ├── socket.lua
│ └── typedef.lua
│ ├── stacktrace.lua
│ ├── template.lua
│ ├── upload.lua
│ ├── utf8.lua
│ ├── utf8data.lua
│ ├── util.lua
│ └── uuid.lua
├── database
├── config.lua
├── src
│ ├── controller
│ │ ├── DatabaseAddController.lua
│ │ ├── DatabaseAddReferenceController.lua
│ │ ├── DatabaseController.lua
│ │ ├── DatabaseDeleteAllReferencesController.lua
│ │ ├── DatabaseDeleteController.lua
│ │ ├── DatabaseDeleteReferenceController.lua
│ │ ├── DatabaseEditController.lua
│ │ ├── DatabaseExecuteController.lua
│ │ ├── DatabaseSaveController.lua
│ │ ├── DatabaseTemplate.css
│ │ └── DatabaseTemplate.js
│ ├── filter
│ │ ├── DatabaseRedirectOnSessionTimeoutFilter.lua
│ │ └── DatabaseThrowErrorOnSessionTimeoutFilter.lua
│ └── widget
│ │ ├── DatabaseEditObject.js
│ │ ├── DatabaseEditor.js
│ │ ├── DatabaseHeader.css
│ │ ├── DatabaseHeader.js
│ │ ├── DatabaseNavigation.css
│ │ ├── DatabaseNavigation.js
│ │ ├── DatabaseResult.js
│ │ └── DatabaseTabs.js
└── static
│ └── database-favicon.ico
├── demo
├── config.lua
├── src
│ ├── controller
│ │ ├── HelloWorldController.lua
│ │ ├── IndexController.lua
│ │ └── ProductDetailController.lua
│ ├── module
│ │ └── DemoProductService.lua
│ └── widget
│ │ ├── DemoError.js
│ │ ├── DemoFooter.js
│ │ ├── DemoHeader.js
│ │ ├── DemoProductDetail.js
│ │ ├── DemoTemplate1.lua
│ │ └── DemoTemplate2.lua
└── static
│ ├── box.jpg
│ └── stars-5.png
├── editor
├── config.lua
├── src
│ ├── controller
│ │ ├── CompareController.lua
│ │ ├── CryptographyController.lua
│ │ ├── EditorController.lua
│ │ ├── EditorDownloadFileController.lua
│ │ ├── EditorEditFileController.lua
│ │ ├── EditorSearchController.lua
│ │ ├── EditorSearchTemplate.js
│ │ ├── EditorTemplate.css
│ │ ├── EditorTemplate.js
│ │ ├── EditorUploadFileController.lua
│ │ └── operation
│ │ │ ├── CreateDirectoryController.lua
│ │ │ ├── CreateFileController.lua
│ │ │ ├── DirectoryController.lua
│ │ │ ├── FileContentController.lua
│ │ │ ├── RemoveController.lua
│ │ │ ├── RenameController.lua
│ │ │ └── SaveController.lua
│ ├── filter
│ │ ├── EditorRedirectOnSessionTimeoutFilter.lua
│ │ └── EditorThrowErrorOnSessionTimeoutFilter.lua
│ ├── module
│ │ ├── Directory.lua
│ │ └── Editor.lua
│ └── widget
│ │ ├── CompareEditor.js
│ │ ├── CompareHeader.js
│ │ ├── CompareTabs.js
│ │ ├── CryptographyTabs.js
│ │ ├── Editor.js
│ │ ├── EditorHeader.css
│ │ ├── EditorHeader.js
│ │ ├── EditorNavigation.css
│ │ ├── EditorNavigation.js
│ │ ├── EditorSearchHeader.js
│ │ ├── EditorSearchPopup.js
│ │ ├── EditorSearchResult.js
│ │ └── UploadResult.js
└── static
│ ├── editor-favicon.ico
│ └── search-favicon.ico
├── orm
├── config.lua
└── src
│ ├── database.lua
│ └── db
│ ├── api
│ ├── common.lua
│ ├── mysql.lua
│ └── postgres.lua
│ └── driver
│ ├── mysql.lua
│ └── postgres.lua
├── repository
├── config.lua
├── src
│ ├── controller
│ │ ├── RepositoryCommitHistoryController.lua
│ │ ├── RepositoryFileHistoryController.lua
│ │ ├── RepositoryLogHistoryController.lua
│ │ ├── RepositoryStatusController.lua
│ │ ├── RepositoryTemplate.css
│ │ ├── RepositoryTemplate.js
│ │ └── operation
│ │ │ ├── AddController.lua
│ │ │ ├── CommitController.lua
│ │ │ ├── DeleteController.lua
│ │ │ ├── FileDiffController.lua
│ │ │ ├── FileRevisionContentController.lua
│ │ │ ├── MergeController.lua
│ │ │ ├── RefreshController.lua
│ │ │ ├── RevertController.lua
│ │ │ └── UpdateController.lua
│ ├── module
│ │ ├── GIT.lua
│ │ └── SVN.lua
│ └── widget
│ │ ├── RepositoryDiff.js
│ │ ├── RepositoryFileHistoryHeader.js
│ │ ├── RepositoryFileHistoryNavigation.js
│ │ ├── RepositoryLog.js
│ │ ├── RepositoryPatch.js
│ │ ├── RepositoryStatusHeader.js
│ │ └── RepositoryStatusNavigation.js
└── static
│ └── repository-favicon.ico
├── security
├── config.lua
└── src
│ ├── controller
│ ├── SecurityLoginPageController.lua
│ ├── SecurityLoginUserController.lua
│ ├── SecurityRegisterPageController.lua
│ └── SecurityRegisterUserController.lua
│ ├── import.lua
│ ├── module
│ └── UserService.lua
│ ├── types.lua
│ └── widget
│ ├── LoginForm.js
│ └── RegisterForm.js
└── shop
├── config.lua
├── src
├── controller
│ ├── ChangeCountryController.lua
│ ├── ChangeLanguageController.lua
│ ├── HomePageController.lua
│ ├── account
│ │ ├── AccountAddUpdateAddressController.lua
│ │ ├── AccountAddressPageController.lua
│ │ ├── AccountAddressesPageController.lua
│ │ ├── AccountOrderPageController.lua
│ │ ├── AccountOrdersPageController.lua
│ │ ├── AccountPageController.lua
│ │ ├── AccountRemoveAddressController.lua
│ │ ├── LoginPageController.lua
│ │ └── RegisterPageController.lua
│ ├── catalog
│ │ ├── CategoryPageController.lua
│ │ └── ProductPageController.lua
│ └── checkout
│ │ ├── AddToCartController.lua
│ │ ├── CartPageController.lua
│ │ ├── CheckoutAddAddressController.lua
│ │ ├── CheckoutAddressPageController.lua
│ │ ├── CheckoutAddressesPageController.lua
│ │ ├── CheckoutConfirmationPageController.lua
│ │ ├── CheckoutDeliveryMethodPageController.lua
│ │ ├── CheckoutPageController.lua
│ │ ├── CheckoutPaymentMethodPageController.lua
│ │ ├── CheckoutPlaceOrderController.lua
│ │ ├── CheckoutReviewOrderPageController.lua
│ │ ├── CheckoutSetAddressController.lua
│ │ ├── CheckoutSetDeliveryMethodController.lua
│ │ ├── CheckoutSetPaymentMethodController.lua
│ │ └── UpdateProductEntryController.lua
├── filter
│ ├── ShopRedirectOnSessionTimeoutFilter.lua
│ └── ShopThrowErrorOnSessionTimeoutFilter.lua
├── import.lua
├── module
│ ├── CartService.lua
│ ├── CountryService.lua
│ ├── ExceptionHandler.lua
│ ├── LocaleService.lua
│ └── PriceService.lua
├── types.lua
└── widget
│ ├── account
│ ├── AccountOptions.js
│ ├── AddressForm.js
│ ├── Addresses.js
│ ├── Order.js
│ ├── Orders.js
│ └── RegisterForm.js
│ ├── catalog
│ ├── HorizontalNavigation.css
│ ├── HorizontalNavigation.js
│ ├── ProductAttributeFilter.js
│ ├── ProductDetail.js
│ └── ProductsGrid.js
│ ├── checkout
│ ├── Cart.css
│ ├── Cart.js
│ ├── DeliveryMethodForm.js
│ └── PaymentMethodForm.js
│ └── header
│ ├── Background.js
│ ├── CallUs.js
│ ├── Error.js
│ ├── Logo.js
│ ├── MiniCart.js
│ ├── RegBackgroundWithPicture.css
│ ├── Search.js
│ └── ShopHeader.js
└── static
├── bg_flag.gif
├── favicon.ico
├── logo.png
├── p1.jpg
├── p2.jpg
├── p3.jpg
├── p4.jpg
├── p5.jpg
├── p6.jpg
├── stars-5.png
├── style.css
└── uk_flag.gif
/.gitignore:
--------------------------------------------------------------------------------
1 | extensions/baseline/static/ace/
2 | extensions/build/
3 | bin/unix/downloads/
4 | bin/unix/html/
5 | bin/unix/lib/
6 | bin/unix/logs/
7 | bin/unix/luajit/
8 | bin/unix/fastcgi.conf
9 | bin/unix/fastcgi.conf.default
10 | bin/unix/fastcgi_params
11 | bin/unix/fastcgi_params.default
12 | bin/unix/koi-utf
13 | bin/unix/koi-win
14 | bin/unix/mime.types
15 | bin/unix/mime.types.default
16 | bin/unix/nginx
17 | bin/unix/nginx.conf
18 | bin/unix/nginx.conf.default
19 | bin/unix/nginx.config.*
20 | bin/unix/nginx.pid
21 | bin/unix/nginx.old
22 | bin/unix/server.reload
23 | bin/unix/scgi_params
24 | bin/unix/scgi_params.default
25 | bin/unix/uwsgi_params
26 | bin/unix/uwsgi_params.default
27 | bin/unix/win-utf
28 | bin/unix/profiles.lua
--------------------------------------------------------------------------------
/CREDITS.txt:
--------------------------------------------------------------------------------
1 | lua | http://www.lua.org/ | Copyright © 1994–2015 Lua.org, PUC-Rio.
2 | luajit | http://luajit.org/ | Copyright © 2005-2015 Mike Pall
3 | nginx | http://nginx.org/ | Copyright (C) 2011-2015 Nginx, Inc.
4 | openssl | https://www.openssl.org/ | Copyright (c) 1998-2016 The OpenSSL Project | Copyright (c) 1995-1998 Eric A. Young, Tim J. Hudson
5 | lua-nginx-module | https://github.com/openresty/lua-nginx-module | Copyright (C) 2009-2015, by Yichun "agentzh" Zhang (章亦春) agentzh@gmail.com, CloudFlare Inc.
6 | lua-resty-mysql | https://github.com/openresty/lua-resty-mysql | Copyright (C) 2012-2013, by Yichun "agentzh" Zhang (章亦春) agentzh@gmail.com, CloudFlare Inc.
7 | lua-resty-postgres | https://github.com/azurewang/lua-resty-postgres | Copyright (C) 2013 Azure Wang(azure1st@gmail.com)
8 | lfs | https://github.com/keplerproject/luafilesystem | Copyright © 2003-2014 Kepler Project.
9 | persistence | http://the-color-black.net/blog/LuaTablePersistence | Copyright (c) 2010 Gerhard Roethlin
10 | dkjson | http://dkolf.de/src/dkjson-lua.fsl/home | Copyright (C) 2010-2013 David Heiko Kolf
11 | uuid | https://github.com/Tieske/uuid | Copyright 2012 Rackspace (original), 2013 Thijs Schreijer (modifications)
12 | date | https://github.com/Tieske/date | Copyright (C) 2006, by Jas Latrix (jastejada@yahoo.com)| Copyright (C) 2013-2014, by Thijs Schreijer
13 | utf8 | Copyright (c) 2006-2007, Kyle Smith | Copyright (C) 2016, StrumaSoft
14 | lua-resty-http | https://github.com/pintsized/lua-resty-http | Copyright (c) 2013, James Hurst
15 | lua-resty-cookie | https://github.com/cloudflare/lua-resty-cookie | Copyright (C) 2013 Jiale Zhi (calio), Cloudflare Inc.
16 | lua-resty-upload | https://github.com/openresty/lua-resty-upload | Copyright (C) Yichun Zhang (agentzh)
17 | skel | https://github.com/n33/skel | Copyright (c) n33
18 | ace | https://github.com/ajaxorg/ace | Copyright (c) 2010, Ajax.org B.V.
19 | google-diff-match-patch | https://code.google.com/p/google-diff-match-patch/ | Apache License 2.0
20 | jQuery.PrettyTextDiff | https://github.com/arnab/jQuery.PrettyTextDiff | Copyright (c) 2013 Arnab Deka.
21 | jsdifflib | https://github.com/cemerick/jsdifflib | Copyright (c) 2007, Snowtide Informatics Systems, Inc.
--------------------------------------------------------------------------------
/LICENSE.txt:
--------------------------------------------------------------------------------
1 | Copyright (C) 2015-2021, StrumaSoft
2 |
3 | All rights reserved.
4 |
5 | Redistribution and use in source and binary forms, with or without modification,
6 | are permitted provided that the following conditions are met:
7 |
8 | 1. Redistributions of source code must retain the above copyright notice,
9 | this list of conditions and the following disclaimer.
10 |
11 | 2. Redistributions in binary form must reproduce the above copyright notice,
12 | this list of conditions and the following disclaimer in the documentation
13 | and/or other materials provided with the distribution.
14 |
15 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
17 | THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
18 | IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
19 | ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
20 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
21 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22 | HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
23 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
24 | EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25 |
--------------------------------------------------------------------------------
/bin/autowire.lua:
--------------------------------------------------------------------------------
1 | -- save old require
2 | local oldRequire = require
3 |
4 |
5 | package.loaded.MODULES = {}
6 | local function configuration (moduleName)
7 | local MODULES = package.loaded.MODULES
8 | local octopusHostDir = ngx.var.octopusHostDir
9 |
10 | if MODULES[octopusHostDir] then
11 | return MODULES[octopusHostDir][moduleName]
12 | else
13 | local modulesConfig = dofile(octopusHostDir .. "/build/src/module.lua")
14 | MODULES[octopusHostDir] = modulesConfig
15 | return modulesConfig[moduleName]
16 | end
17 | end
18 |
19 |
20 | local function newRequire (moduleName, newModule)
21 | if not moduleName then return nil end
22 |
23 | local scripts = configuration(moduleName)
24 | if scripts then
25 | local key
26 | if scripts[1]["extensionDir"]:find(ngx.var.octopusExtensionsDir, 1, true) then
27 | key = "octopus." .. moduleName
28 | elseif moduleName:find("global.", 1, true) then
29 | key = moduleName
30 | else
31 | key = ngx.var.octopusHostDir .. ":" .. moduleName
32 | end
33 |
34 | if newModule then
35 | package.loaded[key] = newModule
36 | return
37 | end
38 |
39 | local cached = package.loaded[key]
40 | if cached then return cached end
41 |
42 | local lastModule, tempModule
43 | for i=#scripts, 2, -1 do -- first script holds metadata
44 | local scriptModule = dofile(scripts[i])
45 |
46 | if i == #scripts then
47 | lastModule = scriptModule
48 | tempModule = lastModule
49 | else
50 | local nonLastModule = scriptModule
51 | local mt = getmetatable(tempModule) or {}
52 | mt.__index = nonLastModule
53 | setmetatable(tempModule, mt)
54 | tempModule = nonLastModule
55 | end
56 | end
57 |
58 | package.loaded[key] = lastModule
59 | return lastModule
60 | end
61 |
62 | return oldRequire(moduleName)
63 | end
64 |
65 |
66 | -- return new require
67 | return newRequire
--------------------------------------------------------------------------------
/bin/unix/octopus.service:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | # cp octopus.service /etc/init.d/octopus
4 | # sudo systemctl daemon-reload
5 | # sudo service octopus restart
6 |
7 | ### BEGIN INIT INFO
8 | # Provides: octopus
9 | # Required-Start: $all
10 | # Required-Stop:
11 | # Default-Start: 2 3 4 5
12 | # Default-Stop:
13 | # Short-Description: octopus the lua web framework
14 | # Description: octopus the lua web framework
15 | ### END INIT INFO
16 |
17 | . /lib/lsb/init-functions
18 |
19 | cd /octopus/bin/unix
20 |
21 | case "$1" in
22 | build)
23 | ./server.sh build
24 | ;;
25 | start)
26 | ./server.sh build
27 | ./server.sh start
28 | ;;
29 | stop)
30 | ./server.sh stop
31 | ;;
32 | restart)
33 | ./server.sh build
34 | ./server.sh stop
35 | ./server.sh start
36 | ;;
37 | reload)
38 | ./server.sh stop
39 | ./server.sh start
40 | ;;
41 | status)
42 | ;;
43 | *)
44 | echo "Usage: $0 {start|stop|status|restart|reload|build}"
45 | esac
46 |
47 | exit 0
--------------------------------------------------------------------------------
/bin/unix/ssl_certificate/server.crt:
--------------------------------------------------------------------------------
1 | -----BEGIN CERTIFICATE-----
2 | MIICoTCCAYmgAwIBAgIBATANBgkqhkiG9w0BAQsFADAUMRIwEAYDVQQDDAlsb2Nh
3 | bGhvc3QwHhcNMjQwMjA3MDY0MzMzWhcNMjUwMjA2MDY0MzMzWjAUMRIwEAYDVQQD
4 | DAlsb2NhbGhvc3QwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC76UEA
5 | db3IfdLHAjN5fTUHH6DjY/ZaQodFCGFqMKkwJKXYIIv6rHHlEIHK6yyM739024HE
6 | Atd8xB4XkAld9fL3QtZHbewPhR5PlWvGFi3t3UBJZH93Nn8lVL9clRHIZw4KZi9l
7 | 81cS7M1DUzfR3xP5KlAcleeLffGVCvXsZdCvuuhiEly5VFuwmfk7kSyru26ym/N0
8 | wF9xmS6MDJvad93RV3eJYPtTqbR5KA4Pn78UtawN3vyL3t8K0CbqsX45Zalzf1lq
9 | cGX4ky7V2Ah3oZ5ZgEPmuwv7UcI4UzIm3CXik1miw30o7LFRqO2BXQ1iD+0lYPOk
10 | kyehEMAzWa0i0DzbAgMBAAEwDQYJKoZIhvcNAQELBQADggEBAKL5G2WY6D+ntmIq
11 | k25pjOL2wu2b01UR+68DzSS21fBSq5jknJZ8hw6Q/IlSaGth9FVgaUJiBNBG62HV
12 | eZ/sf4nw5UJ5c7McbkCz3xYLe/wto2pAg4gtQYVZ+OpRQwDUhbV38b7WodxgZKhl
13 | cTCJLBqgaARnUbVaLhw4SJ1kzIPXpLB8WwkLZCbsicEb5WHOqNNICHKJkCcsD3zg
14 | 8VPQr14OOG8HzTngYLYjNPlGz5N6aBWmDw8Eo1njxUrrUfkcYeOjsuYvnglsCLOT
15 | er1qBbh50WoArVI6t4UlpwZaAkkY15Vvobdig6JIFE07L2FrvtLrqpm1OZVNck1t
16 | VVUnNmE=
17 | -----END CERTIFICATE-----
18 |
--------------------------------------------------------------------------------
/bin/unix/ssl_certificate/server.key:
--------------------------------------------------------------------------------
1 | -----BEGIN PRIVATE KEY-----
2 | MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQC76UEAdb3IfdLH
3 | AjN5fTUHH6DjY/ZaQodFCGFqMKkwJKXYIIv6rHHlEIHK6yyM739024HEAtd8xB4X
4 | kAld9fL3QtZHbewPhR5PlWvGFi3t3UBJZH93Nn8lVL9clRHIZw4KZi9l81cS7M1D
5 | UzfR3xP5KlAcleeLffGVCvXsZdCvuuhiEly5VFuwmfk7kSyru26ym/N0wF9xmS6M
6 | DJvad93RV3eJYPtTqbR5KA4Pn78UtawN3vyL3t8K0CbqsX45Zalzf1lqcGX4ky7V
7 | 2Ah3oZ5ZgEPmuwv7UcI4UzIm3CXik1miw30o7LFRqO2BXQ1iD+0lYPOkkyehEMAz
8 | Wa0i0DzbAgMBAAECggEAAlexEMFnAUXYR9TWMXCHJbSWO992Jb/okcq99CXxJgF+
9 | 88fMFu7paJKhG5d88bDWpO1Lm9bxOsPzIBYSl9JGGiECLNfI9pSRQSq6sjh6kBmP
10 | AJs5H5JVWXDKBexx0U6/lQ+bDalP75N2J52092/RfuyxHPodbda/GT2OvUizpk0n
11 | uSPyB2tGpZhTBOHVWAioxFktO0ry2TQbs4dUC2Nd5Rl7/Njo8+W6HXYTtOIvMeqx
12 | KuV0upd3tG7Y0C1CS/KbWEM03/fSy1ZZfBg8Any5ysCTBm57EMaGT2plJI9YsAOO
13 | scpSuSzcPyDUDMn+nDvhFDcSpyW/ujM3TkkJaTLtoQKBgQDlWRE6T6bD3rICMnU1
14 | bB5x4GW1qV86dQUZGuQZOyo3SDYCJJPQI1o1csCiKV4MZfGQcXbYBTzSYeA/SAwC
15 | aY8xTudbzMqn1LgvJggVugItJ4iGYfBVxOshksYKZwXMRuiMXafsFTBdWSzDv+OU
16 | ktKo5Geo3ens673ECkNoh52AkQKBgQDRv3kXVObp9LIw8GbImir+Yq4Rx5AZ+NT5
17 | qx39in5xb1FfWx6zPUIEw0nqMD1JXkXOCAA7ElJeKOvBFj8vmunOChmrx2qYfRzb
18 | MzC87uZ7svMcJWClhm5vKE6gFiqPtAf0pFukCOYu//tS7GNpspJlwHTKPKo1ZcDP
19 | MhEJT5OcqwKBgADNJ99BSf7jN1IEpR4zq4OQWiqhVeDZadQloOhpqYMZ8H5fbFjM
20 | 1tLa/MtUQ6zdalOr4dNtaUH+746pDMmxXru4X9yVQZwGhUI86shQpxNLURHPI8zY
21 | 7E1ouuJsa7vD/6oF5cFQbaPV3O8uK3hobu4CJk6Tv+6BAF+//W5PEwDRAoGAEWQo
22 | 7DBT/S4W4Evumc9+pR0Vhc/gOOcS8aioke870LgELT3m68G2iaKPrGVXj4/LhevP
23 | 6RX50mjeM2Je1tmnbTgVLNMaGY62J860ydWdMsCBu+G1g8QDwB+9dTShTs0Eo9pE
24 | 5vL98wOymQuUqpzt2pX8mRAypL7NH+Ds3LLGcIUCgYBozXdjgkMGlhTZQXW2wnB/
25 | bN6pZEyq1inON/mXoP5f8s98UP0bx+AF6gqg984nL0hbzucUoq4CY/FMHG23qo6P
26 | y0kB6wDzE4Hsi854MPaiAtPZyOgvd1TsxTDvGaOrP9uyy7s38L9yE3xwZyRk6j0i
27 | fr2GxjuUZw0NW2LJY6XClw==
28 | -----END PRIVATE KEY-----
29 |
--------------------------------------------------------------------------------
/extensions/baseline/config.lua:
--------------------------------------------------------------------------------
1 | local config = {} -- extension configuration
2 |
3 | config.frontend = {
4 | baseline_color1 = "#fff", -- white
5 | baseline_color2 = "#000", -- black
6 | baseline_color3 = "#888",
7 | baseline_color4 = "#000",
8 | baseline_color5 = "144, 144, 144",
9 | baseline_color6 = "#bbb",
10 | baseline_color01 = "#888",
11 | baseline_color02 = "#ccc",
12 | baseline_color04 = "#f6f6f6",
13 | baseline_color05 = "#f2f2f2",
14 | baseline_color06 = "0, 0, 0",
15 | baseline_color08 = "#ebebeb",
16 | baseline_color09 = "#d9d9d9",
17 |
18 | baseline_font1 = "Arial, Helvetica, sans-serif",
19 | baseline_font2 = '"Courier New", monospace',
20 | }
21 |
22 | config.module = {
23 | {name = "BaselineHtmlTemplate", script = "BaselineHtmlTemplate.lua"}
24 | }
25 |
26 | config.javascript = {
27 | {name = "Popup", script = "widget/popup/Popup.js"},
28 | {name = "InfoPopup", script = "widget/popup/InfoPopup.js"},
29 | {name = "OneFieldPopup", script = "widget/popup/OneFieldPopup.js"},
30 | {name = "TwoFieldsPopup", script = "widget/popup/TwoFieldsPopup.js"},
31 | {name = "ThreeFieldsPopup", script = "widget/popup/ThreeFieldsPopup.js"},
32 | {name = "QuestionPopup", script = "widget/popup/QuestionPopup.js"}
33 | }
34 |
35 | config.stylesheet = {
36 | {name = "style", script = "widget/style.css"},
37 | {name = "Popup", script = "widget/popup/Popup.css"}
38 | }
39 |
40 | config.parse = {
41 | {name = "/build/static/nav.css", script = "widget/nav.css"}
42 | }
43 |
44 | config.static = {
45 | "static"
46 | }
47 |
48 | return config -- return extension configuration
--------------------------------------------------------------------------------
/extensions/baseline/src/BaselineHtmlTemplate.lua:
--------------------------------------------------------------------------------
1 | return [[
2 |
3 |
4 |
5 | {{title}}
6 |
7 |
8 |
9 |
10 |
11 |
12 | {{externalCSS}}
13 |
14 |
15 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
27 |
28 | {{externalJS}}
29 |
30 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
42 |
43 |
44 | ]]
--------------------------------------------------------------------------------
/extensions/baseline/src/widget/nav.css:
--------------------------------------------------------------------------------
1 | @charset "UTF-8";
2 |
3 | /* skel-baseline v2.0.3 | (c) n33 | getskel.com | MIT licensed */
4 |
5 | /* Basic */
6 |
7 | body, input, select, textarea {
8 | font-size: 12pt;
9 | }
10 |
11 | /* Header */
12 |
13 | #skel-layers-wrapper {
14 | padding-top: 0;
15 | }
16 |
17 | #header {
18 | display: none;
19 | }
20 |
21 | /* Banner */
22 |
23 | #banner {
24 | padding: 6em 2em;
25 | }
26 |
27 | /* Layers */
28 |
29 | #navButton .toggle {
30 | text-decoration: none;
31 | height: 100%;
32 | left: 0;
33 | position: absolute;
34 | top: 0;
35 | width: 100%;
36 | }
37 |
38 | #navButton .toggle:before {
39 | content: "";
40 | -moz-osx-font-smoothing: grayscale;
41 | -webkit-font-smoothing: antialiased;
42 | font-family: FontAwesome;
43 | font-style: normal;
44 | font-weight: normal;
45 | text-transform: none !important;
46 | }
47 |
48 | #navButton .toggle:before {
49 | background: rgba({{baseline_color5}}, 0.65);
50 | border-radius: 4px;
51 | color: {{baseline_color1}};
52 | display: block;
53 | font-size: 16px;
54 | height: 2.25em;
55 | left: 0.5em;
56 | line-height: 2.25em;
57 | position: absolute;
58 | text-align: center;
59 | top: 0.5em;
60 | width: 3.5em;
61 | }
62 |
63 | #navPanel {
64 | background: {{baseline_color1}};
65 | color: {{baseline_color2}};
66 | }
67 |
68 | #navPanel nav {
69 | padding: 0.5em 1.25em;
70 | }
71 |
72 | #navPanel nav ul {
73 | list-style: none;
74 | margin: 0;
75 | padding: 0;
76 | }
77 |
78 | #navPanel nav ul li {
79 | padding: 0;
80 | }
81 |
82 | #navPanel nav ul li:first-child a:not(.button), #navPanel nav ul li:first-child span:not(.button) {
83 | border-top: 0;
84 | }
85 |
86 | #navPanel nav .button {
87 | width: 100%;
88 | }
--------------------------------------------------------------------------------
/extensions/baseline/src/widget/popup/InfoPopup.js:
--------------------------------------------------------------------------------
1 | Widget.InfoPopup = function (data) {
2 | var info = parse(function(){/*!
3 | {{info}}
4 |
5 |
9 | */}, data)
10 |
11 | this.popup = new Widget.Popup({info: info})
12 | vars.infoPopup = this.popup
13 | this.popup.init()
14 | }
15 |
16 | Widget.InfoPopup.prototype = {
17 | constructor: Widget.InfoPopup
18 | }
--------------------------------------------------------------------------------
/extensions/baseline/src/widget/popup/OneFieldPopup.js:
--------------------------------------------------------------------------------
1 | Widget.OneFieldPopup = function (data) {
2 | data.guid = Widget.guid()
3 |
4 | var info = parse(function(){/*!
5 | {{?@ !isEmpty(data.info)
6 | {{info}}
7 | }}?
8 |
9 |
17 |
18 |
22 |
26 | */}, data)
27 |
28 | this.popup = new Widget.Popup({info: info})
29 | this.popup.proceed = data.proceed
30 | vars.oneFieldPopup = this.popup
31 | this.popup.init()
32 | }
33 |
34 | Widget.OneFieldPopup.prototype = {
35 | constructor: Widget.OneFieldPopup
36 | }
--------------------------------------------------------------------------------
/extensions/baseline/src/widget/popup/Popup.css:
--------------------------------------------------------------------------------
1 | .overlay {
2 | position: fixed;
3 | top: 0px;
4 | right: 0px;
5 | bottom: 0px;
6 | left: 0px;
7 | opacity: 0;
8 | background-color: white;
9 | z-index: 100000;
10 | }
11 |
12 | .popup {
13 | position: fixed;
14 | top: 50%;
15 | left: 50%;
16 | -webkit-transform: translate(-50%, -50%);
17 | transform: translate(-50%, -50%);
18 | max-width: 90%;
19 | overflow-x: auto;
20 | max-height: 90%;
21 | overflow-y: auto;
22 | padding: 30px 30px 30px 30px;
23 | border-radius: 4px;
24 | border: 1px solid black;
25 | background-color: white;
26 | z-index: 100001;
27 | }
28 |
29 | .spaced-down {
30 | margin: 0px 0px 9px 0px;
31 | }
32 |
33 | .spaced-up {
34 | margin: 9px 0px 0px 0px;
35 | }
--------------------------------------------------------------------------------
/extensions/baseline/src/widget/popup/Popup.js:
--------------------------------------------------------------------------------
1 | Widget.Popup = function (data) {
2 | this.data = data
3 | this.html = parse(function(){/*!
4 |
8 | */}, data)
9 | }
10 |
11 | Widget.Popup.prototype = {
12 | constructor: Widget.Popup,
13 |
14 | init: function () {
15 | $("#popups").html(this.html)
16 | },
17 |
18 | delete: function () {
19 | $("#popups").empty()
20 | }
21 | }
--------------------------------------------------------------------------------
/extensions/baseline/src/widget/popup/QuestionPopup.js:
--------------------------------------------------------------------------------
1 | Widget.QuestionPopup = function (data) {
2 | var info = parse(function(){/*!
3 | {{question}}
4 |
5 |
9 |
13 | */}, data)
14 |
15 | this.popup = new Widget.Popup({info: info})
16 | this.popup.proceed = data.proceed
17 | vars.questionPopup = this.popup
18 | this.popup.init()
19 | }
20 |
21 | Widget.QuestionPopup.prototype = {
22 | constructor: Widget.QuestionPopup
23 | }
--------------------------------------------------------------------------------
/extensions/baseline/src/widget/popup/ThreeFieldsPopup.js:
--------------------------------------------------------------------------------
1 | Widget.ThreeFieldsPopup = function (data) {
2 | data.guid1 = Widget.guid()
3 | data.guid2 = Widget.guid()
4 | data.guid3 = Widget.guid()
5 |
6 | var info = parse(function(){/*!
7 | {{?@ !isEmpty(data.info)
8 | {{info}}
9 | }}?
10 |
11 |
19 |
20 |
28 |
29 |
37 |
38 |
42 |
46 | */}, data)
47 |
48 | this.popup = new Widget.Popup({info: info})
49 | this.popup.proceed = data.proceed
50 | vars.threeFieldsPopup = this.popup
51 | this.popup.init()
52 | }
53 |
54 | Widget.ThreeFieldsPopup.prototype = {
55 | constructor: Widget.ThreeFieldsPopup
56 | }
--------------------------------------------------------------------------------
/extensions/baseline/src/widget/popup/TwoFieldsPopup.js:
--------------------------------------------------------------------------------
1 | Widget.TwoFieldsPopup = function (data) {
2 | data.guid1 = Widget.guid()
3 | data.guid2 = Widget.guid()
4 |
5 | var info = parse(function(){/*!
6 | {{?@ !isEmpty(data.info)
7 | {{info}}
8 | }}?
9 |
10 |
18 |
19 |
27 |
28 |
32 |
36 | */}, data)
37 |
38 | this.popup = new Widget.Popup({info: info})
39 | this.popup.proceed = data.proceed
40 | vars.twoFieldsPopup = this.popup
41 | this.popup.init()
42 | }
43 |
44 | Widget.TwoFieldsPopup.prototype = {
45 | constructor: Widget.TwoFieldsPopup
46 | }
--------------------------------------------------------------------------------
/extensions/baseline/static/fonts/FontAwesome.otf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/strumasoft/octopus/4d66e3d6045cbd533353696abd80e48b1d606f18/extensions/baseline/static/fonts/FontAwesome.otf
--------------------------------------------------------------------------------
/extensions/baseline/static/fonts/fontawesome-webfont.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/strumasoft/octopus/4d66e3d6045cbd533353696abd80e48b1d606f18/extensions/baseline/static/fonts/fontawesome-webfont.eot
--------------------------------------------------------------------------------
/extensions/baseline/static/fonts/fontawesome-webfont.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/strumasoft/octopus/4d66e3d6045cbd533353696abd80e48b1d606f18/extensions/baseline/static/fonts/fontawesome-webfont.ttf
--------------------------------------------------------------------------------
/extensions/baseline/static/fonts/fontawesome-webfont.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/strumasoft/octopus/4d66e3d6045cbd533353696abd80e48b1d606f18/extensions/baseline/static/fonts/fontawesome-webfont.woff
--------------------------------------------------------------------------------
/extensions/baseline/static/fonts/fontawesome-webfont.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/strumasoft/octopus/4d66e3d6045cbd533353696abd80e48b1d606f18/extensions/baseline/static/fonts/fontawesome-webfont.woff2
--------------------------------------------------------------------------------
/extensions/baseline/static/js/html5shiv.js:
--------------------------------------------------------------------------------
1 | /*
2 | HTML5 Shiv v3.6.2 | @afarkas @jdalton @jon_neal @rem | MIT/GPL2 Licensed
3 | */
4 | (function(l,f){function m(){var a=e.elements;return"string"==typeof a?a.split(" "):a}function i(a){var b=n[a[o]];b||(b={},h++,a[o]=h,n[h]=b);return b}function p(a,b,c){b||(b=f);if(g)return b.createElement(a);c||(c=i(b));b=c.cache[a]?c.cache[a].cloneNode():r.test(a)?(c.cache[a]=c.createElem(a)).cloneNode():c.createElem(a);return b.canHaveChildren&&!s.test(a)?c.frag.appendChild(b):b}function t(a,b){if(!b.cache)b.cache={},b.createElem=a.createElement,b.createFrag=a.createDocumentFragment,b.frag=b.createFrag();
5 | a.createElement=function(c){return!e.shivMethods?b.createElem(c):p(c,a,b)};a.createDocumentFragment=Function("h,f","return function(){var n=f.cloneNode(),c=n.createElement;h.shivMethods&&("+m().join().replace(/\w+/g,function(a){b.createElem(a);b.frag.createElement(a);return'c("'+a+'")'})+");return n}")(e,b.frag)}function q(a){a||(a=f);var b=i(a);if(e.shivCSS&&!j&&!b.hasCSS){var c,d=a;c=d.createElement("p");d=d.getElementsByTagName("head")[0]||d.documentElement;c.innerHTML="x";
6 | c=d.insertBefore(c.lastChild,d.firstChild);b.hasCSS=!!c}g||t(a,b);return a}var k=l.html5||{},s=/^<|^(?:button|map|select|textarea|object|iframe|option|optgroup)$/i,r=/^(?:a|b|code|div|fieldset|h1|h2|h3|h4|h5|h6|i|label|li|ol|p|q|span|strong|style|table|tbody|td|th|tr|ul)$/i,j,o="_html5shiv",h=0,n={},g;(function(){try{var a=f.createElement("a");a.innerHTML="";j="hidden"in a;var b;if(!(b=1==a.childNodes.length)){f.createElement("a");var c=f.createDocumentFragment();b="undefined"==typeof c.cloneNode||
7 | "undefined"==typeof c.createDocumentFragment||"undefined"==typeof c.createElement}g=b}catch(d){g=j=!0}})();var e={elements:k.elements||"abbr article aside audio bdi canvas data datalist details figcaption figure footer header hgroup main mark meter nav output progress section summary time video",version:"3.6.2",shivCSS:!1!==k.shivCSS,supportsUnknownElements:g,shivMethods:!1!==k.shivMethods,type:"default",shivDocument:q,createElement:p,createDocumentFragment:function(a,b){a||(a=f);if(g)return a.createDocumentFragment();
8 | for(var b=b||i(a),c=b.frag.cloneNode(),d=0,e=m(),h=e.length;d',
53 | orientation: 'vertical',
54 | position: 'top-left',
55 | side: 'left',
56 | width: 250
57 | },
58 | navButton: {
59 | breakpoints: 'medium',
60 | html: '',
61 | position: 'top-left',
62 | side: 'top'
63 | }
64 | }
65 | }
66 | });
67 |
68 | $(function() {
69 |
70 | var $window = $(window),
71 | $body = $('body');
72 |
73 | // Disable animations/transitions until the page has loaded.
74 | $body.addClass('is-loading');
75 |
76 | $window.on('load', function() {
77 | $body.removeClass('is-loading');
78 | });
79 |
80 | });
81 |
82 | })(jQuery);
83 |
--------------------------------------------------------------------------------
/extensions/baseline/static/js/init-shop.js:
--------------------------------------------------------------------------------
1 | /* skel-baseline v2.0.3 | (c) n33 | getskel.com | MIT licensed */
2 |
3 | (function($) {
4 |
5 | skel.init({
6 | reset: 'full',
7 | breakpoints: {
8 | global: {
9 | href: '',
10 | containers: '90%',
11 | grid: { gutters: ['2em', 0] }
12 | },
13 | xlarge: {
14 | media: '(max-width: 1680px)',
15 | href: '',
16 | containers: '90%'
17 | },
18 | large: {
19 | media: '(max-width: 1280px)',
20 | href: '',
21 | containers: '90%',
22 | grid: { gutters: ['1.5em', 0] },
23 | viewport: { scalable: false }
24 | },
25 | medium: {
26 | media: '(max-width: 980px)',
27 | href: '/build/static/nav.css',
28 | containers: '90%'
29 | },
30 | small: {
31 | media: '(max-width: 736px)',
32 | href: '',
33 | containers: '90%',
34 | grid: { gutters: ['1.25em', 0] }
35 | },
36 | xsmall: {
37 | media: '(max-width: 480px)',
38 | href: ''
39 | }
40 | },
41 | plugins: {
42 | layers: {
43 | config: {
44 | mode: 'transform'
45 | },
46 | navPanel: {
47 | animation: 'pushX',
48 | breakpoints: 'medium',
49 | clickToHide: true,
50 | height: '100%',
51 | hidden: true,
52 | html: '',
53 | orientation: 'vertical',
54 | position: 'top-left',
55 | side: 'left',
56 | width: 250
57 | },
58 | navButton: {
59 | breakpoints: 'medium',
60 | html: '',
61 | position: 'top-left',
62 | side: 'top'
63 | }
64 | }
65 | }
66 | });
67 |
68 | $(function() {
69 |
70 | var $window = $(window),
71 | $body = $('body');
72 |
73 | // Disable animations/transitions until the page has loaded.
74 | $body.addClass('is-loading');
75 |
76 | $window.on('load', function() {
77 | $body.removeClass('is-loading');
78 | });
79 |
80 | });
81 |
82 | })(jQuery);
--------------------------------------------------------------------------------
/extensions/baseline/static/js/jquery.pretty-text-diff.js:
--------------------------------------------------------------------------------
1 | // patched by laz
2 |
3 | /*
4 | @preserve jQuery.PrettyTextDiff 1.0.4
5 | See https://github.com/arnab/jQuery.PrettyTextDiff/
6 | */
7 |
8 | (function() {
9 | var $;
10 |
11 | $ = jQuery;
12 |
13 | $.fn.extend({
14 | prettyTextDiff: function(options) {
15 | var dmp, settings;
16 | settings = {
17 | originalContainer: ".original",
18 | changedContainer: ".changed",
19 | diffContainer: ".diff",
20 | cleanup: true,
21 | debug: false
22 | };
23 | settings = $.extend(settings, options);
24 | $.fn.prettyTextDiff.debug("Options: ", settings, settings);
25 | dmp = new diff_match_patch();
26 | return this.each(function() {
27 | var changed, diff_as_html, diffs, original;
28 | if (settings.originalContent && settings.changedContent) {
29 | original = settings.originalContent // enable markup detection
30 | changed = settings.changedContent // enable markup detection
31 | } else {
32 | original = $(settings.originalContainer, this).text();
33 | changed = $(settings.changedContainer, this).text();
34 | }
35 | $.fn.prettyTextDiff.debug("Original text found: ", original, settings);
36 | $.fn.prettyTextDiff.debug("Changed text found: ", changed, settings);
37 | diffs = dmp.diff_main(original, changed);
38 | if (settings.cleanup) {
39 | dmp.diff_cleanupSemantic(diffs);
40 | }
41 | $.fn.prettyTextDiff.debug("Diffs: ", diffs, settings);
42 | diff_as_html = $.map(diffs, function(diff) {
43 | return $.fn.prettyTextDiff.createHTML(diff);
44 | });
45 | $(settings.diffContainer, this).html(diff_as_html.join(''));
46 | return this;
47 | });
48 | }
49 | });
50 |
51 | $.fn.prettyTextDiff.debug = function(message, object, settings) {
52 | if (settings.debug) {
53 | return console.log(message, object);
54 | }
55 | };
56 |
57 | $.fn.prettyTextDiff.createHTML = function(diff) {
58 | var data, html, operation, pattern_amp, pattern_gt, pattern_lt, pattern_para, text;
59 | html = [];
60 | pattern_amp = /&/g;
61 | pattern_lt = //g;
63 | pattern_para = /\r\n/g;
64 | operation = diff[0], data = diff[1];
65 | text = data.replace(pattern_amp, '&').replace(pattern_lt, '<').replace(pattern_gt, '>').replace(pattern_para, '\n');
66 | switch (operation) {
67 | case DIFF_INSERT:
68 | return '' + text + '';
69 | case DIFF_DELETE:
70 | return '' + text + '';
71 | case DIFF_EQUAL:
72 | return '' + text + '';
73 | }
74 | };
75 |
76 | }).call(this);
--------------------------------------------------------------------------------
/extensions/config.lua:
--------------------------------------------------------------------------------
1 | return {
2 | extensions = {
3 | {octopusExtensionsDir, "core"},
4 | {octopusExtensionsDir, "baseline"},
5 | --{octopusExtensionsDir, "orm"}, -- @deprecated > use luaorm > https://github.com/strumasoft/luaorm
6 | {octopusExtensionsDir, "security"},
7 | {octopusExtensionsDir, "editor"},
8 | {octopusExtensionsDir, "repository"},
9 | {octopusExtensionsDir, "database"},
10 | {octopusExtensionsDir, "shop"},
11 | {octopusExtensionsDir, "demo"},
12 | },
13 |
14 | octopusExtensionsDir = octopusExtensionsDir,
15 | octopusHostDir = octopusHostDir,
16 | port = port,
17 | securePort = securePort,
18 | luaCodeCache = luaCodeCache,
19 | serverName = "localhost",
20 | errorLog = "error_log logs/error.log;",
21 | accessLog = "access_log logs/access.log;",
22 | includeDrop = "",
23 | maxBodySize = "50k",
24 |
25 | databaseConnection = {
26 | rdbms = rdbms,
27 | driver = rdbms_driver,
28 | host = rdbms_host,
29 | port = rdbms_port,
30 | user = rdbms_user,
31 | password = rdbms_password,
32 | database = rdbms_db,
33 | compact = false,
34 | usePreparedStatement = false,
35 | debugDB = true,
36 | charset = "utf8",
37 | max_packet_size = 1024 * 1024,
38 | ssl = true
39 | },
40 |
41 | globalParameters = {
42 | octopusHostDir = octopusHostDir,
43 | sourceCtxPath = "",
44 | requireSecurity = requireSecurity,
45 | sessionTimeout = sessionTimeout,
46 | },
47 | }
--------------------------------------------------------------------------------
/extensions/core/config.lua:
--------------------------------------------------------------------------------
1 | local config = {} -- extension configuration
2 |
3 | config.module = {
4 | {name = "builder", script = "builder.lua"},
5 | {name = "cookie", script = "cookie.lua"},
6 | {name = "crypto", script = "rocky/crypto.lua"},
7 | {name = "database", script = "database.lua"},
8 | {name = "date", script = "date.lua"},
9 | {name = "eval", script = "eval.lua"},
10 | {name = "exception", script = "exception.lua"},
11 | {name = "exit", script = "exit.lua"},
12 | {name = "fileutil", script = "fileutil.lua"},
13 | {name = "http", script = "http.lua"},
14 | {name = "http_headers", script = "http_headers.lua"},
15 | {name = "json", script = "json.lua"},
16 | {name = "param", script = "param.lua"},
17 | {name = "parse", script = "parse.lua"},
18 | {name = "persistence", script = "persistence.lua"},
19 | {name = "stacktrace", script = "stacktrace.lua"},
20 | {name = "template", script = "template.lua"},
21 | {name = "upload", script = "upload.lua"},
22 | {name = "utf8", script = "utf8.lua"},
23 | {name = "utf8data", script = "utf8data.lua"},
24 | {name = "util", script = "util.lua"},
25 | {name = "uuid", script = "uuid.lua"},
26 |
27 | {name = "resty.md5", script = "resty/md5.lua"},
28 | {name = "resty.mysql", script = "resty/mysql.lua"},
29 | {name = "resty.rsa", script = "resty/rsa.lua"},
30 | {name = "resty.sha", script = "resty/sha.lua"},
31 | {name = "resty.sha1", script = "resty/sha1.lua"},
32 | {name = "resty.sha256", script = "resty/sha256.lua"},
33 |
34 | {name = "rocky.crypto", script = "rocky/crypto.lua"},
35 | {name = "rocky.luaorm", script = "rocky/luaorm.lua"},
36 | {name = "rocky.ngxssl", script = "rocky/ngxssl.lua"},
37 | {name = "rocky.postgresql", script = "rocky/postgresql.lua"},
38 | {name = "rocky.typedef", script = "rocky/typedef.lua"},
39 | }
40 |
41 | config.javascript = {
42 | {name = "parse", script = "js/parse.js"},
43 | {name = "widget", script = "js/widget.js"}
44 | }
45 |
46 | return config -- return extension configuration
--------------------------------------------------------------------------------
/extensions/core/src/database.lua:
--------------------------------------------------------------------------------
1 | local property = require "property"
2 | local luaorm = require "rocky.luaorm"
3 | local types = require "type"
4 |
5 | local opts = {types = types}
6 | for k,v in pairs(property.databaseConnection) do opts[k] = v end
7 |
8 | return {
9 | connect = function ()
10 | return luaorm.connect(opts)
11 | end
12 | }
13 |
--------------------------------------------------------------------------------
/extensions/core/src/eval.lua:
--------------------------------------------------------------------------------
1 | local param = require "param"
2 |
3 |
4 | local function load_code(code, environment)
5 | if setfenv and loadstring then
6 | local f = assert(loadstring(code))
7 | setfenv(f,environment)
8 | return f
9 | else
10 | return assert(load(code, nil, "t", environment))
11 | end
12 | end
13 |
14 |
15 | local function load_file(fileName, environment)
16 | if setfenv and loadfile then
17 | local f = assert(loadfile(fileName))
18 | setfenv(f,environment)
19 | return f
20 | else
21 | return assert(loadfile(fileName, "t", environment))
22 | end
23 | end
24 |
25 |
26 | local function evalCode(code, environment, addReturn)
27 | if addReturn then
28 | local f = load_code("return " .. code, environment)
29 | local res, res2, res3, res4, res5 = f()
30 | return res, res2, res3, res4, res5
31 | else
32 | local f = load_code(code, environment)
33 | local res, res2, res3, res4, res5 = f()
34 | return res, res2, res3, res4, res5
35 | end
36 | end
37 |
38 |
39 | local function evalFile(fileName, environment)
40 | local f = load_file(fileName, environment)
41 | local res, res2, res3, res4, res5 = f()
42 | return res, res2, res3, res4, res5
43 | end
44 |
45 |
46 | return {
47 | code = evalCode,
48 | file = evalFile
49 | }
--------------------------------------------------------------------------------
/extensions/core/src/exception.lua:
--------------------------------------------------------------------------------
1 | return function (err)
2 | if not ngx then
3 | print(err .. "\n" .. debug.traceback())
4 | error(err)
5 | end
6 |
7 | if err then
8 | if type(err) == "table" then
9 | local json = require "json"
10 | ngx.log(ngx.ERR, json.encode(err) .. "\n" .. debug.traceback())
11 | else
12 | ngx.log(ngx.ERR, err .. "\n" .. debug.traceback())
13 | end
14 | else
15 | err = "error"
16 | ngx.log(ngx.ERR, err .. "\n" .. debug.traceback())
17 | end
18 |
19 | error(err)
20 | end
--------------------------------------------------------------------------------
/extensions/core/src/exit.lua:
--------------------------------------------------------------------------------
1 | return function (err, status)
2 | ngx.status = status or ngx.HTTP_INTERNAL_SERVER_ERROR
3 |
4 | if type(err) == "table" then
5 | local json = require "json"
6 | ngx.say(json.encode(err))
7 | elseif err then
8 | ngx.say(err)
9 | end
10 |
11 | return ngx.exit(ngx.HTTP_OK)
12 | end
--------------------------------------------------------------------------------
/extensions/core/src/http_headers.lua:
--------------------------------------------------------------------------------
1 | local rawget, rawset, setmetatable =
2 | rawget, rawset, setmetatable
3 |
4 | local str_gsub = string.gsub
5 | local str_lower = string.lower
6 |
7 |
8 | local _M = {
9 | _VERSION = '0.01',
10 | }
11 |
12 |
13 | -- Returns an empty headers table with internalised case normalisation.
14 | -- Supports the same cases as in ngx_lua:
15 | --
16 | -- headers.content_length
17 | -- headers["content-length"]
18 | -- headers["Content-Length"]
19 | function _M.new(self)
20 | local mt = {
21 | normalised = {},
22 | }
23 |
24 |
25 | mt.__index = function(t, k)
26 | local k_hyphened = str_gsub(k, "_", "-")
27 | local matched = rawget(t, k)
28 | if matched then
29 | return matched
30 | else
31 | local k_normalised = str_lower(k_hyphened)
32 | return rawget(t, mt.normalised[k_normalised])
33 | end
34 | end
35 |
36 |
37 | -- First check the normalised table. If there's no match (first time) add an entry for
38 | -- our current case in the normalised table. This is to preserve the human (prettier) case
39 | -- instead of outputting lowercased header names.
40 | --
41 | -- If there's a match, we're being updated, just with a different case for the key. We use
42 | -- the normalised table to give us the original key, and perorm a rawset().
43 | mt.__newindex = function(t, k, v)
44 | -- we support underscore syntax, so always hyphenate.
45 | local k_hyphened = str_gsub(k, "_", "-")
46 |
47 | -- lowercase hyphenated is "normalised"
48 | local k_normalised = str_lower(k_hyphened)
49 |
50 | if not mt.normalised[k_normalised] then
51 | mt.normalised[k_normalised] = k_hyphened
52 | rawset(t, k_hyphened, v)
53 | else
54 | rawset(t, mt.normalised[k_normalised], v)
55 | end
56 | end
57 |
58 | return setmetatable({}, mt)
59 | end
60 |
61 |
62 | return _M
63 |
--------------------------------------------------------------------------------
/extensions/core/src/param.lua:
--------------------------------------------------------------------------------
1 | local util = require "util"
2 |
3 |
4 | local m = {} -- module
5 |
6 | setmetatable(m, {
7 | __index = function (table, key)
8 | local x = ngx.var["arg_" .. key]
9 | if x then
10 | return util.unescape(x)
11 | else
12 | return nil
13 | end
14 | end
15 | }
16 | )
17 |
18 | return m -- return module
--------------------------------------------------------------------------------
/extensions/core/src/resty/README.md:
--------------------------------------------------------------------------------
1 | ### OpenResty MySQL driver and related software with very slight modifications
2 | Run resty.sh to download, modify with patch if necessary or remove them
3 | ```sh
4 | bash resty.sh download
5 | bash resty.sh modify
6 | bash resty.sh remove
7 | ```
8 |
9 | ### md5.lua
10 | https://github.com/openresty/lua-resty-string/blob/master/lib/resty/md5.lua
11 |
12 | ### sha.lua
13 | https://github.com/openresty/lua-resty-string/blob/master/lib/resty/sha.lua
14 |
15 | ### sha1.lua
16 | https://github.com/openresty/lua-resty-string/blob/master/lib/resty/sha1.lua
17 |
18 | ### sha256.lua
19 | https://github.com/openresty/lua-resty-string/blob/master/lib/resty/sha256.lua
20 |
21 | ### rsa.lua
22 | https://github.com/spacewander/lua-resty-rsa/blob/master/lib/resty/rsa.lua
23 |
24 | ### mysql.lua
25 | https://github.com/openresty/lua-resty-mysql/blob/master/lib/resty/mysql.lua
--------------------------------------------------------------------------------
/extensions/core/src/resty/md5.lua:
--------------------------------------------------------------------------------
1 | -- Copyright (C) by Yichun Zhang (agentzh)
2 |
3 |
4 | local ffi = require "ffi"
5 | local ffi_new = ffi.new
6 | local ffi_str = ffi.string
7 | local C = ffi.load("ssl.so.3")
8 | local setmetatable = setmetatable
9 | --local error = error
10 |
11 |
12 | local _M = { _VERSION = '0.14' }
13 |
14 | local mt = { __index = _M }
15 |
16 |
17 | ffi.cdef[[
18 | typedef unsigned long MD5_LONG ;
19 |
20 | enum {
21 | MD5_CBLOCK = 64,
22 | MD5_LBLOCK = MD5_CBLOCK/4
23 | };
24 |
25 | typedef struct MD5state_st
26 | {
27 | MD5_LONG A,B,C,D;
28 | MD5_LONG Nl,Nh;
29 | MD5_LONG data[MD5_LBLOCK];
30 | unsigned int num;
31 | } MD5_CTX;
32 |
33 | int MD5_Init(MD5_CTX *c);
34 | int MD5_Update(MD5_CTX *c, const void *data, size_t len);
35 | int MD5_Final(unsigned char *md, MD5_CTX *c);
36 | ]]
37 |
38 | local buf = ffi_new("char[16]")
39 | local ctx_ptr_type = ffi.typeof("MD5_CTX[1]")
40 |
41 |
42 | function _M.new(self)
43 | local ctx = ffi_new(ctx_ptr_type)
44 | if C.MD5_Init(ctx) == 0 then
45 | return nil
46 | end
47 |
48 | return setmetatable({ _ctx = ctx }, mt)
49 | end
50 |
51 |
52 | function _M.update(self, s, len)
53 | return C.MD5_Update(self._ctx, s, len or #s) == 1
54 | end
55 |
56 |
57 | function _M.final(self)
58 | if C.MD5_Final(buf, self._ctx) == 1 then
59 | return ffi_str(buf, 16)
60 | end
61 |
62 | return nil
63 | end
64 |
65 |
66 | function _M.reset(self)
67 | return C.MD5_Init(self._ctx) == 1
68 | end
69 |
70 |
71 | return _M
72 |
73 |
--------------------------------------------------------------------------------
/extensions/core/src/resty/resty.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | # Usage: bash resty.sh download
4 | # Usage: bash resty.sh modify
5 | # Usage: bash resty.sh remove
6 |
7 |
8 | download() {
9 | curl -O https://raw.githubusercontent.com/openresty/lua-resty-string/master/lib/resty/md5.lua
10 | curl -O https://raw.githubusercontent.com/openresty/lua-resty-string/master/lib/resty/sha.lua
11 | curl -O https://raw.githubusercontent.com/openresty/lua-resty-string/master/lib/resty/sha1.lua
12 | curl -O https://raw.githubusercontent.com/openresty/lua-resty-string/master/lib/resty/sha256.lua
13 | curl -O https://raw.githubusercontent.com/spacewander/lua-resty-rsa/master/lib/resty/rsa.lua
14 | curl -O https://raw.githubusercontent.com/openresty/lua-resty-mysql/master/lib/resty/mysql.lua
15 | }
16 |
17 | modify() {
18 | ssl_3_files=("md5" "sha1" "sha256")
19 | for file in "${ssl_3_files[@]}"; do
20 | sed -i 's/ffi\.C/ffi.load("ssl.so.3")/g' "$file.lua"
21 | done
22 |
23 | ssl_1_1_files=("rsa")
24 | for file in "${ssl_1_1_files[@]}"; do
25 | sed -i 's/ffi\.C/ffi.load("ssl.so.1.1")/g' "$file.lua"
26 | done
27 | }
28 |
29 | remove() {
30 | rm *.lua
31 | }
32 |
33 | main() {
34 | case $1 in
35 | download)
36 | download
37 | ;;
38 | modify)
39 | modify
40 | ;;
41 | remove)
42 | remove
43 | ;;
44 | *)
45 | SH=bash
46 | echo "Usage: $SH $0 download"
47 | echo "Usage: $SH $0 modify"
48 | echo "Usage: $SH $0 remove"
49 | exit 0
50 | ;;
51 | esac
52 | }
53 |
54 | main "$@"
--------------------------------------------------------------------------------
/extensions/core/src/resty/sha.lua:
--------------------------------------------------------------------------------
1 | -- Copyright (C) by Yichun Zhang (agentzh)
2 |
3 |
4 | local ffi = require "ffi"
5 |
6 |
7 | local _M = { _VERSION = '0.14' }
8 |
9 |
10 | ffi.cdef[[
11 | typedef unsigned long SHA_LONG;
12 | typedef unsigned long long SHA_LONG64;
13 |
14 | enum {
15 | SHA_LBLOCK = 16
16 | };
17 | ]];
18 |
19 | return _M
20 |
--------------------------------------------------------------------------------
/extensions/core/src/resty/sha1.lua:
--------------------------------------------------------------------------------
1 | -- Copyright (C) by Yichun Zhang (agentzh)
2 |
3 |
4 | require "resty.sha"
5 | local ffi = require "ffi"
6 | local ffi_new = ffi.new
7 | local ffi_str = ffi.string
8 | local C = ffi.load("ssl.so.3")
9 | local setmetatable = setmetatable
10 | --local error = error
11 |
12 |
13 | local _M = { _VERSION = '0.14' }
14 |
15 |
16 | local mt = { __index = _M }
17 |
18 |
19 | ffi.cdef[[
20 | typedef struct SHAstate_st
21 | {
22 | SHA_LONG h0,h1,h2,h3,h4;
23 | SHA_LONG Nl,Nh;
24 | SHA_LONG data[SHA_LBLOCK];
25 | unsigned int num;
26 | } SHA_CTX;
27 |
28 | int SHA1_Init(SHA_CTX *c);
29 | int SHA1_Update(SHA_CTX *c, const void *data, size_t len);
30 | int SHA1_Final(unsigned char *md, SHA_CTX *c);
31 | ]]
32 |
33 | local digest_len = 20
34 |
35 | local buf = ffi_new("char[?]", digest_len)
36 | local ctx_ptr_type = ffi.typeof("SHA_CTX[1]")
37 |
38 |
39 | function _M.new(self)
40 | local ctx = ffi_new(ctx_ptr_type)
41 | if C.SHA1_Init(ctx) == 0 then
42 | return nil
43 | end
44 |
45 | return setmetatable({ _ctx = ctx }, mt)
46 | end
47 |
48 |
49 | function _M.update(self, s)
50 | return C.SHA1_Update(self._ctx, s, #s) == 1
51 | end
52 |
53 |
54 | function _M.final(self)
55 | if C.SHA1_Final(buf, self._ctx) == 1 then
56 | return ffi_str(buf, digest_len)
57 | end
58 |
59 | return nil
60 | end
61 |
62 |
63 | function _M.reset(self)
64 | return C.SHA1_Init(self._ctx) == 1
65 | end
66 |
67 |
68 | return _M
69 |
70 |
--------------------------------------------------------------------------------
/extensions/core/src/resty/sha256.lua:
--------------------------------------------------------------------------------
1 | -- Copyright (C) by Yichun Zhang (agentzh)
2 |
3 |
4 | require "resty.sha"
5 | local ffi = require "ffi"
6 | local ffi_new = ffi.new
7 | local ffi_str = ffi.string
8 | local C = ffi.load("ssl.so.3")
9 | local setmetatable = setmetatable
10 | --local error = error
11 |
12 |
13 | local _M = { _VERSION = '0.14' }
14 |
15 |
16 | local mt = { __index = _M }
17 |
18 |
19 | ffi.cdef[[
20 | typedef struct SHA256state_st
21 | {
22 | SHA_LONG h[8];
23 | SHA_LONG Nl,Nh;
24 | SHA_LONG data[SHA_LBLOCK];
25 | unsigned int num,md_len;
26 | } SHA256_CTX;
27 |
28 | int SHA256_Init(SHA256_CTX *c);
29 | int SHA256_Update(SHA256_CTX *c, const void *data, size_t len);
30 | int SHA256_Final(unsigned char *md, SHA256_CTX *c);
31 | ]]
32 |
33 | local digest_len = 32
34 |
35 | local buf = ffi_new("char[?]", digest_len)
36 | local ctx_ptr_type = ffi.typeof("SHA256_CTX[1]")
37 |
38 |
39 | function _M.new(self)
40 | local ctx = ffi_new(ctx_ptr_type)
41 | if C.SHA256_Init(ctx) == 0 then
42 | return nil
43 | end
44 |
45 | return setmetatable({ _ctx = ctx }, mt)
46 | end
47 |
48 |
49 | function _M.update(self, s)
50 | return C.SHA256_Update(self._ctx, s, #s) == 1
51 | end
52 |
53 |
54 | function _M.final(self)
55 | if C.SHA256_Final(buf, self._ctx) == 1 then
56 | return ffi_str(buf, digest_len)
57 | end
58 |
59 | return nil
60 | end
61 |
62 |
63 | function _M.reset(self)
64 | return C.SHA256_Init(self._ctx) == 1
65 | end
66 |
67 |
68 | return _M
69 |
70 |
--------------------------------------------------------------------------------
/extensions/core/src/rocky/typedef.lua:
--------------------------------------------------------------------------------
1 | -- Copyright (C) 2024, StrumaSoft
2 |
3 |
4 | local function hasMany (type, property)
5 | if property then
6 | return {type = type .. "." .. property, has = "many"}
7 | else
8 | return {type = type, has = "many"}
9 | end
10 | end
11 |
12 | local function hasOne (type, property)
13 | if property then
14 | return {type = type .. "." .. property, has = "one"}
15 | else
16 | return {type = type, has = "one"}
17 | end
18 | end
19 |
20 | return { hasMany = hasMany, hasOne = hasOne }
--------------------------------------------------------------------------------
/extensions/core/src/stacktrace.lua:
--------------------------------------------------------------------------------
1 | return function (err)
2 | if not ngx then
3 | print(err .. "\n" .. debug.traceback())
4 | return
5 | end
6 |
7 | if err then
8 | if type(err) == "table" then
9 | local json = require "json"
10 | ngx.log(ngx.ERR, json.encode(err) .. "\n" .. debug.traceback())
11 | else
12 | ngx.log(ngx.ERR, err .. "\n" .. debug.traceback())
13 | end
14 | else
15 | ngx.log(ngx.ERR, "\n" .. debug.traceback())
16 | end
17 | end
--------------------------------------------------------------------------------
/extensions/core/src/template.lua:
--------------------------------------------------------------------------------
1 | local exception = require "exception"
2 | local eval = require "eval"
3 | local parse = require "parse"
4 |
5 |
6 | package.loaded.TEMPLATES = {}
7 | local function configuration (templateName)
8 | local TEMPLATES = package.loaded.TEMPLATES
9 | local octopusHostDir = ngx.var.octopusHostDir
10 |
11 | if TEMPLATES[octopusHostDir] then
12 | return TEMPLATES[octopusHostDir][templateName]
13 | else
14 | local templatesConfig = dofile(octopusHostDir .. "/build/src/html.lua")
15 | TEMPLATES[octopusHostDir] = templatesConfig
16 | return templatesConfig[templateName]
17 | end
18 | end
19 |
20 |
21 | package.loaded.TEMPLATES_CACHE = {}
22 | local template = {}
23 | setmetatable(template, {
24 | __index = function (t, templateName)
25 | local CACHE = package.loaded.TEMPLATES_CACHE
26 |
27 | local key
28 | if templateName:find("global.", 1, true) then
29 | key = templateName
30 | else
31 | key = ngx.var.octopusHostDir .. ":" .. templateName
32 | end
33 |
34 | local cached = CACHE[key]
35 | if cached then
36 | local view = cached
37 | return function (context, arguments) return parse(view, context, arguments) end
38 | end
39 |
40 | local scripts = configuration(templateName)
41 | if scripts then
42 | local view = eval.file(scripts[#scripts], {})
43 | CACHE[key] = view
44 | return function (context, arguments) return parse(view, context, arguments) end
45 | end
46 |
47 | exception("html template " .. templateName .. " does not exists")
48 | end
49 | })
50 |
51 | return template
--------------------------------------------------------------------------------
/extensions/database/src/controller/DatabaseAddController.lua:
--------------------------------------------------------------------------------
1 | local json = require "json"
2 | local param = require "param"
3 | local util = require "util"
4 | local types = require "type"
5 |
6 |
7 | local typeName = param.type
8 |
9 | if util.isNotEmpty(typeName) then
10 | if types[typeName] then
11 | local arr = {}
12 | for k,v in pairs(types[typeName]) do
13 | arr[#arr + 1] = {name = k, value = nil, type = v}
14 | end
15 | arr[#arr + 1] = typeName -- last element is type name
16 |
17 | ngx.say(json.encode(arr))
18 | else
19 | ngx.say(typeName .. " does not exist!")
20 | end
21 | else
22 | ngx.say("Select type!")
23 | end
--------------------------------------------------------------------------------
/extensions/database/src/controller/DatabaseAddReferenceController.lua:
--------------------------------------------------------------------------------
1 | local json = require "json"
2 | local param = require "param"
3 | local exception = require "exception"
4 | local exit = require "exit"
5 | local util = require "util"
6 | local database = require "database"
7 |
8 |
9 | local from = param.from
10 | local to = param.to
11 | local parentId = param.parentId
12 | local id = param.id
13 |
14 |
15 | local db = database.connect()
16 | local op = db:operators()
17 |
18 |
19 | local function add (typeTo, typeFrom)
20 | if util.isNotEmpty(id) and util.isNotEmpty(parentId) then
21 | if typeTo == typeFrom then -- self referencing
22 | if from < to then
23 | db:add({[from .. "-" .. to] = {key = id, value = parentId}})
24 | else
25 | db:add({[to .. "-" .. from] = {key = parentId, value = id}})
26 | end
27 | else
28 | if from < to then
29 | db:add({[from .. "-" .. to] = {key = parentId, value = id}})
30 | else
31 | db:add({[to .. "-" .. from] = {key = id, value = parentId}})
32 | end
33 | end
34 | else
35 | exception("id or parantId is empty")
36 | end
37 | end
38 |
39 |
40 | local function f ()
41 | -- find if reference(to) object exist
42 | local typeAndPropertyTo = util.split(to, ".")
43 | local typeTo = typeAndPropertyTo[1]
44 | local propertyTo = typeAndPropertyTo[2]
45 |
46 | local toObject = db:findOne({[typeTo] = {id = op.equal(id)}})
47 |
48 | -- add reference
49 | local typeAndPropertyFrom = util.split(from, ".")
50 | local typeFrom = typeAndPropertyFrom[1]
51 | local propertyFrom = typeAndPropertyFrom[2]
52 |
53 | local t = db.types[typeFrom]
54 | local property = t[propertyFrom]
55 | if property then
56 | if property.has then
57 | if property.has == "one" then
58 | local res
59 | if from < to then
60 | res = db:find({[from .. "-" .. to] = {key = op.equal(parentId)}})
61 | else
62 | res = db:find({[to .. "-" .. from] = {value = op.equal(parentId)}})
63 | end
64 | if #res >= 1 then
65 | exception(from .. " must be one not many")
66 | else
67 | add(typeTo, typeFrom)
68 | end
69 | else
70 | add(typeTo, typeFrom)
71 | end
72 | else
73 | exception(from .. " is not reference")
74 | end
75 | else
76 | exception(from .. " does not exists")
77 | end
78 | end
79 |
80 |
81 | local ok, res = pcall(db.transaction, db, f)
82 | db:close()
83 |
84 |
85 | if ok then
86 | ngx.say("Add done!")
87 | else
88 | exit(res)
89 | end
--------------------------------------------------------------------------------
/extensions/database/src/controller/DatabaseController.lua:
--------------------------------------------------------------------------------
1 | local json = require "json"
2 | local parse = require "parse"
3 | local param = require "param"
4 | local property = require "property"
5 | local database = require "database"
6 |
7 |
8 |
9 | local externalJS = [[
10 |
11 |
12 | ]]
13 |
14 |
15 | local externalCSS = [[
16 |
17 | ]]
18 |
19 |
20 | local initJSTemplate = [[
21 | var vars = {}
22 |
23 |
24 | var editor = new Widget.DatabaseEditor({id: "editor"})
25 |
26 | vars.scriptTab = {
27 | guid: Widget.guid(),
28 | id: Widget.guid(),
29 | name: "Script",
30 | html: editor.html
31 | }
32 |
33 | vars.resultTab = {
34 | guid: Widget.guid(),
35 | id: Widget.guid(),
36 | name: "Result",
37 | html: ''
38 | }
39 |
40 | vars.editTab = {
41 | guid: Widget.guid(),
42 | id: Widget.guid(),
43 | name: "Edit",
44 | html: ''
45 | }
46 |
47 | var tabs = [vars.scriptTab, vars.resultTab, vars.editTab]
48 |
49 | var databaseTabs = new Widget.DatabaseTabs({tabs: tabs})
50 |
51 | var databaseNavigation = new Widget.DatabaseNavigation({{types}})
52 | var databaseHeader = new Widget.DatabaseHeader({tabs: tabs})
53 |
54 | var databaseTemplate = new Widget.DatabaseTemplate({
55 | tabs: databaseTabs.html,
56 | navigation: databaseNavigation.html,
57 | header: databaseHeader.html
58 | })
59 |
60 | Widget.setHtmlToPage(databaseTemplate.html);
61 |
62 | editor.init()
63 | databaseNavigation.init()
64 | ]]
65 |
66 |
67 |
68 | local db = database.connect()
69 | db:close()
70 |
71 |
72 | -- sort types --
73 | local typeNames = {}
74 | for k,v in pairs(db.types) do typeNames[#typeNames + 1] = k end
75 | table.sort(typeNames)
76 |
77 | -- wrap everything up --
78 | local types = {}
79 | for i=1,#typeNames do
80 | local k = typeNames[i]
81 | types[#types + 1] = {name = k}
82 | end
83 |
84 |
85 |
86 | local page = parse(require("BaselineHtmlTemplate"), {
87 | title = "Database",
88 | externalJS = externalJS,
89 | externalCSS = externalCSS,
90 | initJS = parse(initJSTemplate, {
91 | types = json.encode(types)
92 | })
93 | })
94 |
95 | ngx.say(page)
--------------------------------------------------------------------------------
/extensions/database/src/controller/DatabaseDeleteAllReferencesController.lua:
--------------------------------------------------------------------------------
1 | local json = require "json"
2 | local exception = require "exception"
3 | local exit = require "exit"
4 | local util = require "util"
5 | local database = require "database"
6 |
7 |
8 | local data = util.parseForm(ngx.req.get_body_data())
9 | local from = data.from
10 | local to = data.to
11 | local parentId = data.parentId
12 |
13 |
14 | local db = database.connect()
15 | local op = db:operators()
16 |
17 |
18 | local function f ()
19 | local typeTo = util.split(to, ".")[1]
20 | local typeFrom = util.split(from, ".")[1]
21 |
22 | if util.isNotEmpty(from) and util.isNotEmpty(to) and util.isNotEmpty(parentId) then
23 | if typeTo == typeFrom then -- self referencing
24 | if from < to then
25 | db:delete({[from .. "-" .. to] = {value = parentId}})
26 | else
27 | db:delete({[to .. "-" .. from] = {key = parentId}})
28 | end
29 | else
30 | if from < to then
31 | db:delete({[from .. "-" .. to] = {key = parentId}})
32 | else
33 | db:delete({[to .. "-" .. from] = {value = parentId}})
34 | end
35 | end
36 | else
37 | exception("from, to or parentId is empty")
38 | end
39 | end
40 |
41 |
42 | local ok, res = pcall(db.transaction, db, f)
43 | db:close()
44 |
45 |
46 | if ok then
47 | ngx.say("Delete done!")
48 | else
49 | exit(res)
50 | end
--------------------------------------------------------------------------------
/extensions/database/src/controller/DatabaseDeleteController.lua:
--------------------------------------------------------------------------------
1 | local json = require "json"
2 | local param = require "param"
3 | local exit = require "exit"
4 | local database = require "database"
5 |
6 |
7 | local instancesToDelete = json.decode(ngx.req.get_body_data())
8 |
9 |
10 | local db = database.connect()
11 | local op = db:operators()
12 |
13 | local function f ()
14 | for i=1,#instancesToDelete do
15 | db:delete({[instancesToDelete[i].type] = {id = instancesToDelete[i].id}})
16 | end
17 | end
18 |
19 | local ok, res = pcall(db.transaction, db, f)
20 | db:close()
21 |
22 |
23 | if ok then
24 | ngx.say("Delete done!")
25 | else
26 | exit(res)
27 | end
--------------------------------------------------------------------------------
/extensions/database/src/controller/DatabaseDeleteReferenceController.lua:
--------------------------------------------------------------------------------
1 | local json = require "json"
2 | local exit = require "exit"
3 | local util = require "util"
4 | local database = require "database"
5 |
6 |
7 | local instancesToDelete = json.decode(ngx.req.get_body_data())
8 |
9 |
10 | local db = database.connect()
11 | local op = db:operators()
12 |
13 | local function f ()
14 | for i=1,#instancesToDelete do
15 | local typeTo = util.split(instancesToDelete[i].to, ".")[1]
16 | local typeFrom = util.split(instancesToDelete[i].from, ".")[1]
17 |
18 | if typeTo == typeFrom then -- self referencing
19 | if instancesToDelete[i].from < instancesToDelete[i].to then
20 | db:delete({[instancesToDelete[i].from .. "-" .. instancesToDelete[i].to] =
21 | {key = instancesToDelete[i].id, value = instancesToDelete[i].parentId}})
22 | else
23 | db:delete({[instancesToDelete[i].to .. "-" .. instancesToDelete[i].from] =
24 | {key = instancesToDelete[i].parentId, value = instancesToDelete[i].id}})
25 | end
26 | else
27 | if instancesToDelete[i].from < instancesToDelete[i].to then
28 | db:delete({[instancesToDelete[i].from .. "-" .. instancesToDelete[i].to] =
29 | {key = instancesToDelete[i].parentId, value = instancesToDelete[i].id}})
30 | else
31 | db:delete({[instancesToDelete[i].to .. "-" .. instancesToDelete[i].from] =
32 | {key = instancesToDelete[i].id, value = instancesToDelete[i].parentId}})
33 | end
34 | end
35 | end
36 | end
37 |
38 | local ok, res = pcall(db.transaction, db, f)
39 | db:close()
40 |
41 |
42 | if ok then
43 | ngx.say("Delete done!")
44 | else
45 | exit(res)
46 | end
--------------------------------------------------------------------------------
/extensions/database/src/controller/DatabaseEditController.lua:
--------------------------------------------------------------------------------
1 | local json = require "json"
2 | local param = require "param"
3 | local util = require "util"
4 | local database = require "database"
5 | local types = require "type"
6 |
7 |
8 | local id = param.id
9 | local typeName = param.type
10 |
11 | if util.isNotEmpty(typeName) then
12 | if types[typeName] then
13 | local db = database.connect()
14 | local op = db:operators()
15 |
16 | local ok, res = pcall(db.find, db, {[typeName] = {id = op.equal(id)}})
17 |
18 | if ok then
19 | if #res == 1 then
20 | local type = types[typeName]
21 |
22 | -- sort property names --
23 | local propertyNames = {}
24 | for k,v in pairs(type) do propertyNames[#propertyNames + 1] = k end
25 | table.sort(propertyNames)
26 |
27 | -- wrap everything up --
28 | local arr = {}
29 | for i=1,#propertyNames do
30 | local k = propertyNames[i]
31 | local v = type[k]
32 | arr[#arr + 1] = {name = k, value = res[1][k], type = v}
33 | end
34 | arr[#arr + 1] = typeName -- last element is type name
35 |
36 | ngx.say(json.encode(arr))
37 | else
38 | ngx.say("Can't edit 0 or more then 1 results!")
39 | end
40 | else
41 | ngx.say(json.encode(res))
42 | end
43 |
44 | db:close()
45 | else
46 | ngx.say(typeName .. " does not exist!")
47 | end
48 | else
49 | ngx.say("Select type!")
50 | end
--------------------------------------------------------------------------------
/extensions/database/src/controller/DatabaseExecuteController.lua:
--------------------------------------------------------------------------------
1 | local eval = require "eval"
2 | local parse = require "parse"
3 | local json = require "json"
4 | local param = require "param"
5 | local database = require "database"
6 | local property = require "property"
7 |
8 |
9 | -- prepare cript
10 |
11 | local script = ngx.req.get_body_data()
12 |
13 | local function f (env)
14 | local res, typeName = eval.code(script, env)
15 | return res, typeName
16 | end
17 |
18 |
19 | -- execute
20 |
21 | local db = database.connect()
22 | local op = db:operators()
23 |
24 | if property.forbidDirectSqlQuery then
25 | db.query = nil
26 | end
27 |
28 | local ok, res, typeName = pcall(f, {db = db, op = op})
29 | db:close()
30 |
31 |
32 | if ok then
33 | if type(res) == "table" then
34 | if #res > 0 then
35 | local results = {}
36 | for i=1,#res do
37 | results[#results + 1] = res[i]
38 | end
39 |
40 | results[#results + 1] = typeName -- last element is type name
41 |
42 | ngx.say(json.encode(results))
43 | else
44 | if typeName then
45 | ngx.say(json.encode({res, typeName}))
46 | else
47 | ngx.say(json.encode(res))
48 | end
49 | end
50 | else
51 | ngx.say(res)
52 | end
53 | else
54 | ngx.say(res)
55 | end
--------------------------------------------------------------------------------
/extensions/database/src/controller/DatabaseSaveController.lua:
--------------------------------------------------------------------------------
1 | local json = require "json"
2 | local param = require "param"
3 | local exit = require "exit"
4 | local database = require "database"
5 |
6 |
7 | local description = json.decode(ngx.req.get_body_data())
8 |
9 |
10 | local db = database.connect()
11 | local op = db:operators()
12 |
13 | local function f ()
14 | if description.spec.id then
15 | description.properties.id = description.spec.id
16 | return db:update({[description.spec.type] = description.properties})
17 | else
18 | return db:add({[description.spec.type] = description.properties})
19 | end
20 | end
21 |
22 | local ok, res = pcall(db.transaction, db, f)
23 | db:close()
24 |
25 |
26 | if ok then
27 | ngx.say(json.encode({info = "Save done!", id = res}))
28 | else
29 | exit(res)
30 | end
--------------------------------------------------------------------------------
/extensions/database/src/controller/DatabaseTemplate.css:
--------------------------------------------------------------------------------
1 | #main {
2 | padding: 1em 0;
3 | }
4 |
5 | #databaseNavigation {
6 | overflow-x: scroll;
7 | }
8 |
9 | #editorDatabaseArea {
10 | padding: 0;
11 | }
12 |
13 | .resultbox {
14 | padding: 15px;
15 | margin: 15px;
16 |
17 | color: #333;
18 | font-size: 1em;
19 | font-weight: normal;
20 |
21 | background: #fff;
22 | border-radius: 6px;
23 | border: solid 1px #ddd;
24 |
25 | /* white-space: pre; */
26 | }
--------------------------------------------------------------------------------
/extensions/database/src/controller/DatabaseTemplate.js:
--------------------------------------------------------------------------------
1 | Widget.DatabaseTemplate = function (data) {
2 | this.data = data
3 | this.html = parse(function(){/*!
4 |
5 |
6 | {{header}}
7 |
8 |
9 |
10 |
11 | {{navigation}}
12 |
13 |
14 |
15 | {{tabs}}
16 |
17 |
18 |
19 | */}, data)
20 | }
21 |
22 | Widget.DatabaseTemplate.prototype = {
23 | constructor: Widget.DatabaseTemplate
24 | }
25 |
26 | Widget.DatabaseTemplate.maxHeight = function () {
27 | return window.innerHeight - Widget.DatabaseHeader.height() - 30 + "px"
28 | }
--------------------------------------------------------------------------------
/extensions/database/src/filter/DatabaseRedirectOnSessionTimeoutFilter.lua:
--------------------------------------------------------------------------------
1 | local property = require "property"
2 | local util = require "util"
3 | local database = require "database"
4 | local userService = require "userService"
5 |
6 |
7 |
8 | -- security --
9 | if property.requireSecurity then
10 | local db = database.connect()
11 | local ok, res = pcall(userService.loggedIn, db, {}, {"dbAdmin"})
12 | db:close()
13 |
14 | -- remove cache --
15 | ngx.ctx = {}
16 |
17 | if not ok or not res then
18 | if util.isNotEmpty(ngx.var.args) then
19 | ngx.redirect(property.securityLoginUrl .. ngx.var.uri .. "?" .. ngx.var.args)
20 | ngx.exit(ngx.HTTP_OK)
21 | else
22 | ngx.redirect(property.securityLoginUrl .. ngx.var.uri)
23 | ngx.exit(ngx.HTTP_OK)
24 | end
25 | end
26 | end
--------------------------------------------------------------------------------
/extensions/database/src/filter/DatabaseThrowErrorOnSessionTimeoutFilter.lua:
--------------------------------------------------------------------------------
1 | local param = require "param"
2 | local property = require "property"
3 | local database = require "database"
4 | local userService = require "userService"
5 |
6 |
7 |
8 | -- security --
9 | if property.requireSecurity then
10 | local db = database.connect()
11 | local ok, res = pcall(userService.loggedIn, db, {}, {"dbAdmin"})
12 | db:close()
13 |
14 | -- remove cache --
15 | ngx.ctx = {}
16 |
17 | if not ok or not res then
18 | ngx.status = ngx.HTTP_FORBIDDEN
19 | ngx.say("ERROR: user not logged in")
20 | ngx.exit(ngx.HTTP_OK)
21 | end
22 | end
--------------------------------------------------------------------------------
/extensions/database/src/widget/DatabaseEditor.js:
--------------------------------------------------------------------------------
1 | Widget.DatabaseEditor = function (data) {
2 | this.data = data
3 | this.html = parse(function(){/*!
4 |
5 | */}, data)
6 | }
7 |
8 | Widget.DatabaseEditor.prototype = {
9 | constructor: Widget.DatabaseEditor,
10 |
11 | init: function () {
12 | var aceEditor = ace.edit(this.data.id)
13 | aceEditor.setTheme("ace/theme/chrome")
14 | aceEditor.getSession().setMode("ace/mode/lua")
15 |
16 | aceEditor.setShowPrintMargin(false)
17 |
18 | aceEditor.getSession().setOptions({ tabSize: 2, useSoftTabs: true });
19 | //aceEditor.getSession().setTabSize(4)
20 | //aceEditor.getSession().setUseSoftTabs(true)
21 |
22 | //aceEditor.getSession().setUseWorker(false) // disable syntax checker and information
23 |
24 | document.getElementById(this.data.id).style.fontSize = "14px"
25 | document.getElementById(this.data.id).style.height = Widget.DatabaseTemplate.maxHeight()
26 |
27 | this.aceEditor = aceEditor
28 | },
29 |
30 | setValue: function (content) {
31 | // delete previous and set new content
32 | this.aceEditor.removeLines()
33 | this.aceEditor.setValue(content, -1)
34 | this.aceEditor.navigateFileStart()
35 | },
36 |
37 | getValue: function () {
38 | return this.aceEditor.getValue()
39 | }
40 | }
--------------------------------------------------------------------------------
/extensions/database/src/widget/DatabaseHeader.css:
--------------------------------------------------------------------------------
1 | #dbmenu {
2 | color: {{baseline_color2}};
3 | }
4 |
5 | .hand {
6 | cursor: pointer;
7 | }
--------------------------------------------------------------------------------
/extensions/database/src/widget/DatabaseNavigation.css:
--------------------------------------------------------------------------------
1 | .database {
2 | color: {{baseline_color2}};
3 | cursor: pointer;
4 | }
5 |
6 | ul.no-bullets
7 | {
8 | list-style-type: none;
9 | padding-left: 0em;
10 | margin: 0em;
11 | }
12 |
13 | .nowrap {
14 | white-space: nowrap;
15 | }
--------------------------------------------------------------------------------
/extensions/database/src/widget/DatabaseNavigation.js:
--------------------------------------------------------------------------------
1 | Widget.DatabaseNavigation = function (types) {
2 | types = types || []
3 |
4 | for (var i = 0; i < types.length; i++) {types[i].guid = Widget.guid()}
5 |
6 | var filteredTypes = []
7 | for (var i = 0; i < types.length; i++) {
8 | if (types[i].name.indexOf("-") < 0) {filteredTypes.push(types[i])}
9 | }
10 |
11 | var data = {types: filteredTypes}
12 |
13 | this.data = data
14 | this.html = parse(function(){/*!
15 | {{? types.length > 0
16 |
27 | }}?
28 | */}, data)
29 | }
30 |
31 | Widget.DatabaseNavigation.prototype = {
32 | constructor: Widget.DatabaseNavigation,
33 |
34 | init: function () {
35 | $("#databaseNavigation").css("max-height", Widget.DatabaseTemplate.maxHeight())
36 | }
37 | }
38 |
39 | Widget.DatabaseNavigation.selectType = function (type, guid) {
40 | Widget.DatabaseNavigation.selectDatabaseGuid(guid)
41 | Widget.DatabaseNavigation.type = type
42 | }
43 |
44 | Widget.DatabaseNavigation.selectDatabaseGuid = function (guid) {
45 | if (!isEmpty(vars.databaseGuid)) {
46 | $("#" + vars.databaseGuid).css("font-weight", "normal")
47 | $("#" + vars.databaseGuid + " span.navigationName").css('text-decoration', 'none')
48 | }
49 |
50 | vars.databaseGuid = guid
51 | $("#" + vars.databaseGuid).css("font-weight", "900")
52 | $("#" + vars.databaseGuid + " span.navigationName").css('text-decoration', 'underline')
53 | }
--------------------------------------------------------------------------------
/extensions/database/src/widget/DatabaseResult.js:
--------------------------------------------------------------------------------
1 | Widget.DatabaseResult = function (results) {
2 | var type
3 | if (results.length > 0 && typeof(results[results.length - 1]) == "string") {
4 | type = results.splice(results.length - 1, 1)[0]
5 | } else {
6 | type = ""
7 | }
8 |
9 | var guid = []
10 | for (var i = 0; i < results.length; i++) {guid.push(Widget.guid())}
11 |
12 | var data = {type: type, results: results, guid: guid}
13 |
14 | this.data = data
15 | this.html = parse(function(){/*!
16 | {{? results.length > 0
17 | {{type}}
18 |
19 |
38 | }}?
39 | */}, data)
40 | }
41 |
42 | Widget.DatabaseResult.prototype = {
43 | constructor: Widget.DatabaseResult
44 | }
--------------------------------------------------------------------------------
/extensions/database/src/widget/DatabaseTabs.js:
--------------------------------------------------------------------------------
1 | Widget.DatabaseTabs = function (data) {
2 | this.data = data
3 | this.html = parse(function(){/*!
4 |
5 | {{# tabs[i]
6 |
8 | {{tabs[i].html}}
9 |
10 | }}#
11 |
12 | */}, data)
13 | }
14 |
15 | Widget.DatabaseTabs.prototype = {
16 | constructor: Widget.DatabaseTabs
17 | }
--------------------------------------------------------------------------------
/extensions/database/static/database-favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/strumasoft/octopus/4d66e3d6045cbd533353696abd80e48b1d606f18/extensions/database/static/database-favicon.ico
--------------------------------------------------------------------------------
/extensions/demo/config.lua:
--------------------------------------------------------------------------------
1 | local config = {} -- extension configuration
2 |
3 | config.localization = {
4 | helloMessage = {en = "Hello World", bg = "Здравейте!!!!"},
5 | copyright = {
6 | en = "© cyberz.eu. All rights reserved.",
7 | bg = "© cyberz.eu. Всички права запазени."},
8 | reload = {en = "Reload", bg = "Презареди"},
9 | showError = {en = "Show Error", bg = "Покажи Грешката"},
10 | addToCart = {en = "Buy", bg = "Купи"},
11 | clickToClose = {en = "click to close", bg = "натисни за да го скриеш"},
12 | noErrors = {en = "no errors", bg = "няма грешки"},
13 | index = {en = "Index", bg = "начало"},
14 | }
15 |
16 | config.location = {
17 | {name = "/", script = "controller/IndexController.lua"},
18 | {name = "/hello", script = "controller/HelloWorldController.lua"},
19 | {name = "/product", script = "controller/ProductDetailController.lua"},
20 | }
21 |
22 | config.module = {
23 | {name = "DemoProductService", script = "module/DemoProductService.lua"},
24 | }
25 |
26 | config.html = {
27 | {name = "t1", script = "widget/DemoTemplate1.lua"},
28 | {name = "t2", script = "widget/DemoTemplate2.lua"},
29 | }
30 |
31 | config.javascript = {
32 | {name = "DemoProductDetail", script = "widget/DemoProductDetail.js"},
33 | {name = "DemoError", script = "widget/DemoError.js"},
34 | {name = "DemoHeader", script = "widget/DemoHeader.js"},
35 | {name = "DemoFooter", script = "widget/DemoFooter.js"},
36 | }
37 |
38 | config.stylesheet = {
39 |
40 | }
41 |
42 | config.static = {
43 | "static"
44 | }
45 |
46 | config.type = {
47 |
48 | }
49 |
50 | return config -- return extension configuration
--------------------------------------------------------------------------------
/extensions/demo/src/controller/HelloWorldController.lua:
--------------------------------------------------------------------------------
1 | local _ = require "template"
2 |
3 | ngx.header.content_type = 'text/plain'
4 |
5 | ngx.say(_.t1{
6 | _ = _, -- import template
7 | message1 = "Hello",
8 | message2 = "Worrld",
9 | message3 = "!!!",
10 | })
11 |
12 | ngx.say(_.t2{
13 | message = "gogo",
14 | logo = "$",
15 | array = {{1,2}, {3,4}, {5,6}},
16 | array2 = {7,8},
17 | array3 = {
18 | x = "X",
19 | y = "Y"
20 | },
21 | array4 = {},
22 | })
--------------------------------------------------------------------------------
/extensions/demo/src/controller/IndexController.lua:
--------------------------------------------------------------------------------
1 | ngx.say([[
2 | Demo
3 | Hello World
4 |
5 | Product with code 1
6 |
7 | Editor & Repository
8 | Editor
9 |
10 | Database
11 | Database, requires proper database credentials, see config.lua
12 |
13 | Shop
14 | Shop, requires import from Database, execute:
15 |
16 | db:dropAllTables()
17 | db:createAllTables()
18 | db:import("shopImport")
19 |
20 | use the following credentials - username 'test@test.com' and password 'test'
21 |
22 | ]])
--------------------------------------------------------------------------------
/extensions/demo/src/controller/ProductDetailController.lua:
--------------------------------------------------------------------------------
1 | local json = require "json"
2 | local parse = require "parse"
3 | local property = require "property"
4 | local localization = require "localization"
5 | local exception = require "exception"
6 | local param = require "param"
7 | local productService = require "DemoProductService"
8 |
9 |
10 |
11 | local function process (data)
12 | data.locale = "en"
13 |
14 | local productCode = param.code
15 | if productCode then
16 | local product = productService.getProduct(productCode)
17 | data.product = product
18 | else
19 | exception("product code required")
20 | end
21 | end
22 |
23 |
24 | local data = {}
25 | local ok, err = pcall(process, data)
26 | if not ok then
27 | data.error = {err}
28 | end
29 |
30 |
31 | ngx.say(parse(require("BaselineHtmlTemplate"), {
32 | title = "Product Detail",
33 | externalJS = [[
34 |
35 | ]],
36 | externalCSS = [[
37 |
38 | ]],
39 | initJS = parse([[
40 | var vars = {}
41 |
42 | vars.locale = {{locale}}
43 |
44 | Widget.setHeader(new Widget.DemoHeader())
45 | Widget.setContainerToPage([
46 | [
47 | {size: "12u", widget: new Widget.DemoError({{error}})}
48 | ],
49 | [
50 | {size: "9u -3u", medium: "8u -4u", small: "12u", widget: new Widget.DemoProductDetail({{product}})}
51 | ]
52 | ])
53 | Widget.setFooter(new Widget.DemoFooter())
54 | ]], json.encodeProperties(data))
55 | }))
--------------------------------------------------------------------------------
/extensions/demo/src/module/DemoProductService.lua:
--------------------------------------------------------------------------------
1 | local exception = require "exception"
2 |
3 |
4 | local function getProduct (productCode)
5 | if productCode == "1" then
6 | return {
7 | code = "1",
8 | name = "Box",
9 | description = "Very good box",
10 | price = "$20",
11 | picture = "/demo/static/box.jpg",
12 | width = "300px",
13 | height = "300px",
14 | }
15 | else
16 | exception("product '" .. productCode .. "' not found")
17 | end
18 | end
19 |
20 |
21 | return {
22 | getProduct = getProduct,
23 | }
--------------------------------------------------------------------------------
/extensions/demo/src/widget/DemoError.js:
--------------------------------------------------------------------------------
1 | Widget.DemoError = function (errors) {
2 | var data = {errors: errors}
3 |
4 | this.data = data
5 | this.html = parse(function(){/*!
6 | {{?@ data.errors instanceof Array
7 |
8 |
9 |
10 | {{# errors[i]
11 |
{{errors[i]}}
12 | }}#
13 |
14 | }}?
15 | */}, data)
16 | }
17 |
18 | Widget.DemoError.prototype = {
19 | constructor: Widget.DemoError
20 | }
21 |
22 | Widget.DemoError.hide = function (guid) {
23 | $("#errors").hide()
24 | }
--------------------------------------------------------------------------------
/extensions/demo/src/widget/DemoFooter.js:
--------------------------------------------------------------------------------
1 | Widget.DemoFooter = function (data) {
2 | data = data || {}
3 |
4 | this.data = data
5 | this.html = parse(function(){/*!
6 |
11 | */}, data)
12 | }
13 |
14 | Widget.DemoFooter.prototype = {
15 | constructor: Widget.DemoFooter
16 | }
--------------------------------------------------------------------------------
/extensions/demo/src/widget/DemoHeader.js:
--------------------------------------------------------------------------------
1 | Widget.DemoHeader = function (data) {
2 | data = data || {}
3 |
4 | this.data = data
5 | this.html = parse(function(){/*!
6 |
21 | */}, data)
22 | }
23 |
24 | Widget.DemoHeader.prototype = {
25 | constructor: Widget.DemoHeader
26 | }
27 |
28 | Widget.DemoHeader.showError = function () {
29 | if($("#errors").length == 0) {
30 | var infoPopup = new Widget.InfoPopup({info: localize("noErrors")})
31 | } else {
32 | $("#errors").show()
33 | }
34 | }
--------------------------------------------------------------------------------
/extensions/demo/src/widget/DemoProductDetail.js:
--------------------------------------------------------------------------------
1 | Widget.DemoProductDetail = function (product) {
2 | var data = {product: product, pictureWidth: property.pictureWidth, pictureHeight: property.pictureHeight}
3 |
4 | this.data = data
5 | this.html = parse(function(){/*!
6 |
7 | {{?@ data.product != null
8 |
9 |
10 |
15 |
16 |
17 |
{{product.name}}
18 |
19 |
20 |
21 | 1 Reviews |
22 | Write a review
23 |
24 |
25 |
26 | Product Code:
27 | {{product.code}}
28 |
29 |
30 |
31 | {{product.price}}
32 |
33 |
34 |
35 |
36 |
37 |
38 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
Description
52 |
Lorem ipsum dolor sit amet, consectetur adipisicing elit
53 |
54 |
55 |
56 |
57 |
58 |
59 |
Reviews (1)
60 |
61 |

62 |
63 |
Aliquam a malesuada lorem. Nunc in porta.
64 |
65 |
66 |
67 |
68 | }}?
69 |
70 | */}, data)
71 | }
72 |
73 | Widget.DemoProductDetail.prototype = {
74 | constructor: Widget.DemoProductDetail
75 | }
76 |
77 | Widget.DemoProductDetail.addToCart = function (productCode, price) {
78 | var infoPopup = new Widget.InfoPopup({info: "Buy product '" + productCode + "' for " + price})
79 | }
--------------------------------------------------------------------------------
/extensions/demo/src/widget/DemoTemplate1.lua:
--------------------------------------------------------------------------------
1 | return [[
2 |
3 |
4 |
5 | {{message1}}
6 |
7 | {{message2}}
8 |
9 | {{message3}}
10 |
11 | {{
12 | _.t2({message = message1 .. message2 .. message3})
13 | }}
14 |
15 | {{= ddd = message1 .. message2 .. message3 }}=
16 | ddd={{ddd}}
17 |
18 | {{@ json }}@
19 | {{ json.encode({a = 3, b = 2}) }}
20 |
21 |
22 |
23 | ----------------------------------------
24 |
25 |
26 | ]]
--------------------------------------------------------------------------------
/extensions/demo/src/widget/DemoTemplate2.lua:
--------------------------------------------------------------------------------
1 | return [[
2 | ^hi-{{message}}$boy|
3 | {{# array2
4 | this row will SHOW
5 | }}#
6 | {{# unknownArray
7 | this row will NOT SHOW
8 | }}#
9 | {{# array5
10 | this row will NOT SHOW TOO
11 | }}#
12 |
13 | {{# array
14 | {{## array[i]
15 | +{{array[i][ii]}}|
16 | }}##
17 |
18 | {{? logo == "$$"
19 | {{## array2
20 | _{{array2[ii]}}|
21 | }}##
22 | }}?
23 | }}#
24 |
25 | {{message}}
26 |
27 | {{# array2
28 | -{{array2[i]}}|
29 | }}#
30 |
31 | usb<>{{logo}}
32 |
33 | {{? logo == "$"
34 | www!
35 |
36 | {{?? logo == "$"
37 | x{{array2[2]}}
38 |
39 | {{# array2
40 | ={{array2[i]}}|
41 | }}#
42 | }}??
43 | }}?
44 |
45 | {{# array3
46 | {{i}} = {{array3[i]}}
47 | }}#
48 |
49 |
50 | ]]
--------------------------------------------------------------------------------
/extensions/demo/static/box.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/strumasoft/octopus/4d66e3d6045cbd533353696abd80e48b1d606f18/extensions/demo/static/box.jpg
--------------------------------------------------------------------------------
/extensions/demo/static/stars-5.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/strumasoft/octopus/4d66e3d6045cbd533353696abd80e48b1d606f18/extensions/demo/static/stars-5.png
--------------------------------------------------------------------------------
/extensions/editor/src/controller/CompareController.lua:
--------------------------------------------------------------------------------
1 | local parse = require "parse"
2 |
3 |
4 | ngx.say(parse(require("BaselineHtmlTemplate"), {
5 | title = "Compare",
6 | externalJS = [[
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 | ]],
18 | externalCSS = [[
19 |
20 | ]],
21 | customJS = [[
22 | function diffUsingJS(viewType, originalContent, changedContent) {
23 | "use strict";
24 | var byId = function (id) { return document.getElementById(id); },
25 | base = difflib.stringAsLines(originalContent),
26 | newtxt = difflib.stringAsLines(changedContent),
27 | sm = new difflib.SequenceMatcher(base, newtxt),
28 | opcodes = sm.get_opcodes(),
29 | diffoutputdiv = byId("diffoutput");
30 |
31 | diffoutputdiv.innerHTML = "";
32 | var contextSize = null;
33 |
34 | diffoutputdiv.appendChild(diffview.buildView({
35 | baseTextLines: base,
36 | newTextLines: newtxt,
37 | opcodes: opcodes,
38 | baseTextName: "OLD",
39 | newTextName: "NEW",
40 | contextSize: contextSize,
41 | viewType: viewType
42 | }));
43 | }
44 | ]],
45 | initJS = [[
46 | var vars = {}
47 |
48 | vars.originalEditor = new Widget.CompareEditor({id: "originalEditor", name: "Old"})
49 | vars.changedEditor = new Widget.CompareEditor({id: "changedEditor", name: "New"})
50 |
51 | Widget.setContainerToPage([
52 | [
53 | {size: "12u", widget: new Widget.CompareHeader()}
54 | ],
55 | [
56 | {size: "6u", small: "12u", widget: vars.originalEditor},
57 | {size: "6u", small: "12u", widget: vars.changedEditor}
58 | ],
59 | [
60 | {size: "12u", widget: new Widget.CompareTabs()}
61 | ]
62 | ])
63 |
64 | vars.originalEditor.init()
65 | vars.originalEditor.setHeight("20em")
66 | vars.changedEditor.init()
67 | vars.changedEditor.setHeight("20em")
68 | ]]
69 | }))
--------------------------------------------------------------------------------
/extensions/editor/src/controller/EditorController.lua:
--------------------------------------------------------------------------------
1 | local json = require "json"
2 | local parse = require "parse"
3 | local param = require "param"
4 | local property = require "property"
5 | local directory = require "Directory"
6 | local util = require "util"
7 | local fileutil = require "fileutil"
8 |
9 |
10 |
11 | local directoryName = param.directoryName
12 | local dirs, parent, title, isGIT
13 |
14 | if directoryName then
15 | dirs = directory.sortedEntries(directoryName)
16 |
17 | for _,v in pairs(dirs) do
18 | if v.name == ".git" and v.mode == "directory" then isGIT = true end
19 | end
20 |
21 | local paths = util.split(directoryName, "/")
22 | parent = {path = directoryName, name = paths[#paths], mode = "directory"}
23 |
24 | title = paths[#paths]
25 | else
26 | local system = io.popen("uname -s"):read("*l")
27 |
28 | local drives
29 | if system == nil then
30 | drives = {"c:/", "d:/"}
31 | else
32 | drives = {"/"}
33 | end
34 |
35 | dirs = {}
36 | for i = 1, #drives do
37 | dirs[#dirs + 1] = {path = drives[i], name = drives[i], mode = "directory"}
38 | end
39 |
40 | parent = nil
41 |
42 | title = "/"
43 | end
44 |
45 |
46 | ngx.say(parse(require("BaselineHtmlTemplate"), {
47 | title = title,
48 | externalJS = [[
49 |
50 |
51 | ]],
52 | externalCSS = [[
53 |
54 | ]],
55 | initJS = parse([[
56 | var vars = {}
57 |
58 | {{? isGIT
59 | vars.repository = {repository: "GIT"}
60 | }}?
61 |
62 | var editor = new Widget.Editor({id: "editor"})
63 | var editorNavigation = new Widget.EditorNavigation({{dirs}}, {{parent}})
64 | var editorHeader = new Widget.EditorHeader("{{title}}")
65 |
66 | var editorTemplate = new Widget.EditorTemplate({
67 | editor: editor.html,
68 | navigation: editorNavigation.html,
69 | header: editorHeader.html
70 | })
71 |
72 | Widget.setHtmlToPage(editorTemplate.html);
73 |
74 | editor.init()
75 | editorNavigation.init()
76 | ]], {
77 | isGIT = isGIT,
78 | title = fileutil.escapeCommandlineSpecialCharacters(title),
79 | dirs = json.encode(dirs),
80 | parent = json.encode(parent)
81 | })
82 | }))
--------------------------------------------------------------------------------
/extensions/editor/src/controller/EditorDownloadFileController.lua:
--------------------------------------------------------------------------------
1 | local param = require "param"
2 | local exit = require "exit"
3 | local util = require "util"
4 | local editor = require "Editor"
5 |
6 |
7 |
8 | ngx.header.content_type = 'application/octet-stream'
9 |
10 |
11 | local function process ()
12 | local fileName = param.f
13 |
14 | local paths = util.split(fileName, "/")
15 | local name = paths[#paths]
16 | ngx.header["Content-Disposition"] = 'attachment; filename="' .. name .. '"'
17 |
18 | return editor.fileContent(fileName)
19 | end
20 |
21 |
22 | local ok, res = pcall(process)
23 | if ok then
24 | if res then ngx.say(res) end
25 | else
26 | exit(res)
27 | end
--------------------------------------------------------------------------------
/extensions/editor/src/controller/EditorEditFileController.lua:
--------------------------------------------------------------------------------
1 | local json = require "json"
2 | local param = require "param"
3 | local property = require "property"
4 | local exit = require "exit"
5 | local editor = require "Editor"
6 | local parse = require "parse"
7 | local directory = require "Directory"
8 | local util = require "util"
9 | local fileutil = require "fileutil"
10 |
11 |
12 |
13 | local externalJS = [[
14 |
15 |
16 | ]]
17 |
18 |
19 | local externalCSS = [[
20 |
21 | ]]
22 |
23 |
24 | local initJSTemplate = [[
25 | var vars = {}
26 |
27 | var editor = new Widget.Editor({id: "editor"})
28 | var editorSearchHeader = new Widget.EditorSearchHeader("{{title}}")
29 |
30 | var editorSearchTemplate = new Widget.EditorSearchTemplate({
31 | editor: editor.html,
32 | header: editorSearchHeader.html
33 | })
34 |
35 | Widget.setHtmlToPage(editorSearchTemplate.html);
36 |
37 | editor.init((window.innerHeight - Widget.EditorHeader.height()) + "px")
38 | vars.searchEditor = editor
39 |
40 | Widget.EditorSearchHeader.toggle();
41 | Widget.EditorNavigation.openFile("{{fileName}}", Widget.guid())
42 | ]]
43 |
44 |
45 | local function process ()
46 | local directoryName = param.directoryName
47 | local fileName = param.fileName
48 |
49 | local paths = util.split(fileName, "/")
50 | local title = paths[#paths]
51 |
52 | return parse(require("BaselineHtmlTemplate"), {
53 | title = title,
54 | externalJS = externalJS,
55 | externalCSS = externalCSS,
56 | initJS = parse(initJSTemplate, {
57 | title = fileutil.escapeCommandlineSpecialCharacters(title),
58 | fileName = fileName
59 | })
60 | })
61 | end
62 |
63 |
64 | local ok, res = pcall(process)
65 | if ok then
66 | if res then ngx.say(res) end
67 | else
68 | exit(res)
69 | end
--------------------------------------------------------------------------------
/extensions/editor/src/controller/EditorSearchTemplate.js:
--------------------------------------------------------------------------------
1 | Widget.EditorSearchTemplate = function (data) {
2 | this.data = data
3 | this.html = parse(function(){/*!
4 |
5 |
6 | {{header}}
7 |
8 |
9 | {{? searchResult
10 |
11 |
12 | {{searchResult}}
13 |
14 |
15 | }}?
16 |
17 | {{editor}}
18 |
19 |
20 |
21 | */}, data)
22 | }
23 |
24 | Widget.EditorSearchTemplate.prototype = {
25 | constructor: Widget.EditorSearchTemplate
26 | }
--------------------------------------------------------------------------------
/extensions/editor/src/controller/EditorTemplate.css:
--------------------------------------------------------------------------------
1 | #main {
2 | padding: 1em 0;
3 | }
4 |
5 | #directoryNavigation {
6 | overflow-x: scroll;
7 | margin-right: 8px;
8 | }
9 |
10 | #editorArea {
11 | padding: 0;
12 | }
13 |
14 | #editorSearchArea.editorSearchWrapper {
15 | padding: 0;
16 | }
--------------------------------------------------------------------------------
/extensions/editor/src/controller/EditorTemplate.js:
--------------------------------------------------------------------------------
1 | Widget.EditorTemplate = function (data) {
2 | this.data = data
3 | this.html = parse(function(){/*!
4 |
5 |
6 | {{header}}
7 |
8 |
9 |
10 |
11 | {{navigation}}
12 |
13 |
14 |
15 | {{editor}}
16 |
17 |
18 |
19 | */}, data)
20 | }
21 |
22 | Widget.EditorTemplate.prototype = {
23 | constructor: Widget.EditorTemplate,
24 |
25 | setDirectoryNavigation: function (html) {
26 | $("#directoryNavigation").html(html)
27 | }
28 | }
29 |
30 | Widget.EditorTemplate.maxHeight = function () {
31 | return (window.innerHeight - Widget.EditorHeader.height() - 25) + "px"
32 | }
33 |
--------------------------------------------------------------------------------
/extensions/editor/src/controller/operation/CreateDirectoryController.lua:
--------------------------------------------------------------------------------
1 | local param = require "param"
2 | local exit = require "exit"
3 | local util = require "util"
4 | local editor = require "Editor"
5 |
6 |
7 |
8 | local function process ()
9 | local directoryName = param.directoryName
10 |
11 | editor.createDirectory(directoryName)
12 |
13 | if util.isNotEmpty(param.repository) then
14 | local repository = require(param.repository)
15 |
16 | local username = param.username
17 | local password = param.password
18 |
19 | if param.repository == "SVN" then
20 | return repository.add(username, password, directoryName)
21 | end
22 | end
23 | end
24 |
25 |
26 | local ok, res = pcall(process)
27 | if ok then
28 | if res then ngx.say(res) end
29 | else
30 | exit(res)
31 | end
--------------------------------------------------------------------------------
/extensions/editor/src/controller/operation/CreateFileController.lua:
--------------------------------------------------------------------------------
1 | local param = require "param"
2 | local exit = require "exit"
3 | local util = require "util"
4 | local editor = require "Editor"
5 |
6 |
7 |
8 | local function process ()
9 | local fileName = param.fileName
10 |
11 | editor.createFile(fileName)
12 |
13 | if util.isNotEmpty(param.repository) then
14 | local repository = require(param.repository)
15 |
16 | local username = param.username
17 | local password = param.password
18 |
19 | return repository.add(username, password, fileName)
20 | end
21 | end
22 |
23 |
24 | local ok, res = pcall(process)
25 | if ok then
26 | if res then ngx.say(res) end
27 | else
28 | exit(res)
29 | end
--------------------------------------------------------------------------------
/extensions/editor/src/controller/operation/DirectoryController.lua:
--------------------------------------------------------------------------------
1 | local json = require "json"
2 | local param = require "param"
3 | local exit = require "exit"
4 | local directory = require "Directory"
5 |
6 |
7 |
8 | local function process ()
9 | local dir = param.d
10 | if dir == nil then dir = "/" end
11 |
12 | return json.encode(directory.sortedEntries(dir))
13 | end
14 |
15 |
16 | local ok, res = pcall(process)
17 | if ok then
18 | if res then ngx.say(res) end
19 | else
20 | exit(res)
21 | end
--------------------------------------------------------------------------------
/extensions/editor/src/controller/operation/FileContentController.lua:
--------------------------------------------------------------------------------
1 | local param = require "param"
2 | local exit = require "exit"
3 | local util = require "util"
4 | local editor = require "Editor"
5 |
6 |
7 |
8 | local notPlainTextExtensions = [[
9 | flac mp3 ogg oga mogg raw voc vox wav wma wv webm
10 | 3gp 3g2 flv f4v f4p f4a f4b ogv gif gifv avi mp4 m4p m4v mpg mp2 mpeg mpe mpv mts m2ts mov qt wmv yuv
11 | jpg jpeg jpe jif jfif jfi png webp tiff tif psd raw arw cr2 nrw k25 bmp dib heif heic ind indd indt jp2 j2k jpf jpx jpm mj2 ico svgz ai eps
12 | pdf doc docx dot odt ott xls xlsx ppt pptx
13 | exe dll so o a ar cpio shar lbr iso mar sbx f xf lz lzma lzmo rz sfark sz q z xz
14 | 7z s7z ace afa alz apk arc ark cdx b1 cab dmg jar rar gz tgz tbz2 tar bz2 txz war zip zipx zz
15 | ]]
16 |
17 | ngx.header.content_type = 'text/plain'
18 |
19 |
20 | local function process ()
21 | local fileName = param.f
22 |
23 | local paths = util.split(fileName, "/")
24 | local name = paths[#paths]
25 |
26 | local extensions, hasExtension = util.split(name, ".")
27 | local extension = extensions[#extensions]
28 |
29 | if hasExtension and notPlainTextExtensions:findQuery(" " .. extension .. " ", 1, true, true) then
30 | return "File is not plain text!"
31 | else
32 | return editor.fileContent(fileName)
33 | end
34 | end
35 |
36 |
37 | local ok, res = pcall(process)
38 | if ok then
39 | if res then ngx.say(res) end
40 | else
41 | exit(res)
42 | end
43 |
--------------------------------------------------------------------------------
/extensions/editor/src/controller/operation/RemoveController.lua:
--------------------------------------------------------------------------------
1 | local param = require "param"
2 | local exit = require "exit"
3 | local util = require "util"
4 | local editor = require "Editor"
5 |
6 |
7 |
8 | local function process ()
9 | local path = param.path
10 |
11 | if util.isNotEmpty(param.repository) then
12 | local repository = require(param.repository)
13 |
14 | local username = param.username
15 | local password = param.password
16 |
17 | if param.repository == "GIT" and param.isFile == "false" then
18 | editor.remove(path)
19 | else
20 | return repository.delete(username, password, path)
21 | end
22 | else
23 | editor.remove(path)
24 | end
25 | end
26 |
27 |
28 | local ok, res = pcall(process)
29 | if ok then
30 | if res then ngx.say(res) end
31 | else
32 | exit(res)
33 | end
--------------------------------------------------------------------------------
/extensions/editor/src/controller/operation/RenameController.lua:
--------------------------------------------------------------------------------
1 | local param = require "param"
2 | local exit = require "exit"
3 | local util = require "util"
4 | local editor = require "Editor"
5 |
6 |
7 |
8 | local function process ()
9 | local oldName = param.oldName
10 | local newName = param.newName
11 |
12 | if util.isNotEmpty(param.repository) then
13 | local repository = require(param.repository)
14 |
15 | local username = param.username
16 | local password = param.password
17 | local directoryName = param.directoryName
18 |
19 | return repository.move(username, password, oldName, newName, directoryName)
20 | else
21 | editor.rename(oldName, newName)
22 | end
23 | end
24 |
25 |
26 | local ok, res = pcall(process)
27 | if ok then
28 | if res then ngx.say(res) end
29 | else
30 | exit(res)
31 | end
--------------------------------------------------------------------------------
/extensions/editor/src/controller/operation/SaveController.lua:
--------------------------------------------------------------------------------
1 | local param = require "param"
2 | local exit = require "exit"
3 | local editor = require "Editor"
4 |
5 |
6 |
7 | local function process ()
8 | local fileName = param.f
9 |
10 | editor.save(fileName, ngx.req.get_body_data())
11 | end
12 |
13 |
14 | local ok, res = pcall(process)
15 | if ok then
16 | if res then ngx.say(res) end
17 | else
18 | exit(res)
19 | end
--------------------------------------------------------------------------------
/extensions/editor/src/filter/EditorRedirectOnSessionTimeoutFilter.lua:
--------------------------------------------------------------------------------
1 | local property = require "property"
2 | local database = require "database"
3 | local util = require "util"
4 | local userService = require "userService"
5 |
6 |
7 |
8 | -- security --
9 | if property.requireSecurity then
10 | local db = database.connect()
11 | local ok, res = pcall(userService.loggedIn, db, {}, {"codeEditor"})
12 | db:close()
13 |
14 | -- remove cache --
15 | ngx.ctx = {}
16 |
17 | if not ok or not res then
18 | if util.isNotEmpty(ngx.var.args) then
19 | ngx.redirect(property.securityLoginUrl .. ngx.var.uri .. "?" .. ngx.var.args)
20 | ngx.exit(ngx.HTTP_OK)
21 | else
22 | ngx.redirect(property.securityLoginUrl .. ngx.var.uri)
23 | ngx.exit(ngx.HTTP_OK)
24 | end
25 | end
26 | end
--------------------------------------------------------------------------------
/extensions/editor/src/filter/EditorThrowErrorOnSessionTimeoutFilter.lua:
--------------------------------------------------------------------------------
1 | local param = require "param"
2 | local property = require "property"
3 | local database = require "database"
4 | local userService = require "userService"
5 |
6 |
7 |
8 | -- security --
9 | if property.requireSecurity then
10 | local db = database.connect()
11 | local ok, res = pcall(userService.loggedIn, db, {}, {"codeEditor"})
12 | db:close()
13 |
14 | -- remove cache --
15 | ngx.ctx = {}
16 |
17 | if not ok or not res then
18 | ngx.status = ngx.HTTP_FORBIDDEN
19 | ngx.say("ERROR: user not logged in")
20 | ngx.exit(ngx.HTTP_OK)
21 | end
22 | end
--------------------------------------------------------------------------------
/extensions/editor/src/module/Directory.lua:
--------------------------------------------------------------------------------
1 | local m = {} -- module
2 |
3 |
4 | local lfs = require "lfs"
5 | local fileutil = require "fileutil"
6 |
7 |
8 | --
9 | -- sourceCtxPath
10 | --
11 |
12 | local function sourceCtxPath ()
13 | local property = require "property"
14 | return property.sourceCtxPath or ""
15 | end
16 |
17 |
18 | function m.entries(dir)
19 | assert(dir and dir ~= "", "directory parameter is missing or empty")
20 |
21 | -- remove slash at the end of directory unless root is specified
22 | if dir ~= "/" then
23 | if string.sub(dir, -1) == "/" then
24 | dir = string.sub(dir, 1, -2)
25 | end
26 | end
27 |
28 | fileutil.noBackDirectory(dir)
29 |
30 | -- collect all entries in map with attributes
31 | local map = {}
32 | for entry in lfs.dir(sourceCtxPath() .. dir) do
33 | if entry ~= "." and entry ~= ".." then
34 | local path
35 | if dir ~= "/" then
36 | path = dir .. "/" .. entry
37 | else
38 | path = "/" .. entry
39 | end
40 |
41 | local attr = lfs.attributes(sourceCtxPath() .. path)
42 | if attr then
43 | attr.path = path
44 | map[entry] = attr
45 | else
46 | map[entry] = {path = path, mode = "unknown"}
47 | end
48 | end
49 | end
50 |
51 | return map
52 | end
53 |
54 |
55 | function m.sortedEntries(dir)
56 | -- get map of dir entries and their attributes --
57 | local map = m.entries(dir)
58 |
59 | -- sort dir and file entries --
60 | local sortedEntries, dirEntries, fileEntries = {}, {}, {}
61 | for entry, attr in pairs(map) do
62 | if attr.mode == "directory" then
63 | dirEntries[#dirEntries + 1] = entry
64 | else
65 | fileEntries[#fileEntries + 1] = entry
66 | end
67 | end
68 | table.sort(dirEntries)
69 | for i=1,#dirEntries do sortedEntries[#sortedEntries + 1] = dirEntries[i] end
70 | table.sort(fileEntries)
71 | for i=1,#fileEntries do sortedEntries[#sortedEntries + 1] = fileEntries[i] end
72 |
73 | -- wrap evrything up --
74 | local dirs = {}
75 | for i=1,#sortedEntries do
76 | local entry = sortedEntries[i]
77 | local attr = map[entry]
78 | dirs[#dirs + 1] = {path = attr.path, name = entry, mode = attr.mode}
79 | end
80 |
81 | return dirs
82 | end
83 |
84 |
85 | return m -- return module
--------------------------------------------------------------------------------
/extensions/editor/src/widget/CompareEditor.js:
--------------------------------------------------------------------------------
1 | Widget.CompareEditor = function (data) {
2 | var editor = new Widget.Editor(data)
3 |
4 | editor.html = parse(function(){/*!
5 | {{name}}
6 |
7 | */}, data)
8 |
9 | return editor
10 | }
11 |
12 | Widget.CompareEditor.prototype = {
13 | constructor: Widget.CompareEditor
14 | }
--------------------------------------------------------------------------------
/extensions/editor/src/widget/CompareHeader.js:
--------------------------------------------------------------------------------
1 | Widget.CompareHeader = function () {
2 | var data = {}
3 | if (localStorage.getItem("isDark") === "true") {
4 | data.theme = "fa-moon-o";
5 | setTimeout(() => Widget.EditorHeader.theme(true), 50);
6 | } else {
7 | data.theme = "fa-sun-o";
8 | }
9 |
10 | this.data = data
11 | this.html = parse(function(){/*!
12 |
29 | */}, data)
30 | }
31 |
32 | Widget.CompareHeader.prototype = {
33 | constructor: Widget.CompareHeader
34 | }
35 |
36 | Widget.CompareHeader.compare = function () {
37 | var originalContent = vars.originalEditor.getValue()
38 | var changedContent = vars.changedEditor.getValue()
39 |
40 | $("#oldfilecontent .diffbox").html(Widget.createHTML(originalContent))
41 | $("#newfilecontent .diffbox").html(Widget.createHTML(changedContent))
42 |
43 | diffUsingJS(0, originalContent, changedContent)
44 |
45 | $("#comparator").prettyTextDiff({
46 | cleanup: $("#cleanup").is(":checked"),
47 | originalContent: originalContent,
48 | changedContent: changedContent,
49 | diffContainer: ".diffbox"
50 | })
51 |
52 | Widget.CompareTabs.show("comparator", $("button.diffComparatorButton:last-child").attr('id'))
53 | }
--------------------------------------------------------------------------------
/extensions/editor/src/widget/CompareTabs.js:
--------------------------------------------------------------------------------
1 | Widget.CompareTabs = function () {
2 | var tabs = [
3 | {
4 | guid: Widget.guid(),
5 | id: "oldfilecontent",
6 | name: "old",
7 | html: ''
8 | },
9 | {
10 | guid: Widget.guid(),
11 | id: "newfilecontent",
12 | name: "new",
13 | html: ''
14 | },
15 | {
16 | guid: Widget.guid(),
17 | id: "diffoutput",
18 | name: "diff",
19 | html: ''
20 | },
21 | {
22 | guid: Widget.guid(),
23 | id: "comparator",
24 | name: "match",
25 | html: ''
26 | }
27 | ]
28 | var data = {tabs: tabs}
29 |
30 | this.data = data
31 | this.html = parse(function(){/*!
32 |
33 | {{# tabs[i]
34 |
39 | }}#
40 |
41 |
42 |
43 | {{# tabs[i]
44 |
46 | {{tabs[i].html}}
47 |
48 | }}#
49 |
50 | */}, data)
51 | }
52 |
53 | Widget.CompareTabs.prototype = {
54 | constructor: Widget.CompareTabs
55 | }
56 |
57 | Widget.CompareTabs.show = function (id, guid) {
58 | $(".diffComparator").hide()
59 | $(".diffComparatorButton").css('text-decoration', 'none')
60 |
61 | $("#" + id).show()
62 | $("#" + guid).css('text-decoration', 'underline')
63 | }
--------------------------------------------------------------------------------
/extensions/editor/src/widget/EditorHeader.css:
--------------------------------------------------------------------------------
1 | #menu {
2 | color: {{baseline_color2}};
3 | }
4 |
5 | #menu.dark {
6 | color: {{baseline_color1}};
7 | }
8 |
9 | .hand {
10 | cursor: pointer;
11 | }
--------------------------------------------------------------------------------
/extensions/editor/src/widget/EditorNavigation.css:
--------------------------------------------------------------------------------
1 | .directory {
2 | color: {{baseline_color2}};
3 | cursor: pointer;
4 | }
5 |
6 | #directoryNavigation.dark .directory {
7 | color: {{baseline_color1}};
8 | }
9 |
10 | #listbox.dark .directory {
11 | color: {{baseline_color1}};
12 | }
13 |
14 | .file {
15 | color: {{baseline_color2}};
16 | cursor: pointer;
17 | }
18 |
19 | #directoryNavigation.dark .file {
20 | color: {{baseline_color1}};
21 | }
22 |
23 | #listbox.dark .file {
24 | color: {{baseline_color1}};
25 | }
26 |
27 | .unknown {
28 | color: red;
29 | cursor: pointer;
30 | }
31 |
32 | ul.no-bullets
33 | {
34 | list-style-type: none;
35 | padding-left: 0em;
36 | margin: 0em;
37 | }
38 |
39 | .nowrap {
40 | white-space: nowrap;
41 | }
--------------------------------------------------------------------------------
/extensions/editor/src/widget/EditorSearchPopup.js:
--------------------------------------------------------------------------------
1 | Widget.EditorSearchPopup = function (data) {
2 | data.proceedButtonGuid = Widget.guid()
3 | data.queryGuid = Widget.guid()
4 | data.replaceGuid = Widget.guid()
5 | data.filterGuid = Widget.guid()
6 | data.isRegexGuid = Widget.guid()
7 | data.isFileNameGuid = Widget.guid()
8 | data.isIgnoreCaseGuid = Widget.guid()
9 |
10 | var info = parse(function(){/*!
11 | {{?@ !isEmpty(data.info)
12 | {{info}}
13 | }}?
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
36 | Close
37 |
38 |
42 | Search / Replace
43 |
44 | */}, data)
45 |
46 | this.popup = new Widget.Popup({info: info})
47 | this.popup.proceed = data.proceed
48 | vars.editorSearchPopup = this.popup
49 | this.popup.init()
50 | }
51 |
52 | Widget.EditorSearchPopup.prototype = {
53 | constructor: Widget.EditorSearchPopup
54 | }
--------------------------------------------------------------------------------
/extensions/editor/src/widget/EditorSearchResult.js:
--------------------------------------------------------------------------------
1 | Widget.EditorSearchResult = function (filePaths) {
2 | var files = []
3 |
4 | if (filePaths != null) {
5 | for (var i = 0; i < filePaths.length; i++) {
6 | files[i] = {}
7 | files[i].guid = Widget.guid()
8 | files[i].path = filePaths[i]
9 | }
10 | }
11 |
12 | var data = {files: files}
13 |
14 | this.data = data
15 | this.html = parse(function(){/*!
16 | {{? files.length > 0
17 |
28 | }}?
29 | */}, data)
30 | }
31 |
32 | Widget.EditorSearchResult.prototype = {
33 | constructor: Widget.EditorSearchResult
34 | }
--------------------------------------------------------------------------------
/extensions/editor/src/widget/UploadResult.js:
--------------------------------------------------------------------------------
1 | Widget.UploadResult = function (files) {
2 | var data = {files: files}
3 |
4 | this.data = data
5 | this.html = parse(function(){/*!
6 | {{? files.length > 0
7 |
17 | }}?
18 | */}, data)
19 | }
20 |
21 | Widget.UploadResult.prototype = {
22 | constructor: Widget.UploadResult
23 | }
--------------------------------------------------------------------------------
/extensions/editor/static/editor-favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/strumasoft/octopus/4d66e3d6045cbd533353696abd80e48b1d606f18/extensions/editor/static/editor-favicon.ico
--------------------------------------------------------------------------------
/extensions/editor/static/search-favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/strumasoft/octopus/4d66e3d6045cbd533353696abd80e48b1d606f18/extensions/editor/static/search-favicon.ico
--------------------------------------------------------------------------------
/extensions/orm/config.lua:
--------------------------------------------------------------------------------
1 | local config = {} -- extension configuration
2 |
3 | config.property = {
4 | usePreparedStatement = true,
5 | debugDB = false,
6 | }
7 |
8 | config.module = {
9 | {name = "database", script = "database.lua"}, -- @deprecated > use luaorm > https://github.com/strumasoft/luaorm
10 | {name = "db.api.common", script = "db/api/common.lua"},
11 | {name = "db.api.mysql", script = "db/api/mysql.lua"},
12 | {name = "db.api.postgres", script = "db/api/postgres.lua"},
13 | {name = "db.driver.mysql", script = "db/driver/mysql.lua"},
14 | {name = "db.driver.postgres", script = "db/driver/postgres.lua"},
15 | }
16 |
17 |
18 | return config -- return extension configuration
--------------------------------------------------------------------------------
/extensions/repository/src/controller/RepositoryLogHistoryController.lua:
--------------------------------------------------------------------------------
1 | local json = require "json"
2 | local parse = require "parse"
3 | local param = require "param"
4 | local exit = require "exit"
5 | local exception = require "exception"
6 | local util = require "util"
7 |
8 |
9 |
10 | local externalJS = [[
11 |
12 |
13 |
14 | ]]
15 |
16 |
17 | local externalCSS = [[
18 |
19 | ]]
20 |
21 |
22 | local initJSTemplate = [[
23 | var vars = {}
24 |
25 | var repositoryLog = new Widget.RepositoryLog()
26 |
27 | var repositoryTemplate = new Widget.RepositoryTemplate({
28 | diff: repositoryLog.html
29 | })
30 |
31 | $.ajax({
32 | async: false,
33 | url: window.location.href + "&log=true",
34 | success: function (content) {
35 | Widget.setHtmlToPage(repositoryTemplate.html)
36 | Widget.RepositoryLog.setContent(content)
37 | },
38 | error: Widget.errorHandler
39 | })
40 | ]]
41 |
42 |
43 | local function process ()
44 | if util.isEmpty(param.repository) then exception("repository name like GIT/SVN is required") end
45 | local repository = require(param.repository)
46 |
47 | local username = param.username
48 | local password = param.password
49 | local directoryName = param.directoryName
50 |
51 | if param.log then
52 | local limit
53 | if util.isNotEmpty(param.limit) then limit = param.limit end
54 |
55 | return repository.logHistory(username, password, directoryName, limit)
56 | else
57 | local paths = util.split(directoryName, "/")
58 |
59 | return parse(require("BaselineHtmlTemplate"), {
60 | title = paths[#paths],
61 | customCSS = [[
62 | #skel-layers-wrapper {padding-top: 0;}
63 | ]],
64 | externalJS = externalJS,
65 | externalCSS = externalCSS,
66 | initJS = parse(initJSTemplate, json.encodeProperties({}))
67 | })
68 | end
69 | end
70 |
71 |
72 | local ok, res = pcall(process)
73 | if ok then
74 | if res then ngx.say(res) end
75 | else
76 | exit(res)
77 | end
--------------------------------------------------------------------------------
/extensions/repository/src/controller/RepositoryTemplate.css:
--------------------------------------------------------------------------------
1 | ins {
2 | background-color: #c6ffc6;
3 | text-decoration: none;
4 | }
5 |
6 | .diffbox.dark ins {
7 | color: {{baseline_color2}};
8 | }
9 |
10 | del {
11 | background-color: #ffc6c6;
12 | text-decoration: none;
13 | }
14 |
15 | .diffbox.dark del {
16 | color: {{baseline_color2}};
17 | }
18 |
19 | #diffoutput {
20 | margin: 15px;
21 | }
22 |
23 | #diffComparatorTabs {
24 | margin: 15px;
25 | }
26 |
27 | .diffbox {
28 | padding: 15px;
29 | margin: 0px 5px 15px 5px;
30 |
31 | color: {{baseline_color2}};
32 | font-size: 14px;
33 | font-weight: normal;
34 | line-height: 16px;
35 |
36 | background: {{baseline_color1}};
37 | border-radius: 6px;
38 | border: solid 1px {{baseline_color2}};
39 |
40 | overflow-x: scroll;
41 | }
42 |
43 | .diffbox.dark {
44 | color: {{baseline_color1}};
45 | background: {{baseline_color2}};
46 | }
47 |
48 | #listbox {
49 | padding-top: 10px;
50 | margin: 5px;
51 |
52 | background: {{baseline_color1}};
53 | border-radius: 6px;
54 | border: solid 1px {{baseline_color2}};
55 |
56 | overflow-x: scroll;
57 | }
58 |
59 | #listbox.dark {
60 | background: {{baseline_color2}};
61 | border: solid 1px {{baseline_color1}};
62 | }
63 |
64 | .repolog {
65 | margin: 0 0 0 0;
66 | color: {{baseline_color2}};
67 | }
68 |
69 | #listbox.dark .repolog {
70 | color: {{baseline_color1}};
71 | }
72 |
73 | table.diff tbody td {
74 | color: {{baseline_color2}};
75 | font-size: 14px;
76 | }
77 |
78 | #diffoutput.dark table.diff tbody td {
79 | color: {{baseline_color1}};
80 | }
81 |
82 | #diffoutput.dark table.diff tbody td.insert {
83 | color: {{baseline_color2}};
84 | }
85 |
86 | #diffoutput.dark table.diff tbody td.delete {
87 | color: {{baseline_color2}};
88 | }
89 |
90 | #diffoutput.dark table.diff tbody td.replace {
91 | color: {{baseline_color2}};
92 | }
93 |
94 | table.diff {
95 | white-space: pre-wrap;
96 | }
--------------------------------------------------------------------------------
/extensions/repository/src/controller/RepositoryTemplate.js:
--------------------------------------------------------------------------------
1 | Widget.RepositoryTemplate = function (data) {
2 | this.data = data
3 | this.html = parse(function(){/*!
4 |
5 |
6 | {{header}}
7 |
8 |
9 |
10 | {{navigation}}
11 |
12 |
13 |
14 |
15 | {{diff}}
16 |
17 |
18 |
19 | */}, data)
20 | }
21 |
22 | Widget.RepositoryTemplate.prototype = {
23 | constructor: Widget.RepositoryTemplate
24 | }
--------------------------------------------------------------------------------
/extensions/repository/src/controller/operation/AddController.lua:
--------------------------------------------------------------------------------
1 | local param = require "param"
2 | local exit = require "exit"
3 | local exception = require "exception"
4 | local util = require "util"
5 |
6 |
7 |
8 | local function process ()
9 | if util.isEmpty(param.repository) then exception("repository name like GIT/SVN is required") end
10 | local repository = require(param.repository)
11 |
12 | local username = param.username
13 | local password = param.password
14 | local path = param.path
15 | local directoryName = param.directoryName
16 |
17 | return repository.add(username, password, path, directoryName)
18 | end
19 |
20 |
21 | local ok, res = pcall(process)
22 | if ok then
23 | if res then ngx.say(res) end
24 | else
25 | exit(res)
26 | end
--------------------------------------------------------------------------------
/extensions/repository/src/controller/operation/CommitController.lua:
--------------------------------------------------------------------------------
1 | local param = require "param"
2 | local exit = require "exit"
3 | local exception = require "exception"
4 | local util = require "util"
5 |
6 |
7 |
8 | local function process ()
9 | if util.isEmpty(param.repository) then exception("repository name like GIT/SVN is required") end
10 | local repository = require(param.repository)
11 |
12 | local username = param.username
13 | local password = param.password
14 | local message = param.message
15 | local directoryName = param.directoryName
16 |
17 | local list = {}
18 |
19 | local file = param["f" .. #list] -- from 0 to N-1
20 | while file do
21 | list[#list + 1] = file
22 | file = param["f" .. #list]
23 | end
24 |
25 | return repository.commit(username, password, message, list, directoryName)
26 | end
27 |
28 |
29 | local ok, res = pcall(process)
30 | if ok then
31 | if res then ngx.say(res) end
32 | else
33 | exit(res)
34 | end
--------------------------------------------------------------------------------
/extensions/repository/src/controller/operation/DeleteController.lua:
--------------------------------------------------------------------------------
1 | local param = require "param"
2 | local exit = require "exit"
3 | local exception = require "exception"
4 | local util = require "util"
5 |
6 |
7 |
8 | local function process ()
9 | if util.isEmpty(param.repository) then exception("repository name like GIT/SVN is required") end
10 | local repository = require(param.repository)
11 |
12 | local username = param.username
13 | local password = param.password
14 | local path = param.path
15 | local directoryName = param.directoryName
16 |
17 | return repository.delete(username, password, path, directoryName)
18 | end
19 |
20 |
21 | local ok, res = pcall(process)
22 | if ok then
23 | if res then ngx.say(res) end
24 | else
25 | exit(res)
26 | end
--------------------------------------------------------------------------------
/extensions/repository/src/controller/operation/FileDiffController.lua:
--------------------------------------------------------------------------------
1 | local param = require "param"
2 | local exit = require "exit"
3 | local exception = require "exception"
4 | local util = require "util"
5 |
6 |
7 |
8 | local function process ()
9 | if util.isEmpty(param.repository) then exception("repository name like GIT/SVN is required") end
10 | local repository = require(param.repository)
11 |
12 | local username = param.username
13 | local password = param.password
14 | local oldRevision = param.oldRevision
15 | local newRevision = param.newRevision
16 | local fileName = param.fileName
17 | local newFileName = param.newFileName
18 | local directoryName = param.directoryName
19 |
20 | return repository.fileDiff(username, password, oldRevision, newRevision, fileName, newFileName, directoryName)
21 | end
22 |
23 |
24 | local ok, res = pcall(process)
25 | if ok then
26 | if res then ngx.say(res) end
27 | else
28 | exit(res)
29 | end
--------------------------------------------------------------------------------
/extensions/repository/src/controller/operation/FileRevisionContentController.lua:
--------------------------------------------------------------------------------
1 | local param = require "param"
2 | local exit = require "exit"
3 | local exception = require "exception"
4 | local util = require "util"
5 |
6 |
7 |
8 | ngx.header.content_type = 'text/plain'
9 |
10 |
11 | local function process ()
12 | if util.isEmpty(param.repository) then exception("repository name like GIT/SVN is required") end
13 | local repository = require(param.repository)
14 |
15 | local username = param.username
16 | local password = param.password
17 | local revision = param.revision
18 | local fileName = param.fileName
19 | local directoryName = param.directoryName
20 |
21 | return repository.fileRevisionContent(username, password, revision, fileName, directoryName)
22 | end
23 |
24 |
25 | local ok, res = pcall(process)
26 | if ok then
27 | if res then ngx.say(res) end
28 | else
29 | exit(res)
30 | end
--------------------------------------------------------------------------------
/extensions/repository/src/controller/operation/MergeController.lua:
--------------------------------------------------------------------------------
1 | local param = require "param"
2 | local exit = require "exit"
3 | local exception = require "exception"
4 | local util = require "util"
5 |
6 |
7 |
8 | local function process ()
9 | if util.isEmpty(param.repository) then exception("repository name like GIT/SVN is required") end
10 | local repository = require(param.repository)
11 |
12 | local username = param.username
13 | local password = param.password
14 | local fromRevision = param.fromRevision
15 | local toRevision = param.toRevision
16 | local path = param.path
17 |
18 | return repository.merge(username, password, fromRevision, toRevision, path)
19 | end
20 |
21 |
22 | local ok, res = pcall(process)
23 | if ok then
24 | if res then ngx.say(res) end
25 | else
26 | exit(res)
27 | end
--------------------------------------------------------------------------------
/extensions/repository/src/controller/operation/RefreshController.lua:
--------------------------------------------------------------------------------
1 | local param = require "param"
2 | local exit = require "exit"
3 | local exception = require "exception"
4 | local util = require "util"
5 |
6 |
7 |
8 | local function process ()
9 | if util.isEmpty(param.repository) then exception("repository name like GIT/SVN is required") end
10 | local repository = require(param.repository)
11 |
12 | local username = param.username
13 | local password = param.password
14 | local path = param.path
15 | local directoryName = param.directoryName
16 |
17 | return repository.refresh(username, password, path, directoryName)
18 | end
19 |
20 |
21 | local ok, res = pcall(process)
22 | if ok then
23 | if res then ngx.say(res) end
24 | else
25 | exit(res)
26 | end
--------------------------------------------------------------------------------
/extensions/repository/src/controller/operation/RevertController.lua:
--------------------------------------------------------------------------------
1 | local param = require "param"
2 | local exit = require "exit"
3 | local exception = require "exception"
4 | local util = require "util"
5 |
6 |
7 |
8 | local function process ()
9 | if util.isEmpty(param.repository) then exception("repository name like GIT/SVN is required") end
10 | local repository = require(param.repository)
11 |
12 | local username = param.username
13 | local password = param.password
14 | local path = param.path
15 | local recursively = param.recursively
16 | local directoryName = param.directoryName
17 |
18 | return repository.revert(username, password, path, recursively, directoryName)
19 | end
20 |
21 |
22 | local ok, res = pcall(process)
23 | if ok then
24 | if res then ngx.say(res) end
25 | else
26 | exit(res)
27 | end
--------------------------------------------------------------------------------
/extensions/repository/src/controller/operation/UpdateController.lua:
--------------------------------------------------------------------------------
1 | local param = require "param"
2 | local exit = require "exit"
3 | local exception = require "exception"
4 | local util = require "util"
5 |
6 |
7 |
8 | local function process ()
9 | if util.isEmpty(param.repository) then exception("repository name like GIT/SVN is required") end
10 | local repository = require(param.repository)
11 |
12 | local username = param.username
13 | local password = param.password
14 | local revision = param.revision
15 | local path = param.path
16 |
17 | return repository.update(username, password, revision, path)
18 | end
19 |
20 |
21 | local ok, res = pcall(process)
22 | if ok then
23 | if res then ngx.say(res) end
24 | else
25 | exit(res)
26 | end
--------------------------------------------------------------------------------
/extensions/repository/src/widget/RepositoryDiff.js:
--------------------------------------------------------------------------------
1 | Widget.RepositoryDiff = function (data) {
2 | var tabs = [
3 | {
4 | guid: Widget.guid(),
5 | id: "oldfilecontent",
6 | name: "old",
7 | html: ''
8 | },
9 | {
10 | guid: Widget.guid(),
11 | id: "newfilecontent",
12 | name: "new",
13 | html: ''
14 | },
15 | {
16 | guid: Widget.guid(),
17 | id: "diffoutput",
18 | name: "diff",
19 | html: ''
20 | },
21 | {
22 | guid: Widget.guid(),
23 | id: "comparator",
24 | name: "match",
25 | html: ''
26 | },
27 | {
28 | guid: Widget.guid(),
29 | id: "patch",
30 | name: "patch",
31 | html: ''
32 | }
33 | ]
34 | data.tabs = tabs
35 |
36 | this.data = data
37 | this.html = parse(function(){/*!
38 |
39 | {{# tabs[i]
40 |
45 | }}#
46 |
47 |
48 |
49 | {{# tabs[i]
50 |
52 | {{tabs[i].html}}
53 |
54 | }}#
55 |
56 | */}, data)
57 | }
58 |
59 | Widget.RepositoryDiff.prototype = {
60 | constructor: Widget.RepositoryDiff
61 | }
62 |
63 | Widget.RepositoryDiff.show = function (id, guid) {
64 | $(".diffComparator").hide()
65 | $(".diffComparatorButton").css('text-decoration', 'none')
66 |
67 | $("#" + id).show()
68 | $("#" + guid).css('text-decoration', 'underline')
69 | }
--------------------------------------------------------------------------------
/extensions/repository/src/widget/RepositoryFileHistoryNavigation.js:
--------------------------------------------------------------------------------
1 | Widget.RepositoryFileHistoryNavigation = function (revisions) {
2 | revisions = revisions || []
3 |
4 | for (var i = 0; i < revisions.length; i++) {revisions[i].guid = Widget.guid()}
5 |
6 | var data = {revisions: revisions}
7 |
8 | this.data = data
9 |
10 | if (getURLParameter("repository") == "SVN") {
11 | this.html = parse(function(){/*!
12 | {{? revisions.length > 0
13 |
14 | {{# revisions[i]
15 | -
16 |
17 |
20 |
21 |
22 |
23 | }}#
24 |
25 | }}?
26 | */}, data)
27 | } else if (getURLParameter("repository") == "GIT") {
28 | this.html = parse(function(){/*!
29 | {{? revisions.length > 0
30 |
31 | {{# revisions[i]
32 | -
33 |
34 |
40 |
41 |
42 |
43 | }}#
44 |
45 | }}?
46 | */}, data)
47 | }
48 | }
49 |
50 | Widget.RepositoryFileHistoryNavigation.prototype = {
51 | constructor: Widget.RepositoryFileHistoryNavigation
52 | }
--------------------------------------------------------------------------------
/extensions/repository/src/widget/RepositoryLog.js:
--------------------------------------------------------------------------------
1 | Widget.RepositoryLog = function () {
2 | var data = {}
3 | if (localStorage.getItem("isDark") === "true") {
4 | data.clazz = "dark";
5 | }
6 |
7 | this.data = data
8 | this.html = parse(function(){/*!
9 |
14 | */}, data)
15 | }
16 |
17 | Widget.RepositoryLog.prototype = {
18 | constructor: Widget.RepositoryLog
19 | }
20 |
21 | Widget.RepositoryLog.setContent = function (content) {
22 | $('#repositoryLogContent').html(Widget.createHTML(content))
23 | }
--------------------------------------------------------------------------------
/extensions/repository/src/widget/RepositoryPatch.js:
--------------------------------------------------------------------------------
1 | Widget.RepositoryPatch = function () {
2 | var data = {}
3 |
4 | this.data = data
5 | this.html = parse(function(){/*!
6 |
7 | */}, data)
8 | }
9 |
10 | Widget.RepositoryPatch.prototype = {
11 | constructor: Widget.RepositoryPatch
12 | }
13 |
14 | Widget.RepositoryPatch.setContent = function (contents) {
15 | let clazz = "";
16 | if (localStorage.getItem("isDark") === "true") {
17 | clazz = "dark";
18 | }
19 |
20 | var html = ""
21 | for (var i = 0; i < contents.length; i++) {
22 | html = html
23 | + ''
24 | + Widget.decoratePatch(Widget.createHTML(contents[i]))
25 | + "
"
26 | }
27 |
28 | $('#patch').html(html)
29 | }
--------------------------------------------------------------------------------
/extensions/repository/src/widget/RepositoryStatusNavigation.js:
--------------------------------------------------------------------------------
1 | Widget.RepositoryStatusNavigation = function (statuses) {
2 | statuses = statuses || []
3 |
4 | for (var i = 0; i < statuses.length; i++) {statuses[i].guid = Widget.guid()}
5 |
6 | var data = {statuses: statuses}
7 |
8 | this.data = data
9 | if (getURLParameter("repository") == "SVN") {
10 | this.html = parse(function(){/*!
11 | {{? statuses.length > 0
12 |
13 | {{# statuses[i]
14 | -
15 |
16 |
22 |
23 |
24 |
25 | }}#
26 |
27 | }}?
28 | */}, data)
29 | } else if (getURLParameter("repository") == "GIT") {
30 | this.html = parse(function(){/*!
31 | {{? statuses.length > 0
32 |
33 | {{# statuses[i]
34 | -
35 |
36 |
42 |
43 |
44 |
45 | }}#
46 |
47 | }}?
48 | */}, data)
49 | }
50 | }
51 |
52 | Widget.RepositoryStatusNavigation.prototype = {
53 | constructor: Widget.RepositoryStatusNavigation
54 | }
--------------------------------------------------------------------------------
/extensions/repository/static/repository-favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/strumasoft/octopus/4d66e3d6045cbd533353696abd80e48b1d606f18/extensions/repository/static/repository-favicon.ico
--------------------------------------------------------------------------------
/extensions/security/config.lua:
--------------------------------------------------------------------------------
1 | local config = {} -- extension configuration
2 |
3 | config.frontend = {
4 | securityLoginUrl = "/security/login",
5 | securityRegisterUrl = "/security/register",
6 | securityLoginUserUrl = "/security/loginUser",
7 | securityRegisterUserUrl = "/security/registerUser",
8 | }
9 |
10 | config.property = {
11 | failedLoginAttempts = 7,
12 | failedLoginAttemptsTimeout = 10800, -- 3h
13 | }
14 |
15 | config.localization = {
16 |
17 | }
18 |
19 | config.location = {
20 | {name = property.securityLoginUrl, script = "controller/SecurityLoginPageController.lua"},
21 | {name = property.securityRegisterUrl, script = "controller/SecurityRegisterPageController.lua"},
22 | {name = property.securityLoginUserUrl, script = "controller/SecurityLoginUserController.lua", requestBody = true},
23 | {name = property.securityRegisterUserUrl, script = "controller/SecurityRegisterUserController.lua", requestBody = true},
24 | }
25 |
26 | config.javascript = {
27 | {name = "SecurityLoginForm", script = "widget/LoginForm.js"},
28 | {name = "SecurityRegisterForm", script = "widget/RegisterForm.js"},
29 | }
30 |
31 | config.stylesheet = {
32 |
33 | }
34 |
35 | config.module = {
36 | {name = "userService", script = "module/UserService.lua"},
37 | {name = "securityImport", script = "import.lua"},
38 | }
39 |
40 | config.static = {
41 |
42 | }
43 |
44 | config.type = {
45 | "types.lua"
46 | }
47 |
48 | return config -- return extension configuration
--------------------------------------------------------------------------------
/extensions/security/src/controller/SecurityLoginPageController.lua:
--------------------------------------------------------------------------------
1 | local json = require "json"
2 | local parse = require "parse"
3 | local param = require "param"
4 | local property = require "property"
5 | local userService = require "userService"
6 |
7 |
8 |
9 | local to = userService.redirectTo(property.securityLoginUrl)
10 |
11 |
12 | local data = {to = to}
13 |
14 |
15 | ngx.say(parse(require("BaselineHtmlTemplate"), {
16 | title = "Login",
17 | externalJS = [[
18 |
19 | ]],
20 | initJS = parse([[
21 | var vars = {}
22 |
23 | Widget.setContainerToPage([
24 | [
25 | {size: "6u", medium: "8u", small: "12u", widget: new Widget.LoginForm({to: {{to}}})}
26 | ]
27 | ]);
28 | ]], json.encodeProperties(data))
29 | }))
--------------------------------------------------------------------------------
/extensions/security/src/controller/SecurityLoginUserController.lua:
--------------------------------------------------------------------------------
1 | local json = require "json"
2 | local property = require "property"
3 | local database = require "database"
4 | local util = require "util"
5 | local userService = require "userService"
6 |
7 |
8 |
9 | local parameters = util.parseForm(util.urldecode(ngx.req.get_body_data()))
10 |
11 | local db = database.connect()
12 | local ok, res = pcall(userService.loginAndSetToken, db, parameters.email, parameters.password)
13 | db:close()
14 |
15 | if ok and res then
16 | local to = userService.redirectTo(property.securityLoginUserUrl)
17 |
18 | if util.isNotEmpty(to) then
19 | return ngx.redirect(to)
20 | else
21 | ngx.say("successful login")
22 | end
23 | else
24 | ngx.say("wrong credentials")
25 | end
--------------------------------------------------------------------------------
/extensions/security/src/controller/SecurityRegisterPageController.lua:
--------------------------------------------------------------------------------
1 | local json = require "json"
2 | local parse = require "parse"
3 | local param = require "param"
4 | local property = require "property"
5 | local userService = require "userService"
6 |
7 |
8 |
9 | local data = {}
10 |
11 |
12 | ngx.say(parse(require("BaselineHtmlTemplate"), {
13 | title = "Register",
14 | externalJS = [[
15 |
16 | ]],
17 | initJS = parse([[
18 | var vars = {}
19 |
20 | Widget.setContainerToPage([
21 | [
22 | {size: "6u", medium: "8u", small: "12u", widget: new Widget.RegisterForm({})}
23 | ]
24 | ]);
25 | ]], json.encodeProperties(data))
26 | }))
--------------------------------------------------------------------------------
/extensions/security/src/controller/SecurityRegisterUserController.lua:
--------------------------------------------------------------------------------
1 | local json = require "json"
2 | local property = require "property"
3 | local database = require "database"
4 | local util = require "util"
5 | local userService = require "userService"
6 |
7 |
8 |
9 | local parameters = util.parseForm(util.urldecode(ngx.req.get_body_data()))
10 |
11 | if util.isNotEmpty(parameters.email)
12 | and util.isNotEmpty(parameters.password)
13 | and util.isNotEmpty(parameters.repeatPassword)
14 | and (parameters.password == parameters.repeatPassword)
15 | then
16 | local db = database.connect()
17 | local ok, res = pcall(userService.registerAndSetToken, db, parameters.email, parameters.password)
18 | db:close()
19 |
20 | if ok then
21 | ngx.say("successful register")
22 | else
23 | ngx.say("unsuccessful register")
24 | end
25 | else
26 | ngx.say("wrong data")
27 | end
--------------------------------------------------------------------------------
/extensions/security/src/import.lua:
--------------------------------------------------------------------------------
1 | return {
2 | objects = {
3 | userPermission = {
4 | open = {code = "open"},
5 |
6 | read = {code = "read"},
7 | write = {code = "write"},
8 |
9 | execute = {code = "execute"},
10 | add = {code = "add"},
11 | remove = {code = "remove"},
12 | edit = {code = "edit"},
13 | save = {code = "save"},
14 | refresh = {code = "refresh"},
15 | },
16 |
17 | userGroup = {
18 | dbAdmin = {code = "dbAdmin"},
19 | codeEditor = {code = "codeEditor"},
20 | }
21 | },
22 |
23 | relations = {
24 | ["userGroup.permissions-userPermission.groups"] = {
25 | codeEditor_read = {key = "codeEditor", value = "read"},
26 | codeEditor_write = {key = "codeEditor", value = "write"},
27 |
28 | dbAdmin_execute = {key = "dbAdmin", value = "execute"},
29 | dbAdmin_add = {key = "dbAdmin", value = "add"},
30 | dbAdmin_remove = {key = "dbAdmin", value = "remove"},
31 | dbAdmin_edit = {key = "dbAdmin", value = "edit"},
32 | dbAdmin_save = {key = "dbAdmin", value = "save"},
33 | dbAdmin_refresh = {key = "dbAdmin", value = "refresh"},
34 | },
35 | }
36 | }
--------------------------------------------------------------------------------
/extensions/security/src/types.lua:
--------------------------------------------------------------------------------
1 | return {
2 |
3 | user = {
4 | email = {type = "string", unique = true},
5 | passwordSalt = "string",
6 | passwordHash = "string",
7 | token = "string",
8 | lastLoginTime = "integer",
9 | lastFailedLoginTime = "integer",
10 | failedLoginAttempts = "integer",
11 | groups = hasMany("userGroup", "users"),
12 | permissions = hasMany("userPermission", "users")
13 | },
14 |
15 | userGroup = {
16 | code = {type = "string", unique = true},
17 | users = hasMany("user", "groups"),
18 | permissions = hasMany("userPermission", "groups")
19 | },
20 |
21 | userPermission = {
22 | code = {type = "string", unique = true},
23 | users = hasMany("user", "permissions"),
24 | groups = hasMany("userGroup", "permissions")
25 | },
26 | }
--------------------------------------------------------------------------------
/extensions/security/src/widget/LoginForm.js:
--------------------------------------------------------------------------------
1 | Widget.LoginForm = function (data) {
2 | this.data = data
3 | this.html = parse(function(){/*!
4 | Login
5 |
6 |
22 | */}, data)
23 | }
24 |
25 | Widget.LoginForm.prototype = {
26 | constructor: Widget.LoginForm
27 | }
--------------------------------------------------------------------------------
/extensions/security/src/widget/RegisterForm.js:
--------------------------------------------------------------------------------
1 | Widget.RegisterForm = function (data) {
2 | this.data = data
3 | this.html = parse(function(){/*!
4 | Register
5 |
6 |
25 | */}, data)
26 | }
27 |
28 | Widget.RegisterForm.prototype = {
29 | constructor: Widget.RegisterForm
30 | }
--------------------------------------------------------------------------------
/extensions/shop/src/controller/ChangeCountryController.lua:
--------------------------------------------------------------------------------
1 | local param = require "param"
2 | local countryService = require "countryService"
3 |
4 |
5 | countryService.setCountry(param.country)
--------------------------------------------------------------------------------
/extensions/shop/src/controller/ChangeLanguageController.lua:
--------------------------------------------------------------------------------
1 | local param = require "param"
2 | local localeService = require "localeService"
3 |
4 |
5 | localeService.setLocale(param.locale)
--------------------------------------------------------------------------------
/extensions/shop/src/controller/account/AccountAddUpdateAddressController.lua:
--------------------------------------------------------------------------------
1 | local json = require "json"
2 | local parse = require "parse"
3 | local property = require "property"
4 | local localization = require "localization"
5 | local database = require "database"
6 | local exit = require "exit"
7 | local exception = require "exception"
8 | local exceptionHandler = require "exceptionHandler"
9 | local util = require "util"
10 | local userService = require "userService"
11 | local localeService = require "localeService"
12 | local priceService = require "priceService"
13 | local cartService = require "cartService"
14 |
15 |
16 |
17 | local function process (db, data)
18 | local op = db:operators()
19 |
20 |
21 | local locale = localeService.getLocale(db)
22 | data.locale = locale
23 |
24 |
25 | local address = util.parseForm(util.urldecode(ngx.req.get_body_data()))
26 | data.address = address
27 |
28 | if util.isNotEmpty(address.id) then
29 | db:update({address = address})
30 | else
31 | local user = userService.authenticatedUser(db)
32 | if user then
33 | address.user = user
34 | db:add({address = address})
35 |
36 | user.addresses = nil -- refresh
37 | end
38 | end
39 | end
40 |
41 |
42 | local data = {}
43 | local db = database.connect()
44 | local ok, err = pcall(process, db, data)
45 | db:close()
46 |
47 |
48 | if ok then
49 | return ngx.redirect(property.shopUrl .. property.accountAddressesUrl)
50 | else
51 | exceptionHandler.toCookie(err)
52 |
53 | if data.address and data.address.id then
54 | return ngx.redirect(property.shopUrl .. property.accountAddressUrl .. "?address=" .. data.address.id)
55 | else
56 | return ngx.redirect(property.shopUrl .. property.accountAddressesUrl)
57 | end
58 | end
--------------------------------------------------------------------------------
/extensions/shop/src/controller/account/AccountOrderPageController.lua:
--------------------------------------------------------------------------------
1 | local json = require "json"
2 | local parse = require "parse"
3 | local param = require "param"
4 | local property = require "property"
5 | local localization = require "localization"
6 | local database = require "database"
7 | local exception = require "exception"
8 | local exceptionHandler = require "exceptionHandler"
9 | local util = require "util"
10 | local localeService = require "localeService"
11 | local priceService = require "priceService"
12 | local cartService = require "cartService"
13 |
14 |
15 |
16 | local function process (db, data)
17 | local op = db:operators()
18 |
19 |
20 | local locale = localeService.getLocale(db)
21 | data.locale = locale
22 |
23 |
24 | if util.isNotEmpty(param.order) then
25 | local order = db:findOne({order = {id = op.equal(param.order)}})
26 | data.order = cartService.convertCart(db, order)
27 | else
28 | exception("order is required")
29 | end
30 | end
31 |
32 |
33 | local data = {}
34 | local db = database.connect()
35 | local ok, err = pcall(process, db, data)
36 | db:close()
37 | if not ok then
38 | exceptionHandler.toData(data, err)
39 | end
40 |
41 |
42 | ngx.say(parse(require("BaselineHtmlTemplate"), {
43 | title = "Account Order",
44 | externalJS = [[
45 |
46 | ]],
47 | externalCSS = [[
48 |
49 |
50 |
51 | ]],
52 | initJS = parse([[
53 | var vars = {}
54 |
55 | vars.locale = {{locale}}
56 |
57 | Widget.setContainerToPage([
58 | [
59 | {size: "12u", widget: new Widget.ShopHeader()}
60 | ],
61 | [
62 | {size: "3u", medium: "6u", small: "12u", widget: new Widget.Logo()},
63 | {size: "3u", medium: "6u", small: "12u", widget: new Widget.CallUs()},
64 | {size: "3u", medium: "6u", small: "12u", widget: new Widget.Search()},
65 | {size: "3u", medium: "6u", small: "12u", widget: new Widget.MiniCart()}
66 | ],
67 | [
68 | {size: "12u", widget: new Widget.Error({{error}})}
69 | ],
70 | [
71 | {size: "6u", medium: "8u", small: "12u", widget: "My Account
"}
72 | ],
73 | [
74 | {size: "3u", medium: "6u", small: "12u", widget: new Widget.AccountOptions()},
75 | {size: "9u", medium: "6u", small: "12u", widget: new Widget.Order({{order}})}
76 | ]
77 | ]);
78 | ]], json.encodeProperties(data))
79 | }))
--------------------------------------------------------------------------------
/extensions/shop/src/controller/account/AccountPageController.lua:
--------------------------------------------------------------------------------
1 | local json = require "json"
2 | local parse = require "parse"
3 | local param = require "param"
4 | local property = require "property"
5 | local localization = require "localization"
6 | local database = require "database"
7 | local exception = require "exception"
8 | local exceptionHandler = require "exceptionHandler"
9 | local localeService = require "localeService"
10 | local priceService = require "priceService"
11 | local cartService = require "cartService"
12 |
13 |
14 |
15 | local function process (db, data)
16 | local locale = localeService.getLocale(db)
17 | data.locale = locale
18 | end
19 |
20 |
21 | local data = {}
22 | local db = database.connect()
23 | local ok, err = pcall(process, db, data)
24 | db:close()
25 | if not ok then
26 | exceptionHandler.toData(data, err)
27 | end
28 |
29 |
30 | ngx.say(parse(require("BaselineHtmlTemplate"), {
31 | title = "Account",
32 | externalJS = [[
33 |
34 | ]],
35 | externalCSS = [[
36 |
37 |
38 |
39 | ]],
40 | initJS = parse([[
41 | var vars = {}
42 |
43 | vars.locale = {{locale}}
44 |
45 | Widget.setContainerToPage([
46 | [
47 | {size: "12u", widget: new Widget.ShopHeader()}
48 | ],
49 | [
50 | {size: "3u", medium: "6u", small: "12u", widget: new Widget.Logo()},
51 | {size: "3u", medium: "6u", small: "12u", widget: new Widget.CallUs()},
52 | {size: "3u", medium: "6u", small: "12u", widget: new Widget.Search()},
53 | {size: "3u", medium: "6u", small: "12u", widget: new Widget.MiniCart()}
54 | ],
55 | [
56 | {size: "12u", widget: new Widget.Error({{error}})}
57 | ],
58 | [
59 | {size: "6u", medium: "8u", small: "12u", widget: "My Account
"}
60 | ],
61 | [
62 | {size: "3u", medium: "6u", small: "12u", widget: new Widget.AccountOptions()}
63 | ]
64 | ]);
65 | ]], json.encodeProperties(data))
66 | }))
--------------------------------------------------------------------------------
/extensions/shop/src/controller/account/AccountRemoveAddressController.lua:
--------------------------------------------------------------------------------
1 | local json = require "json"
2 | local parse = require "parse"
3 | local param = require "param"
4 | local property = require "property"
5 | local localization = require "localization"
6 | local database = require "database"
7 | local exit = require "exit"
8 | local exception = require "exception"
9 | local exceptionHandler = require "exceptionHandler"
10 | local util = require "util"
11 | local userService = require "userService"
12 | local localeService = require "localeService"
13 | local priceService = require "priceService"
14 | local cartService = require "cartService"
15 |
16 |
17 |
18 | local function process (db, data)
19 | local op = db:operators()
20 |
21 |
22 | local locale = localeService.getLocale(db)
23 | data.locale = locale
24 |
25 |
26 | if util.isNotEmpty(param.address) then
27 | db:delete({address = {id = param.address}})
28 | else
29 | exception("address is required")
30 | end
31 | end
32 |
33 |
34 | local data = {}
35 | local db = database.connect()
36 | local ok, err = pcall(process, db, data)
37 | db:close()
38 |
39 |
40 | if ok then
41 | return ngx.redirect(property.shopUrl .. property.accountAddressesUrl)
42 | else
43 | exceptionHandler.toCookie(err)
44 | return ngx.redirect(property.shopUrl .. property.accountAddressesUrl)
45 | end
--------------------------------------------------------------------------------
/extensions/shop/src/controller/account/LoginPageController.lua:
--------------------------------------------------------------------------------
1 | local json = require "json"
2 | local parse = require "parse"
3 | local property = require "property"
4 | local localization = require "localization"
5 | local database = require "database"
6 | local exception = require "exception"
7 | local exceptionHandler = require "exceptionHandler"
8 | local util = require "util"
9 | local userService = require "userService"
10 | local localeService = require "localeService"
11 | local priceService = require "priceService"
12 | local cartService = require "cartService"
13 |
14 |
15 |
16 | local function process (db, data)
17 | local locale = localeService.getLocale(db)
18 | data.locale = locale
19 |
20 |
21 | local to = userService.redirectTo(property.shopUrl .. property.loginUrl)
22 | if util.isNotEmpty(to) then
23 | data.to = to
24 | else
25 | data.to = property.shopUrl .. property.accountUrl
26 | end
27 |
28 |
29 | data.registerUrl = property.shopUrl .. property.registerUrl
30 | end
31 |
32 |
33 | local data = {}
34 | local db = database.connect()
35 | local ok, err = pcall(process, db, data)
36 | db:close()
37 | if not ok then
38 | exceptionHandler.toData(data, err)
39 | end
40 |
41 |
42 | ngx.say(parse(require("BaselineHtmlTemplate"), {
43 | title = "Login",
44 | externalJS = [[
45 |
46 | ]],
47 | externalCSS = [[
48 |
49 |
50 |
51 | ]],
52 | initJS = parse([[
53 | var vars = {}
54 |
55 | vars.locale = {{locale}}
56 |
57 | Widget.setContainerToPage([
58 | [
59 | {size: "12u", widget: new Widget.ShopHeader()}
60 | ],
61 | [
62 | {size: "3u", medium: "6u", small: "12u", widget: new Widget.Logo()},
63 | {size: "3u", medium: "6u", small: "12u", widget: new Widget.CallUs()},
64 | {size: "3u", medium: "6u", small: "12u", widget: new Widget.Search()},
65 | {size: "3u", medium: "6u", small: "12u", widget: new Widget.MiniCart()}
66 | ],
67 | [
68 | {size: "12u", widget: new Widget.Error({{error}})}
69 | ],
70 | [
71 | {size: "6u", medium: "8u", small: "12u", widget: new Widget.LoginForm({to: {{to}}})}
72 | ],
73 | [
74 | {size: "6u", medium: "8u", small: "12u", widget: ''}
75 | ]
76 | ]);
77 | ]], json.encodeProperties(data))
78 | }))
--------------------------------------------------------------------------------
/extensions/shop/src/controller/account/RegisterPageController.lua:
--------------------------------------------------------------------------------
1 | local json = require "json"
2 | local parse = require "parse"
3 | local property = require "property"
4 | local localization = require "localization"
5 | local database = require "database"
6 | local exception = require "exception"
7 | local exceptionHandler = require "exceptionHandler"
8 | local util = require "util"
9 | local userService = require "userService"
10 | local localeService = require "localeService"
11 | local priceService = require "priceService"
12 | local cartService = require "cartService"
13 |
14 |
15 |
16 | local function process (db, data)
17 | local locale = localeService.getLocale(db)
18 | data.locale = locale
19 |
20 |
21 | local to = userService.redirectTo(property.shopUrl .. property.registerUrl)
22 | if util.isNotEmpty(to) then
23 | data.to = to
24 | else
25 | data.to = property.shopUrl .. property.accountUrl
26 | end
27 | end
28 |
29 |
30 | local data = {}
31 | local db = database.connect()
32 | local ok, err = pcall(process, db, data)
33 | db:close()
34 | if not ok then
35 | exceptionHandler.toData(data, err)
36 | end
37 |
38 |
39 | ngx.say(parse(require("BaselineHtmlTemplate"), {
40 | title = "Register",
41 | externalJS = [[
42 |
43 | ]],
44 | externalCSS = [[
45 |
46 |
47 |
48 | ]],
49 | initJS = parse([[
50 | var vars = {}
51 |
52 | vars.locale = {{locale}}
53 |
54 | Widget.setContainerToPage([
55 | [
56 | {size: "12u", widget: new Widget.ShopHeader()}
57 | ],
58 | [
59 | {size: "3u", medium: "6u", small: "12u", widget: new Widget.Logo()},
60 | {size: "3u", medium: "6u", small: "12u", widget: new Widget.CallUs()},
61 | {size: "3u", medium: "6u", small: "12u", widget: new Widget.Search()},
62 | {size: "3u", medium: "6u", small: "12u", widget: new Widget.MiniCart()}
63 | ],
64 | [
65 | {size: "12u", widget: new Widget.Error({{error}})}
66 | ],
67 | [
68 | {size: "6u", medium: "8u", small: "12u", widget: new Widget.RegisterForm({to: {{to}}})}
69 | ]
70 | ]);
71 | ]], json.encodeProperties(data))
72 | }))
--------------------------------------------------------------------------------
/extensions/shop/src/controller/catalog/ProductPageController.lua:
--------------------------------------------------------------------------------
1 | local json = require "json"
2 | local parse = require "parse"
3 | local property = require "property"
4 | local localization = require "localization"
5 | local database = require "database"
6 | local exception = require "exception"
7 | local exceptionHandler = require "exceptionHandler"
8 | local util = require "util"
9 | local localeService = require "localeService"
10 | local priceService = require "priceService"
11 |
12 |
13 |
14 | local function process (db, data)
15 | local op = db:operators()
16 |
17 |
18 | local locale = localeService.getLocale(db)
19 | data.locale = locale
20 |
21 |
22 | local productCode
23 | local uries = util.split(ngx.var.uri, "/")
24 | if property.productUrl == "/" .. uries[#uries - 1] then
25 | productCode = uries[#uries]
26 | end
27 |
28 | if productCode then
29 | local product = db:findOne({product = {code = op.equal(productCode)}}, {
30 | "pictures",
31 | "prices",
32 | {name = {locale = locale}}
33 | })
34 | priceService.convertProductsPrices(db, product)
35 | data.product = product
36 | end
37 | end
38 |
39 |
40 | local data = {}
41 | local db = database.connect()
42 | local ok, err = pcall(process, db, data)
43 | db:close()
44 | if not ok then
45 | exceptionHandler.toData(data, err)
46 | end
47 |
48 |
49 | ngx.say(parse(require("BaselineHtmlTemplate"), {
50 | title = "Product Detail",
51 | externalJS = [[
52 |
53 |
54 | ]],
55 | externalCSS = [[
56 |
57 |
58 |
59 | ]],
60 | initJS = parse([[
61 | var vars = {}
62 |
63 | vars.locale = {{locale}}
64 |
65 | Widget.setContainerToPage([
66 | [
67 | {size: "12u", widget: new Widget.ShopHeader()}
68 | ],
69 | [
70 | {size: "3u", medium: "6u", small: "12u", widget: new Widget.Logo()},
71 | {size: "3u", medium: "6u", small: "12u", widget: new Widget.CallUs()},
72 | {size: "3u", medium: "6u", small: "12u", widget: new Widget.Search()},
73 | {size: "3u", medium: "6u", small: "12u", widget: new Widget.MiniCart()}
74 | ],
75 | [
76 | {size: "12u", widget: new Widget.Error({{error}})}
77 | ],
78 | [
79 | {size: "9u -3u", medium: "8u -4u", small: "12u", widget: new Widget.ProductDetail({{product}})}
80 | ]
81 | ])
82 | ]], json.encodeProperties(data))
83 | }))
--------------------------------------------------------------------------------
/extensions/shop/src/controller/checkout/AddToCartController.lua:
--------------------------------------------------------------------------------
1 | local json = require "json"
2 | local parse = require "parse"
3 | local param = require "param"
4 | local property = require "property"
5 | local localization = require "localization"
6 | local database = require "database"
7 | local exit = require "exit"
8 | local localeService = require "localeService"
9 | local priceService = require "priceService"
10 | local cartService = require "cartService"
11 |
12 |
13 |
14 | local function process (db, data)
15 | local locale = localeService.getLocale(db)
16 | data.locale = locale
17 |
18 |
19 | local cart = cartService.addToCart(db, param.productCode, param.quantity)
20 | data.cart = cartService.convertCart(db, cart)
21 | end
22 |
23 |
24 | local data = {}
25 | local db = database.connect()
26 | local ok, err = pcall(process, db, data)
27 | db:close()
28 |
29 |
30 | if ok then
31 | ngx.say(json.encode(data))
32 | else
33 | exit(err)
34 | end
--------------------------------------------------------------------------------
/extensions/shop/src/controller/checkout/CheckoutAddAddressController.lua:
--------------------------------------------------------------------------------
1 | local json = require "json"
2 | local parse = require "parse"
3 | local property = require "property"
4 | local localization = require "localization"
5 | local database = require "database"
6 | local exit = require "exit"
7 | local exception = require "exception"
8 | local exceptionHandler = require "exceptionHandler"
9 | local util = require "util"
10 | local userService = require "userService"
11 | local localeService = require "localeService"
12 | local priceService = require "priceService"
13 | local cartService = require "cartService"
14 |
15 |
16 |
17 | local function process (db, data)
18 | local op = db:operators()
19 |
20 |
21 | local locale = localeService.getLocale(db)
22 | data.locale = locale
23 |
24 |
25 | local cart = cartService.getCart(db)
26 | local user = userService.authenticatedUser(db)
27 | if user then
28 | local function addAddressTransaction ()
29 | local address = util.parseForm(util.urldecode(ngx.req.get_body_data()))
30 | address.user = user
31 | address.carts = {cart}
32 | db:add({address = address})
33 |
34 | user.addresses = nil -- refresh
35 | end
36 |
37 | local ok, res = pcall(db.transaction, db, addAddressTransaction)
38 | if not ok then exception("user=" .. user.id .. " => " .. res) end
39 | end
40 | end
41 |
42 |
43 | local data = {}
44 | local db = database.connect()
45 | local ok, err = pcall(process, db, data)
46 | db:close()
47 |
48 |
49 | if ok then
50 | return ngx.redirect(property.shopUrl .. property.checkoutDeliveryMethodUrl)
51 | else
52 | exceptionHandler.toCookie(err)
53 | return ngx.redirect(property.shopUrl .. property.checkoutAddressUrl)
54 | end
--------------------------------------------------------------------------------
/extensions/shop/src/controller/checkout/CheckoutConfirmationPageController.lua:
--------------------------------------------------------------------------------
1 | local json = require "json"
2 | local parse = require "parse"
3 | local param = require "param"
4 | local property = require "property"
5 | local localization = require "localization"
6 | local database = require "database"
7 | local exception = require "exception"
8 | local exceptionHandler = require "exceptionHandler"
9 | local localeService = require "localeService"
10 | local priceService = require "priceService"
11 | local cartService = require "cartService"
12 |
13 |
14 |
15 | local function process (db, data)
16 | local locale = localeService.getLocale(db)
17 | data.locale = locale
18 | end
19 |
20 |
21 | local data = {}
22 | local db = database.connect()
23 | local ok, err = pcall(process, db, data)
24 | db:close()
25 | if not ok then
26 | exceptionHandler.toData(data, err)
27 | end
28 |
29 |
30 | ngx.say(parse(require("BaselineHtmlTemplate"), {
31 | title = "Thank You",
32 | externalJS = [[
33 |
34 | ]],
35 | externalCSS = [[
36 |
37 |
38 |
39 | ]],
40 | initJS = parse([[
41 | var vars = {}
42 |
43 | vars.locale = {{locale}}
44 |
45 | Widget.setContainerToPage([
46 | [
47 | {size: "12u", widget: new Widget.ShopHeader()}
48 | ],
49 | [
50 | {size: "3u", medium: "6u", small: "12u", widget: new Widget.Logo()},
51 | {size: "3u", medium: "6u", small: "12u", widget: new Widget.CallUs()},
52 | {size: "3u", medium: "6u", small: "12u", widget: new Widget.Search()},
53 | {size: "3u", medium: "6u", small: "12u", widget: new Widget.MiniCart()}
54 | ],
55 | [
56 | {size: "12u", widget: new Widget.Error({{error}})}
57 | ],
58 | [
59 | {size: "6u", medium: "8u", small: "12u", widget: "Thank You For Your Order
"}
60 | ]
61 | ]);
62 | ]], json.encodeProperties(data))
63 | }))
--------------------------------------------------------------------------------
/extensions/shop/src/controller/checkout/CheckoutPageController.lua:
--------------------------------------------------------------------------------
1 | local json = require "json"
2 | local parse = require "parse"
3 | local param = require "param"
4 | local property = require "property"
5 | local localization = require "localization"
6 | local database = require "database"
7 | local exit = require "exit"
8 | local exception = require "exception"
9 | local exceptionHandler = require "exceptionHandler"
10 | local localeService = require "localeService"
11 | local priceService = require "priceService"
12 | local cartService = require "cartService"
13 |
14 |
15 |
16 | local function process (db, data)
17 | local locale = localeService.getLocale(db)
18 | data.locale = locale
19 |
20 |
21 | local cart = cartService.getCart(db)
22 | if cart.productEntries then
23 | data.redirectUrl = property.shopUrl .. property.checkoutAddressesUrl
24 | return
25 | else
26 | exceptionHandler.toCookie("cart does not have products")
27 | data.redirectUrl = property.shopUrl .. property.cartUrl
28 | return
29 | end
30 | end
31 |
32 |
33 | local data = {}
34 | local db = database.connect()
35 | local ok, err = pcall(process, db, data)
36 | db:close()
37 |
38 |
39 | if ok and data.redirectUrl then
40 | return ngx.redirect(data.redirectUrl)
41 | else
42 | exceptionHandler.toCookie(err)
43 | return ngx.redirect(property.shopUrl .. property.cartUrl)
44 | end
--------------------------------------------------------------------------------
/extensions/shop/src/controller/checkout/CheckoutPlaceOrderController.lua:
--------------------------------------------------------------------------------
1 | local json = require "json"
2 | local parse = require "parse"
3 | local param = require "param"
4 | local property = require "property"
5 | local localization = require "localization"
6 | local database = require "database"
7 | local exception = require "exception"
8 | local exceptionHandler = require "exceptionHandler"
9 | local exit = require "exit"
10 | local uuid = require "uuid"
11 | local localeService = require "localeService"
12 | local priceService = require "priceService"
13 | local cartService = require "cartService"
14 |
15 |
16 |
17 | local function process (db, data)
18 | local op = db:operators()
19 |
20 |
21 | local locale = localeService.getLocale(db)
22 | data.locale = locale
23 |
24 |
25 | local cart = cartService.getCart(db)
26 | if not cart.productEntries or not cart.address or not cart.deliveryMethod or not cart.paymentMethod then
27 | exceptionHandler.toCookie("cart does not have products/address/deliveryMethod/paymentMethod")
28 | data.redirectUrl = property.shopUrl .. property.cartUrl
29 | return
30 | end
31 |
32 |
33 | local order = db:findOne({cart = {id = op.equal(cart.id)}}, {
34 | "totalGrossPrice",
35 | "totalNetPrice",
36 | "totalVAT",
37 | {productEntries = {"unitPrice", "totalPrice", "product"}},
38 | "deliveryMethod",
39 | "paymentMethod",
40 | "address",
41 | "user",
42 | })
43 |
44 | uuid.seed(db:timestamp())
45 | order.code = uuid()
46 | order.creationTime = os.date("%Y-%m-%d %H:%M:%S")
47 |
48 | db:addAll({order = order}, {
49 | {productEntries = {"product"}},
50 | "deliveryMethod",
51 | "paymentMethod",
52 | "user",
53 | })
54 | end
55 |
56 |
57 | local data = {}
58 | local db = database.connect()
59 | local ok, err = pcall(process, db, data)
60 | db:close()
61 |
62 |
63 | if ok then
64 | if data.redirectUrl then
65 | return ngx.redirect(data.redirectUrl)
66 | else
67 | return ngx.redirect(property.shopUrl .. property.checkoutConfirmationUrl)
68 | end
69 | else
70 | exceptionHandler.toCookie(err)
71 | return ngx.redirect(property.shopUrl .. property.checkoutReviewOrderUrl)
72 | end
--------------------------------------------------------------------------------
/extensions/shop/src/controller/checkout/CheckoutSetAddressController.lua:
--------------------------------------------------------------------------------
1 | local json = require "json"
2 | local parse = require "parse"
3 | local param = require "param"
4 | local property = require "property"
5 | local localization = require "localization"
6 | local database = require "database"
7 | local exit = require "exit"
8 | local exception = require "exception"
9 | local exceptionHandler = require "exceptionHandler"
10 | local util = require "util"
11 | local localeService = require "localeService"
12 | local priceService = require "priceService"
13 | local cartService = require "cartService"
14 |
15 |
16 |
17 | local function process (db, data)
18 | local op = db:operators()
19 |
20 |
21 | local locale = localeService.getLocale(db)
22 | data.locale = locale
23 |
24 |
25 | if util.isNotEmpty(param.address) then
26 | local address = db:findOne({address = {id = op.equal(param.address)}})
27 |
28 | local cart = cartService.getCart(db)
29 | cart.address = address
30 | db:update({cart = cart})
31 | else
32 | exception("address is empty")
33 | end
34 | end
35 |
36 |
37 | local data = {}
38 | local db = database.connect()
39 | local ok, err = pcall(process, db, data)
40 | db:close()
41 |
42 |
43 | if ok then
44 | return ngx.redirect(property.shopUrl .. property.checkoutDeliveryMethodUrl)
45 | else
46 | exceptionHandler.toCookie(err)
47 | return ngx.redirect(property.shopUrl .. property.checkoutAddressesUrl)
48 | end
--------------------------------------------------------------------------------
/extensions/shop/src/controller/checkout/CheckoutSetDeliveryMethodController.lua:
--------------------------------------------------------------------------------
1 | local json = require "json"
2 | local parse = require "parse"
3 | local param = require "param"
4 | local property = require "property"
5 | local localization = require "localization"
6 | local database = require "database"
7 | local exit = require "exit"
8 | local exception = require "exception"
9 | local exceptionHandler = require "exceptionHandler"
10 | local util = require "util"
11 | local localeService = require "localeService"
12 | local priceService = require "priceService"
13 | local cartService = require "cartService"
14 |
15 |
16 |
17 | local function process (db, data)
18 | local op = db:operators()
19 |
20 |
21 | local locale = localeService.getLocale(db)
22 | data.locale = locale
23 |
24 |
25 | if util.isNotEmpty(param.deliveryMethod) then
26 | local deliveryMethod = db:findOne({deliveryMethod = {id = op.equal(param.deliveryMethod)}})
27 |
28 | local cart = cartService.getCart(db)
29 | cart.deliveryMethod = deliveryMethod
30 | db:update({cart = cart})
31 | else
32 | exception("deliveryMethod is empty")
33 | end
34 | end
35 |
36 |
37 | local data = {}
38 | local db = database.connect()
39 | local ok, err = pcall(process, db, data)
40 | db:close()
41 |
42 |
43 | if ok then
44 | return ngx.redirect(property.shopUrl .. property.checkoutPaymentMethodUrl)
45 | else
46 | exceptionHandler.toCookie(err)
47 | return ngx.redirect(property.shopUrl .. property.checkoutDeliveryMethodUrl)
48 | end
--------------------------------------------------------------------------------
/extensions/shop/src/controller/checkout/CheckoutSetPaymentMethodController.lua:
--------------------------------------------------------------------------------
1 | local json = require "json"
2 | local parse = require "parse"
3 | local param = require "param"
4 | local property = require "property"
5 | local localization = require "localization"
6 | local database = require "database"
7 | local exit = require "exit"
8 | local exception = require "exception"
9 | local exceptionHandler = require "exceptionHandler"
10 | local util = require "util"
11 | local localeService = require "localeService"
12 | local priceService = require "priceService"
13 | local cartService = require "cartService"
14 |
15 |
16 |
17 | local function process (db, data)
18 | local op = db:operators()
19 |
20 |
21 | local locale = localeService.getLocale(db)
22 | data.locale = locale
23 |
24 |
25 | if util.isNotEmpty(param.paymentMethod) then
26 | local paymentMethod = db:findOne({paymentMethod = {id = op.equal(param.paymentMethod)}})
27 |
28 | local cart = cartService.getCart(db)
29 | cart.paymentMethod = paymentMethod
30 | db:update({cart = cart})
31 | else
32 | exception("paymentMethod is empty")
33 | end
34 | end
35 |
36 |
37 | local data = {}
38 | local db = database.connect()
39 | local ok, err = pcall(process, db, data)
40 | db:close()
41 |
42 |
43 | if ok then
44 | return ngx.redirect(property.shopUrl .. property.checkoutReviewOrderUrl)
45 | else
46 | exceptionHandler.toCookie(err)
47 | return ngx.redirect(property.shopUrl .. property.checkoutPaymentMethodUrl)
48 | end
--------------------------------------------------------------------------------
/extensions/shop/src/controller/checkout/UpdateProductEntryController.lua:
--------------------------------------------------------------------------------
1 | local json = require "json"
2 | local parse = require "parse"
3 | local param = require "param"
4 | local property = require "property"
5 | local localization = require "localization"
6 | local database = require "database"
7 | local exit = require "exit"
8 | local localeService = require "localeService"
9 | local priceService = require "priceService"
10 | local cartService = require "cartService"
11 |
12 |
13 |
14 | local function process (db, data)
15 | local locale = localeService.getLocale(db)
16 | data.locale = locale
17 |
18 |
19 | local cart = cartService.updateProductEntry(db, param.productEntryId, param.quantity)
20 | data.cart = cartService.convertCart(db, cart)
21 | end
22 |
23 |
24 | local data = {}
25 | local db = database.connect()
26 | local ok, err = pcall(process, db, data)
27 | db:close()
28 |
29 |
30 | if ok then
31 | ngx.say(json.encode(data))
32 | else
33 | exit(err)
34 | end
--------------------------------------------------------------------------------
/extensions/shop/src/filter/ShopRedirectOnSessionTimeoutFilter.lua:
--------------------------------------------------------------------------------
1 | local property = require "property"
2 | local database = require "database"
3 | local util = require "util"
4 | local userService = require "userService"
5 |
6 |
7 |
8 | -- security --
9 | if property.shopRequireSecurity then
10 | local db = database.connect()
11 | local ok, res = pcall(userService.loggedIn, db)
12 | db:close()
13 |
14 | -- remove cache --
15 | ngx.ctx = {}
16 |
17 | if not ok or not res then
18 | if util.isNotEmpty(ngx.var.args) then
19 | ngx.redirect(property.shopUrl .. property.loginUrl .. ngx.var.uri .. "?" .. ngx.var.args)
20 | ngx.exit(ngx.HTTP_OK)
21 | else
22 | ngx.redirect(property.shopUrl .. property.loginUrl .. ngx.var.uri)
23 | ngx.exit(ngx.HTTP_OK)
24 | end
25 | end
26 | end
--------------------------------------------------------------------------------
/extensions/shop/src/filter/ShopThrowErrorOnSessionTimeoutFilter.lua:
--------------------------------------------------------------------------------
1 | local param = require "param"
2 | local property = require "property"
3 | local database = require "database"
4 | local userService = require "userService"
5 |
6 |
7 |
8 | -- security --
9 | if property.shopRequireSecurity then
10 | local db = database.connect()
11 | local ok, res = pcall(userService.loggedIn, db)
12 | db:close()
13 |
14 | -- remove cache --
15 | ngx.ctx = {}
16 |
17 | if not ok or not res then
18 | ngx.status = ngx.HTTP_FORBIDDEN
19 | ngx.say("ERROR: user not logged in")
20 | ngx.exit(ngx.HTTP_OK)
21 | end
22 | end
--------------------------------------------------------------------------------
/extensions/shop/src/module/CountryService.lua:
--------------------------------------------------------------------------------
1 | local uuid = require "uuid"
2 | local cookie = require "cookie"
3 | local exception = require "exception"
4 | local util = require "util"
5 |
6 |
7 |
8 | local countryCookieName = "country"
9 |
10 |
11 | --
12 | -- NOTE: ngx.ctx.country holds country, currency and locale for the whole request
13 | --
14 | local function getCountry (db)
15 | local property = require "property"
16 |
17 | local op = db:operators()
18 |
19 | if ngx.ctx.country then
20 | return ngx.ctx.country
21 | end
22 |
23 | local countryIsocode, err = cookie:get(countryCookieName)
24 | if util.isEmpty(countryIsocode) or err then
25 | local country = db:findOne({country = {isocode = op.equal(property.defaultCountryIsocode)}})
26 | ngx.ctx.country = country
27 | return country
28 | else
29 | local country = db:findOne({country = {isocode = op.equal(countryIsocode)}})
30 | ngx.ctx.country = country
31 | return country
32 | end
33 | end
34 |
35 |
36 | local function setCountry (countryIsocode)
37 | --local property = require "property"
38 |
39 | -- set countryIsocode in cookie
40 | local ok, err = cookie:set({
41 | key = countryCookieName,
42 | value = countryIsocode,
43 | path = "/",
44 | domain = ngx.var.host,
45 | --max_age = property.sessionTimeout,
46 | --secure = true,
47 | httponly = true
48 | })
49 |
50 | if not ok then
51 | exception(err)
52 | end
53 | end
54 |
55 |
56 | return {
57 | getCountry = getCountry,
58 | setCountry = setCountry,
59 | }
--------------------------------------------------------------------------------
/extensions/shop/src/module/LocaleService.lua:
--------------------------------------------------------------------------------
1 | local uuid = require "uuid"
2 | local cookie = require "cookie"
3 | local exception = require "exception"
4 | local util = require "util"
5 | local countryService = require "countryService"
6 |
7 |
8 |
9 | local localeCookieName = "locale"
10 |
11 |
12 | local function getLocale (db)
13 | local locale, err = cookie:get(localeCookieName)
14 | if util.isEmpty(locale) or err then
15 | local country = countryService.getCountry(db)
16 | return country.locale
17 | --local property = require "property"
18 | --return property.defaultLocale
19 | else
20 | return locale
21 | end
22 | end
23 |
24 |
25 | local function setLocale (locale)
26 | --local property = require "property"
27 |
28 | -- set locale in cookie
29 | local ok, err = cookie:set({
30 | key = localeCookieName,
31 | value = locale,
32 | path = "/",
33 | domain = ngx.var.host,
34 | --max_age = property.sessionTimeout,
35 | --secure = true,
36 | httponly = true
37 | })
38 |
39 | if not ok then
40 | exception(err)
41 | end
42 | end
43 |
44 |
45 | return {
46 | getLocale = getLocale,
47 | setLocale = setLocale
48 | }
--------------------------------------------------------------------------------
/extensions/shop/src/widget/account/AccountOptions.js:
--------------------------------------------------------------------------------
1 | Widget.AccountOptions = function (data) {
2 | this.data = data
3 | this.html = parse(function(){/*!
4 |
9 | */}, data)
10 | }
11 |
12 | Widget.AccountOptions.prototype = {
13 | constructor: Widget.AccountOptions
14 | }
--------------------------------------------------------------------------------
/extensions/shop/src/widget/account/AddressForm.js:
--------------------------------------------------------------------------------
1 | Widget.AddressForm = function (data) {
2 | this.data = data
3 | this.html = parse(function(){/*!
4 |
46 | */}, data)
47 | }
48 |
49 | Widget.AddressForm.prototype = {
50 | constructor: Widget.AddressForm
51 | }
--------------------------------------------------------------------------------
/extensions/shop/src/widget/account/Addresses.js:
--------------------------------------------------------------------------------
1 | Widget.Addresses = function (data) {
2 | data.formId = Widget.guid()
3 |
4 | this.data = data
5 | this.html = parse(function(){/*!
6 |
34 | */}, data)
35 | }
36 |
37 | Widget.Addresses.prototype = {
38 | constructor: Widget.Addresses
39 | }
40 |
41 | Widget.Addresses.setActionUrl = function (formId, actionUrl) {
42 | $("#" + formId).attr("action", actionUrl)
43 | }
--------------------------------------------------------------------------------
/extensions/shop/src/widget/account/Order.js:
--------------------------------------------------------------------------------
1 | Widget.Order = function (cart) {
2 | if (cart && cart.productEntries) {
3 | for (var i = 0; i < cart.productEntries.length; i++) {
4 | var product = cart.productEntries[i].product
5 |
6 | product.url = property.shopUrl + property.productUrl + "/" + product.code
7 | }
8 | }
9 |
10 | var data = {cart: cart, pictureWidth: property.thumbnailPictureWidth, pictureHeight: property.thumbnailPictureHeight}
11 |
12 | this.data = data
13 | this.html = parse(function(){/*!
14 |
15 |
16 |
17 |
18 | Picture |
19 | Name |
20 | Unit Price |
21 | Quantity |
22 | Total Price |
23 |
24 |
25 |
26 | {{# cart.productEntries[i]
27 |
28 |
29 |
30 |
31 |
32 | |
33 | {{cart.productEntries[i].product.name[0].content}} |
34 |
35 | {{cart.productEntries[i].unitPrice}}
36 | |
37 |
38 | {{cart.productEntries[i].quantity}}
39 | |
40 |
41 | {{cart.productEntries[i].totalPrice}}
42 | |
43 |
44 | }}#
45 |
46 |
47 |
48 | |
49 |
50 | Net Price: {{cart.totalNetPrice}}
51 | |
52 |
53 |
54 | |
55 |
56 | VAT: {{cart.totalVAT}}
57 | |
58 |
59 |
60 | |
61 |
62 | Gross Price: {{cart.totalGrossPrice}}
63 | |
64 |
65 |
66 |
67 |
68 | */}, data)
69 | }
70 |
71 | Widget.Order.prototype = {
72 | constructor: Widget.Order
73 | }
--------------------------------------------------------------------------------
/extensions/shop/src/widget/account/Orders.js:
--------------------------------------------------------------------------------
1 | Widget.Orders = function (data) {
2 | this.data = data
3 | this.html = parse(function(){/*!
4 |
20 | */}, data)
21 | }
22 |
23 | Widget.Orders.prototype = {
24 | constructor: Widget.Orders
25 | }
--------------------------------------------------------------------------------
/extensions/shop/src/widget/account/RegisterForm.js:
--------------------------------------------------------------------------------
1 | Widget.RegisterForm = function (data) {
2 | this.data = data
3 | this.html = parse(function(){/*!
4 | Register
5 |
6 |
27 | */}, data)
28 | }
29 |
30 | Widget.RegisterForm.prototype = {
31 | constructor: Widget.RegisterForm
32 | }
--------------------------------------------------------------------------------
/extensions/shop/src/widget/catalog/HorizontalNavigation.css:
--------------------------------------------------------------------------------
1 | /* menu */
ul.menu2 {
list-style-type: none;
margin: 0px 0px 19px 0px;
padding: 0;
}
li.menu2 {
display: inline;
background: #36c2b9;
padding: 13px 13px 13px 13px;
margin: 0px -3px 0px 0px;
}
a.menu2 {
text-decoration: none !important;
color: white;
/*
border: 4px solid red;
*/
}
--------------------------------------------------------------------------------
/extensions/shop/src/widget/catalog/HorizontalNavigation.js:
--------------------------------------------------------------------------------
1 | Widget.HorizontalNavigation = function (categories) {
2 | if (categories) {
3 | for (var i = 0; i < categories.length; i++) {
4 | categories[i].url = property.shopUrl + property.categoryUrl + "/" + categories[i].code
5 | }
6 | }
7 |
8 | var data = {categories: categories}
9 |
10 | this.data = data
11 | this.html = parse(function(){/*!
12 | {{? categories.length > 0
13 |
18 | }}?
19 | */}, data)
20 | }
21 |
22 | Widget.HorizontalNavigation.prototype = {
23 | constructor: Widget.HorizontalNavigation
24 | }
--------------------------------------------------------------------------------
/extensions/shop/src/widget/catalog/ProductAttributeFilter.js:
--------------------------------------------------------------------------------
1 | Widget.ProductAttributeFilter = function (productAttributes) {
2 | if (productAttributes && productAttributes instanceof Array) {
3 | for (var j = 0; j < productAttributes.length; j++) {
4 | for (var i = 0; i < productAttributes[j].values.length; i++) {productAttributes[j].values[i].guid = Widget.guid()}
5 | }
6 | }
7 |
8 | var data = {productAttributes: productAttributes}
9 |
10 | this.data = data
11 | this.html = parse(function(){/*!
12 | {{# productAttributes[j]
13 | {{? productAttributes[j].values.length > 0
14 | {{productAttributes[j].name[0].content}}
15 |
27 | }}?
28 | }}#
29 | */}, data)
30 | }
31 |
32 | Widget.ProductAttributeFilter.prototype = {
33 | constructor: Widget.ProductAttributeFilter
34 | }
--------------------------------------------------------------------------------
/extensions/shop/src/widget/catalog/ProductDetail.js:
--------------------------------------------------------------------------------
1 | Widget.ProductDetail = function (product) {
2 | var data = {product: product, pictureWidth: property.pictureWidth, pictureHeight: property.pictureHeight}
3 |
4 | this.data = data
5 | this.html = parse(function(){/*!
6 |
7 |
12 |
13 |
14 |
{{product.name[0].content}}
15 |
16 |
17 |
18 | 1 Reviews |
19 | Write a review
20 |
21 |
22 |
23 | Product Code:
24 | {{product.code}}
25 |
26 |
27 |
28 | {{product.prices[0]}}
29 |
30 |
31 |
32 |
33 |
34 |
35 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
Description
49 |
Lorem ipsum dolor sit amet, consectetur adipisicing elit
50 |
51 |
52 |
53 |
54 |
55 |
56 |
Reviews (1)
57 |
58 |

59 |
60 |
Aliquam a malesuada lorem. Nunc in porta.
61 |
62 |
63 |
64 | */}, data)
65 | }
66 |
67 | Widget.ProductDetail.prototype = {
68 | constructor: Widget.ProductDetail
69 | }
--------------------------------------------------------------------------------
/extensions/shop/src/widget/catalog/ProductsGrid.js:
--------------------------------------------------------------------------------
1 | Widget.ProductsGrid = function (products) {
2 | if (products) {
3 | for (var i = 0; i < products.length; i++) {
4 | products[i].url = property.shopUrl + property.productUrl + "/" + products[i].code
5 | }
6 | }
7 |
8 | var data = {products: products, pictureWidth: property.pictureWidth, pictureHeight: property.pictureHeight}
9 |
10 | this.data = data
11 | this.html = parse(function(){/*!
12 | {{? products.length > 0
13 |
14 | {{# products[i]
15 |
16 |
17 |
18 |
19 |
20 |
21 | {{products[i].name[0].content}}
22 |
23 |
24 | {{products[i].prices[0]}}
25 |
26 |
27 |
28 |
29 |
31 |
32 |
33 |
34 | }}#
35 |
36 | }}?
37 | */}, data)
38 | }
39 |
40 | Widget.ProductsGrid.prototype = {
41 | constructor: Widget.ProductsGrid
42 | }
--------------------------------------------------------------------------------
/extensions/shop/src/widget/checkout/Cart.css:
--------------------------------------------------------------------------------
1 | input.quantity {
display: inline;
width: 60px !important;
text-align: center;
}
.inline {
display: inline;
}
--------------------------------------------------------------------------------
/extensions/shop/src/widget/checkout/DeliveryMethodForm.js:
--------------------------------------------------------------------------------
1 | Widget.DeliveryMethodForm = function (deliveryMethods) {
2 | var data = {deliveryMethods: deliveryMethods, action: property.shopUrl + property.checkoutSetDeliveryMethodUrl}
3 |
4 | this.data = data
5 | this.html = parse(function(){/*!
6 |
22 | */}, data)
23 | }
24 |
25 | Widget.DeliveryMethodForm.prototype = {
26 | constructor: Widget.DeliveryMethodForm
27 | }
--------------------------------------------------------------------------------
/extensions/shop/src/widget/checkout/PaymentMethodForm.js:
--------------------------------------------------------------------------------
1 | Widget.PaymentMethodForm = function (paymentMethods) {
2 | var data = {paymentMethods: paymentMethods, action: property.shopUrl + property.checkoutSetPaymentMethodUrl}
3 |
4 | this.data = data
5 | this.html = parse(function(){/*!
6 |
22 | */}, data)
23 | }
24 |
25 | Widget.PaymentMethodForm.prototype = {
26 | constructor: Widget.PaymentMethodForm
27 | }
--------------------------------------------------------------------------------
/extensions/shop/src/widget/header/Background.js:
--------------------------------------------------------------------------------
1 | Widget.Background = function () {
2 | $("body").css('height', $(window).height())
3 |
4 | var setBackgroundImage = function (imageUrl) {
5 | $("body").css('background', '#FFFFF1 url(' + imageUrl + ') center 0px no-repeat')
6 | }
7 |
8 |
9 | var imageUrl1 = "http://s1emagst.akamaized.net/layout/bg/images/db/5/7385.jpg"
10 | var imageUrl2 = "http://s1emagst.akamaized.net/layout/bg/images/db/5/7391.jpg"
11 |
12 | skel.on('change', function() {
13 | if (skel.isActive('small')) {
14 | setBackgroundImage(imageUrl1)
15 | } else {
16 | setBackgroundImage(imageUrl2)
17 | }
18 | });
19 | }
20 |
21 | Widget.Background.prototype = {
22 | constructor: Widget.Background
23 | }
--------------------------------------------------------------------------------
/extensions/shop/src/widget/header/CallUs.js:
--------------------------------------------------------------------------------
1 | Widget.CallUs = function () {
2 | var data = {}
3 |
4 | this.data = data
5 | this.html = parse(function(){/*!
6 |
7 |
8 |
9 |
10 |
11 |
0123-456-789
12 |
free call orders 24/24h
13 |
14 |
15 | */}, data)
16 | }
17 |
18 | Widget.CallUs.prototype = {
19 | constructor: Widget.CallUs
20 | }
--------------------------------------------------------------------------------
/extensions/shop/src/widget/header/Error.js:
--------------------------------------------------------------------------------
1 | Widget.Error = function (errors) {
2 | var data = {errors: errors, guid: Widget.guid()}
3 |
4 | this.data = data
5 | this.html = parse(function(){/*!
6 | {{?@ data.errors instanceof Array
7 |
8 |
9 |
10 | {{# errors[i]
11 |
{{errors[i]}}
12 | }}#
13 |
14 | }}?
15 | */}, data)
16 | }
17 |
18 | Widget.Error.prototype = {
19 | constructor: Widget.Error
20 | }
21 |
22 | Widget.Error.hide = function (guid) {
23 | $("#" + guid).hide()
24 | }
--------------------------------------------------------------------------------
/extensions/shop/src/widget/header/Logo.js:
--------------------------------------------------------------------------------
1 | Widget.Logo = function () {
2 | var data = {logoUrl: property.shopUrl + property.shopHomeUrl}
3 |
4 | this.data = data
5 | this.html = parse(function(){/*!
6 |
11 | */}, data)
12 | }
13 |
14 | Widget.Logo.prototype = {
15 | constructor: Widget.Logo
16 | }
--------------------------------------------------------------------------------
/extensions/shop/src/widget/header/MiniCart.js:
--------------------------------------------------------------------------------
1 | Widget.MiniCart = function () {
2 | var data = {}
3 |
4 | this.data = data
5 | this.html = parse(function(){/*!
6 |
7 |
14 |
15 |
16 | Your shopping cart is empty!
17 |
18 |
19 |
20 | */}, data)
21 | }
22 |
23 | Widget.MiniCart.prototype = {
24 | constructor: Widget.MiniCart
25 | }
26 |
27 | Widget.MiniCart.updateNumberOfProducts = function () {
28 | var numberOfProducts = $("#eshop-cart-total")
29 | var oldNumber = parseInt(numberOfProducts.attr("oldNumberOfProducts"))
30 | numberOfProducts.attr("oldNumberOfProducts", oldNumber + 1)
31 | numberOfProducts.html(oldNumber + 1)
32 | }
--------------------------------------------------------------------------------
/extensions/shop/src/widget/header/RegBackgroundWithPicture.css:
--------------------------------------------------------------------------------
1 | body {
2 | background-color: #d50911;
3 | background-image: none;
4 | background-position: center 0px;
5 | padding-top: 0px;
6 | }
7 | body {
8 | background: #d50911 url(http://s1emagst.akamaized.net/layout/bg/images/db/5/7619.jpg) center 0px no-repeat;
9 | }
--------------------------------------------------------------------------------
/extensions/shop/src/widget/header/Search.js:
--------------------------------------------------------------------------------
1 | Widget.Search = function () {
2 | var data = {}
3 |
4 | this.data = data
5 | this.html = parse(function(){/*!
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 | */}, data)
15 | }
16 |
17 | Widget.Search.prototype = {
18 | constructor: Widget.Search
19 | }
--------------------------------------------------------------------------------
/extensions/shop/src/widget/header/ShopHeader.js:
--------------------------------------------------------------------------------
1 | Widget.ShopHeader = function (data) {
2 | data = data || {}
3 |
4 | data.homeUrl = property.shopUrl + property.shopHomeUrl
5 | data.accountUrl = property.shopUrl + property.accountUrl
6 | data.cartUrl = property.shopUrl + property.cartUrl
7 | data.checkoutUrl = property.shopUrl + property.checkoutUrl
8 |
9 | this.data = data
10 | this.html = parse(function(){/*!
11 |
38 | */}, data)
39 | }
40 |
41 | Widget.ShopHeader.prototype = {
42 | constructor: Widget.ShopHeader
43 | }
44 |
45 | Widget.ShopHeader.setCountry = function (country) {
46 | $.get(property.shopUrl + property.changeCountryUrl, {country: country}, function(data) {
47 | location.reload()
48 | })
49 | }
--------------------------------------------------------------------------------
/extensions/shop/static/bg_flag.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/strumasoft/octopus/4d66e3d6045cbd533353696abd80e48b1d606f18/extensions/shop/static/bg_flag.gif
--------------------------------------------------------------------------------
/extensions/shop/static/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/strumasoft/octopus/4d66e3d6045cbd533353696abd80e48b1d606f18/extensions/shop/static/favicon.ico
--------------------------------------------------------------------------------
/extensions/shop/static/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/strumasoft/octopus/4d66e3d6045cbd533353696abd80e48b1d606f18/extensions/shop/static/logo.png
--------------------------------------------------------------------------------
/extensions/shop/static/p1.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/strumasoft/octopus/4d66e3d6045cbd533353696abd80e48b1d606f18/extensions/shop/static/p1.jpg
--------------------------------------------------------------------------------
/extensions/shop/static/p2.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/strumasoft/octopus/4d66e3d6045cbd533353696abd80e48b1d606f18/extensions/shop/static/p2.jpg
--------------------------------------------------------------------------------
/extensions/shop/static/p3.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/strumasoft/octopus/4d66e3d6045cbd533353696abd80e48b1d606f18/extensions/shop/static/p3.jpg
--------------------------------------------------------------------------------
/extensions/shop/static/p4.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/strumasoft/octopus/4d66e3d6045cbd533353696abd80e48b1d606f18/extensions/shop/static/p4.jpg
--------------------------------------------------------------------------------
/extensions/shop/static/p5.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/strumasoft/octopus/4d66e3d6045cbd533353696abd80e48b1d606f18/extensions/shop/static/p5.jpg
--------------------------------------------------------------------------------
/extensions/shop/static/p6.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/strumasoft/octopus/4d66e3d6045cbd533353696abd80e48b1d606f18/extensions/shop/static/p6.jpg
--------------------------------------------------------------------------------
/extensions/shop/static/stars-5.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/strumasoft/octopus/4d66e3d6045cbd533353696abd80e48b1d606f18/extensions/shop/static/stars-5.png
--------------------------------------------------------------------------------
/extensions/shop/static/style.css:
--------------------------------------------------------------------------------
1 | /* call us */
2 |
3 | .eshop-phone {
4 | font-size: 40px;
5 | color: #36c2b9;
6 | }
7 |
8 | .eshop-call-us h2 {
9 | color: #36c2b9;
10 | margin: 0 0 -0.1em 0;
11 | }
12 |
13 | .eshop-call-us p {
14 | font-family: "Lato", Arial, sans-serif;
15 | font-size: 14px;
16 | color: #bbb;
17 | }
18 |
19 | /* search */
20 | .add-on {
21 | border-radius: 0px 4px 4px 0px;
22 | background: #36c2b9;
23 | border: none;
24 | padding: 0.17em 1.3em 5px 20px;
25 | font-size: 30px;
26 | height: auto;
27 | width: 50px;
28 | color: white;
29 | }
30 |
31 | input.search-field {
32 | border-radius: 0px 4px 4px 0px;
33 | border-radius: 4px 0px 0px 4px;
34 | }
35 |
36 | /* basket */
37 | .eshop-items {
38 | background: #36c2b9;
39 | width: 190px;
40 | }
41 |
42 | .eshop-items a {
43 | color: white;
44 | font-size: 15px;
45 | font-weight: bold;
46 | line-height: 25px;
47 | text-decoration: none;
48 | display: inline-block;
49 | font-weight: bold;
50 | padding: 10px 8px 10px 12px;
51 | text-transform: uppercase;
52 | }
53 |
54 | /* addToCart */
55 | .addToCart {
56 | margin-bottom: 50px;
57 | }
--------------------------------------------------------------------------------
/extensions/shop/static/uk_flag.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/strumasoft/octopus/4d66e3d6045cbd533353696abd80e48b1d606f18/extensions/shop/static/uk_flag.gif
--------------------------------------------------------------------------------