0xGA: Check-in [f1d02a401c]

Yet another PHP framework, but made for org-mode and geeks.

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Big simplification of 0xGA deployment (no more chroot --> use containers like LXC \!)
Timelines: family | ancestors | descendants | both | narv
Files: files | file ages | folders
SHA1:f1d02a401cd9bb92026cb515d76b365fc1ce0733
User & Date: milouse 2014-12-25 01:02:08
Context
2014-12-25
01:03
Update readme check-in: 913bab0bcb user: milouse tags: narv
01:02
Big simplification of 0xGA deployment (no more chroot --> use containers like LXC \!) check-in: f1d02a401c user: milouse tags: narv
2014-12-24
23:53
Reorganize sources check-in: 3a3e945478 user: milouse tags: narv
Changes

Changes to create_narv_installer.sh.

46
47
48
49
50
51
52
53
54
55
56
57
58
59
60




















61
62
63
64
65
66
67
..
71
72
73
74
75
76
77
78
79

80
81
82
83
84




85
86
87
88
            if ! gpg --verify narv_install.sh.asc ; then
                exit 1
            fi
        fi
    fi
fi

WORKINGREP=`realpath ./narvroot`

echo "$PAYLOAD" | base64 -d > narv.tar.gz
tar xzf narv.tar.gz
rm narv.tar.gz
gzip -d narv.gz narv.py.gz
chmod u+x narv





















echo ":: will init Narv in $WORKINGREP"

if [ -e "$WORKINGREP" ] ; then
    echo
    echo "ERROR: $WORKINGREP already exists on your system."
    echo
    echo "If you really wants to do a fresh install at this place, remove it first.
................................................................................

mkdir $WORKINGREP

echo ":: creating shared necessary directories structure"
install -d -m755 $WORKINGREP/var/db
install -d -m755 $WORKINGREP/var/log
install -d -m777 $WORKINGREP/var/tmp
install -d -m755 $WORKINGREP/usr/bin
install -d -m755 $WORKINGREP/etc


install -D -m755 narv.py $WORKINGREP/bin
install -D -m755 narv    $WORKINGREP/bin

rm narv narv.py





echo "General installation finished."
echo "You may now want to create your first app by entering the command:"
echo "$WORKINGREP/usr/bin/narv create [-d $WORKINGREP] <appname>"







<
<






>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







 







|

>




|
>
>
>
>



|
46
47
48
49
50
51
52


53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
..
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
            if ! gpg --verify narv_install.sh.asc ; then
                exit 1
            fi
        fi
    fi
fi



echo "$PAYLOAD" | base64 -d > narv.tar.gz
tar xzf narv.tar.gz
rm narv.tar.gz
gzip -d narv.gz narv.py.gz
chmod u+x narv

if [ -n "$1" ]; then
    if [ "$1" = 'update' ]; then
        if [ ! -f 'bin/narv' ]; then
            echo "ERROR: Could not find a valid 0xGA installation"
            exit 1
        fi

        rm bin/narv bin/narv.py

        install -D -m755 narv.py bin
        install -D -m755 narv    bin

        rm narv narv.py
        echo "Update finished."
        exit
    fi
fi

WORKINGREP=`realpath ./narvroot`

echo ":: will init Narv in $WORKINGREP"

if [ -e "$WORKINGREP" ] ; then
    echo
    echo "ERROR: $WORKINGREP already exists on your system."
    echo
    echo "If you really wants to do a fresh install at this place, remove it first.
................................................................................

mkdir $WORKINGREP

echo ":: creating shared necessary directories structure"
install -d -m755 $WORKINGREP/var/db
install -d -m755 $WORKINGREP/var/log
install -d -m777 $WORKINGREP/var/tmp
install -d -m755 $WORKINGREP/bin
install -d -m755 $WORKINGREP/etc
install -d -m755 $WORKINGREP/home

install -D -m755 narv.py $WORKINGREP/bin
install -D -m755 narv    $WORKINGREP/bin

rm narv narv.py narv_install.sh

if [ -f narv_install.sh.asc ]; then
    rm narv_install.sh.asc
fi

echo "General installation finished."
echo "You may now want to create your first app by entering the command:"
echo "$WORKINGREP/bin/narv create -d $WORKINGREP <appname>"

Added example/application.el.

































































































































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
;;; Org-mode configuration

;;; Default to HTML5
(setq org-html-doctype "html5")
(setq org-html-html5-fancy t)

;;; Disable default org style (you DO want to use your own style)
(setq org-html-head-include-default-style nil)

;;; Project configuration
(setq org-publish-project-alist
      '(
        ("APPNAME-org"
         :base-directory "~/Documents/APPNAME"
         :recursive t
         :publishing-function (org-html-publish-to-html org-org-publish-to-org)
         :publishing-directory "WORKINGREP/home/APPNAME"
         :base-extension "org"
;;       :language "fr"                     ;; Your language?
;;       :headline-levels 3                 ;; You can customize
;;       :section-numbers nil               ;; the following lines too
;;       :table-of-contents nil
;;       :html-preamble "<h1>My Blog</h1>"
;;       :html-postamble "<p>Still reading?</p>"
;;       :html-head "<link rel=\"stylesheet\" href=\"/.themes/style.css\" type=\"text/css\"/>"
         )
        ("APPNAME-data"
         :base-directory "~/Documents/APPNAME"
         :recursive t
         :base-extension "png\\|jpg\\|pdf\\|ogg\\|conf"
         :publishing-function org-publish-attachment
         :publishing-directory "WORKINGREP/home/APPNAME")
        ("APPNAME-style"
         :base-directory "~/Documents/APPNAME/.themes"
         :recursive t
         :base-extension "css\\|js\\|png\\|jpg\\|otf"
         :publishing-function org-publish-attachment
         :publishing-directory "WORKINGREP/home/APPNAME/.themes")
        ("APPNAME" :components ("APPNAME-org" "APPNAME-data" "APPNAME-style"))))


;;; Utility functions. DO NOT MODIFY !

(defun ed/orgx-get-file-title ()
  (with-current-buffer (current-buffer)
    (save-excursion
      (goto-char (point-min))
      (if (re-search-forward "#\\+title: ?\\(.*\\)" nil t)
          (match-string 1)
        ""))))

(defun ed/orgx-get-file-name ()
  (when (string= (substring (buffer-name) 0 11) "content.org")
    (file-name-nondirectory (directory-file-name (file-name-directory buffer-file-name)))))

(defun asciify-string (string)
  "Convert STRING to ASCII string.
For example:
“passé” becomes “passe”"
  ;; Code originally by Teemu Likonen found on
  ;; http://ergoemacs.org/emacs/emacs_zap_gremlins.html
  (with-temp-buffer
    (insert string)
    (call-process-region (point-min) (point-max) "iconv" t t nil "--to-code=ASCII//TRANSLIT")
    (buffer-substring-no-properties (point-min) (point-max))))

(defun ed/orgx-get-permalink (title)
  (interactive "sTitle: ")
  (message
   (replace-regexp-in-string
    "--+" "-"
    (replace-regexp-in-string
     "^-+\\|-+$" ""
     (replace-regexp-in-string
      "[^a-z]" "-" (downcase (asciify-string title)))))))

(defun ed/orgx-parse-links ()
  (save-excursion
    (goto-char (point-min))
    (let* ((base-path (file-name-directory buffer-file-name))
           (media-folder (file-name-as-directory (concat base-path "media"))))
      (while (re-search-forward org-any-link-re nil t)
        (let* ((link-url (match-string 2))
               (file-path (when (and (stringp link-url)
                                     (string= (substring link-url 0 5) "file:"))
                            (substring link-url 5)))
               (file-name (when (and (stringp file-path)
                                     (file-exists-p file-path)
                                     (file-readable-p file-path))
                            (file-name-nondirectory file-path)))
               (dest-file (when (stringp file-name)
                            (concat media-folder file-name))))
          (when (and (stringp dest-file)
                     (not (file-exists-p dest-file)))
            (copy-file file-path dest-file)
            (save-excursion
              (search-backward link-url)
              (replace-match (concat media-folder file-name)))
            (message (concat file-path " copied to " dest-file))))))))

(defun ed/orgx-propagate-save ()
  (let* ((base-path (file-name-directory buffer-file-name))
         (meta-file (concat base-path "meta.conf"))
         (file-title (ed/orgx-get-file-title)))
    (when (and (string= (file-name-nondirectory buffer-file-name) "content.org")
               (file-exists-p meta-file)
               (file-writable-p meta-file))
      (ed/orgx-parse-links)
      (with-current-buffer (find-file-noselect meta-file)
        (goto-char (point-min))
        (when (re-search-forward "title=.*" nil t)
          (replace-match (concat "title=" file-title))
          (save-buffer 0))
        (kill-buffer))
      (message (concat "Saved " (ed/orgx-get-file-name))))))
(add-hook 'after-save-hook 'ed/orgx-propagate-save)

(defun ed/orgx-create-file-structure (title destination &optional buffer)
  (unless (file-exists-p (directory-file-name destination))
    (make-directory destination t)
    (make-directory (concat destination "media"))
    (make-directory (concat destination "templates"))
    (let ((timestamp (current-time)))
      (with-current-buffer (find-file-noselect (concat destination "meta.conf"))
        (insert "[metadata]\nauthor=" (user-full-name) "\ntimestamp="
                (format-time-string "%Y%m%d%H%M%S" timestamp)
                "\ntitle=" title)
        (save-buffer 0)
        (kill-buffer))
      (when buffer
        (with-current-buffer buffer
          (ed/orgx-parse-links)
          (copy-file buffer-file-name
                     (concat destination "content.org"))))
      (with-current-buffer (find-file (concat destination "content.org"))
        (unless buffer
          (goto-char 1)
          (insert "#+title: " title "\n#+date: "
                  (format-time-string "<%Y-%m-%d %a %H:%M>" timestamp)
                  "\n\n"))))
    (message (concat "Opened " (ed/orgx-get-permalink title)))))

(defun ed/orgx-create-file (dir filename)
  "Creating a new orgx file and open it"
  (interactive "Ddirectory where to save your new orgx file: \nsname of your new orgx file: ")
  (let ((destination
         (file-name-as-directory
          (concat (file-name-as-directory dir)
                  (ed/orgx-get-permalink filename)))))
    (ed/orgx-create-file-structure filename destination)))

(defun ed/orgx-create-from-buffer (dir)
  "Creating a new orgx file from the current buffer"
  (interactive "Ddirectory where to save your new orgx file: ")
  (let* ((file-title (ed/orgx-get-file-title))
         (filename (if (string= file-title "")
                       (file-name-sans-extension (buffer-name))
                     (ed/orgx-get-permalink file-title)))
         (destination
          (file-name-as-directory (concat (file-name-as-directory dir) filename))))
    (ed/orgx-create-file-structure file-title destination (current-buffer))))

(defun ed/orgx-open-file (dir)
  "Open an orgx file"
  (interactive "Dorgx file to open: ")
  (let* ((file-path (file-name-as-directory dir))
         (meta-file (concat file-path "meta.conf"))
         (content-file (concat file-path "content.org")))
    (if (and (file-exists-p meta-file)
             (file-writable-p meta-file)
             (file-exists-p content-file)
             (file-writable-p content-file))
        (progn
          (find-file content-file)
          (message (concat "Opened " (ed/orgx-get-file-name))))
      (message (concat "Not a valid orgx file: " dir)))))

Changes to narv_install.sh.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201




















202
203
204
205
206
207
208
...
209
210
211
212
213
214
215
216
217
218
219
220

221
222
223
224
225




226
227
228
229
#!/usr/bin/env bash

PAYLOAD="H4sIAMHNIlQAA+3YU3Anbfvg8ZgT27Zt28nEtjPxhL/Ytm3btm1rYk/sZJ+ndg/2ZPd/9O7W1uZz
cnVV90EfXHdV99fW0NGF3twD6D+J8R8cbGz/TiYONsb/ef57ycTBygbExMzKxMjGysjEyALEyMTM
8s8gZPyPvtX/8NvJ2dCRkBDol6WN3W8n0//lc//V/f9HEURAQYn0EquAgNr+swlAUzyXjhvi8V83
qL8kwyV5CItI5esbyWqMxsxVacfIxg4dx7SsJH9IVQr+8EeYcz4o94rtgGw9buVYo2i7SgNmfM4/
mTo6O6gXhS8WKO7xNKu9Kc0ZVvI5APfC3+wLHWKZuCX/C4XOYscbYJ82KfqXD9CA4JWy8xCw+LSH
RcqCr+ErAOBFMfBBpJpc4PTD6tjnisQYhL7zuvKHMqCahxo2wi+GjiFEih3Gldd0XmlAy1fQA+lY
HmygPf+7e3Jw4fx8u/XyMnd6+Hfq5nRu+7GZTSrA4Q8RfcpNG1QwCf+Dfx5DscgOLOc7/Q1r33pG
h0tfFYpv1xrjVHP3oiRtasgFMlwU/whQYAN8L2jLeBzEnoFPZPrpuCXlPQ2hvCHCBR5ONRzVggKm
uxAzsOe5wzuT4G3WtBmFkGW+4kcrLLzNZ/ec74dMC+xjUmvXMvJf489robECSVFsGqvLCNVR4qi1
RATzTYQmqGFav+OZmGk9zUIHUcApuAzi3GIabApJ6wzR0RxeDO151Ux8WOgRaKsUKPvxbmjGu7Hz
3Q9b5jdHXLDQuN0o0y6SeNDVTT8a1nou2E3rVqM51u7gY9of0B479dszboNCCr5u5D93gpAk3ga/
EvxMkWZAPWp9qRDcBgG5RNa4DsmE3gx/kWNets3hf4B0+4ITDFkQo2t5JBKSfvj5opctg2aFfiV7
SLIhExOF7ewZbVHFjEEOs2BfEjcS1j+/nRuSVFueI+jH9HELGsZWKjJLE1JCjzgg7XTt99/xHJUA
fIBgkbY8+lChg0Aw6PJNEeBfAou8QfR+7PWLlaYRlq6AJ9IcTcIKninIquDO/qTxezOaBPg3j8rL
OuWDwy2tezPoDAkNbAF8XD7Pb059Mgm6LnfqSnvc/z5envaNKTHc69wTlrYq4lcSY7kDwQ08zbKH
QTn2AhbrOwIp4UB0SuBlxew9ivmgxkKUUUHqFBV1+r2NAxOjlznx1Op60BeYjp3KpBsNjxhWmafT
QiYspK4Io6hFNjuJw9vuW7gq1zFI3ec7xmyTWSPBTzmbgSkSocXXj2K51GNZDYgB+rSIcVhX23gE
R8A11E1wu0KZ+Tf0rdK0P8gtDlhYlVEJ1pGn2fOxouBF0EdgXSWRyOjproCP9nDOYyjLqV6vWbHq
oORwvO8pNG5O1w5B0SOJNctskYKty7RhLpZFnBhgZflDjxBkLs/xLNOCPf0YVbIhxrblP/Gs0SdJ
TdQ554IlLDRk8Gmw2sExPwb5Jfo7iuo85lvgkD6tcc0F+BV61d5txwUUXCZKZdLa+pWGqssbCh0n
BtLWcCITNEhNT+074MjEMzTkJqxxVdiSiBDUDcKhZz/m9EWQWrv0ELzJZNruAmcCBvWFIdmcCHRv
SLX0diDz30AusG3DRwrv1kG7cMtMdWRNjJMMvCkq4aqNPxu1bMUi6fR1K7EqYap7GvOU6T17UxGN
6nyFdBwmpzDgol8UGcduP75S3OJx+nuo/Cm7sVlDhk3Uqaoz8j/fVWbHH5fWalZcpKKaIot+t/UJ
3DC9t35N0R8JHkwHhcHiCPykj0JRN/DbDqMiKGfQBS2eJFAY9grCvxHdHBK2zzShRNS80cmjHL+H
G98KUAjAe6cQeFyyQ066QOIAYUK+Qi65+CPwUVRDLosZVA/X3xDfZEk6X5vF8tKaxfSqaFQg7uD6
lUEgFQ4/zylhjqREzpx763MBayNUZPJ7T5gNdiT6N3T9hSC/yprfI9WEGjv+HSdEyhsg/NI34hJo
mfQmsm2VIRZko2JBePGhVlsqCa3K4ho7xOCsAdyADfRnvvUcg4k+UY3zMq+uXKahDKTA1UWllvIb
adCYM7JVW3C5KpNIFj0eQdNidJIXdAG2alVmpSTaMnGp4bpkQa4Ku23vhqQsSfG4zZF0FkatxqI4
owT68SqVGS3kKiF5drWADxd/12rDmLkvu0ah3QEP6Y0dZ4KPnSjLWxWUcg5m4dVPpLyDl+XjH8Bl
rHO/2ZXEG3nPzeJq5IjV6H+z70YhtjgyO2SFBqYmLDVgbEJ/wVdheiWLjTIErjIFW7VxgbB+dmWA
P0ylwmYi2aSzXhtGTh/IdoOONEE+yik5IQqlk60Z1dOWoxrg/P1pSWyCpAa2iN8qqe9BvvS0zxq/
H9/haJa9Y9QLVGISwsFJ6jkpR+wJeuS95IopJQM1m57lZL89Gm7B36JOWE8t25Nvj+ug/9pzHQUT
rNTtxBzfzz3eBCodGAjPwa8VJxodiSabXg/muTMN6XIoOBKc0Y7I4hr72c3l9+Zpb3a/9+ohdtqg
5Z0AGbhCOBi2FXyWF16uIn6ofwB56XM9hqa4PBbJDq24myCZm2mugvNzXCGwVvpiNDMa5fTLmRd/
uEvj3sVaM8fMhLWQDLkesEY9Wwonm/iF6+3x2hgIQqElnexnX6GQeMAI2vfEhmwZiE5yBFHLEpJF
4P2cFywql2jhrWfsYTX5FQE/HEVXF95NWZnj/QpdG1wmA+xFf7eLGCKOPxSJ33njr83p7uogdaNy
tZIoraA3zRlaSMQYI9M/HvIBlInpzKYW3ktN262ypwZup56slFzd+ci+o4ubpV0zTU8fvdPJ7e3U
qG5xc7g2NtZ3upct1+HWrIq43QGNcRX1283F0R5AXWdzjKO44Qj5DsPO0ZtmZKyqJ7psPJ5s3rKs
HU0la3flr+7SBeCp0r4LdTuSi18vHaNGIyuFdL7Yahfh81QjYkVyuHh5mjbR/Rl80B2fuH2hnRJL
dDm1FVJLo7qj/OqqwtmFMETXs/JrxutRO/Bp+sI7A7VT15yUxTfklK8a9BiiGTl1xMZmCYPeGBOr
jl4dJmgcvUn/JqqzRe3R240cp+bOtcT+5fUZhF4vm6CnKzBA5t0D7Nj8+eICDcDp6QqPQUBPHyPf
XcRQOt7A4YLCryuwa07tgTVZhjksz4BseKCETn43KCvzEKEZ/bxNF+KNu/VgLoXsDfuRlnr3aRRM
6Mp7FnIK5Tm0R5v25nsj7CIaMZTvUljQKUxDchcF0YRGAakmNj+OG55WPvqR6WreCCyoD4tjvbld
+sswcTDgT+udjjSnyonxml/lvGYgqgxv7YpQkucrEDxsmtmhXDNotXIE0TU1+qV2aJEh6NbJXEbu
HUkMcPP9uT/bLleyfTssjIU2BR7ZjnBpIZoTPHX1MhGHK3XMJBwVmylj7zuybKclttJ8nsdTFzcG
Za6aqYFlWNrrGx91j7O/J1T8JBcoa+vrazEPZAVHy1yrRIW1nd0DGImDCd9VEr9He7MOv3QJJt0o
DN35OOOVNc3wobEc6uxdENRsK3nizS2+G5rdKESM9ljK6D3SByBsSQTVGCe4KzEVgUqIV7LU0LzI
b1X85V2TQxzdbHsEPh1S1Q1UMiHsjiXKQFtyKId37/YoLxSZE79hV1HHSLBcoOCSNpKPH13Qvv49
qIH1RlES0nCVqrcdtOnHJXPr5mXk4S8v+n6KKOKTwc0cQjf8txvrGB9pN8GQ+MDQP39ciroC5x7v
1q4+ra/eQLYjRl0J+K73gZALVJhwkTEGiC4M4zHhxx5CRDxj60I1LFWzph8fW/7eTU/LP22Mz7ev
LWZPxmZdBaRT/zJ26BGSmcnmC2i4aGR30sISp32h5RkWWfD2cr89KgvKl/rnyHeSgoyg7ZtgGXlJ
7mSvb505cV3IajAOs5dXOHgw4bwkpqLaZkbiNw7GwQ+RysbCopOuyYFgbQ8SKyqfgdVq2ncaXJTQ
u7KKSxjC8uorD8p/XR+UHIKjp5rUR5jLlx5xrUqNaMY1bI0NLddx+KzMv/8hzETCh1zk5aHGhZqk
52yYHUhxFGXps/fGHsIXJygoxbbwnhXLBLQUJjBw7bMjRcvPKI/ogEfvr9iydKuhT81qamsYvjXr
cIyrCDxqMsoxNQXwhaU/ilNNBWz6T5t1M+ZKeTbCXj1rOD8zAXZAotBxfB0Vr1k4EAd1pEeg519C
JZhOO6NzncWhRRmSp0z9yIkCnAcHhWD7ksiR48ZKEnnQqZ2YdTI2302ge56NqPk2q+WGUHOm4J4Y
kNehVn5dRhx/1MIL+ve28T8YIj098a/PB+9jHY9J4NRSZO9qJMO+3Rra4Y48R74j5JCVFnTjnl7j
vJ6za9dMID+WpNktmfQbvN7sj7z1hNwqnMifxKSO2x3EP4IW22FzyCAH/6I/O4lZdY1QKdToUaPl
civOqsFALIsCI/VJKSKL/xK5WUz5iaxCzoc5+wjsInRA2ZQLxcYT0B7Z8WxctvtOH5eB+EJuvQm6
RZKViYff8woUQ1sREMcH59vhVfh3LO12ME8XgeIGWRpn0NR8j4xF4pqOu8CZOU+b+fDaiq1+XeRG
Ziq0MuJEFhxi+iaSSIWSNzDNU4hD2wcSxY3ij/ykJmu2IQU+nUYgfocftwdxG2Yv7PvmKd/wjq42
RP6gDS/PqjWhSeZouluLm4m1YWOV0jK9R9jqPeEb8hC+t6QEtq5ElcL0ZT/8xZXLqazWcD0+lVgN
r8QJmIbGUfPsmEA6acTYkKwchc8i3c30n7pjueQ1YrYS0Q1vKhAbGpTWVl6JhIIDb/ub22fMxcTs
B5gM2c+wqTpQLI2v9xGf+e3lr/cnga8bfcZ8OcvIVY/YfUx3MK1pGWot0QO5OrSChqw5ZHqunJK/
wx1k54O5ORDOEkpyJfyus9d3FtTPmVHGyLL63j97QnI0OTPFAdFKnFdKGtNT1Ht3ihuxyKTTuUuo
sIN1TMxCZGC/U+UHS5itMYoTfcxyFLnwrY7hAzg+SZT7mmMrETAaKQ7nr/WzCTL1Orm6J1VKyHLO
cdkkB4VNAlyetaGaNNH9p9Im2fEsu+Y7EaE6UJyFf6i7AMoqteavJ8uss8f5dJwDZs2N5WUOcoRp
uxu7yXJaYylO/kbDaFUc+39wHEODcx2PkfefcD4B/VhV9zGePraWAqPDkBFpg5wrw8zRUmvZoPSP
FcP0s/yoc6kKTq2lJnYGZPMGy0uIO7ZVNRd3pOKxSS89pBZwIP4Ao2W3d579WWrAILmGLB8EFyV1
qcsuSikNv7o70ZQvWuFApR0CyBT3JpP1Wqm6zKJiX4pX5c13Qr48IzIJbY+igG3KKTZIvqsHVZhT
Dt3uvaoWXwX7bNwY7gq3g9s8ttZO8YLuFTDsQOT5ouZEC67/ZEXird1MFrTtXUmR71CfR50IE1VO
OmpLL2UfjF9KZvZLu8IuzGCZFS4ReQqnJqYzoKY5m0UK1ZI3jKNDTWfxvlFpmwyNsiuaaVyzx08r
jOGljWFG4A48MgBfYcc7dnNGFn+SmURrEWX48RZ5RcXpuCMNXiuAHxs7EGgJahnOBZ2AI0OmfpFq
quHkngydb4vkWeWiY9xQlm75NAAgokPBiEuxiKEpPqprJJJCdWguG81086twR2N6sizJ8wtYAjej
zwkmVg53qHlqLSu3YZeCMwoog6g4Q0z/wkuAbm9IUp14Ka8ottZnbNcz4CjlZYDpUAtpq2YpkIHZ
sIlXvBQWXRJsoFqR08WDp1y0YD3lzHvjKTdjUmDfxUGa1z8SUTpzne8tseZDO7eodIHTSeuaXqs6
5SZvKnSXJidwssquXAnJtUqoJhpsVvqVa0exnRk9emQ4tzIbqwlRaZlNF8nu5qZ2uk4rZ0YsnHBW
yNRmFu6Sr3tnHOvUrN5ztqZ0TBu/VFld28JvM9WyWbWiTaGNoQFuvvswSBhHoz0NuySO490bWOSE
hQaoaKV2UhsJkCYuD6azNsWng+5B3V5ePuFuDT+0ci2tqQ2V7ShKMm3fGdXSqQKbHx9GUe/mNNaW
O5QKGM+x87JvPppOhtX+0ayH0Cz/qG6ld/ZprChZgB88LYy/uK84t4HK11veSwzqH5moCWdyjEG+
2CEIlrdtmn8RxKcOlN2pq2abBg/bk/xUfgCNYmrRFqIrzOobI6TD/VzB29xQGO1tR7liRQ085dJX
vqGpbeyXk164TTyhwx/ErwZ5+iMXV2uDDSnM3XY3vcmF76RCuLNVlpzoK1fepiFeq6S+rFTkAa1R
NRGNEwJ5w5auBg5uiDY0qqpvflhee22zutYRXK0RmM3ao/ZNx1SUbENjhTXTA77maplNE5ZLf69p
XpISJtcYPdym1r/fUfErsEBqbam+rXl2aaheabYFdYKbscVfNd436Zp3PN+9C9tVLMi6qjxNbhtf
WDPdmhSz3UiLqZxWqSlPn6OU4yHt96qyDSHWZh5oK1mP2jrJaFO07N3WWc98nlOMXtv9cOep6Ifu
LtnKMlHMSBwF7GzX+3o44PAPH0GfkAPHAHeusBvDLnSX45qMRqB1Q2UFrNjeenvhQOZqwS/F88ub
PRoTH4aewgUK25NulSCZl+B+pGqxbro5VgGeMHW72PEUmfBzNnpWQQsAsQ5o1g2+EQ77+ZmG7kZr
8zZLI9hTiqkqzO8pwBDblzDHLYzJ68FCgDp6+fXfVIYRTFe32UAQhmyHFYAEeceRo29boDO4I2gb
oLuyfyrSsG+ISfAUNtpZDAZY7mgSxQNwH+6UoxeSmEctcDfoX9AvmJUBOySTFdFqEKAHUtMg6Cph
caEItnF7xkMdOCrxPj2ASlWU5SQsIYJwS8xw0lDE3sy7Ni8WIkhrUZGt7JvM01S0r+kF6lUb7wv4
QEPaWJowcWwMZRiCHX4II66cQmmasHyVNzItxq+SZ7dlxV5ZC2/BLb87XTZueS1fu5Lf6DDDHm+d
Lg10kPo95fJjqItospE21XEClnnMc2FNUnTVs4PvnA+EDkv21AsiVyQCg4xpXDvmCzb303+EX/h/
2//+rX709u7/0QT8X/VfJmZ2ICZmFhYOFmY2Fnbmf/svB+t3//0/4t/+e1vupfzf++8/mwDUxfvh
tMFe33NeI5h0EytrMm77tv3bWc3WUW7dpPrUFNl829kZG55MGFk53AB6tJ4i4evD5UYIhJRywyuN
vIoOqSNia8ioB+hojGMBtKakojNz/jZYxdVoZPxaXGH0ZcGp3kxTz9b8gJD9WGA3YY5yR70SPdDh
jsr8SFluquQsNS1mo52Z4EU3YPDuVxr60UYefThgKfISnthumP2QH+1cl+VZIg72NetFq/YSnZNV
f6i62NKMT6PBMcGuovGoEf+XVTOFJnXp6FOiBdR7tbiLsApT79bs+o/u7m7vJyF+LLAX83Eq/64S
H1xKjJoFZpofnObnO2X2ezVwEXZ3GxxF/g1trPYC4+bXqMcFc+2SXBQMynGfng9h1UM2rMR/KQpw
4knd0yJIobno2FHi1VTTrk7ByGSOe+rjxVmgI3wQSYf9SNHyyZ1uXyZG8RZPGAsF2gYaqzWnDJ3r
nCGtXCZZ3PAT7zGdj7TJVKldON0Slhds2D4AN+DZEDfBS7XteXwOi7cN5lh0QBOIcTsDpVgzHKSI
p+W5wGMy4FvS65P0RI2SyGZ5cVrAFn2nfKl/qvPjZyjlkQHJpA590Y3wdMFxRFxDiCKEDGsHjaPp
N0HiGu2+H01akp1ktf4y3I65htvxe9mRSjMO0xzuea1s7THBozW9bq2SEcTOa8BlNnWxcLdR6Z7L
WdpnEERaW7FctC7JNWKzOZhNpFViVtA3r4x8DcK1QeLa0R5/SzXafgrOLWXksFvJBiCw7GqCiWph
uxxgpKR0k7GJsrunUdFFXXR1FIFQcWyoX/mtlU6ccJQqDIgL9k7wSm6nh4voehRZYNUsZCrfgojf
LgnNqrcO4eG3hYxAt0lFDKib/BZccExG4XmABobz3y8htNZCPKVAGbHbIyDPMgNoococ4VrMFqz/
vQQ0szcZYoes5I//VhskW4PWXGlLtd4IwjpOQR9DC0QwKAe6mhU4U0B2Ec5GxsLv1W6vrneQrb7u
cyeVsKKO8ZiyjacfbELB6ooFT43CdW0sHhT8Kkjb+sNevzw4+dGKJp54GJD2AngxDUUrMpTBYDsM
ES49McvGcwoV5PYMJdpN9j1pl4x3jK/SSW5AO6NdK7TuO+OJFEvv93RxBvpNjGzu/Hs1uC8/anFC
PJtJkkUt0pc1itRjVcNw0ZDQshDY7IROdwD9l4OwqbESqh1loVTuOOPZ63Fy8EoAD7ZIDh47VLWX
31TQK5e7PL2HQ28DA9Sz6VOdj/cI9xIu6PYnU/b238U76nC4EbYyKQXR/G7reYCV3RmnLxhJuSOI
gbUmvaPabU3rJRxe22un8WmrPrJ9IKT8lmjUElbVRlzu1EI4AIGqkI+5Hm2aGhVoaVF6QdsbLlCG
geI20HsICIh4gq7snx0a7vS/RIMgDfVo1dQLiD74QSr5wo35sozzqzEL/PJ+vqcYGUqyqTci4lCx
2gBYl17VVsQvYK+xz1Ct/1Hwo8w/h62mFObCD1rB9ZTt8Qx+atJBwtFgXhrxNwuua1nRoRtrHq1T
3ohDx0ER1CXbCslH0hV2gYcgPblJsX0wl4cveyx44etEhk/XWQ3MrJTvb7v0XyUdyYRWZ0UCL3j1
pUDQYFfRzInBUzCgvxAAeRZ0cavEbvBU4vZBAkd90NLJ5MFU8E4M6k9zFy3jD1NlFh7kfHXK8oj3
11hRjJhQdAtLzvYk1LQMtZe/6oKLYj/APRTi0i4H0PjQEPO9TZqg3f9UYB/VWyA4y6PGmouSrQq9
hx3iYVPEm4VoGFDIuxyBIwM+HyeOr7WQcIldII5KrvibdWN5jOzcZJgQJReI44pKUIaXQ9qLiyRV
fubsejtT38/pJ90Dk1DTBSBkclX51qSj3FKeUQj15m/6hLTnoFlVdru3ULM1nykVL8SklSYimkUQ
UwwlFynKzEj7Gjziblht3ZatCGLzsZd1UOThjNIsJYrvem8FdsyA3Nvw010qUF0UZsNXW1Mqap8+
NW4/ij6Zj2xLoXIJ5K/8atoKQmfGvgBhjVjQl6XTI4FWsPPwb4QuYQmg4qIzy7hhKJAoE+Jo4J58
lUbfSW/kNTKOWO6fckqyAPBxPqfeCo9AK8O7ZdB647J8sKQSGIOJWjfcbb1vj7AQSj1tinCXgR2/
Gbl8Xt4G/qy0g3Eu5V/BjF1nkiUV+WsYl00duIr0QiLRM8DNRXZz0IhO1/cWN91M3sTyFUmFR93Y
H73wCjslNnVdiOHE0RaLjghXnYAOhMSFxszh4MnL0uT3de9o2F/miDhVH32ELqPPhoud7w+d9qXb
eGdCQ2PiGfBpwemrTRJg+IDvSo7CPLXSqe3NHQWfWShJpOT4XoQELWFoMgVfVBsIGvcYS6/Z+afB
32GkKOfnIwMj2UFjo7zpVKO5ZvdYX1nB795AFMYoQNdCcZyTORmpE4rMD4Wfs+O24AlH78UoiuWJ
ThiTuJKlj2Gi9buHTJIZ7fA5lc7yetiN5u1VUD818VWiz9fulSISwpoT2HN4sufWf52n/7FN2BCz
Un0d8jObLix67n14U4pbQZleLD69SjqxLuzLwvPFc/RCfsl2dClduWej641F/ePGS04gBr+w6QeH
6EFjJZl36JLbgoZJaZPLbQ4Jb12YKnZnXP9EHuZAPCPNUljYCmkGblaSmtyuKVGL8gaCHC3Yy6v8
futav73nUJY6sX+W+/tnX4lVRO4L/9b8aUm47ZaQh1EjdZXQu1FUFZcdp+8MBaaBUUDsbm8EgO4w
21aw0ambKgjO1QRHIBe3Fki571FXEPB48dhIzEnTYfF8QSpNsl9yT354zl0zCP18Vu1XE87KcFlX
pQX5RUgXPDJYhYlv8jvkjOqqPtv7Zg6UreJ9KqWv4Yn8Z2dpuQX7WXbsgNotXhYoI29QjgjFDaNJ
t+bncGyDHYyGklDUiNsG4Y9SDYUH0E4bxHtjzGlDq77IS6GIehp6h04i2ZlqfloIC9oObkUY5ifg
xaEYjW1AKMIhAaQZTwZ88S0SxBIXmyNRL7w86AHvmnKdMWaA6vxxr2XJfpEhT2Gx1GrqADpmyOKI
P9NedQ5L6+0zDA+avEJus2NuzK9koIMSMomdsyqMJI/XWYr6k3QmRqsgC1usUTU+Xpi3P6LZL7vH
fxybnQv7kHjp4J0jLRQQ8Xp2TvNf0XG8Hw25rZcoOoEaD0+z4QKXydaEnG2SwsdYbs9jQ4yOsw/W
5mYLGYYKZwxMCKRgNznAtUvE/Fd4gMiO/TuiR9hZ1ePr4g+wWVBt3Anx/J1NvPMthvZRuMDYFbbe
yC4zB2AWF7qHaHT4b0uaSGdWSU8+ouL98IMX09dJvwSiTqOWrWB/PcC7iV0DhJkF2dKI9NjHzmcv
OiFprqxPf61CS6vCl7cqFU+fEB5Bl+K1AbmgHH55flTjB+I8gb3huSjve2exdhu1AjvWOlHJ6K0j
lahvnb/51X3iPfZPForMKn95qn6hLOpqRsiQvhSz4iHYuthVnjPPDZwtX407qO2axxvrmZw3Tps0
FjEJVPZzP88oV7YOPGui3oNdIFk1Rp2wVgnJ6TV3oMjjk+voY361pR0Y7fKrzejJNuzfT9FmebXC
aKQ3uZcXR7YAqd3MrvReKWzyjaUoeBri4pZm0iC1H+0/TKlkpbnVsMm/Wp0fG4DSb6fReAgurF6P
Wmkm5cmSkllrWKxpDX0EtZTAuz2hBk7LlPYkkg9HE8Kfx3WYkgEalBVaw0Z3Zp7cLMMYNyucwG1v
da3Jigdk8iwQnOb1/SUcWBDDy9PV2LS1sYyufQ9qh/eqRfCn3/ARhfhVTpEUwloVMaJMzSpqO86t
ze3nDLjBN095IuRIM9yMFBf54Fh+sppAzNhg0zn7B4g+Fa4qXftn5xsQmPrSYM2/iixtmExKNEY+
axyvM2DGybPnm+4aJHFZnZkECHXBmKCY7c+FdCIgJKi4cjJpe8FwJMBzqJkfwdlcplx4QJ6f9WTg
N22lt2gcEYEVtjrKuugl1rpZ8vl9tXUPOTq83UWcigHKrHabOeH0ul9Ph0b0qwPeKv78jtvPL9KE
+HMXlj3oKXxSM7lOuqmd0XZ4rrOwgvGY8GnqEkDIsOnad2PYkeutOhyTuFg/6l80T5znfI19EO3g
nI0zLLdUH0CMr0YcHIUBwYkr60/I3FJkJuQcQ6wV/khWIl9VIJYAj7egc1lJiLtLlzfh9zrMkpfB
znptgkn5ACGKmcfa05/e6qBZZtJalTd82Ty83sgq3i2S460govT34pexW58M3AQZVqpVV0LVJsRL
rvZx64P/nNc1EitxGQIsgv6EslipJuYu5ArEhlhXh9/RZRhwibWs5wi8WDGIk1fpoD115DAyxHUi
dG9AcagUh68Mf+fLy37IU0q2tUdJ8fkvqyd/MmsiEdcKmz4ip+wzpwfouR3yA0stu0tPePg37PBM
JGjTHOZV5S0nwj5kS4zd0ozTPaEx+5aSzCTdpyZuwdfMEzycP0Uc0Phy8o3luhtJf11oCs2rswzy
L6X/0H05MzL5maymJxErAmlIhaKq73S+P8Ws9HR5iv1du5tLegHvF4CcpImL8OeHNO5KL495jo3g
WZXBbDs2XuAmEEhBqdKAqB5mfVE/fXWV3Zq4AEzBqM2MJlxAvr89xUnxyTh0Sz25O3CQ8NK9cGHq
dSsN6C9GrVKQ73CKuZB8YdbTuCtbitNXaPdrxpkfSKXv6WPsdkK0uOwCuSptpecZZ4dtRb5fBz3Y
IBylpLDc0vGSnAoxsigKAWKvV4jAuWzqvNmSwkF+yyfx1yjy/KWZsJPMnhrRqmWifr9tA1gHSKoO
tMypPuDqPC41CgN6e/Wx9bV2nTT49wV1nK7eGHh2NLcMsXewQTQy2PemP18//7yRUxJvuf9FccmY
zbNVfPIzX5GuN6xVrAcKKto/YQ3IMji2nQWq9VdDDyn6amu9qL2HTQUxxFmpeOMcwPjhSAmDfeS7
nGMAX9s52cY/8HfUQZVbTvYNqvDc3SQe1gKNhqv5GGinjAnv54B6GCnWkAzme6n9dA0whX3baei6
0U1twbMrQU2Xa59OcE/P89UeqX6Px828zMJ0BcRPkDbiLGZsT7OrtGLHql8NzeoMyx2rVoii9RQ/
ZnhNt2c3XKvfd/R0RBG80ior2q4LPBsQMcBpmbD5NDYEeto/K5I+HpoubZlnH8Ggn+naTdlcpEdO
+mreLDHcvto1oqWoJsoPveXOcZLoF2S7QnDbrxEUKtUTN9rlk38L75+uF1BdBDsye06vKVKVWJNo
Sk8OAPH2I2AYNMsdJpxwO26r5bmsXFiTPqXCod+Ld2PhEpJcksVWmqn+XHqBE023kfGMSkQWlflL
O+E8NhUmDs2PKxB45Nc5drCtt0yiqWecvyVYTEPPhLLEIJ0/Sufjz5nd7yN0TEu2Oh+/bIn0Q5UU
iuTOB9ZozoCuK82zIAX/WXhBK/o1wTnxcfaFd/zK0DCsxagy1xLrkeKMtpw36meKk9Gobm+bzQeZ
+chyene2pyc4wyR0cpGroqWjkt3foi97wOPG2ictTgs5xoPRB/XhixaWxWrXBWTnZEAD46E1KYaD
o7c8unneYkdlz3N8Zlo/yR+hnJIpfKp3F+9mAYGJ0bXztbWNtbUQeMJykLEpPE/nKdf87WLI6pJa
uCgQnmUKrIwM76xk+/l1aUDp7Bs3WutrC5bRA83iTu6u5915UzVqbejo6tw4Woh9tX6Xz5sFaSUt
28/94vY+6a8CGKeciMYslRmWNapgMGVvZH1CC2y0dhEiQrsQ5H+++2/UQYIF7SCkhjSln+rFDjkJ
MIJBHZAep9UNu0WyhdwyZjpcZw2duwaWrleFFkP6lYdvnHGzzuB7Arc0DA3t7Az7Rkc4GEyfjs3f
f2U5gZMNvAIrZN2X2NbsQQ/e83XkieK3YLYLNk8QLna9iprVXcz1GsMA9YqAutMrzZMAJ8m2LMNJ
RcBTWmurl7bQvR4GT1FuL481eyLpEeUFVxgHSy7NiZVHjwHHcct2Ub/kFZP+88PuenJkz5SnAWSI
8Jb4tZ0lyp/Y5GN/09JjmBgp3xW9QKvlalqFMZ/lMiR6nQW9tnjVg7H7aHdvRnx+X7sVlvquny4z
NG494eYkbBfNGd3BN7iHLn+sqKHpSMHjvIq53z1oOVf9U8ikY6m5ahteeWod+uYHoSNrb0UXVxbq
8nP2CKXdO0Ndh+7W3E2sEauU9XP0yD07xl6Q7J7jZPY6B8iIlH9WNynWjCykbgeDHAg+q+1eT9SU
enyyxP/tpvXt27dv3759+/bt27dv3759+/bt27dv3759+/bt27dv3759+/bt27dv/z/4b7sP4RYA
UAAA"

if which gpg &> /dev/null; then
  if gpg -k 8C9CEE3D &> /dev/null; then
    echo -n 'Check sig? [Y|n] '
    read check_sign
    if [ "$check_sign" != "n" ]; then
      wget http://projects.depar.is/0xGA/doc/tip/narv_install.sh.asc
      if ! gpg --verify narv_install.sh.asc ; then
        exit 1
      fi
    fi
  fi
fi

WORKINGREP=`realpath ./narvroot`

echo "$PAYLOAD" | base64 -d > narv.tar.gz
tar xzf narv.tar.gz
rm narv.tar.gz
gzip -d narv.gz narv.py.gz
chmod u+x narv





















echo ":: will init Narv in $WORKINGREP"

if [ -e "$WORKINGREP" ] ; then
    echo
    echo "ERROR: $WORKINGREP already exists on your system."
    echo
    echo "If you really wants to do a fresh install at this place, remove it first.
................................................................................
This program will now exit to let you do all the necessary things before."
    exit 1
fi

mkdir $WORKINGREP

echo ":: creating shared necessary directories structure"
install -dm 755 $WORKINGREP/var/db
install -dm 755 $WORKINGREP/var/log
install -dm 777 $WORKINGREP/var/tmp
install -dm 755	$WORKINGREP/usr/bin
install -dm 755	$WORKINGREP/etc


install -Dm 755 narv.py $WORKINGREP/usr/bin
install -Dm 755 narv    $WORKINGREP/usr/bin

rm narv narv.py





echo "General installation finished."
echo "You may now want to create your first app by entering the command:"
echo "$WORKINGREP/usr/bin/narv create [-d $WORKINGREP] <appname>"


|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<


|
|
|
|
|
|
|
|
|
|


<
<






>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







 







|
|
|
|
|
>

|
|

|
>
>
>
>



|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130

















































131
132
133
134
135
136
137
138
139
140
141
142
143
144


145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
...
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
#!/usr/bin/env bash

PAYLOAD="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
4x//+Mc//vFf+w/l7rbnACgAAA=="


















































if which gpg &> /dev/null; then
    if gpg -k 8C9CEE3D &> /dev/null; then
        echo -n 'Check sig? [Y|n] '
        read check_sign
        if [ "$check_sign" != "n" ]; then
            wget http://projects.depar.is/0xGA/doc/tip/narv_install.sh.asc
            if ! gpg --verify narv_install.sh.asc ; then
                exit 1
            fi
        fi
    fi
fi



echo "$PAYLOAD" | base64 -d > narv.tar.gz
tar xzf narv.tar.gz
rm narv.tar.gz
gzip -d narv.gz narv.py.gz
chmod u+x narv

if [ -n "$1" ]; then
    if [ "$1" = 'update' ]; then
        if [ ! -f 'bin/narv' ]; then
            echo "ERROR: Could not find a valid 0xGA installation"
            exit 1
        fi

        rm bin/narv bin/narv.py

        install -D -m755 narv.py bin
        install -D -m755 narv    bin

        rm narv narv.py
        echo "Update finished."
        exit
    fi
fi

WORKINGREP=`realpath ./narvroot`

echo ":: will init Narv in $WORKINGREP"

if [ -e "$WORKINGREP" ] ; then
    echo
    echo "ERROR: $WORKINGREP already exists on your system."
    echo
    echo "If you really wants to do a fresh install at this place, remove it first.
................................................................................
This program will now exit to let you do all the necessary things before."
    exit 1
fi

mkdir $WORKINGREP

echo ":: creating shared necessary directories structure"
install -d -m755 $WORKINGREP/var/db
install -d -m755 $WORKINGREP/var/log
install -d -m777 $WORKINGREP/var/tmp
install -d -m755 $WORKINGREP/bin
install -d -m755 $WORKINGREP/etc
install -d -m755 $WORKINGREP/home

install -D -m755 narv.py $WORKINGREP/bin
install -D -m755 narv    $WORKINGREP/bin

rm narv narv.py narv_install.sh

if [ -f narv_install.sh.asc ]; then
    rm narv_install.sh.asc
fi

echo "General installation finished."
echo "You may now want to create your first app by entering the command:"
echo "$WORKINGREP/bin/narv create -d $WORKINGREP <appname>"

Changes to narv_install.sh.asc.

1
2
3
4
5
6
7
8
9
10
11
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2

iQEcBAABAgAGBQJUIs3qAAoJEKcU7KyMnO49j24IAKvZHex48OC3Vx4SaJIexapk
pJoicoFpXM5LBKHlOioh/8JKGQzmRiSHrVQOqXqsN4S2dcK0qFRkVzD077o50gpB
0ChbtvzrfKRQ34i45/fB/iMlmgJ9Fna7Llwp/MWwrrL5cUDTCKrkahTO1CPAPXQG
Y1GEBs6PfWQippnXzFp9cH8wbu3EbkXzPO2B0agKyKWum2Kss17CFchRiYKNGOKb
/H4k+/IVJnOQmaqCpH+7B/+YMdrYUCsPBzIK9tQ/DgBl5j8R3Td4ODGpeOUoD/oP
0wVEMfL0nk7SqulTWm6pxO0gvoDuhAR2hz2rlO3mlqbepvDRxZENoMvan3NNtLM=
=ewNn
-----END PGP SIGNATURE-----



|
|
|
|
|
|
|

1
2
3
4
5
6
7
8
9
10
11
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2

iQEcBAABCAAGBQJUm1OMAAoJEKcU7KyMnO49J3AH/0YV0hdf0Q+nQYSP/J+TUgqN
ynijfBX7DT95BB/pIj7i5qTUaAqc37zT2+gTx1hS/jhd4v0pZs4TwmjJA4Ccif7N
DndmwuwWkEoTs65BURTATWL/9XZGsNlDGGEd6inSDPw1IrGS+6xc/maZ/4hCqifo
MdsuV+Kcbx3l2Ng9HWsUMN+lm9c3iFlahUIOgv6dHouEO1J0iY+/voH5R7GpvTcN
Vn3m7QZUqMzCB5BPTQACE0oT/mn1MaSDLeziO1CFEjQem2/oL3L+g8Im10lIMzhi
9gX23UtJnnTv3nSth3CFdVmt0b4hQoLtdXjVHYtHrvzjXaDYX0CLH63QAAcTZPE=
=lUv6
-----END PGP SIGNATURE-----

Changes to src/narv.

53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
...
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
...
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
...
264
265
266
267
268
269
270
271
272

273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
...
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500

501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524


525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562






563
564
565
566
567
568
        exit 1;
    elif pgrep -f $APPNAME.py >/dev/null ; then
        pgrep -f $APPNAME.py > $WORKINGREP/var/$APPNAME.pid
        echo "Your Narv application seems to be always running. Try $0 stop $APPNAME"
        exit 1;
    fi

    daemon_begin_log_line "Starting $WORKINGREP/usr/bin/$APPNAME.py"

    # Must be root to do the following
    if [ "$UID" = "0" ] ; then
        # ensure we have a fresh copy of these
        copy_passwd_files
    fi

    $WORKINGREP/usr/bin/$APPNAME.py &
    pgrep -f $APPNAME.py > $WORKINGREP/var/$APPNAME.pid
    daemon_end_log_line 0
}

function narv_stop {
    if [ ! -f "$WORKINGREP/var/$APPNAME.pid" ] ; then
        echo "Your Narv application is NOT running."
        exit 1;
    fi
    daemon_begin_log_line "Stopping $WORKINGREP/usr/bin/$APPNAME.py"
    pkill -f $APPNAME.py
    rm $WORKINGREP/var/$APPNAME.pid
    if pgrep -f $APPNAME.py >/dev/null ; then
        yup=no
        count=0
        while [ "$yup" != "yes" ] ; do
            sleep 1
................................................................................
}

function narv_restart {
    if [ ! -f "$WORKINGREP/var/$APPNAME.pid" ] ; then
        echo "Your Narv application is NOT running."
        exit 1;
    fi
    echo -n "Stopping $WORKINGREP/usr/bin/$APPNAME.py"
    pkill -f $APPNAME.py
    echo "                   ..."
    echo -n "Starting $WORKINGREP/usr/bin/$APPNAME.py"
    $WORKINGREP/usr/bin/$APPNAME.py &
    pgrep -f $APPNAME.py > $WORKINGREP/var/$APPNAME.pid
    echo "                   [OK]"
}

function copy_passwd_files {
    #exec 6>&1 # bind fd #6 to stdout (save stdout)
    #exec > $WORKINGREP/etc/passwd # redirect stdout to etc/passwd
    #cat <<EOF
#root:x:0:0:root:/root:/bin/bash
#nobody:x:1:1:nobody:/:/bin/false
#EOF

    #exec > $WORKINGREP/etc/group # redirect stdout to etc/group
    #cat <<EOF
#root:x:0:root
#nobody:x:1:
#EOF

    #exec 1>&6 6>&- # Restore stdout and close fd #6
    # be really sure to have all your access delegated in a shadow file
    if [ -f "$WORKINGREP/etc/passwd" ]; then
        rm $WORKINGREP/etc/passwd
    fi
    cp /etc/passwd $WORKINGREP/etc/passwd

    if [ -f "$WORKINGREP/etc/group" ]; then
        rm $WORKINGREP/etc/group
    fi
    cp /etc/group $WORKINGREP/etc/group

    chmod 600 $WORKINGREP/etc/passwd
    chmod 600 $WORKINGREP/etc/group
}

function init_chroot {
    if [ "$UID" != "0" ] ; then
        echo "You must be root to create the chroot"
        return
    fi

    # Programs to add in the chroot for minimal functionnalities
    BINS="bash env false python3 sqlite3"
    echo "Populate new chroot... Please wait"

    for basecommand in $BINS ; do
        # Look for the totality of involved binaries per program
        all=`whereis -b $basecommand | cut -f2 -d":"`

        for comm in $all ; do
            # Create parent folder and copy current binary
            mkdir -p $WORKINGREP`dirname $comm` > /dev/null 2>&1
            cp -R -L "$comm" $WORKINGREP`dirname $comm`

            # Find related lib and copy them to the chroot
            for f in `ldd $comm 2>/dev/null | cut -f2 -d ">" | cut -f1 -d "(" ` ; do
                if [[ -f $f || -h $f ]]; then
                    mkdir -p $WORKINGREP`dirname $f` > /dev/null 2>&1
                    cp -R -L "$f" $WORKINGREP`dirname $f`
                fi
            done
        done
    done

    # We need this lib from threading too
    cp -R -L /usr/lib/libgcc_s.so.1 $WORKINGREP/usr/lib/

    copy_passwd_files
    chmod -R 777 var

    # Creating /bin for compatibility. Link MUST be local
    if [ ! -e "$WORKINGREP/bin" ] ; then
        cd $WORKINGREP
        ln -s usr/bin
    fi

    echo "Chroot created"
}

function cleanup_chroot {
    echo ":: Deleting old chroot files"
    find $WORKINGREP/usr ! -name $APPNAME\.py -a ! -name narv -a ! -name narv\.py -delete
    find $WORKINGREP/etc ! -name rc\.conf -a ! -name routes\.conf -delete
    if [ -d "$WORKINGREP/lib64" ]; then
        rm -r $WORKINGREP/lib64
    fi
    if [ -d "$WORKINGREP/usr/bin/__pycache__" ]; then
        rm -r $WORKINGREP/usr/bin/__pycache__/
    fi
    rm $WORKINGREP/bin
}


APPNAME=$USER
FOSSILFILE=/dev/null
COMMAND="help"
WORKINGREP=`pwd`
DOMAINNAME='localhost'

................................................................................
                shift
                FOSSILFILE=`realpath $1`
                ;;
            --host|-H)
                shift
                DOMAINNAME=$1
                ;;
            create|cleanup-chroot|init-chroot|update-chroot|poke|restart|start|stop|-h|'help')
                COMMAND=$1
                ;;
            *)
                APPNAME=$1
                ;;
        esac
        shift
................................................................................
            echo "--host|-H: Domain name of your application"
            echo "<appname>: Name of your application"
            echo
            echo "If you have any doubt, please see help"
            echo "$0 help"
        fi

        echo ":: configuring new Website"
        install -dm 755 $WORKINGREP/home/$APPNAME/.themes

        install -dm 755 $WORKINGREP/srv/$APPNAME

        exec 6>&1 # bind fd #6 to stdout (save stdout)
        exec > $WORKINGREP/etc/rc.conf # redirect stdout to etc/rc.conf
        cat <<EOF
[general]
debug = info

[$DOMAINNAME]
something = wonderfull
EOF

        exec > $WORKINGREP/etc/routes.conf
        cat <<EOF
[$DOMAINNAME]
/ = my_first_custom_path
EOF

        exec > $WORKINGREP/usr/bin/$APPNAME.py
        cat <<EOF
#!/usr/bin/env python3
# -*- coding: utf-8 -*-

from narv import IcanDoThat
from narv import Narv

................................................................................

    def my_first_custom_path(self):
        self.extension = 'html'
        return b'<h1>Hello World!</h1>'


if __name__ == "__main__":
    app = Narv(('', 8000), MyBeautifulApp)
    app.start()
EOF

        exec > $WORKINGREP/var/$APPNAME.el
        cat <<EOF
;;; Org-mode configuration

;;; Default to HTML5
(setq org-html-doctype "html5")
(setq org-html-html5-fancy t)

;;; Disable default org style (you DO want to use your own style)
(setq org-html-head-include-default-style nil)

;;; Project configuration
(setq org-publish-project-alist
      '(
        ("${APPNAME}-org"
         :base-directory "${WORKINGREP}/home/$APPNAME"
         :recursive t
         :publishing-function (org-html-publish-to-html org-org-publish-to-org)
         :publishing-directory "${WORKINGREP}/srv/$APPNAME"
         :base-extension "org"
;;       :language "fr"                     ;; Your language?
;;       :headline-levels 3                 ;; You can customize
;;       :section-numbers nil               ;; the following lines too
;;       :table-of-contents nil
;;       :html-preamble "<h1>My Blog</h1>"
;;       :html-postamble "<p>Still reading?</p>"
;;       :html-head "<link rel=\"stylesheet\" href=\"/.themes/style.css\" type=\"text/css\"/>"
         )
        ("${APPNAME}-data"
         :base-directory "${WORKINGREP}/home/$APPNAME"
         :recursive t
         :base-extension "png\\\|jpg\\\|pdf\\\|ogg\\\|conf"
         :publishing-function org-publish-attachment
         :publishing-directory "${WORKINGREP}/srv/$APPNAME")
        ("${APPNAME}-style"
         :base-directory "${WORKINGREP}/home/${APPNAME}/.themes"
         :recursive t
         :base-extension "css\\\|js\\\|png\\\|jpg\\\|otf"
         :publishing-function org-publish-attachment
         :publishing-directory "${WORKINGREP}/srv/${APPNAME}/.themes")
        ("$APPNAME" :components ("${APPNAME}-org" "${APPNAME}-data" "${APPNAME}-style"))))


;;; Utility functions. DO NOT MODIFY !

(defun ed/orgx-get-file-title ()
  (with-current-buffer (current-buffer)
    (save-excursion
      (goto-char (point-min))
      (if (re-search-forward "#\\\+title: ?\\\(.*\\\)" nil t)
          (match-string 1)
        ""))))

(defun ed/orgx-get-file-name ()
  (when (string= (substring (buffer-name) 0 11) "content.org")
    (file-name-nondirectory (directory-file-name (file-name-directory buffer-file-name)))))

(defun asciify-string (string)
  "Convert STRING to ASCII string.
For example:
“passé” becomes “passe”"
  ;; Code originally by Teemu Likonen found on
  ;; http://ergoemacs.org/emacs/emacs_zap_gremlins.html
  (with-temp-buffer
    (insert string)
    (call-process-region (point-min) (point-max) "iconv" t t nil "--to-code=ASCII//TRANSLIT")
    (buffer-substring-no-properties (point-min) (point-max))))

(defun ed/orgx-get-permalink (title)
  (interactive "sTitle: ")
  (message
   (replace-regexp-in-string
    "--+" "-"
    (replace-regexp-in-string
     "^-+\\\|-+$" ""
     (replace-regexp-in-string
      "[^a-z]" "-" (downcase (asciify-string title)))))))

(defun ed/orgx-parse-links ()
  (save-excursion
    (goto-char (point-min))
    (let* ((base-path (file-name-directory buffer-file-name))
           (media-folder (file-name-as-directory (concat base-path "media"))))
      (while (re-search-forward org-any-link-re nil t)
        (let* ((link-url (match-string 2))
               (file-path (when (and (stringp link-url)
                                     (string= (substring link-url 0 5) "file:"))
                            (substring link-url 5)))
               (file-name (when (and (stringp file-path)
                                     (file-exists-p file-path)
                                     (file-readable-p file-path))
                            (file-name-nondirectory file-path)))
               (dest-file (when (stringp file-name)
                            (concat media-folder file-name))))
          (when (and (stringp dest-file)
                     (not (file-exists-p dest-file)))
            (copy-file file-path dest-file)
            (save-excursion
              (search-backward link-url)
              (replace-match (concat media-folder file-name)))
            (message (concat file-path " copied to " dest-file))))))))

(defun ed/orgx-propagate-save ()
  (let* ((base-path (file-name-directory buffer-file-name))
         (meta-file (concat base-path "meta.conf"))
         (file-title (ed/orgx-get-file-title)))
    (when (and (string= (file-name-nondirectory buffer-file-name) "content.org")
               (file-exists-p meta-file)
               (file-writable-p meta-file))
      (ed/orgx-parse-links)
      (with-current-buffer (find-file-noselect meta-file)
        (goto-char (point-min))
        (when (re-search-forward "title=.*" nil t)
          (replace-match (concat "title=" file-title))
          (save-buffer 0))
        (kill-buffer))
      (message (concat "Saved " (ed/orgx-get-file-name))))))
(add-hook 'after-save-hook 'ed/orgx-propagate-save)

(defun ed/orgx-create-file-structure (title destination &optional buffer)
  (unless (file-exists-p (directory-file-name destination))
    (make-directory destination t)
    (make-directory (concat destination "media"))
    (make-directory (concat destination "templates"))
    (let ((timestamp (current-time)))
      (with-current-buffer (find-file-noselect (concat destination "meta.conf"))
        (insert "[metadata]\nauthor=" (user-full-name) "\ntimestamp="
                (format-time-string "%Y%m%d%H%M%S" timestamp)
                "\ntitle=" title)
        (save-buffer 0)
        (kill-buffer))
      (when buffer
        (with-current-buffer buffer
          (ed/orgx-parse-links)
          (copy-file buffer-file-name
                     (concat destination "content.org"))))
      (with-current-buffer (find-file (concat destination "content.org"))
        (unless buffer
          (goto-char 1)
          (insert "#+title: " title "\n#+date: "
                  (format-time-string "<%Y-%m-%d %a %H:%M>" timestamp)
                  "\n\n"))))
    (message (concat "Opened " (ed/orgx-get-permalink title)))))

(defun ed/orgx-create-file (dir filename)
  "Creating a new orgx file and open it"
  (interactive "Ddirectory where to save your new orgx file: \nsname of your new orgx file: ")
  (let ((destination
         (file-name-as-directory
          (concat (file-name-as-directory dir)
                  (ed/orgx-get-permalink filename)))))
    (ed/orgx-create-file-structure filename destination)))

(defun ed/orgx-create-from-buffer (dir)
  "Creating a new orgx file from the current buffer"
  (interactive "Ddirectory where to save your new orgx file: ")
  (let* ((file-title (ed/orgx-get-file-title))
         (filename (if (string= file-title "")
                       (file-name-sans-extension (buffer-name))
                     (ed/orgx-get-permalink file-title)))
         (destination
          (file-name-as-directory (concat (file-name-as-directory dir) filename))))
    (ed/orgx-create-file-structure file-title destination (current-buffer))))

(defun ed/orgx-open-file (dir)
  "Open an orgx file"
  (interactive "Dorgx file to open: ")
  (let* ((file-path (file-name-as-directory dir))
         (meta-file (concat file-path "meta.conf"))
         (content-file (concat file-path "content.org")))
    (if (and (file-exists-p meta-file)
             (file-writable-p meta-file)
             (file-exists-p content-file)
             (file-writable-p content-file))
        (progn
          (find-file content-file)
          (message (concat "Opened " (ed/orgx-get-file-name))))
      (message (concat "Not a valid orgx file: " dir)))))
EOF

        exec > $WORKINGREP/var/${APPNAME}@narv.service
        cat <<EOF
[Unit]
Description=$APPNAME Narv Web Application
After=network.target

[Service]
Type=simple

PIDFile=/srv/http/narvroot/var/${APPNAME}.pid
ExecStart=/srv/http/narvroot/usr/bin/narv start $APPNAME -d /srv/http/narvroot/
ExecStop=/srv/http/narvroot/usr/bin/narv stop $APPNAME -d /srv/http/narvroot/

[Install]
WantedBy=network.target
EOF

        exec 1>&6 6>&- # Restore stdout and close fd #6

        chmod u+x $WORKINGREP/usr/bin/$APPNAME.py

        echo "Application installation finished."
        echo ":: A sample emacs configuration file has been created in
:: $WORKINGREP/$APPNAME.el
:: Feel free to customize it."
        echo
        echo ":: Sample configuration files has been put in
:: $WORKINGREP/etc/
:: Don't forget to review and customize them."
        echo
        echo ":: You may start your new app now by entering the following command:"
        echo
        echo "$0 start"


        ;;
    start)
        narv_start
        ;;
    stop)
        narv_stop
        ;;
    restart)
        narv_restart
        ;;
    init-chroot)
        init_chroot

        echo ":: Creating false dev mount points"
        # Creating /dev/null
        install -dm 755 $WORKINGREP/dev
        mknod $WORKINGREP/dev/null c 1 3

        # Creating urandom
        mknod -m 0444 $WORKINGREP/dev/random c 1 8
        mknod -m 0444 $WORKINGREP/dev/urandom c 1 9
        ;;
    cleanup-chroot)
        cleanup_chroot

        echo ":: Removing false dev mount points"
        rm $WORKINGREP/dev/null
        rm $WORKINGREP/dev/random
        rm $WORKINGREP/dev/urandom
        rmdir $WORKINGREP/dev
        ;;
    update-chroot)
        cleanup_chroot
        init_chroot
        ;;
    poke)
        pkill -10 -f $APPNAME.py
        ;;






    *)
        echo "There's something strange
in your neighborhood.
Who ya gonna call?"
        ;;
esac







|

<
<
<
<
<
<
|









|







 







|


|
|



<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







 







|







 







<
|
>
|


|








|





|







 







|



<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|







>
|
|
|







|

|
<
<
<







|
>
>










<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<



>
>
>
>
>
>






53
54
55
56
57
58
59
60
61






62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
...
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
























































































118
119
120
121
122
123
124
...
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
...
170
171
172
173
174
175
176

177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
...
208
209
210
211
212
213
214
215
216
217
218




















































































































































































219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240



241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260

























261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
        exit 1;
    elif pgrep -f $APPNAME.py >/dev/null ; then
        pgrep -f $APPNAME.py > $WORKINGREP/var/$APPNAME.pid
        echo "Your Narv application seems to be always running. Try $0 stop $APPNAME"
        exit 1;
    fi

    daemon_begin_log_line "Starting $WORKINGREP/bin/$APPNAME.py"







    $WORKINGREP/bin/$APPNAME.py &
    pgrep -f $APPNAME.py > $WORKINGREP/var/$APPNAME.pid
    daemon_end_log_line 0
}

function narv_stop {
    if [ ! -f "$WORKINGREP/var/$APPNAME.pid" ] ; then
        echo "Your Narv application is NOT running."
        exit 1;
    fi
    daemon_begin_log_line "Stopping $WORKINGREP/bin/$APPNAME.py"
    pkill -f $APPNAME.py
    rm $WORKINGREP/var/$APPNAME.pid
    if pgrep -f $APPNAME.py >/dev/null ; then
        yup=no
        count=0
        while [ "$yup" != "yes" ] ; do
            sleep 1
................................................................................
}

function narv_restart {
    if [ ! -f "$WORKINGREP/var/$APPNAME.pid" ] ; then
        echo "Your Narv application is NOT running."
        exit 1;
    fi
    echo -n "Stopping $WORKINGREP/bin/$APPNAME.py"
    pkill -f $APPNAME.py
    echo "                   ..."
    echo -n "Starting $WORKINGREP/bin/$APPNAME.py"
    $WORKINGREP/bin/$APPNAME.py &
    pgrep -f $APPNAME.py > $WORKINGREP/var/$APPNAME.pid
    echo "                   [OK]"
}

























































































APPNAME=$USER
FOSSILFILE=/dev/null
COMMAND="help"
WORKINGREP=`pwd`
DOMAINNAME='localhost'

................................................................................
                shift
                FOSSILFILE=`realpath $1`
                ;;
            --host|-H)
                shift
                DOMAINNAME=$1
                ;;
            create|update|poke|restart|start|stop|-h|'help')
                COMMAND=$1
                ;;
            *)
                APPNAME=$1
                ;;
        esac
        shift
................................................................................
            echo "--host|-H: Domain name of your application"
            echo "<appname>: Name of your application"
            echo
            echo "If you have any doubt, please see help"
            echo "$0 help"
        fi


        cd $WORKINGREP
        daemon_begin_log_line ":: Configuring new application"
        install -d -m755 home/$APPNAME/.themes

        exec 6>&1 # bind fd #6 to stdout (save stdout)
        exec > etc/rc.conf # redirect stdout to etc/rc.conf
        cat <<EOF
[general]
debug = info

[$DOMAINNAME]
something = wonderfull
EOF

        exec > etc/routes.conf
        cat <<EOF
[$DOMAINNAME]
/ = my_first_custom_path
EOF

        exec > bin/$APPNAME.py
        cat <<EOF
#!/usr/bin/env python3
# -*- coding: utf-8 -*-

from narv import IcanDoThat
from narv import Narv

................................................................................

    def my_first_custom_path(self):
        self.extension = 'html'
        return b'<h1>Hello World!</h1>'


if __name__ == "__main__":
    app = Narv(('', 9042), MyBeautifulApp)
    app.start()
EOF





















































































































































































        exec > var/${APPNAME}@narv.service
        cat <<EOF
[Unit]
Description=$APPNAME Narv Web Application
After=network.target

[Service]
Type=simple
User=nobody
PIDFile=${WORKINGREP}/var/${APPNAME}.pid
ExecStart=${WORKINGREP}/bin/narv start $APPNAME -d ${WORKINGREP}/
ExecStop=${WORKINGREP}/bin/narv stop $APPNAME -d ${WORKINGREP}/

[Install]
WantedBy=network.target
EOF

        exec 1>&6 6>&- # Restore stdout and close fd #6

        chmod u+x bin/$APPNAME.py

        daemon_end_log_line 0



        echo
        echo ":: Sample configuration files has been put in
:: $WORKINGREP/etc/
:: Don't forget to review and customize them."
        echo
        echo ":: You may start your new app now by entering the following command:"
        echo
        echo "$0 start $APPNAME -d ${WORKINGREP}/"
        echo
        echo ":: and go check it at http://${DOMAINNAME}:9042/"
        ;;
    start)
        narv_start
        ;;
    stop)
        narv_stop
        ;;
    restart)
        narv_restart
        ;;

























    poke)
        pkill -10 -f $APPNAME.py
        ;;
    update)
        wget http://projects.depar.is/0xGA/doc/tip/narv_install.sh
        chmod u+x narv_install.sh
        ./narv_install.sh update
        rm narv_install.sh
        ;;
    *)
        echo "There's something strange
in your neighborhood.
Who ya gonna call?"
        ;;
esac

Changes to src/narv.py.

570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
class Narv:
    def __init__(self, server_infos=('', 8000), request_handler=IcanDoThat):

        log_level = 'info'
        drop_priviledges = True
        narv_root_path = os.path.normpath(os.path.join(
            os.path.dirname(os.path.abspath(__file__)),
            '../../'))

        config = ConfigParser()
        config.read(os.path.join(narv_root_path, 'etc/rc.conf'))

        if 'general' in config:
            if 'debug' in config['general']:
                log_level = config['general']['debug']







|







570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
class Narv:
    def __init__(self, server_infos=('', 8000), request_handler=IcanDoThat):

        log_level = 'info'
        drop_priviledges = True
        narv_root_path = os.path.normpath(os.path.join(
            os.path.dirname(os.path.abspath(__file__)),
            '../'))

        config = ConfigParser()
        config.read(os.path.join(narv_root_path, 'etc/rc.conf'))

        if 'general' in config:
            if 'debug' in config['general']:
                log_level = config['general']['debug']