Explorar el Código

Merge branch 'stretch' of https://github.com/bashrc/freedombone

Bob Mottram hace 7 años
padre
commit
c33f236ed5

+ 4
- 0
doc/EN/app_cryptpad.org Ver fichero

16
 </center>
16
 </center>
17
 #+END_EXPORT
17
 #+END_EXPORT
18
 
18
 
19
+#+BEGIN_CENTER
20
+[[file:images/cryptpad.jpg]]
21
+#+END_CENTER
22
+
19
 This is similar to [[./app_etherpad.html][EtherPad]] but with better security and more document types which can be collaboratively edited in real time. It includes not just text editing but also creating presentations, voting and editing source code.
23
 This is similar to [[./app_etherpad.html][EtherPad]] but with better security and more document types which can be collaboratively edited in real time. It includes not just text editing but also creating presentations, voting and editing source code.
20
 
24
 
21
 For added security this system is only available via an onion address, so you and your collaborators will need to be using Tor compatible browsers.
25
 For added security this system is only available via an onion address, so you and your collaborators will need to be using Tor compatible browsers.

+ 39
- 0
doc/EN/app_kanboard.org Ver fichero

1
+#+TITLE:
2
+#+AUTHOR: Bob Mottram
3
+#+EMAIL: bob@freedombone.net
4
+#+KEYWORDS: freedombone, kanboard
5
+#+DESCRIPTION: How to use KanBoard
6
+#+OPTIONS: ^:nil toc:nil
7
+#+HTML_HEAD: <link rel="stylesheet" type="text/css" href="freedombone.css" />
8
+
9
+#+BEGIN_CENTER
10
+[[file:images/logo.png]]
11
+#+END_CENTER
12
+
13
+#+BEGIN_EXPORT html
14
+<center>
15
+<h1>KanBoard</h1>
16
+</center>
17
+#+END_EXPORT
18
+
19
+Kanbans are one way of managing projects. They're traditionally used in businesses but can also be useful for personal TODO lists or within open source or DIY projects. If you have a list of things which need to be done and want to keep track of progress then this provides a way to do that.
20
+
21
+* Installation
22
+Log into your system with:
23
+
24
+#+begin_src bash
25
+ssh myusername@mydomain -p 2222
26
+#+end_src
27
+
28
+Using cursor keys, space bar and Enter key select *Administrator controls* and type in your password.
29
+
30
+Select *Add/Remove Apps* then *kanboard*. You will then be asked for a domain name and if you are using FreeDNS also the code for the domain which can be found under *Dynamic DNS* on the FreeDNS site (the random string from "/quick cron example/" which appears after /update.php?/ and before />>/). For more details on obtaining a domain and making it accessible via dynamic DNS see the [[./faq.html][FAQ]]. Typically the domain name you use will be a subdomain, such as /kanban.mydomainname.net/. It will need to be a domain which you have bought somewhere and own and not one of the FreeDNS subdomains, otherwise you won't be able to get a SSL/TLS certificate for it.
31
+
32
+After the install has completed go to *Security settings* and select *Create a new Let's Encrypt certificate* and enter the domain name that you are using for KanBoard. If you're using the "onion only" version of the system then you don't need to do this. If the certificate is obtained successfully then you will see a congratulations message.
33
+
34
+* Initial setup
35
+If you have just obtained a Lets Encrypt certificate as above then go to *About* on the administrator control panel and you should see your KanBoard domain listed there along with an onion address. You can then navigate to your site in a browser.
36
+
37
+The default login is username "admin" and password "admin". Obviously the first thing you'll need to do is log in and change the password, which can be done by going to "My Profile" on the drop down list on the right hand side.
38
+
39
+For more details of how to use KanBoard see the [[https://kanboard.net/documentation][documentation here]].

+ 4
- 0
doc/EN/apps.org Ver fichero

75
 * Jitsi Meet
75
 * Jitsi Meet
76
 Experimental WebRTC video conferencing system, similar to Google Hangouts. This may not be fully functional, but is hoped to be in the near future.
76
 Experimental WebRTC video conferencing system, similar to Google Hangouts. This may not be fully functional, but is hoped to be in the near future.
77
 
77
 
78
+* KanBoard
79
+A simple kanban system for managing projects or TODO lists.
80
+
81
+[[./app_kanboard.html][How to use it]]
78
 * Koel
82
 * Koel
79
 Access your music collection from any internet connected device.
83
 Access your music collection from any internet connected device.
80
 
84
 

BIN
img/cryptpad.jpg Ver fichero


+ 4
- 1
src/freedombone-app-cryptpad Ver fichero

37
 CRYPTPAD_ONION_PORT=8119
37
 CRYPTPAD_ONION_PORT=8119
38
 CRYPTPAD_PORT=9003
38
 CRYPTPAD_PORT=9003
39
 CRYPTPAD_REPO="https://github.com/xwiki-labs/cryptpad"
39
 CRYPTPAD_REPO="https://github.com/xwiki-labs/cryptpad"
40
-CRYPTPAD_COMMIT='ed5b005216be9b9029c1ccd25a5fdc7908ed8730'
40
+CRYPTPAD_COMMIT='76e69f0ba85b0e3e21cad2c3eb0012c2429d4bb8'
41
 CRYPTPAD_DIR=/etc/cryptpad
41
 CRYPTPAD_DIR=/etc/cryptpad
42
 
42
 
43
 cryptpad_variables=(ONION_ONLY)
43
 cryptpad_variables=(ONION_ONLY)
89
     set_repo_commit $CRYPTPAD_DIR "cryptpad commit" "$CRYPTPAD_COMMIT" $CRYPTPAD_REPO
89
     set_repo_commit $CRYPTPAD_DIR "cryptpad commit" "$CRYPTPAD_COMMIT" $CRYPTPAD_REPO
90
 
90
 
91
     cd $CRYPTPAD_DIR
91
     cd $CRYPTPAD_DIR
92
+    npm install
93
+    chown -R cryptpad:cryptpad $CRYPTPAD_DIR
94
+    su -c 'bower install' - cryptpad
92
 
95
 
93
     systemctl start cryptpad
96
     systemctl start cryptpad
94
 }
97
 }

+ 2
- 2
src/freedombone-app-gogs Ver fichero

139
     fi
139
     fi
140
 
140
 
141
     function_check create_database
141
     function_check create_database
142
-    create_database gogs "$GOGS_ADMIN_PASSWORD"
142
+    create_database gogs "$GIT_ADMIN_PASSWORD"
143
 }
143
 }
144
 
144
 
145
 function reconfigure_gogs {
145
 function reconfigure_gogs {
302
         suspend_site ${GIT_DOMAIN_NAME}
302
         suspend_site ${GIT_DOMAIN_NAME}
303
 
303
 
304
         function_check backup_database_to_friend
304
         function_check backup_database_to_friend
305
-        backup_database_to_friend $GOGS_USERNAME
305
+        backup_database_to_friend gogs
306
 
306
 
307
         echo $"Obtaining Gogs settings backup"
307
         echo $"Obtaining Gogs settings backup"
308
 
308
 

+ 579
- 0
src/freedombone-app-kanboard Ver fichero

1
+#!/bin/bash
2
+#
3
+# .---.                  .              .
4
+# |                      |              |
5
+# |--- .--. .-.  .-.  .-.|  .-. .--.--. |.-.  .-. .--.  .-.
6
+# |    |   (.-' (.-' (   | (   )|  |  | |   )(   )|  | (.-'
7
+# '    '     --'  --'  -' -  -' '  '   -' -'   -' '   -  --'
8
+#
9
+#                    Freedom in the Cloud
10
+#
11
+# kanboard kanban
12
+#
13
+# License
14
+# =======
15
+#
16
+# Copyright (C) 2017 Bob Mottram <bob@freedombone.net>
17
+#
18
+# This program is free software: you can redistribute it and/or modify
19
+# it under the terms of the GNU Affero General Public License as published by
20
+# the Free Software Foundation, either version 3 of the License, or
21
+# (at your option) any later version.
22
+#
23
+# This program is distributed in the hope that it will be useful,
24
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
25
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
26
+# GNU Affero General Public License for more details.
27
+#
28
+# You should have received a copy of the GNU Affero General Public License
29
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
30
+
31
+VARIANTS='full full-vim social'
32
+
33
+IN_DEFAULT_INSTALL=0
34
+SHOW_ON_ABOUT=1
35
+
36
+KANBOARD_DOMAIN_NAME=
37
+KANBOARD_CODE=
38
+KANBOARD_ONION_PORT=8121
39
+KANBOARD_REPO="https://github.com/kanboard/kanboard"
40
+KANBOARD_COMMIT='7a6b1bc3da0af442e02b5a2dc430a4ded8e7c4ee'
41
+KANBOARD_ADMIN_PASSWORD=
42
+
43
+
44
+kanboard_variables=(ONION_ONLY
45
+                    KANBOARD_DOMAIN_NAME
46
+                    KANBOARD_CODE
47
+                    DDNS_PROVIDER
48
+                    MY_USERNAME)
49
+
50
+function logging_on_kanboard {
51
+    kanboard_configfile=/var/www/${KANBOARD_DOMAIN_NAME}/htdocs/config.php
52
+    sed -i "s|define('LOG_FILE'.*|define('LOG_FILE', DATA_DIR.DIRECTORY_SEPARATOR.'debug.log');|g" $kanboard_configfile
53
+}
54
+
55
+function logging_off_kanboard {
56
+    kanboard_configfile=/var/www/${KANBOARD_DOMAIN_NAME}/htdocs/config.php
57
+    sed -i "s|define('LOG_FILE'.*|define('LOG_FILE', '/dev/null');|g" $kanboard_configfile
58
+}
59
+
60
+function remove_user_kanboard {
61
+    remove_username="$1"
62
+
63
+    ${PROJECT_NAME}-pass -u $remove_username --rmapp kanboard
64
+}
65
+
66
+function add_user_kanboard {
67
+    new_username="$1"
68
+    new_user_password="$2"
69
+
70
+    ${PROJECT_NAME}-pass -u $new_username -a kanboard -p "$new_user_password"
71
+    echo '0'
72
+}
73
+
74
+function install_interactive_kanboard {
75
+    if [ ! $ONION_ONLY ]; then
76
+        ONION_ONLY='no'
77
+    fi
78
+
79
+    if [[ $ONION_ONLY != "no" ]]; then
80
+        KANBOARD_DOMAIN_NAME='kanboard.local'
81
+    else
82
+        KANBOARD_DETAILS_COMPLETE=
83
+        while [ ! $KANBOARD_DETAILS_COMPLETE ]
84
+        do
85
+            data=$(tempfile 2>/dev/null)
86
+            trap "rm -f $data" 0 1 2 5 15
87
+            if [[ $DDNS_PROVIDER == "default@freedns.afraid.org" ]]; then
88
+                dialog --backtitle $"Freedombone Configuration" \
89
+                       --title $"KanBoard Configuration" \
90
+                       --form $"\nPlease enter your KanBoard details.\n\nIMPORTANT: This should be a domain name which is supported by Let's Encrypt." 13 55 2 \
91
+                       $"Domain:" 1 1 "$(grep 'KANBOARD_DOMAIN_NAME' temp.cfg | awk -F '=' '{print $2}')" 1 15 33 40 \
92
+                       $"Code:" 2 1 "$(grep 'KANBOARD_CODE' temp.cfg | awk -F '=' '{print $2}')" 2 15 33 255 \
93
+                       2> $data
94
+            else
95
+                dialog --backtitle $"Freedombone Configuration" \
96
+                       --title $"KanBoard Configuration" \
97
+                       --form $"\nPlease enter your KanBoard details.\n\nIMPORTANT: This should be a domain name which is supported by Let's Encrypt." 13 55 2 \
98
+                       $"Domain:" 1 1 "$(grep 'KANBOARD_DOMAIN_NAME' temp.cfg | awk -F '=' '{print $2}')" 1 15 33 40 \
99
+                       2> $data
100
+            fi
101
+            sel=$?
102
+            case $sel in
103
+                1) exit 1;;
104
+                255) exit 1;;
105
+            esac
106
+            KANBOARD_DOMAIN_NAME=$(cat $data | sed -n 1p)
107
+            if [ $KANBOARD_DOMAIN_NAME ]; then
108
+                if [[ $KANBOARD_DOMAIN_NAME == "$HUBZILLA_DOMAIN_NAME" ]]; then
109
+                    KANBOARD_DOMAIN_NAME=""
110
+                fi
111
+                TEST_DOMAIN_NAME=$KANBOARD_DOMAIN_NAME
112
+                validate_domain_name
113
+                if [[ $TEST_DOMAIN_NAME != $KANBOARD_DOMAIN_NAME ]]; then
114
+                    KANBOARD_DOMAIN_NAME=
115
+                    dialog --title $"Domain name validation" --msgbox "$TEST_DOMAIN_NAME" 15 50
116
+                else
117
+                    if [[ $DDNS_PROVIDER == "default@freedns.afraid.org" ]]; then
118
+                        KANBOARD_CODE=$(cat $data | sed -n 2p)
119
+                        validate_freedns_code "$KANBOARD_CODE"
120
+                        if [ ! $VALID_CODE ]; then
121
+                            KANBOARD_DOMAIN_NAME=
122
+                        fi
123
+                    fi
124
+                fi
125
+            fi
126
+            if [ $KANBOARD_DOMAIN_NAME ]; then
127
+                KANBOARD_DETAILS_COMPLETE="yes"
128
+            fi
129
+        done
130
+
131
+        # save the results in the config file
132
+        write_config_param "KANBOARD_CODE" "$KANBOARD_CODE"
133
+    fi
134
+    write_config_param "KANBOARD_DOMAIN_NAME" "$KANBOARD_DOMAIN_NAME"
135
+    APP_INSTALLED=1
136
+}
137
+
138
+function change_password_kanboard {
139
+    curr_username="$1"
140
+    new_user_password="$2"
141
+
142
+    read_config_param 'KANBOARD_DOMAIN_NAME'
143
+
144
+    ${PROJECT_NAME}-pass -u "$curr_username" -a kanboard -p "$new_user_password"
145
+}
146
+
147
+function kanboard_create_database {
148
+    if [ -f $IMAGE_PASSWORD_FILE ]; then
149
+        KANBOARD_ADMIN_PASSWORD="$(printf `cat $IMAGE_PASSWORD_FILE`)"
150
+    else
151
+        if [ ! $KANBOARD_ADMIN_PASSWORD ]; then
152
+            KANBOARD_ADMIN_PASSWORD="$(create_password ${MINIMUM_PASSWORD_LENGTH})"
153
+        fi
154
+    fi
155
+    if [ ! $KANBOARD_ADMIN_PASSWORD ]; then
156
+        return
157
+    fi
158
+
159
+    function_check create_database
160
+    create_database kanboard "$KANBOARD_ADMIN_PASSWORD" $MY_USERNAME
161
+}
162
+
163
+function reconfigure_kanboard {
164
+    echo -n ''
165
+}
166
+
167
+function upgrade_kanboard {
168
+    CURR_KANBOARD_COMMIT=$(get_completion_param "kanboard commit")
169
+    if [[ "$CURR_KANBOARD_COMMIT" == "$KANBOARD_COMMIT" ]]; then
170
+        return
171
+    fi
172
+
173
+    if grep -q "kanboard domain" $COMPLETION_FILE; then
174
+        KANBOARD_DOMAIN_NAME=$(get_completion_param "kanboard domain")
175
+    fi
176
+
177
+    # update to the next commit
178
+    function_check set_repo_commit
179
+    set_repo_commit /var/www/$KANBOARD_DOMAIN_NAME/htdocs "kanboard commit" "$KANBOARD_COMMIT" $KANBOARD_REPO
180
+
181
+    chown -R www-data:www-data /var/www/${KANBOARD_DOMAIN_NAME}/htdocs
182
+}
183
+
184
+
185
+function backup_local_kanboard {
186
+    KANBOARD_DOMAIN_NAME='kanboard'
187
+    if grep -q "kanboard domain" $COMPLETION_FILE; then
188
+        KANBOARD_DOMAIN_NAME=$(get_completion_param "kanboard domain")
189
+    fi
190
+
191
+    source_directory=/var/www/${KANBOARD_DOMAIN_NAME}/htdocs/backup
192
+    if [ ! -d $source_directory ]; then
193
+        mkdir $source_directory
194
+    fi
195
+    cp -p /var/www/${KANBOARD_DOMAIN_NAME}/htdocs/config.php $source_directory
196
+
197
+    function_check suspend_site
198
+    suspend_site ${KANBOARD_DOMAIN_NAME}
199
+
200
+    function_check backup_directory_to_usb
201
+    dest_directory=kanboardconfig
202
+    backup_directory_to_usb $source_directory $dest_directory
203
+
204
+    source_directory=/var/www/${KANBOARD_DOMAIN_NAME}/htdocs/data
205
+    dest_directory=kanboardfile
206
+    backup_directory_to_usb $source_directory $dest_directory
207
+
208
+    function_check backup_database_to_usb
209
+    backup_database_to_usb kanboard
210
+
211
+    function_check restart_site
212
+    restart_site
213
+}
214
+
215
+function restore_local_kanboard {
216
+    if ! grep -q "kanboard domain" $COMPLETION_FILE; then
217
+        return
218
+    fi
219
+    KANBOARD_DOMAIN_NAME=$(get_completion_param "kanboard domain")
220
+    if [ $KANBOARD_DOMAIN_NAME ]; then
221
+        echo $"Restoring kanboard"
222
+        temp_restore_dir=/root/tempkanboard
223
+        kanboard_dir=/var/www/${KANBOARD_DOMAIN_NAME}/htdocs
224
+
225
+        function_check kanboard_create_database
226
+        kanboard_create_database
227
+
228
+        restore_database kanboard
229
+        if [ -d $temp_restore_dir ]; then
230
+            rm -rf $temp_restore_dir
231
+        fi
232
+
233
+        function_check restore_directory_from_usb
234
+        restore_directory_from_usb $temp_restore_dir kanboardconfig
235
+        if [ -d $temp_restore_dir ]; then
236
+            cp $temp_restore_dir$kanboard_dir/backup/config.php $kanboard_dir/
237
+            chown www-data:www-data $kanboard_dir/config.php
238
+            rm -rf $temp_restore_dir
239
+        fi
240
+
241
+        restore_directory_from_usb $temp_restore_dir kanboardfile
242
+        if [ -d $temp_restore_dir ]; then
243
+            cp -rp $temp_restore_dir$kanboard_dir/data $kanboard_dir/
244
+            chown -R www-data:www-data $kanboard_dir/data
245
+            rm -rf $temp_restore_dir
246
+        fi
247
+
248
+        kanboard_update_after_restore kanboard ${KANBOARD_DOMAIN_NAME}
249
+
250
+        echo $"Restore of kanboard complete"
251
+    fi
252
+}
253
+
254
+function backup_remote_kanboard {
255
+    KANBOARD_DOMAIN_NAME='kanboard'
256
+    if grep -q "kanboard domain" $COMPLETION_FILE; then
257
+        KANBOARD_DOMAIN_NAME=$(get_completion_param "kanboard domain")
258
+    fi
259
+
260
+    source_directory=/var/www/${KANBOARD_DOMAIN_NAME}/htdocs/backup
261
+    if [ ! -d $source_directory ]; then
262
+        mkdir $source_directory
263
+    fi
264
+    cp -p /var/www/${KANBOARD_DOMAIN_NAME}/htdocs/config.php $source_directory
265
+
266
+    function_check suspend_site
267
+    suspend_site ${KANBOARD_DOMAIN_NAME}
268
+
269
+    function_check backup_directory_to_friend
270
+    dest_directory=kanboardconfig
271
+    backup_directory_to_friend $source_directory $dest_directory
272
+
273
+    source_directory=/var/www/${KANBOARD_DOMAIN_NAME}/htdocs/data
274
+    dest_directory=kanboardfile
275
+    backup_directory_to_friend $source_directory $dest_directory
276
+
277
+    function_check backup_database_to_friend
278
+    backup_database_to_friend kanboard
279
+
280
+    function_check restart_site
281
+    restart_site
282
+}
283
+
284
+function restore_remote_kanboard {
285
+    if ! grep -q "kanboard domain" $COMPLETION_FILE; then
286
+        return
287
+    fi
288
+    KANBOARD_DOMAIN_NAME=$(get_completion_param "kanboard domain")
289
+    if [ $KANBOARD_DOMAIN_NAME ]; then
290
+        echo $"Restoring kanboard"
291
+        temp_restore_dir=/root/tempkanboard
292
+        kanboard_dir=/var/www/${KANBOARD_DOMAIN_NAME}/htdocs
293
+
294
+        function_check kanboard_create_database
295
+        kanboard_create_database
296
+
297
+        function_check restore_database_from_friend
298
+        restore_database_from_friend kanboard
299
+        if [ -d $temp_restore_dir ]; then
300
+            rm -rf $temp_restore_dir
301
+        fi
302
+
303
+        function_check restore_directory_from_friend
304
+        restore_directory_from_friend $temp_restore_dir kanboardconfig
305
+        if [ -d $temp_restore_dir ]; then
306
+            cp $temp_restore_dir$kanboard_dir/backup/config.php $kanboard_dir/
307
+            chown www-data:www-data $kanboard_dir/config.php
308
+            rm -rf $temp_restore_dir
309
+        fi
310
+
311
+        restore_directory_from_friend $temp_restore_dir kanboardfile
312
+        if [ -d $temp_restore_dir ]; then
313
+            cp -rp $temp_restore_dir$kanboard_dir/data $kanboard_dir/
314
+            chown -R www-data:www-data $kanboard_dir/data
315
+            rm -rf $temp_restore_dir
316
+        fi
317
+
318
+        kanboard_update_after_restore kanboard ${KANBOARD_DOMAIN_NAME}
319
+
320
+        echo $"Restore of kanboard complete"
321
+    fi
322
+}
323
+
324
+function remove_kanboard {
325
+    if [ ${#KANBOARD_DOMAIN_NAME} -eq 0 ]; then
326
+        return
327
+    fi
328
+    read_config_param "KANBOARD_DOMAIN_NAME"
329
+    read_config_param "MY_USERNAME"
330
+    echo "Removing $KANBOARD_DOMAIN_NAME"
331
+    nginx_dissite $KANBOARD_DOMAIN_NAME
332
+    remove_certs $KANBOARD_DOMAIN_NAME
333
+
334
+    if [ -d /var/www/$KANBOARD_DOMAIN_NAME ]; then
335
+        rm -rf /var/www/$KANBOARD_DOMAIN_NAME
336
+    fi
337
+    if [ -f /etc/nginx/sites-available/$KANBOARD_DOMAIN_NAME ]; then
338
+        rm /etc/nginx/sites-available/$KANBOARD_DOMAIN_NAME
339
+    fi
340
+    function_check drop_database
341
+    drop_database kanboard
342
+    function_check remove_onion_service
343
+    remove_onion_service kanboard ${KANBOARD_ONION_PORT}
344
+    remove_app kanboard
345
+    remove_completion_param install_kanboard
346
+    sed -i '/kanboard/d' $COMPLETION_FILE
347
+    remove_backup_database_local kanboard
348
+
349
+    function_check remove_ddns_domain
350
+    remove_ddns_domain $KANBOARD_DOMAIN_NAME
351
+}
352
+
353
+function install_kanboard {
354
+    if [ ! $ONION_ONLY ]; then
355
+        ONION_ONLY='no'
356
+    fi
357
+
358
+    if [ ! $KANBOARD_DOMAIN_NAME ]; then
359
+        echo $'No domain name was given for kanboard'
360
+        exit 73478
361
+    fi
362
+
363
+    kanboard_hourly_script kanboard $KANBOARD_DOMAIN_NAME
364
+
365
+    function_check install_mariadb
366
+    install_mariadb
367
+
368
+    function_check get_mariadb_password
369
+    get_mariadb_password
370
+
371
+    function_check repair_databases_script
372
+    repair_databases_script
373
+
374
+    apt-get -yq install php-gettext php-curl php-gd php-mysql git curl
375
+    apt-get -yq install memcached php-memcached php-intl exiftool libfcgi0ldbl
376
+
377
+    if [ ! -d /var/www/$KANBOARD_DOMAIN_NAME ]; then
378
+        mkdir /var/www/$KANBOARD_DOMAIN_NAME
379
+    fi
380
+    if [ ! -d /var/www/$KANBOARD_DOMAIN_NAME/htdocs ]; then
381
+
382
+        if [ -d /repos/kanboard ]; then
383
+            mkdir /var/www/$KANBOARD_DOMAIN_NAME/htdocs
384
+            cp -r -p /repos/kanboard/. /var/www/$KANBOARD_DOMAIN_NAME/htdocs
385
+            cd /var/www/$KANBOARD_DOMAIN_NAME/htdocs
386
+            git pull
387
+        else
388
+            function_check git_clone
389
+            git_clone $KANBOARD_REPO /var/www/$KANBOARD_DOMAIN_NAME/htdocs
390
+        fi
391
+
392
+        if [ ! -d /var/www/$KANBOARD_DOMAIN_NAME/htdocs ]; then
393
+            echo $'Unable to clone kanboard repo'
394
+            exit 89365
395
+        fi
396
+    fi
397
+
398
+    cd /var/www/$KANBOARD_DOMAIN_NAME/htdocs
399
+    git checkout $KANBOARD_COMMIT -b $KANBOARD_COMMIT
400
+    set_completion_param "kanboard commit" "$KANBOARD_COMMIT"
401
+
402
+    chmod g+w /var/www/$KANBOARD_DOMAIN_NAME/htdocs
403
+    chmod a+w /var/www/$KANBOARD_DOMAIN_NAME/htdocs/data
404
+    chown -R www-data:www-data /var/www/$KANBOARD_DOMAIN_NAME/htdocs
405
+
406
+    function_check kanboard_create_database
407
+    kanboard_create_database
408
+
409
+    if [ ! -f "/etc/aliases" ]; then
410
+        touch /etc/aliases
411
+    fi
412
+    if ! grep -q "www-data: root" /etc/aliases; then
413
+        echo 'www-data: root' >> /etc/aliases
414
+    fi
415
+
416
+    function_check add_ddns_domain
417
+    add_ddns_domain $KANBOARD_DOMAIN_NAME
418
+
419
+    KANBOARD_ONION_HOSTNAME=$(add_onion_service kanboard 80 ${KANBOARD_ONION_PORT})
420
+
421
+    kanboard_nginx_site=/etc/nginx/sites-available/$KANBOARD_DOMAIN_NAME
422
+    if [[ $ONION_ONLY == "no" ]]; then
423
+        function_check nginx_http_redirect
424
+        nginx_http_redirect $KANBOARD_DOMAIN_NAME "index index.php"
425
+        echo 'server {' >> $kanboard_nginx_site
426
+        echo '  listen 443 ssl;' >> $kanboard_nginx_site
427
+        echo '  listen [::]:443 ssl;' >> $kanboard_nginx_site
428
+        echo "  server_name $KANBOARD_DOMAIN_NAME;" >> $kanboard_nginx_site
429
+        echo '' >> $kanboard_nginx_site
430
+        function_check nginx_compress
431
+        nginx_compress $KANBOARD_DOMAIN_NAME
432
+        echo '' >> $kanboard_nginx_site
433
+        echo '  # Security' >> $kanboard_nginx_site
434
+        function_check nginx_ssl
435
+        nginx_ssl $KANBOARD_DOMAIN_NAME
436
+
437
+        function_check nginx_disable_sniffing
438
+        nginx_disable_sniffing $KANBOARD_DOMAIN_NAME
439
+
440
+        echo '  add_header Strict-Transport-Security max-age=15768000;' >> $kanboard_nginx_site
441
+        echo '' >> $kanboard_nginx_site
442
+        echo '  # Logs' >> $kanboard_nginx_site
443
+        echo '  access_log /dev/null;' >> $kanboard_nginx_site
444
+        echo '  error_log /dev/null;' >> $kanboard_nginx_site
445
+        echo '' >> $kanboard_nginx_site
446
+        echo '  # Root' >> $kanboard_nginx_site
447
+        echo "  root /var/www/$KANBOARD_DOMAIN_NAME/htdocs;" >> $kanboard_nginx_site
448
+        echo '' >> $kanboard_nginx_site
449
+        echo '  # Index' >> $kanboard_nginx_site
450
+        echo '  index index.php;' >> $kanboard_nginx_site
451
+        echo '' >> $kanboard_nginx_site
452
+        echo '  # PHP' >> $kanboard_nginx_site
453
+        echo '  location ~ \.php {' >> $kanboard_nginx_site
454
+        echo '    include snippets/fastcgi-php.conf;' >> $kanboard_nginx_site
455
+        echo '    fastcgi_pass unix:/var/run/php/php7.0-fpm.sock;' >> $kanboard_nginx_site
456
+        echo '    fastcgi_read_timeout 30;' >> $kanboard_nginx_site
457
+        echo '  }' >> $kanboard_nginx_site
458
+        echo '' >> $kanboard_nginx_site
459
+        echo '  # Location' >> $kanboard_nginx_site
460
+        echo '  location / {' >> $kanboard_nginx_site
461
+        function_check nginx_limits
462
+        nginx_limits $KANBOARD_DOMAIN_NAME '15m'
463
+        echo '    try_files $uri $uri/ @kanboard;' >> $kanboard_nginx_site
464
+        echo '  }' >> $kanboard_nginx_site
465
+        echo '' >> $kanboard_nginx_site
466
+        echo '  # Fancy URLs' >> $kanboard_nginx_site
467
+        echo '  location @kanboard {' >> $kanboard_nginx_site
468
+        echo '    rewrite ^(.*)$ /index.php?p=$1 last;' >> $kanboard_nginx_site
469
+        echo '  }' >> $kanboard_nginx_site
470
+        echo '' >> $kanboard_nginx_site
471
+        echo '  # Restrict access that is unnecessary anyway' >> $kanboard_nginx_site
472
+        echo '  location ~ /\.(ht|git) {' >> $kanboard_nginx_site
473
+        echo '    deny all;' >> $kanboard_nginx_site
474
+        echo '  }' >> $kanboard_nginx_site
475
+        echo '' >> $kanboard_nginx_site
476
+        # DO NOT ENABLE KEYBASE. kanboard really doesn't like having a .well-known directory
477
+        echo '}' >> $kanboard_nginx_site
478
+    else
479
+        echo -n '' > $kanboard_nginx_site
480
+    fi
481
+    echo 'server {' >> $kanboard_nginx_site
482
+    echo "    listen 127.0.0.1:$KANBOARD_ONION_PORT default_server;" >> $kanboard_nginx_site
483
+    echo "    server_name $KANBOARD_ONION_HOSTNAME;" >> $kanboard_nginx_site
484
+    echo '' >> $kanboard_nginx_site
485
+    function_check nginx_compress
486
+    nginx_compress $KANBOARD_DOMAIN_NAME
487
+    echo '' >> $kanboard_nginx_site
488
+    function_check nginx_disable_sniffing
489
+    nginx_disable_sniffing $KANBOARD_DOMAIN_NAME
490
+    echo '' >> $kanboard_nginx_site
491
+    echo '  # Logs' >> $kanboard_nginx_site
492
+    echo '  access_log /dev/null;' >> $kanboard_nginx_site
493
+    echo '  error_log /dev/null;' >> $kanboard_nginx_site
494
+    echo '' >> $kanboard_nginx_site
495
+    echo '  # Root' >> $kanboard_nginx_site
496
+    echo "  root /var/www/$KANBOARD_DOMAIN_NAME/htdocs;" >> $kanboard_nginx_site
497
+    echo '' >> $kanboard_nginx_site
498
+    echo '  # Index' >> $kanboard_nginx_site
499
+    echo '  index index.php;' >> $kanboard_nginx_site
500
+    echo '' >> $kanboard_nginx_site
501
+    echo '  # PHP' >> $kanboard_nginx_site
502
+    echo '  location ~ \.php {' >> $kanboard_nginx_site
503
+    echo '    include snippets/fastcgi-php.conf;' >> $kanboard_nginx_site
504
+    echo '    fastcgi_pass unix:/var/run/php/php7.0-fpm.sock;' >> $kanboard_nginx_site
505
+    echo '    fastcgi_read_timeout 30;' >> $kanboard_nginx_site
506
+    echo '  }' >> $kanboard_nginx_site
507
+    echo '' >> $kanboard_nginx_site
508
+    echo '  # Location' >> $kanboard_nginx_site
509
+    echo '  location / {' >> $kanboard_nginx_site
510
+    function_check nginx_limits
511
+    nginx_limits $KANBOARD_DOMAIN_NAME '15m'
512
+    echo '    try_files $uri $uri/ @kanboard;' >> $kanboard_nginx_site
513
+    echo '  }' >> $kanboard_nginx_site
514
+    echo '' >> $kanboard_nginx_site
515
+    echo '  # Fancy URLs' >> $kanboard_nginx_site
516
+    echo '  location @kanboard {' >> $kanboard_nginx_site
517
+    echo '    rewrite ^(.*)$ /index.php?p=$1 last;' >> $kanboard_nginx_site
518
+    echo '  }' >> $kanboard_nginx_site
519
+    echo '' >> $kanboard_nginx_site
520
+    echo '  # Restrict access that is unnecessary anyway' >> $kanboard_nginx_site
521
+    echo '  location ~ /\.(ht|git) {' >> $kanboard_nginx_site
522
+    echo '    deny all;' >> $kanboard_nginx_site
523
+    echo '  }' >> $kanboard_nginx_site
524
+    echo '' >> $kanboard_nginx_site
525
+    # DO NOT ENABLE KEYBASE. kanboard really doesn't like having a .well-known directory
526
+    echo '}' >> $kanboard_nginx_site
527
+
528
+    function_check configure_php
529
+    configure_php
530
+
531
+    function_check create_site_certificate
532
+    create_site_certificate $KANBOARD_DOMAIN_NAME 'yes'
533
+
534
+    # Ensure that the database gets backed up locally, if remote
535
+    # backups are not being used
536
+    function_check backup_databases_script_header
537
+    backup_databases_script_header
538
+
539
+    function_check backup_database_local
540
+    backup_database_local kanboard
541
+
542
+    function_check nginx_ensite
543
+    nginx_ensite $KANBOARD_DOMAIN_NAME
544
+
545
+    KANBOARD_SERVER=${KANBOARD_DOMAIN_NAME}
546
+    if [[ $ONION_ONLY != 'no' ]]; then
547
+        KANBOARD_SERVER=${KANBOARD_ONION_HOSTNAME}
548
+    fi
549
+
550
+    # Create the configuration
551
+    kanboard_configfile=/var/www/${KANBOARD_DOMAIN_NAME}/htdocs/config.php
552
+    cp /var/www/${KANBOARD_DOMAIN_NAME}/htdocs/config.default.php $kanboard_configfile
553
+    sed -i "s|define('MAIL_FROM'.*|define('MAIL_FROM', '$MY_EMAIL_ADDRESS');|g" $kanboard_configfile
554
+    sed -i "s|define('DB_DRIVER'.*|define('DB_DRIVER', 'mysql');|g" $kanboard_configfile
555
+    sed -i "s|define('DB_USERNAME'.*|define('DB_USERNAME', 'root');|g" $kanboard_configfile
556
+    sed -i "s|define('DB_PASSWORD'.*|define('DB_PASSWORD', '$MARIADB_PASSWORD');|g" $kanboard_configfile
557
+    sed -i "s|define('DB_HOSTNAME'.*|define('DB_HOSTNAME', 'localhost');|g" $kanboard_configfile
558
+    sed -i "s|define('DB_NAME'.*|define('DB_NAME', 'kanboard');|g" $kanboard_configfile
559
+    sed -i "s|define('DB_PORT'.*|define('DB_PORT', null);|g" $kanboard_configfile
560
+    logging_off_kanboard
561
+
562
+    initialise_database kanboard /var/www/${KANBOARD_DOMAIN_NAME}/htdocs/app/Schema/Sql/mysql.sql
563
+    chown -R www-data:www-data /var/www/${KANBOARD_DOMAIN_NAME}/htdocs
564
+
565
+    cd /var/www/${KANBOARD_DOMAIN_NAME}/htdocs
566
+    install_composer
567
+
568
+    systemctl restart mariadb
569
+    systemctl restart php7.0-fpm
570
+    systemctl restart nginx
571
+
572
+    ${PROJECT_NAME}-pass -u $MY_USERNAME -a kanboard -p "$KANBOARD_ADMIN_PASSWORD"
573
+
574
+    set_completion_param "kanboard domain" "$KANBOARD_DOMAIN_NAME"
575
+
576
+    APP_INSTALLED=1
577
+}
578
+
579
+# NOTE: deliberately there is no "exit 0"

+ 1
- 13
src/freedombone-app-koel Ver fichero

715
     install_koel_main
715
     install_koel_main
716
 
716
 
717
     cd /var/www/$KOEL_DOMAIN_NAME/htdocs
717
     cd /var/www/$KOEL_DOMAIN_NAME/htdocs
718
+    install_composer
718
 
719
 
719
-    # curl -sS https://getcomposer.org/installer | php
720
-    if [ -f ~/freedombone/image_build/composer_install ]; then
721
-        cat ~/freedombone/image_build/composer_install | php
722
-    else
723
-        if [ -f /home/$MY_USERNAME/freedombone/image_build/composer_install ]; then
724
-            cat /home/$MY_USERNAME/freedombone/image_build/composer_install | php
725
-        fi
726
-    fi
727
     npm install -g yarn
720
     npm install -g yarn
728
-    php composer.phar install
729
-    if [ ! "$?" = "0" ]; then
730
-        echo $'Unable to run composer install'
731
-        exit 7252198
732
-    fi
733
     npm install
721
     npm install
734
 
722
 
735
     function_check get_mariadb_password
723
     function_check get_mariadb_password

+ 2
- 9
src/freedombone-app-movim Ver fichero

383
     # Fix typo
383
     # Fix typo
384
     sed -i 's|weksocket|websocket|g' app/widgets/AdminTest/admintest.js
384
     sed -i 's|weksocket|websocket|g' app/widgets/AdminTest/admintest.js
385
 
385
 
386
-    # curl -sS https://getcomposer.org/installer | php
387
-    if [ -f ~/freedombone/image_build/composer_install ]; then
388
-        cat ~/freedombone/image_build/composer_install | php
389
-    else
390
-        if [ -f /home/$MY_USERNAME/freedombone/image_build/composer_install ]; then
391
-            cat /home/$MY_USERNAME/freedombone/image_build/composer_install | php
392
-        fi
393
-    fi
394
-    php composer.phar install
386
+    cd /var/www/$MOVIM_DOMAIN_NAME/htdocs
387
+    install_composer
395
 
388
 
396
     cd /var/www/$MOVIM_DOMAIN_NAME/htdocs/config
389
     cd /var/www/$MOVIM_DOMAIN_NAME/htdocs/config
397
     cp db.example.inc.php db.inc.php
390
     cp db.example.inc.php db.inc.php

+ 13
- 5
src/freedombone-app-profanity Ver fichero

34
 SHOW_ON_ABOUT=1
34
 SHOW_ON_ABOUT=1
35
 
35
 
36
 LIBMESODE_REPO="https://github.com/boothj5/libmesode"
36
 LIBMESODE_REPO="https://github.com/boothj5/libmesode"
37
-LIBMESODE_COMMIT='e3db0e9bfba61b2d82193874343a94a88f910800'
37
+LIBMESODE_COMMIT='b91872cf7e7ed4d2443ab5c622f4cdb395d64dbe'
38
 
38
 
39
 PROFANITY_REPO="https://github.com/boothj5/profanity"
39
 PROFANITY_REPO="https://github.com/boothj5/profanity"
40
-PROFANITY_COMMIT='2fafaec8a7dc9bc01ee894d83214590598b32914'
40
+PROFANITY_COMMIT='f8b855b09f2c4e9b461b0b7854afabbecf6d5b4a'
41
 
41
 
42
 PROFANITY_OMEMO_PLUGIN_REPO="https://github.com/ReneVolution/profanity-omemo-plugin"
42
 PROFANITY_OMEMO_PLUGIN_REPO="https://github.com/ReneVolution/profanity-omemo-plugin"
43
-PROFANITY_OMEMO_PLUGIN_COMMIT='3ec8ec173656bed9761b740b086123e07c749548'
43
+PROFANITY_OMEMO_PLUGIN_COMMIT='78be0c8367c6379829986755c0d1da287c031234'
44
 
44
 
45
 xmpp_variables=(ONION_ONLY
45
 xmpp_variables=(ONION_ONLY
46
                 INSTALLED_WITHIN_DOCKER
46
                 INSTALLED_WITHIN_DOCKER
285
         echo 'enabled=true' >> $XMPP_CLIENT_ACCOUNTS
285
         echo 'enabled=true' >> $XMPP_CLIENT_ACCOUNTS
286
         echo "jid=${MY_USERNAME}@${DEFAULT_DOMAIN_NAME}" >> $XMPP_CLIENT_ACCOUNTS
286
         echo "jid=${MY_USERNAME}@${DEFAULT_DOMAIN_NAME}" >> $XMPP_CLIENT_ACCOUNTS
287
         echo "server=$XMPP_ONION_HOSTNAME" >> $XMPP_CLIENT_ACCOUNTS
287
         echo "server=$XMPP_ONION_HOSTNAME" >> $XMPP_CLIENT_ACCOUNTS
288
-        echo "pgp.keyid=$MY_GPG_PUBLIC_KEY_ID" >> $XMPP_CLIENT_ACCOUNTS
288
+        # There is a bug where profanity doesn't refresh the screen
289
+        # after gpg-agent has asked for a password, so for now
290
+        # don't set the gpg key by default
291
+        #echo "pgp.keyid=$MY_GPG_PUBLIC_KEY_ID" >> $XMPP_CLIENT_ACCOUNTS
292
+        echo "pgp.keyid=" >> $XMPP_CLIENT_ACCOUNTS
289
         echo 'resource=profanity' >> $XMPP_CLIENT_ACCOUNTS
293
         echo 'resource=profanity' >> $XMPP_CLIENT_ACCOUNTS
290
         echo "muc.service=chat.${DEFAULT_DOMAIN_NAME}" >> $XMPP_CLIENT_ACCOUNTS
294
         echo "muc.service=chat.${DEFAULT_DOMAIN_NAME}" >> $XMPP_CLIENT_ACCOUNTS
291
         echo "muc.nick=${MY_USERNAME}" >> $XMPP_CLIENT_ACCOUNTS
295
         echo "muc.nick=${MY_USERNAME}" >> $XMPP_CLIENT_ACCOUNTS
310
         fi
314
         fi
311
         echo "jid=${MY_USERNAME}@${XMPP_ONION_HOSTNAME}" >> $XMPP_CLIENT_ACCOUNTS
315
         echo "jid=${MY_USERNAME}@${XMPP_ONION_HOSTNAME}" >> $XMPP_CLIENT_ACCOUNTS
312
         echo "server=$XMPP_ONION_HOSTNAME" >> $XMPP_CLIENT_ACCOUNTS
316
         echo "server=$XMPP_ONION_HOSTNAME" >> $XMPP_CLIENT_ACCOUNTS
313
-        echo "pgp.keyid=$MY_GPG_PUBLIC_KEY_ID" >> $XMPP_CLIENT_ACCOUNTS
317
+        # There is a bug where profanity doesn't refresh the screen
318
+        # after gpg-agent has asked for a password, so for now
319
+        # don't set the gpg key by default
320
+        #echo "pgp.keyid=$MY_GPG_PUBLIC_KEY_ID" >> $XMPP_CLIENT_ACCOUNTS
321
+        echo "pgp.keyid=" >> $XMPP_CLIENT_ACCOUNTS
314
         echo 'resource=profanity' >> $XMPP_CLIENT_ACCOUNTS
322
         echo 'resource=profanity' >> $XMPP_CLIENT_ACCOUNTS
315
         echo "muc.service=${XMPP_ONION_HOSTNAME}" >> $XMPP_CLIENT_ACCOUNTS
323
         echo "muc.service=${XMPP_ONION_HOSTNAME}" >> $XMPP_CLIENT_ACCOUNTS
316
         echo "muc.nick=${MY_USERNAME}" >> $XMPP_CLIENT_ACCOUNTS
324
         echo "muc.nick=${MY_USERNAME}" >> $XMPP_CLIENT_ACCOUNTS

+ 494
- 0
src/freedombone-app-wekan Ver fichero

1
+#!/bin/bash
2
+#
3
+# .---.                  .              .
4
+# |                      |              |
5
+# |--- .--. .-.  .-.  .-.|  .-. .--.--. |.-.  .-. .--.  .-.
6
+# |    |   (.-' (.-' (   | (   )|  |  | |   )(   )|  | (.-'
7
+# '    '     --'  --'  -' -  -' '  '   -' -'   -' '   -  --'
8
+#
9
+#                    Freedom in the Cloud
10
+#
11
+# Wekan kanban
12
+#
13
+# License
14
+# =======
15
+#
16
+# Copyright (C) 2017 Bob Mottram <bob@freedombone.net>
17
+#
18
+# This program is free software: you can redistribute it and/or modify
19
+# it under the terms of the GNU Affero General Public License as published by
20
+# the Free Software Foundation, either version 3 of the License, or
21
+# (at your option) any later version.
22
+#
23
+# This program is distributed in the hope that it will be useful,
24
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
25
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
26
+# GNU Affero General Public License for more details.
27
+#
28
+# You should have received a copy of the GNU Affero General Public License
29
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
30
+
31
+VARIANTS=''
32
+
33
+IN_DEFAULT_INSTALL=0
34
+SHOW_ON_ABOUT=0
35
+
36
+WEKAN_DOMAIN_NAME=
37
+WEKAN_CODE=
38
+WEKAN_PORT=8081
39
+WEKAN_ONION_PORT=8120
40
+WEKAN_REPO="https://github.com/wekan/wekan"
41
+WEKAN_COMMIT='dc547c38d1f5ca72729f6d8f81eb03671ca15934'
42
+FLOW_ROUTER_REPO="git://github.com/wekan/flow-router.git"
43
+FLOW_ROUTER_COMMIT='0c1f6423ed9b68eb00cfb1a19492438917a38956'
44
+WEKAN_DIR=/etc/wekan
45
+
46
+wekan_variables=(ONION_ONLY
47
+                 WEKAN_DOMAIN_NAME
48
+                 WEKAN_CODE
49
+                 DDNS_PROVIDER
50
+                 MY_USERNAME)
51
+
52
+function logging_on_wekan {
53
+    echo -n ''
54
+}
55
+
56
+function logging_off_wekan {
57
+    echo -n ''
58
+}
59
+
60
+function remove_user_wekan {
61
+    remove_username="$1"
62
+}
63
+
64
+function add_user_wekan {
65
+    new_username="$1"
66
+    new_user_password="$2"
67
+    echo '0'
68
+}
69
+
70
+function install_interactive_wekan {
71
+    if [[ $ONION_ONLY != "no" ]]; then
72
+        GIT_DOMAIN_NAME='wekan.local'
73
+        write_config_param "WEKAN_DOMAIN_NAME" "$WEKAN_DOMAIN_NAME"
74
+    else
75
+        function_check interactive_site_details
76
+        interactive_site_details wekan
77
+    fi
78
+    APP_INSTALLED=1
79
+}
80
+
81
+function change_password_wekan {
82
+    curr_username="$1"
83
+    new_user_password="$2"
84
+}
85
+
86
+function reconfigure_wekan {
87
+    echo -n ''
88
+}
89
+
90
+function upgrade_wekan {
91
+    CURR_WEKAN_COMMIT=$(get_completion_param "wekan commit")
92
+    if [[ "$CURR_WEKAN_COMMIT" == "$WEKAN_COMMIT" ]]; then
93
+        return
94
+    fi
95
+
96
+    systemctl stop wekan
97
+
98
+    # update to the next commit
99
+    function_check set_repo_commit
100
+    set_repo_commit $WEKAN_DIR "wekan commit" "$WEKAN_COMMIT" $WEKAN_REPO
101
+
102
+    systemctl start wekan
103
+}
104
+
105
+function backup_local_wekan {
106
+    source_directory=$WEKAN_DIR/data
107
+    if [ -d $source_directory ]; then
108
+        systemctl stop wekan
109
+
110
+        dest_directory=wekan
111
+        function_check suspend_site
112
+        suspend_site wekan
113
+
114
+        function_check backup_database_to_usb
115
+        backup_database_to_usb wekan
116
+
117
+        function_check backup_directory_to_usb
118
+        backup_directory_to_usb $source_directory $dest_directory
119
+
120
+        function_check restart_site
121
+        restart_site
122
+
123
+        systemctl start wekan
124
+    fi
125
+}
126
+
127
+function restore_local_wekan {
128
+    if [ -d $WEKAN_DIR ]; then
129
+        systemctl stop wekan
130
+
131
+        function_check restore_database
132
+        restore_database gogs ${WEKAN_DOMAIN_NAME}
133
+
134
+        temp_restore_dir=/root/tempwekan
135
+        function_check restore_directory_from_usb
136
+        restore_directory_from_usb $temp_restore_dir wekan
137
+        cp -r $temp_restore_dir$WEKAN_DIR/data/* $WEKAN_DIR/data/
138
+
139
+        systemctl start wekan
140
+    fi
141
+}
142
+
143
+function backup_remote_wekan {
144
+    if grep -q "wekan domain" $COMPLETION_FILE; then
145
+        temp_backup_dir=$WEKAN_DIR/data
146
+        if [ -d $temp_backup_dir ]; then
147
+            systemctl stop wekan
148
+
149
+            function_check suspend_site
150
+            suspend_site wekan
151
+
152
+            echo $"Backing up Wekan installation"
153
+
154
+            function_check backup_database_to_friend
155
+            backup_database_to_friend wekan
156
+
157
+            function_check backup_directory_to_friend
158
+            backup_directory_to_friend $temp_backup_dir wekan
159
+
160
+            function_check restart_site
161
+            restart_site
162
+
163
+            systemctl start wekan
164
+        else
165
+            echo $"wekan domain specified but not found in ${temp_backup_dir}"
166
+        fi
167
+    fi
168
+}
169
+
170
+function restore_remote_wekan {
171
+    if [ -d $WEKAN_DIR ]; then
172
+        systemctl stop wekan
173
+
174
+        function_check restore_database_from_friend
175
+        restore_database_from_friend wekan
176
+
177
+        temp_restore_dir=/root/tempwekan
178
+        function_check restore_directory_from_usb
179
+        restore_directory_from_friend $temp_restore_dir wekan
180
+        cp -r $temp_restore_dir$WEKAN_DIR/data/* $WEKAN_DIR/data/
181
+
182
+        systemctl start wekan
183
+    fi
184
+}
185
+
186
+function remove_wekan {
187
+    systemctl stop wekan
188
+    systemctl disable wekan
189
+    if [ -f /etc/systemd/system/wekan.service ]; then
190
+        rm /etc/systemd/system/wekan.service
191
+    fi
192
+    systemctl daemon-reload
193
+
194
+    function_check remove_nodejs
195
+    remove_nodejs wekan
196
+
197
+    nginx_dissite wekan
198
+
199
+    if [ -d $WEKAN_DIR ]; then
200
+        rm -rf $WEKAN_DIR
201
+    fi
202
+    if [ -f /etc/nginx/sites-available/wekan ]; then
203
+        rm /etc/nginx/sites-available/wekan
204
+    fi
205
+    function_check drop_database
206
+    drop_database wekan
207
+    function_check remove_onion_service
208
+    remove_onion_service wekan ${WEKAN_ONION_PORT}
209
+    remove_app wekan
210
+    remove_completion_param install_wekan
211
+    sed -i '/wekan/d' $COMPLETION_FILE
212
+
213
+    groupdel -f gogs
214
+    userdel -r wekan
215
+    remove_meteor
216
+}
217
+
218
+function wekan_create_database {
219
+    if [ -f ${IMAGE_PASSWORD_FILE} ]; then
220
+        WEKAN_ADMIN_PASSWORD="$(printf `cat $IMAGE_PASSWORD_FILE`)"
221
+    else
222
+        if [ ! ${GIT_ADMIN_PASSWORD} ]; then
223
+            WEKAN_ADMIN_PASSWORD="$(create_password ${MINIMUM_PASSWORD_LENGTH})"
224
+        fi
225
+    fi
226
+    if [ ! $WEKAN_ADMIN_PASSWORD ]; then
227
+        return
228
+    fi
229
+
230
+    function_check create_database
231
+    create_database gogs "$WEKAN_ADMIN_PASSWORD"
232
+}
233
+
234
+function install_wekan_main {
235
+    if [[ $(app_is_installed wekan_main) == "1" ]]; then
236
+        return
237
+    fi
238
+
239
+    if [ ! -d /var/www/wekan ]; then
240
+        mkdir /var/www/wekan
241
+    fi
242
+    if [ -d $WEKAN_DIR ]; then
243
+        rm -rf $WEKAN_DIR
244
+    fi
245
+
246
+    if [ -d /repos/wekan ]; then
247
+        mkdir -p $WEKAN_DIR
248
+        cp -r -p /repos/wekan/. $WEKAN_DIR
249
+        cd $WEKAN_DIR
250
+        git pull
251
+    else
252
+        function_check git_clone
253
+        git_clone $WEKAN_REPO $WEKAN_DIR
254
+    fi
255
+
256
+    if [ ! -d $WEKAN_DIR ]; then
257
+        echo $'Unable to clone wekan repo'
258
+        exit 783251
259
+    fi
260
+
261
+    # an unprivileged user to run as
262
+    useradd -d $WEKAN_DIR/ wekan
263
+    groupadd wekan
264
+
265
+    cd $WEKAN_DIR
266
+    git checkout $WEKAN_COMMIT -b $WEKAN_COMMIT
267
+    set_completion_param "wekan commit" "$WEKAN_COMMIT"
268
+
269
+    chown -R wekan:wekan $WEKAN_DIR
270
+
271
+    WEKAN_ONION_HOSTNAME=$(add_onion_service wekan 80 ${WEKAN_ONION_PORT})
272
+    set_completion_param "wekan onion domain" "$WEKAN_ONION_HOSTNAME"
273
+
274
+    wekan_nginx_site=/etc/nginx/sites-available/${WEKAN_DOMAIN_NAME}
275
+    if [[ ${ONION_ONLY} == "no" ]]; then
276
+        function_check nginx_http_redirect
277
+        nginx_http_redirect ${WEKAN_DOMAIN_NAME}
278
+        echo 'server {' >> /etc/nginx/sites-available/${WEKAN_DOMAIN_NAME}
279
+        echo '    listen 443 ssl;' >> /etc/nginx/sites-available/${WEKAN_DOMAIN_NAME}
280
+        echo '    listen [::]:443 ssl;' >> /etc/nginx/sites-available/${WEKAN_DOMAIN_NAME}
281
+        echo "    root /var/www/${WEKAN_DOMAIN_NAME}/htdocs;" >> /etc/nginx/sites-available/${WEKAN_DOMAIN_NAME}
282
+        echo "    server_name ${WEKAN_DOMAIN_NAME};" >> /etc/nginx/sites-available/${WEKAN_DOMAIN_NAME}
283
+        echo '    access_log /dev/null;' >> /etc/nginx/sites-available/${WEKAN_DOMAIN_NAME}
284
+        echo "    error_log /dev/null;" >> /etc/nginx/sites-available/${WEKAN_DOMAIN_NAME}
285
+        echo '' >> /etc/nginx/sites-available/${WEKAN_DOMAIN_NAME}
286
+        function_check nginx_ssl
287
+        nginx_ssl ${WEKAN_DOMAIN_NAME}
288
+        function_check nginx_disable_sniffing
289
+        nginx_disable_sniffing ${WEKAN_DOMAIN_NAME}
290
+        echo '    add_header Strict-Transport-Security max-age=0;' >> /etc/nginx/sites-available/${WEKAN_DOMAIN_NAME}
291
+        echo '' >> /etc/nginx/sites-available/${WEKAN_DOMAIN_NAME}
292
+        echo '    location / {' >> /etc/nginx/sites-available/${WEKAN_DOMAIN_NAME}
293
+        function_check nginx_limits
294
+        nginx_limits ${WEKAN_DOMAIN_NAME} '15m'
295
+        echo "        proxy_pass http://localhost:$WEKAN_PORT;" >> /etc/nginx/sites-available/${WEKAN_DOMAIN_NAME}
296
+        echo '    }' >> /etc/nginx/sites-available/${WEKAN_DOMAIN_NAME}
297
+        echo '' >> /etc/nginx/sites-available/${WEKAN_DOMAIN_NAME}
298
+        echo '    fastcgi_buffers 64 4K;' >> /etc/nginx/sites-available/${WEKAN_DOMAIN_NAME}
299
+        echo '' >> /etc/nginx/sites-available/${WEKAN_DOMAIN_NAME}
300
+        echo '    error_page 403 /core/templates/403.php;' >> /etc/nginx/sites-available/${WEKAN_DOMAIN_NAME}
301
+        echo '    error_page 404 /core/templates/404.php;' >> /etc/nginx/sites-available/${WEKAN_DOMAIN_NAME}
302
+        echo '' >> /etc/nginx/sites-available/${WEKAN_DOMAIN_NAME}
303
+        echo '    location = /robots.txt {' >> /etc/nginx/sites-available/${WEKAN_DOMAIN_NAME}
304
+        echo '        allow all;' >> /etc/nginx/sites-available/${WEKAN_DOMAIN_NAME}
305
+        echo '        log_not_found off;' >> /etc/nginx/sites-available/${WEKAN_DOMAIN_NAME}
306
+        echo '        access_log /dev/null;' >> /etc/nginx/sites-available/${WEKAN_DOMAIN_NAME}
307
+        echo '    }' >> /etc/nginx/sites-available/${WEKAN_DOMAIN_NAME}
308
+        echo '' >> /etc/nginx/sites-available/${WEKAN_DOMAIN_NAME}
309
+        nginx_keybase ${WEKAN_DOMAIN_NAME}
310
+        echo '}' >> /etc/nginx/sites-available/${WEKAN_DOMAIN_NAME}
311
+        echo '' >> /etc/nginx/sites-available/${WEKAN_DOMAIN_NAME}
312
+    else
313
+        echo -n '' > /etc/nginx/sites-available/${WEKAN_DOMAIN_NAME}
314
+    fi
315
+    echo 'server {' >> /etc/nginx/sites-available/${WEKAN_DOMAIN_NAME}
316
+    echo "    listen 127.0.0.1:${WEKAN_ONION_PORT} default_server;" >> /etc/nginx/sites-available/${WEKAN_DOMAIN_NAME}
317
+    echo "    root /var/www/$WEKAN_DOMAIN_NAME/htdocs;" >> /etc/nginx/sites-available/${WEKAN_DOMAIN_NAME}
318
+    echo "    server_name $WEKAN_DOMAIN_NAME;" >> /etc/nginx/sites-available/${WEKAN_DOMAIN_NAME}
319
+    echo '    access_log /dev/null;' >> /etc/nginx/sites-available/${WEKAN_DOMAIN_NAME}
320
+    echo "    error_log /dev/null;" >> /etc/nginx/sites-available/${WEKAN_DOMAIN_NAME}
321
+    echo '' >> /etc/nginx/sites-available/${WEKAN_DOMAIN_NAME}
322
+    function_check nginx_disable_sniffing
323
+    nginx_disable_sniffing ${WEKAN_DOMAIN_NAME}
324
+    echo '    add_header Strict-Transport-Security max-age=0;' >> /etc/nginx/sites-available/${WEKAN_DOMAIN_NAME}
325
+    echo '' >> /etc/nginx/sites-available/${WEKAN_DOMAIN_NAME}
326
+    echo '    location / {' >> /etc/nginx/sites-available/${WEKAN_DOMAIN_NAME}
327
+    function_check nginx_limits
328
+    nginx_limits ${WEKAN_DOMAIN_NAME} '15m'
329
+    echo "        proxy_pass http://localhost:$WEKAN_PORT;" >> /etc/nginx/sites-available/${WEKAN_DOMAIN_NAME}
330
+    echo '    }' >> /etc/nginx/sites-available/${WEKAN_DOMAIN_NAME}
331
+    echo '' >> /etc/nginx/sites-available/${WEKAN_DOMAIN_NAME}
332
+    echo '    fastcgi_buffers 64 4K;' >> /etc/nginx/sites-available/${WEKAN_DOMAIN_NAME}
333
+    echo '' >> /etc/nginx/sites-available/${WEKAN_DOMAIN_NAME}
334
+    echo '    error_page 403 /core/templates/403.php;' >> /etc/nginx/sites-available/${WEKAN_DOMAIN_NAME}
335
+    echo '    error_page 404 /core/templates/404.php;' >> /etc/nginx/sites-available/${WEKAN_DOMAIN_NAME}
336
+    echo '' >> /etc/nginx/sites-available/${WEKAN_DOMAIN_NAME}
337
+    echo '    location = /robots.txt {' >> /etc/nginx/sites-available/${WEKAN_DOMAIN_NAME}
338
+    echo '        allow all;' >> /etc/nginx/sites-available/${WEKAN_DOMAIN_NAME}
339
+    echo '        log_not_found off;' >> /etc/nginx/sites-available/${WEKAN_DOMAIN_NAME}
340
+    echo '        access_log /dev/null;' >> /etc/nginx/sites-available/${WEKAN_DOMAIN_NAME}
341
+    echo '    }' >> /etc/nginx/sites-available/${WEKAN_DOMAIN_NAME}
342
+    echo '' >> /etc/nginx/sites-available/${WEKAN_DOMAIN_NAME}
343
+    nginx_keybase ${WEKAN_DOMAIN_NAME}
344
+    echo '}' >> /etc/nginx/sites-available/${WEKAN_DOMAIN_NAME}
345
+
346
+    function_check nginx_ensite
347
+    nginx_ensite wekan
348
+
349
+    install_completed wekan_main
350
+}
351
+
352
+function install_wekan {
353
+    apt-get -qy install build-essential c++ capnproto curl
354
+
355
+    function_check install_nodejs
356
+    install_nodejs wekan
357
+
358
+    install_wekan_main
359
+    install_meteor
360
+
361
+    cd $WEKAN_DIR
362
+
363
+    su -c 'npm install babel-runtime' - wekan
364
+    su -c 'npm install node-gyp' - wekan
365
+    su -c 'npm install node-pre-gyp' - wekan
366
+    su -c 'npm install fibers' - wekan
367
+    su -c 'npm install bcrypt' - wekan
368
+    su -c 'npm install bson' - wekan
369
+    su -c 'npm install es6-promise' - wekan
370
+    su -c 'npm install meteor-node-stubs' - wekan
371
+    su -c 'npm install winston' - wekan
372
+    su -c 'npm install winston-zulip' - wekan
373
+    su -c 'npm install xss' - wekan
374
+
375
+    # Remove any directories from previous installs
376
+    if [ -d $WEKAN_DIR/.meteor ]; then
377
+        rm -rf $WEKAN_DIR/.meteor
378
+    fi
379
+    if [ -d $WEKAN_DIR/app ]; then
380
+        rm -rf $WEKAN_DIR/app
381
+    fi
382
+    if [ -d $WEKAN_DIR/app_build ]; then
383
+        rm -rf $WEKAN_DIR/app_build
384
+    fi
385
+
386
+    # Get additional packages
387
+    mkdir -p $WEKAN_DIR/.meteor/packages
388
+    chown wekan:wekan --recursive $WEKAN_DIR/.meteor
389
+    cd $WEKAN_DIR/.meteor/packages
390
+    if [ ! -d /repos/flowrouter ]; then
391
+        su -c "git clone --depth 1 -b master $FLOW_ROUTER_REPO kadira-flow-router" - wekan
392
+    else
393
+        mkdir kadira-flow-router
394
+        cp -r -p /repos/flowrouter/. kadira-flow-router
395
+        cd kadira-flow-router
396
+        git pull
397
+        cd ..
398
+    fi
399
+    cd kadira-flow-router
400
+    git checkout $FLOW_ROUTER_COMMIT -b $FLOW_ROUTER_COMMIT
401
+    cd ..
402
+    if [ ! -d /repos/meteoruseraccounts ]; then
403
+        su -c "git clone --depth 1 -b master $METEOR_USERACCOUNTS_REPO meteor-useraccounts-core" - wekan
404
+    else
405
+        mkdir meteor-useraccounts-core
406
+        cp -r -p /repos/meteoruseraccounts/. meteor-useraccounts-core
407
+        cd meteor-useraccounts-core
408
+        git pull
409
+        cd ..
410
+    fi
411
+    cd meteor-useraccounts-core
412
+    git checkout $METEOR_USERACCOUNTS_COMMIT -b $METEOR_USERACCOUNTS_COMMIT
413
+    cd ..
414
+    if [ ! -f $WEKAN_DIR/.meteor/packages/meteor-useraccounts-core/package.js ]; then
415
+        echo $"File not found: $WEKAN_DIR/.meteor/packages/meteor-useraccounts-core/package.js"
416
+        exit 7289529
417
+    fi
418
+    sed -i 's/api\.versionsFrom/\/\/api.versionsFrom/' $WEKAN_DIR/.meteor/packages/meteor-useraccounts-core/package.js
419
+    cd $WEKAN_DIR/.meteor
420
+    su -c "$WEKAN_DIR/.meteor/meteor -- help" - wekan
421
+
422
+    # Build app
423
+    if [ ! -d $WEKAN_DIR/app ]; then
424
+        echo $'No app subdirectory found'
425
+        exit 294569
426
+    fi
427
+    cd $WEKAN_DIR/app
428
+    su -c "$WEKAN_DIR/.meteor/meteor add standard-minifier-js" - wekan
429
+    su -c "$WEKAN_DIR/.meteor/meteor npm install" - wekan
430
+    su -c "$WEKAN_DIR/.meteor/meteor build --directory $WEKAN_DIR/app_build" - wekan
431
+    cp $WEKAN_DIR/app/fix-download-unicode/cfs_access-point.txt $WEKAN_DIR/app_build/bundle/programs/server/packages/cfs_access-point.js
432
+    chown wekan:wekan $WEKAN_DIR/app_build/bundle/programs/server/packages/cfs_access-point.js
433
+    sed -i "s|build\/Release\/bson|browser_build\/bson|g" $WEKAN_DIR/app_build/bundle/programs/server/npm/node_modules/meteor/cfs_gridfs/node_modules/mongodb/node_modules/bson/ext/index.js
434
+    if [ ! -d $WEKAN_DIR/app_build/bundle/programs/server/npm/node_modules/meteor/npm-bcrypt ]; then
435
+        echo $"No subdirectory found: $WEKAN_DIR/app_build/bundle/programs/server/npm/node_modules/meteor/npm-bcrypt"
436
+        exit 479832
437
+    fi
438
+    cd $WEKAN_DIR/app_build/bundle/programs/server/npm/node_modules/meteor/npm-bcrypt
439
+    su -c 'rm -rf node_modules/bcrypt' - wekan
440
+    su -c 'npm install bcrypt' - wekan
441
+    cd $WEKAN_DIR/app_build/bundle/programs/server/
442
+    su -c 'npm install' - wekan
443
+    mv $WEKAN_DIR/app_build/bundle ../build
444
+
445
+    if [ ! -f $WEKAN_DIR/build/main.js ]; then
446
+        echo $'main.js not found'
447
+        exit 7828252
448
+    fi
449
+
450
+    # Cleanup
451
+    rm -R $WEKAN_DIR/.meteor
452
+    rm -R $WEKAN_DIR/app
453
+    rm -R $WEKAN_DIR/app_build
454
+
455
+    chown -R wekan:wekan $WEKAN_DIR
456
+
457
+    function_check install_mariadb
458
+    install_mariadb
459
+
460
+    function_check get_mariadb_password
461
+    get_mariadb_password
462
+
463
+    function_check wekan_create_database
464
+    wekan_create_database
465
+
466
+    # daemon
467
+    echo '[Unit]' > /etc/systemd/system/wekan.service
468
+    echo 'Description=Wekan' >> /etc/systemd/system/wekan.service
469
+    echo 'After=syslog.target' >> /etc/systemd/system/wekan.service
470
+    echo 'After=network.target' >> /etc/systemd/system/wekan.service
471
+    echo '' >> /etc/systemd/system/wekan.service
472
+    echo '[Service]' >> /etc/systemd/system/wekan.service
473
+    echo 'User=wekan' >> /etc/systemd/system/wekan.service
474
+    echo 'Group=wekan' >> /etc/systemd/system/wekan.service
475
+    echo "WorkingDirectory=$WEKAN_DIR" >> /etc/systemd/system/wekan.service
476
+    echo "ExecStart=/usr/local/bin/node $WEKAN_DIR/build/main.js" >> /etc/systemd/system/wekan.service
477
+    echo 'Environment=PATH=/usr/bin:/usr/local/bin' >> /etc/systemd/system/wekan.service
478
+    echo 'Environment=NODE_ENV=production' >> /etc/systemd/system/wekan.service
479
+    echo 'Restart=on-failure' >> /etc/systemd/system/wekan.service
480
+    echo '' >> /etc/systemd/system/wekan.service
481
+    echo '[Install]' >> /etc/systemd/system/wekan.service
482
+    echo 'WantedBy=multi-user.target' >> /etc/systemd/system/wekan.service
483
+    systemctl enable wekan.service
484
+    systemctl daemon-reload
485
+    systemctl start wekan.service
486
+
487
+    systemctl restart nginx
488
+
489
+    set_completion_param "wekan domain" "$WEKAN_DOMAIN_NAME"
490
+
491
+    APP_INSTALLED=1
492
+}
493
+
494
+# NOTE: deliberately there is no "exit 0"

+ 5
- 0
src/freedombone-image-customise Ver fichero

1274
     git clone $TOXID_REPO $rootdir/repos/toxid
1274
     git clone $TOXID_REPO $rootdir/repos/toxid
1275
     git clone $TOXIC_REPO $rootdir/repos/toxic
1275
     git clone $TOXIC_REPO $rootdir/repos/toxic
1276
     git clone $TURTL_REPO $rootdir/repos/turtl
1276
     git clone $TURTL_REPO $rootdir/repos/turtl
1277
+    git clone $KANBOARD_REPO $rootdir/repos/kanboard
1278
+    #git clone $WEKAN_REPO $rootdir/repos/wekan
1279
+    #git clone $FLOW_ROUTER_REPO $rootdir/repos/flowrouter
1280
+    #git clone $METEOR_USERACCOUNTS_REPO $rootdir/repos/meteoruseraccounts
1281
+    #git clone $METEOR_REPO $rootdir/repos/meteor
1277
     #git clone $ZERONET_REPO $rootdir/repos/zeronet
1282
     #git clone $ZERONET_REPO $rootdir/repos/zeronet
1278
     #git clone $QTOX_REPO $rootdir/repos/qtox
1283
     #git clone $QTOX_REPO $rootdir/repos/qtox
1279
 }
1284
 }

+ 220
- 0
src/freedombone-utils-meteor Ver fichero

1
+#!/bin/bash
2
+#
3
+# .---.                  .              .
4
+# |                      |              |
5
+# |--- .--. .-.  .-.  .-.|  .-. .--.--. |.-.  .-. .--.  .-.
6
+# |    |   (.-' (.-' (   | (   )|  |  | |   )(   )|  | (.-'
7
+# '    '     --'  --'  -' -  -' '  '   -' -'   -' '   -  --'
8
+#
9
+#                    Freedom in the Cloud
10
+#
11
+# Functions for installing meteor
12
+# See meteor.com
13
+#
14
+# License
15
+# =======
16
+#
17
+# Copyright (C) 2017 Bob Mottram <bob@freedombone.net>
18
+#
19
+# This program is free software: you can redistribute it and/or modify
20
+# it under the terms of the GNU Affero General Public License as published by
21
+# the Free Software Foundation, either version 3 of the License, or
22
+# (at your option) any later version.
23
+#
24
+# This program is distributed in the hope that it will be useful,
25
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
26
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
27
+# GNU Affero General Public License for more details.
28
+#
29
+# You should have received a copy of the GNU Affero General Public License
30
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
31
+
32
+METEOR_RELEASE='1.4.4.1'
33
+METEOR_REPO="https://github.com/meteor/meteor"
34
+METEOR_COMMIT='b52c6587d7542c0f27481a3bee8c65be06068ac1'
35
+METEOR_USERACCOUNTS_REPO="git://github.com/meteor-useraccounts/core.git"
36
+METEOR_USERACCOUNTS_COMMIT='2e8986813b51f321f908d2f6211f6f81f76cd627'
37
+
38
+function meteor_cleanUp {
39
+    rm -rf "$TARBALL_FILE"
40
+    rm -rf "$INSTALL_TMPDIR"
41
+}
42
+
43
+function install_meteor_script {
44
+    meteor_dir=$1
45
+
46
+    if [ ! $meteor_dir ]; then
47
+        echo $'No meteor install directory specified'
48
+        exit 692025
49
+    fi
50
+
51
+    if [ ! -d $meteor_dir ]; then
52
+        echo $'Meteor install directory not found'
53
+        exit 845382
54
+    fi
55
+
56
+    if [[ "$(arch)" == "arm"* ]]; then
57
+        echo 'meteor does not support ARM'
58
+        exit 8362952
59
+    fi
60
+    if [[ "$(arch)" == "i386" || "$(arch)" == "x86_32" ]]; then
61
+        PLATFORM="os.linux.x86_32"
62
+    else
63
+        PLATFORM="os.linux.x86_64"
64
+    fi
65
+
66
+    RELEASE="$METEOR_RELEASE"
67
+
68
+    DIR_PREFIX="/usr/local"
69
+
70
+    TARBALL_URL="$https://meteorinstall-4168.kxcdn.com/packages-bootstrap/${RELEASE}/meteor-bootstrap-${PLATFORM}.tar.gz"
71
+    INSTALL_TMPDIR="$meteor_dir/.meteor-install-tmp"
72
+    TARBALL_FILE="$meteor_dir/.meteor-tarball-tmp"
73
+
74
+    # Remove temporary files now in case they exist.
75
+    meteor_cleanUp
76
+
77
+    if [ -d $INSTALL_TMPDIR ]; then
78
+        rm -rf $INSTALL_TMPDIR
79
+    fi
80
+    mkdir "$INSTALL_TMPDIR"
81
+
82
+    if [ ! -f ${TARBALL_FILE} ]; then
83
+        echo "Downloading Meteor distribution"
84
+        # keep trying to curl the file until it works (resuming where possible)
85
+        MAX_ATTEMPTS=10
86
+        RETRY_DELAY_SECS=5
87
+        set +e
88
+        ATTEMPTS=0
89
+        while [ $ATTEMPTS -lt $MAX_ATTEMPTS ]
90
+        do
91
+            ATTEMPTS=$((ATTEMPTS + 1))
92
+
93
+            curl --progress-bar --fail --continue-at - \
94
+                 "$TARBALL_URL" --output "$TARBALL_FILE"
95
+
96
+            if [ $? -eq 0 ]
97
+            then
98
+                break
99
+            fi
100
+
101
+            echo "Retrying download in $RETRY_DELAY_SECS seconds..."
102
+            sleep $RETRY_DELAY_SECS
103
+        done
104
+    fi
105
+
106
+    if [ ! -f ${TARBALL_FILE} ]; then
107
+        echo $'meteor tarball could not be downloaded'
108
+        exit 7272452
109
+    fi
110
+
111
+    tar -xzf "$TARBALL_FILE" -C "$INSTALL_TMPDIR" -o
112
+
113
+    if [ ! -f ${INSTALL_TMPDIR}/.meteor/meteor ]; then
114
+        echo $'tarball not extracted'
115
+        exit 693252
116
+    fi
117
+
118
+    mv "${INSTALL_TMPDIR}/.meteor" "$meteor_dir"
119
+
120
+    meteor_cleanUp
121
+
122
+    echo ''
123
+    echo "Meteor ${RELEASE} has been installed in $meteor_dir/.meteor"
124
+
125
+    METEOR_SYMLINK_TARGET="$(readlink "$meteor_dir/.meteor/meteor")"
126
+    METEOR_TOOL_DIRECTORY="$(dirname "$METEOR_SYMLINK_TARGET")"
127
+    LAUNCHER="$meteor_dir/.meteor/$METEOR_TOOL_DIRECTORY/scripts/admin/launch-meteor"
128
+
129
+    if cp "$LAUNCHER" "$DIR_PREFIX/bin/meteor" >/dev/null 2>&1; then
130
+        echo "Writing a launcher script to $DIR_PREFIX/bin/meteor for your convenience."
131
+        cat <<"EOF"
132
+
133
+To get started fast:
134
+
135
+  $ meteor create ~/my_cool_app
136
+  $ cd ~/my_cool_app
137
+  $ meteor
138
+
139
+Or see the docs at:
140
+
141
+  docs.meteor.com
142
+
143
+EOF
144
+    elif type sudo >/dev/null 2>&1; then
145
+        echo "Writing a launcher script to $DIR_PREFIX/bin/meteor for your convenience."
146
+        echo "This may prompt for your password."
147
+
148
+        # New macs (10.9+) don't ship with /usr/local, however it is still in
149
+        # the default PATH. We still install there, we just need to create the
150
+        # directory first.
151
+        # XXX this means that we can run sudo too many times. we should never
152
+        #     run it more than once if it fails the first time
153
+        if [ ! -d "$DIR_PREFIX/bin" ] ; then
154
+            sudo mkdir -m 755 "$DIR_PREFIX" || true
155
+            sudo mkdir -m 755 "$DIR_PREFIX/bin" || true
156
+        fi
157
+
158
+        if sudo cp "$LAUNCHER" "$DIR_PREFIX/bin/meteor"; then
159
+            cat <<"EOF"
160
+
161
+To get started fast:
162
+
163
+  $ meteor create ~/my_cool_app
164
+  $ cd ~/my_cool_app
165
+  $ meteor
166
+
167
+Or see the docs at:
168
+
169
+  docs.meteor.com
170
+
171
+EOF
172
+        else
173
+            cat <<EOF
174
+
175
+Couldn't write the launcher script. Please either:
176
+
177
+  (1) Run the following as root:
178
+        cp "$LAUNCHER" /usr/bin/meteor
179
+  (2) Add "\$meteor_dir/.meteor" to your path, or
180
+  (3) Rerun this command to try again.
181
+
182
+Then to get started, take a look at 'meteor --help' or see the docs at
183
+docs.meteor.com.
184
+EOF
185
+        fi
186
+    else
187
+        cat <<EOF
188
+
189
+Now you need to do one of the following:
190
+
191
+  (1) Add "\$meteor_dir/.meteor" to your path, or
192
+  (2) Run this command as root:
193
+        cp "$LAUNCHER" /usr/bin/meteor
194
+
195
+Then to get started, take a look at 'meteor --help' or see the docs at
196
+docs.meteor.com.
197
+EOF
198
+    fi
199
+
200
+}
201
+
202
+function install_meteor {
203
+    apt-get -yq install curl
204
+    if [ ! -d $INSTALL_DIR/meteor ]; then
205
+        mkdir $INSTALL_DIR/meteor
206
+    fi
207
+    cd $INSTALL_DIR/meteor
208
+    install_meteor_script
209
+}
210
+
211
+function remove_meteor {
212
+    if [ -f /usr/local/bin/meteor ]; then
213
+        rm /usr/local/bin/meteor
214
+    fi
215
+    if [ -f /usr/bin/meteor ]; then
216
+        rm /usr/bin/meteor
217
+    fi
218
+}
219
+
220
+# NOTE: deliberately no exit 0

+ 16
- 0
src/freedombone-utils-web Ver fichero

917
     fi
917
     fi
918
 }
918
 }
919
 
919
 
920
+function install_composer {
921
+    # curl -sS https://getcomposer.org/installer | php
922
+    if [ -f ~/${PROJECT_NAME}/image_build/composer_install ]; then
923
+        cat ~/${PROJECT_NAME}/image_build/composer_install | php
924
+    else
925
+        if [ -f /home/$MY_USERNAME/${PROJECT_NAME}/image_build/composer_install ]; then
926
+            cat /home/$MY_USERNAME/${PROJECT_NAME}/image_build/composer_install | php
927
+        fi
928
+    fi
929
+    php composer.phar install
930
+    if [ ! "$?" = "0" ]; then
931
+        echo $'Unable to run composer install'
932
+        exit 7252198
933
+    fi
934
+}
935
+
920
 # NOTE: deliberately no exit 0
936
 # NOTE: deliberately no exit 0

+ 12
- 4
website/EN/app_cryptpad.html Ver fichero

3
 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
3
 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
4
 <html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
4
 <html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
5
 <head>
5
 <head>
6
-<!-- 2017-05-28 Sun 11:33 -->
6
+<!-- 2017-07-27 Thu 15:16 -->
7
 <meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
7
 <meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
8
 <meta name="viewport" content="width=device-width, initial-scale=1" />
8
 <meta name="viewport" content="width=device-width, initial-scale=1" />
9
 <title></title>
9
 <title></title>
248
 <h1>CryptPad</h1>
248
 <h1>CryptPad</h1>
249
 </center>
249
 </center>
250
 
250
 
251
+<div class="org-center">
252
+
253
+<div class="figure">
254
+<p><img src="images/cryptpad.jpg" alt="cryptpad.jpg" />
255
+</p>
256
+</div>
257
+</div>
258
+
251
 <p>
259
 <p>
252
 This is similar to <a href="./app_etherpad.html">EtherPad</a> but with better security and more document types which can be collaboratively edited in real time. It includes not just text editing but also creating presentations, voting and editing source code.
260
 This is similar to <a href="./app_etherpad.html">EtherPad</a> but with better security and more document types which can be collaboratively edited in real time. It includes not just text editing but also creating presentations, voting and editing source code.
253
 </p>
261
 </p>
264
 Documents are stored locally within the browser of each user and the server just acts as a coordinator. No documents are stored on the server.
272
 Documents are stored locally within the browser of each user and the server just acts as a coordinator. No documents are stored on the server.
265
 </p>
273
 </p>
266
 
274
 
267
-<div id="outline-container-orgd443efe" class="outline-2">
268
-<h2 id="orgd443efe">Installation</h2>
269
-<div class="outline-text-2" id="text-orgd443efe">
275
+<div id="outline-container-orgf7a5294" class="outline-2">
276
+<h2 id="orgf7a5294">Installation</h2>
277
+<div class="outline-text-2" id="text-orgf7a5294">
270
 <p>
278
 <p>
271
 Log into your system with:
279
 Log into your system with:
272
 </p>
280
 </p>

+ 323
- 0
website/EN/app_kanboard.html Ver fichero

1
+<?xml version="1.0" encoding="utf-8"?>
2
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
3
+"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
4
+<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
5
+<head>
6
+<!-- 2017-07-25 Tue 23:23 -->
7
+<meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
8
+<meta name="viewport" content="width=device-width, initial-scale=1" />
9
+<title></title>
10
+<meta name="generator" content="Org mode" />
11
+<meta name="author" content="Bob Mottram" />
12
+<meta name="description" content="How to use KanBoard"
13
+ />
14
+<meta name="keywords" content="freedombone, kanboard" />
15
+<style type="text/css">
16
+ <!--/*--><![CDATA[/*><!--*/
17
+  .title  { text-align: center;
18
+             margin-bottom: .2em; }
19
+  .subtitle { text-align: center;
20
+              font-size: medium;
21
+              font-weight: bold;
22
+              margin-top:0; }
23
+  .todo   { font-family: monospace; color: red; }
24
+  .done   { font-family: monospace; color: green; }
25
+  .priority { font-family: monospace; color: orange; }
26
+  .tag    { background-color: #eee; font-family: monospace;
27
+            padding: 2px; font-size: 80%; font-weight: normal; }
28
+  .timestamp { color: #bebebe; }
29
+  .timestamp-kwd { color: #5f9ea0; }
30
+  .org-right  { margin-left: auto; margin-right: 0px;  text-align: right; }
31
+  .org-left   { margin-left: 0px;  margin-right: auto; text-align: left; }
32
+  .org-center { margin-left: auto; margin-right: auto; text-align: center; }
33
+  .underline { text-decoration: underline; }
34
+  #postamble p, #preamble p { font-size: 90%; margin: .2em; }
35
+  p.verse { margin-left: 3%; }
36
+  pre {
37
+    border: 1px solid #ccc;
38
+    box-shadow: 3px 3px 3px #eee;
39
+    padding: 8pt;
40
+    font-family: monospace;
41
+    overflow: auto;
42
+    margin: 1.2em;
43
+  }
44
+  pre.src {
45
+    position: relative;
46
+    overflow: visible;
47
+    padding-top: 1.2em;
48
+  }
49
+  pre.src:before {
50
+    display: none;
51
+    position: absolute;
52
+    background-color: white;
53
+    top: -10px;
54
+    right: 10px;
55
+    padding: 3px;
56
+    border: 1px solid black;
57
+  }
58
+  pre.src:hover:before { display: inline;}
59
+  /* Languages per Org manual */
60
+  pre.src-asymptote:before { content: 'Asymptote'; }
61
+  pre.src-awk:before { content: 'Awk'; }
62
+  pre.src-C:before { content: 'C'; }
63
+  /* pre.src-C++ doesn't work in CSS */
64
+  pre.src-clojure:before { content: 'Clojure'; }
65
+  pre.src-css:before { content: 'CSS'; }
66
+  pre.src-D:before { content: 'D'; }
67
+  pre.src-ditaa:before { content: 'ditaa'; }
68
+  pre.src-dot:before { content: 'Graphviz'; }
69
+  pre.src-calc:before { content: 'Emacs Calc'; }
70
+  pre.src-emacs-lisp:before { content: 'Emacs Lisp'; }
71
+  pre.src-fortran:before { content: 'Fortran'; }
72
+  pre.src-gnuplot:before { content: 'gnuplot'; }
73
+  pre.src-haskell:before { content: 'Haskell'; }
74
+  pre.src-hledger:before { content: 'hledger'; }
75
+  pre.src-java:before { content: 'Java'; }
76
+  pre.src-js:before { content: 'Javascript'; }
77
+  pre.src-latex:before { content: 'LaTeX'; }
78
+  pre.src-ledger:before { content: 'Ledger'; }
79
+  pre.src-lisp:before { content: 'Lisp'; }
80
+  pre.src-lilypond:before { content: 'Lilypond'; }
81
+  pre.src-lua:before { content: 'Lua'; }
82
+  pre.src-matlab:before { content: 'MATLAB'; }
83
+  pre.src-mscgen:before { content: 'Mscgen'; }
84
+  pre.src-ocaml:before { content: 'Objective Caml'; }
85
+  pre.src-octave:before { content: 'Octave'; }
86
+  pre.src-org:before { content: 'Org mode'; }
87
+  pre.src-oz:before { content: 'OZ'; }
88
+  pre.src-plantuml:before { content: 'Plantuml'; }
89
+  pre.src-processing:before { content: 'Processing.js'; }
90
+  pre.src-python:before { content: 'Python'; }
91
+  pre.src-R:before { content: 'R'; }
92
+  pre.src-ruby:before { content: 'Ruby'; }
93
+  pre.src-sass:before { content: 'Sass'; }
94
+  pre.src-scheme:before { content: 'Scheme'; }
95
+  pre.src-screen:before { content: 'Gnu Screen'; }
96
+  pre.src-sed:before { content: 'Sed'; }
97
+  pre.src-sh:before { content: 'shell'; }
98
+  pre.src-sql:before { content: 'SQL'; }
99
+  pre.src-sqlite:before { content: 'SQLite'; }
100
+  /* additional languages in org.el's org-babel-load-languages alist */
101
+  pre.src-forth:before { content: 'Forth'; }
102
+  pre.src-io:before { content: 'IO'; }
103
+  pre.src-J:before { content: 'J'; }
104
+  pre.src-makefile:before { content: 'Makefile'; }
105
+  pre.src-maxima:before { content: 'Maxima'; }
106
+  pre.src-perl:before { content: 'Perl'; }
107
+  pre.src-picolisp:before { content: 'Pico Lisp'; }
108
+  pre.src-scala:before { content: 'Scala'; }
109
+  pre.src-shell:before { content: 'Shell Script'; }
110
+  pre.src-ebnf2ps:before { content: 'ebfn2ps'; }
111
+  /* additional language identifiers per "defun org-babel-execute"
112
+       in ob-*.el */
113
+  pre.src-cpp:before  { content: 'C++'; }
114
+  pre.src-abc:before  { content: 'ABC'; }
115
+  pre.src-coq:before  { content: 'Coq'; }
116
+  pre.src-groovy:before  { content: 'Groovy'; }
117
+  /* additional language identifiers from org-babel-shell-names in
118
+     ob-shell.el: ob-shell is the only babel language using a lambda to put
119
+     the execution function name together. */
120
+  pre.src-bash:before  { content: 'bash'; }
121
+  pre.src-csh:before  { content: 'csh'; }
122
+  pre.src-ash:before  { content: 'ash'; }
123
+  pre.src-dash:before  { content: 'dash'; }
124
+  pre.src-ksh:before  { content: 'ksh'; }
125
+  pre.src-mksh:before  { content: 'mksh'; }
126
+  pre.src-posh:before  { content: 'posh'; }
127
+  /* Additional Emacs modes also supported by the LaTeX listings package */
128
+  pre.src-ada:before { content: 'Ada'; }
129
+  pre.src-asm:before { content: 'Assembler'; }
130
+  pre.src-caml:before { content: 'Caml'; }
131
+  pre.src-delphi:before { content: 'Delphi'; }
132
+  pre.src-html:before { content: 'HTML'; }
133
+  pre.src-idl:before { content: 'IDL'; }
134
+  pre.src-mercury:before { content: 'Mercury'; }
135
+  pre.src-metapost:before { content: 'MetaPost'; }
136
+  pre.src-modula-2:before { content: 'Modula-2'; }
137
+  pre.src-pascal:before { content: 'Pascal'; }
138
+  pre.src-ps:before { content: 'PostScript'; }
139
+  pre.src-prolog:before { content: 'Prolog'; }
140
+  pre.src-simula:before { content: 'Simula'; }
141
+  pre.src-tcl:before { content: 'tcl'; }
142
+  pre.src-tex:before { content: 'TeX'; }
143
+  pre.src-plain-tex:before { content: 'Plain TeX'; }
144
+  pre.src-verilog:before { content: 'Verilog'; }
145
+  pre.src-vhdl:before { content: 'VHDL'; }
146
+  pre.src-xml:before { content: 'XML'; }
147
+  pre.src-nxml:before { content: 'XML'; }
148
+  /* add a generic configuration mode; LaTeX export needs an additional
149
+     (add-to-list 'org-latex-listings-langs '(conf " ")) in .emacs */
150
+  pre.src-conf:before { content: 'Configuration File'; }
151
+
152
+  table { border-collapse:collapse; }
153
+  caption.t-above { caption-side: top; }
154
+  caption.t-bottom { caption-side: bottom; }
155
+  td, th { vertical-align:top;  }
156
+  th.org-right  { text-align: center;  }
157
+  th.org-left   { text-align: center;   }
158
+  th.org-center { text-align: center; }
159
+  td.org-right  { text-align: right;  }
160
+  td.org-left   { text-align: left;   }
161
+  td.org-center { text-align: center; }
162
+  dt { font-weight: bold; }
163
+  .footpara { display: inline; }
164
+  .footdef  { margin-bottom: 1em; }
165
+  .figure { padding: 1em; }
166
+  .figure p { text-align: center; }
167
+  .inlinetask {
168
+    padding: 10px;
169
+    border: 2px solid gray;
170
+    margin: 10px;
171
+    background: #ffffcc;
172
+  }
173
+  #org-div-home-and-up
174
+   { text-align: right; font-size: 70%; white-space: nowrap; }
175
+  textarea { overflow-x: auto; }
176
+  .linenr { font-size: smaller }
177
+  .code-highlighted { background-color: #ffff00; }
178
+  .org-info-js_info-navigation { border-style: none; }
179
+  #org-info-js_console-label
180
+    { font-size: 10px; font-weight: bold; white-space: nowrap; }
181
+  .org-info-js_search-highlight
182
+    { background-color: #ffff00; color: #000000; font-weight: bold; }
183
+  .org-svg { width: 90%; }
184
+  /*]]>*/-->
185
+</style>
186
+<link rel="stylesheet" type="text/css" href="freedombone.css" />
187
+<script type="text/javascript">
188
+/*
189
+@licstart  The following is the entire license notice for the
190
+JavaScript code in this tag.
191
+
192
+Copyright (C) 2012-2017 Free Software Foundation, Inc.
193
+
194
+The JavaScript code in this tag is free software: you can
195
+redistribute it and/or modify it under the terms of the GNU
196
+General Public License (GNU GPL) as published by the Free Software
197
+Foundation, either version 3 of the License, or (at your option)
198
+any later version.  The code is distributed WITHOUT ANY WARRANTY;
199
+without even the implied warranty of MERCHANTABILITY or FITNESS
200
+FOR A PARTICULAR PURPOSE.  See the GNU GPL for more details.
201
+
202
+As additional permission under GNU GPL version 3 section 7, you
203
+may distribute non-source (e.g., minimized or compacted) forms of
204
+that code without the copy of the GNU GPL normally required by
205
+section 4, provided you include this license notice and a URL
206
+through which recipients can access the Corresponding Source.
207
+
208
+
209
+@licend  The above is the entire license notice
210
+for the JavaScript code in this tag.
211
+*/
212
+<!--/*--><![CDATA[/*><!--*/
213
+ function CodeHighlightOn(elem, id)
214
+ {
215
+   var target = document.getElementById(id);
216
+   if(null != target) {
217
+     elem.cacheClassElem = elem.className;
218
+     elem.cacheClassTarget = target.className;
219
+     target.className = "code-highlighted";
220
+     elem.className   = "code-highlighted";
221
+   }
222
+ }
223
+ function CodeHighlightOff(elem, id)
224
+ {
225
+   var target = document.getElementById(id);
226
+   if(elem.cacheClassElem)
227
+     elem.className = elem.cacheClassElem;
228
+   if(elem.cacheClassTarget)
229
+     target.className = elem.cacheClassTarget;
230
+ }
231
+/*]]>*///-->
232
+</script>
233
+</head>
234
+<body>
235
+<div id="preamble" class="status">
236
+<a name="top" id="top"></a>
237
+</div>
238
+<div id="content">
239
+<div class="org-center">
240
+
241
+<div class="figure">
242
+<p><img src="images/logo.png" alt="logo.png" />
243
+</p>
244
+</div>
245
+</div>
246
+
247
+<center>
248
+<h1>KanBoard</h1>
249
+</center>
250
+
251
+<p>
252
+Kanbans are one way of managing projects. They're traditionally used in businesses but can also be useful for personal TODO lists or within open source or DIY projects. If you have a list of things which need to be done and want to keep track of progress then this provides a way to do that.
253
+</p>
254
+
255
+<div id="outline-container-orgfd145f9" class="outline-2">
256
+<h2 id="orgfd145f9">Installation</h2>
257
+<div class="outline-text-2" id="text-orgfd145f9">
258
+<p>
259
+Log into your system with:
260
+</p>
261
+
262
+<div class="org-src-container">
263
+<pre><code class="src src-bash">ssh myusername@mydomain -p 2222
264
+</code></pre>
265
+</div>
266
+
267
+<p>
268
+Using cursor keys, space bar and Enter key select <b>Administrator controls</b> and type in your password.
269
+</p>
270
+
271
+<p>
272
+Select <b>Add/Remove Apps</b> then <b>kanboard</b>. You will then be asked for a domain name and if you are using FreeDNS also the code for the domain which can be found under <b>Dynamic DNS</b> on the FreeDNS site (the random string from "<i>quick cron example</i>" which appears after <i>update.php?</i> and before <i>&gt;&gt;</i>). For more details on obtaining a domain and making it accessible via dynamic DNS see the <a href="./faq.html">FAQ</a>. Typically the domain name you use will be a subdomain, such as <i>kanban.mydomainname.net</i>. It will need to be a domain which you have bought somewhere and own and not one of the FreeDNS subdomains, otherwise you won't be able to get a SSL/TLS certificate for it.
273
+</p>
274
+
275
+<p>
276
+After the install has completed go to <b>Security settings</b> and select <b>Create a new Let's Encrypt certificate</b> and enter the domain name that you are using for KanBoard. If you're using the "onion only" version of the system then you don't need to do this. If the certificate is obtained successfully then you will see a congratulations message.
277
+</p>
278
+</div>
279
+</div>
280
+
281
+<div id="outline-container-org2e3435d" class="outline-2">
282
+<h2 id="org2e3435d">Initial setup</h2>
283
+<div class="outline-text-2" id="text-org2e3435d">
284
+<p>
285
+If you have just obtained a Lets Encrypt certificate as above then go to <b>About</b> on the administrator control panel and you should see your KanBoard domain listed there along with an onion address. You can then navigate to your site in a browser.
286
+</p>
287
+
288
+<p>
289
+The default login is username "admin" and password "admin". Obviously the first thing you'll need to do is log in and change the password, which can be done by going to "My Profile" on the drop down list on the right hand side.
290
+</p>
291
+
292
+<p>
293
+For more details of how to use KanBoard see the <a href="https://kanboard.net/documentation">documentation here</a>.
294
+</p>
295
+</div>
296
+</div>
297
+</div>
298
+<div id="postamble" class="status">
299
+
300
+<style type="text/css">
301
+.back-to-top {
302
+    position: fixed;
303
+    bottom: 2em;
304
+    right: 0px;
305
+    text-decoration: none;
306
+    color: #000000;
307
+    background-color: rgba(235, 235, 235, 0.80);
308
+    font-size: 12px;
309
+    padding: 1em;
310
+    display: none;
311
+}
312
+
313
+.back-to-top:hover {
314
+    background-color: rgba(135, 135, 135, 0.50);
315
+}
316
+</style>
317
+
318
+<div class="back-to-top">
319
+<a href="#top">Back to top</a> | <a href="mailto:bob@freedombone.net">E-mail me</a>
320
+</div>
321
+</div>
322
+</body>
323
+</html>

+ 109
- 97
website/EN/apps.html Ver fichero

3
 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
3
 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
4
 <html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
4
 <html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
5
 <head>
5
 <head>
6
-<!-- 2017-06-25 Sun 21:57 -->
6
+<!-- 2017-07-25 Tue 23:25 -->
7
 <meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
7
 <meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
8
 <meta name="viewport" content="width=device-width, initial-scale=1" />
8
 <meta name="viewport" content="width=device-width, initial-scale=1" />
9
 <title></title>
9
 <title></title>
264
 </div>
264
 </div>
265
 </div>
265
 </div>
266
 
266
 
267
-<div id="outline-container-org63f1146" class="outline-2">
268
-<h2 id="org63f1146">CryptPad</h2>
269
-<div class="outline-text-2" id="text-org63f1146">
267
+<div id="outline-container-org9a19246" class="outline-2">
268
+<h2 id="org9a19246">CryptPad</h2>
269
+<div class="outline-text-2" id="text-org9a19246">
270
 <p>
270
 <p>
271
 Collaborate on editing documents, presentations and source code, or vote on things. All with a good level of security.
271
 Collaborate on editing documents, presentations and source code, or vote on things. All with a good level of security.
272
 </p>
272
 </p>
276
 </p>
276
 </p>
277
 </div>
277
 </div>
278
 </div>
278
 </div>
279
-<div id="outline-container-orgf372cd2" class="outline-2">
280
-<h2 id="orgf372cd2">DLNA</h2>
281
-<div class="outline-text-2" id="text-orgf372cd2">
279
+<div id="outline-container-orgaf887a3" class="outline-2">
280
+<h2 id="orgaf887a3">DLNA</h2>
281
+<div class="outline-text-2" id="text-orgaf887a3">
282
 <p>
282
 <p>
283
 Enables you to use the system as a music server which any DLNA compatible devices can connect to within your home network.
283
 Enables you to use the system as a music server which any DLNA compatible devices can connect to within your home network.
284
 </p>
284
 </p>
288
 </p>
288
 </p>
289
 </div>
289
 </div>
290
 </div>
290
 </div>
291
-<div id="outline-container-orge69d870" class="outline-2">
292
-<h2 id="orge69d870">Dokuwiki</h2>
293
-<div class="outline-text-2" id="text-orge69d870">
291
+<div id="outline-container-org24b3d95" class="outline-2">
292
+<h2 id="org24b3d95">Dokuwiki</h2>
293
+<div class="outline-text-2" id="text-org24b3d95">
294
 <p>
294
 <p>
295
 A databaseless wiki system.
295
 A databaseless wiki system.
296
 </p>
296
 </p>
300
 </p>
300
 </p>
301
 </div>
301
 </div>
302
 </div>
302
 </div>
303
-<div id="outline-container-org748292e" class="outline-2">
304
-<h2 id="org748292e">Emacs</h2>
305
-<div class="outline-text-2" id="text-org748292e">
303
+<div id="outline-container-orga7568ea" class="outline-2">
304
+<h2 id="orga7568ea">Emacs</h2>
305
+<div class="outline-text-2" id="text-orga7568ea">
306
 <p>
306
 <p>
307
 If you use the Mutt client to read your email then this will set it up to use emacs for composing new mail.
307
 If you use the Mutt client to read your email then this will set it up to use emacs for composing new mail.
308
 </p>
308
 </p>
312
 </p>
312
 </p>
313
 </div>
313
 </div>
314
 </div>
314
 </div>
315
-<div id="outline-container-org9e62d1f" class="outline-2">
316
-<h2 id="org9e62d1f">Etherpad</h2>
317
-<div class="outline-text-2" id="text-org9e62d1f">
315
+<div id="outline-container-org3d4300f" class="outline-2">
316
+<h2 id="org3d4300f">Etherpad</h2>
317
+<div class="outline-text-2" id="text-org3d4300f">
318
 <p>
318
 <p>
319
 Collaborate on creating documents in real time. Maybe you're planning a holiday with other family members or creating documentation for a Free Software project along with other volunteers. Etherpad is hard to beat for simplicity and speed. Only users of the system will be able to access it.
319
 Collaborate on creating documents in real time. Maybe you're planning a holiday with other family members or creating documentation for a Free Software project along with other volunteers. Etherpad is hard to beat for simplicity and speed. Only users of the system will be able to access it.
320
 </p>
320
 </p>
324
 </p>
324
 </p>
325
 </div>
325
 </div>
326
 </div>
326
 </div>
327
-<div id="outline-container-org8eb5191" class="outline-2">
328
-<h2 id="org8eb5191">Friendica</h2>
329
-<div class="outline-text-2" id="text-org8eb5191">
327
+<div id="outline-container-org91f769f" class="outline-2">
328
+<h2 id="org91f769f">Friendica</h2>
329
+<div class="outline-text-2" id="text-org91f769f">
330
 <p>
330
 <p>
331
 Federated social network system.
331
 Federated social network system.
332
 </p>
332
 </p>
336
 </p>
336
 </p>
337
 </div>
337
 </div>
338
 </div>
338
 </div>
339
-<div id="outline-container-orge13ef3e" class="outline-2">
340
-<h2 id="orge13ef3e">Ghost</h2>
341
-<div class="outline-text-2" id="text-orge13ef3e">
339
+<div id="outline-container-org6266e6b" class="outline-2">
340
+<h2 id="org6266e6b">Ghost</h2>
341
+<div class="outline-text-2" id="text-org6266e6b">
342
 <p>
342
 <p>
343
 Modern looking blogging system.
343
 Modern looking blogging system.
344
 </p>
344
 </p>
348
 </p>
348
 </p>
349
 </div>
349
 </div>
350
 </div>
350
 </div>
351
-<div id="outline-container-org18ba256" class="outline-2">
352
-<h2 id="org18ba256">GNU Social</h2>
353
-<div class="outline-text-2" id="text-org18ba256">
351
+<div id="outline-container-orge7307c0" class="outline-2">
352
+<h2 id="orge7307c0">GNU Social</h2>
353
+<div class="outline-text-2" id="text-orge7307c0">
354
 <p>
354
 <p>
355
 Federated social network. You can "<i>remote follow</i>" other users within the GNU Social federation.
355
 Federated social network. You can "<i>remote follow</i>" other users within the GNU Social federation.
356
 </p>
356
 </p>
360
 </p>
360
 </p>
361
 </div>
361
 </div>
362
 </div>
362
 </div>
363
-<div id="outline-container-orgbf05b19" class="outline-2">
364
-<h2 id="orgbf05b19">Gogs</h2>
365
-<div class="outline-text-2" id="text-orgbf05b19">
363
+<div id="outline-container-org42d8a6c" class="outline-2">
364
+<h2 id="org42d8a6c">Gogs</h2>
365
+<div class="outline-text-2" id="text-org42d8a6c">
366
 <p>
366
 <p>
367
 Lightweight git project hosting system. You can mirror projects from Github, or if Github turns evil then just host your own projects while retaining the familiar <i>fork-and-pull</i> workflow. If you can use Github then you can also use Gogs.
367
 Lightweight git project hosting system. You can mirror projects from Github, or if Github turns evil then just host your own projects while retaining the familiar <i>fork-and-pull</i> workflow. If you can use Github then you can also use Gogs.
368
 </p>
368
 </p>
372
 </p>
372
 </p>
373
 </div>
373
 </div>
374
 </div>
374
 </div>
375
-<div id="outline-container-org14e55c0" class="outline-2">
376
-<h2 id="org14e55c0">HTMLy</h2>
377
-<div class="outline-text-2" id="text-org14e55c0">
375
+<div id="outline-container-org21d5b80" class="outline-2">
376
+<h2 id="org21d5b80">HTMLy</h2>
377
+<div class="outline-text-2" id="text-org21d5b80">
378
 <p>
378
 <p>
379
 Databaseless blogging system. Quite simple and with a markdown-like format.
379
 Databaseless blogging system. Quite simple and with a markdown-like format.
380
 </p>
380
 </p>
384
 </p>
384
 </p>
385
 </div>
385
 </div>
386
 </div>
386
 </div>
387
-<div id="outline-container-org4db6ae4" class="outline-2">
388
-<h2 id="org4db6ae4">Hubzilla</h2>
389
-<div class="outline-text-2" id="text-org4db6ae4">
387
+<div id="outline-container-org47d8fc7" class="outline-2">
388
+<h2 id="org47d8fc7">Hubzilla</h2>
389
+<div class="outline-text-2" id="text-org47d8fc7">
390
 <p>
390
 <p>
391
 Web publishing platform with social network like features and good privacy controls so that it's possible to specify who can see which content. Includes photo albums, calendar, wiki and file storage.
391
 Web publishing platform with social network like features and good privacy controls so that it's possible to specify who can see which content. Includes photo albums, calendar, wiki and file storage.
392
 </p>
392
 </p>
396
 </p>
396
 </p>
397
 </div>
397
 </div>
398
 </div>
398
 </div>
399
-<div id="outline-container-org7fae7fd" class="outline-2">
400
-<h2 id="org7fae7fd">IRC Server (ngirc)</h2>
401
-<div class="outline-text-2" id="text-org7fae7fd">
399
+<div id="outline-container-org71113c6" class="outline-2">
400
+<h2 id="org71113c6">IRC Server (ngirc)</h2>
401
+<div class="outline-text-2" id="text-org71113c6">
402
 <p>
402
 <p>
403
 Run your own IRC chat channel which can be secured with a password and accessible via an onion address. A bouncer is included so that you can receive messages sent while you were offline. Works with Hexchat and other popular clients.
403
 Run your own IRC chat channel which can be secured with a password and accessible via an onion address. A bouncer is included so that you can receive messages sent while you were offline. Works with Hexchat and other popular clients.
404
 </p>
404
 </p>
408
 </p>
408
 </p>
409
 </div>
409
 </div>
410
 </div>
410
 </div>
411
-<div id="outline-container-org0422600" class="outline-2">
412
-<h2 id="org0422600">Jitsi Meet</h2>
413
-<div class="outline-text-2" id="text-org0422600">
411
+<div id="outline-container-org9f28087" class="outline-2">
412
+<h2 id="org9f28087">Jitsi Meet</h2>
413
+<div class="outline-text-2" id="text-org9f28087">
414
 <p>
414
 <p>
415
 Experimental WebRTC video conferencing system, similar to Google Hangouts. This may not be fully functional, but is hoped to be in the near future.
415
 Experimental WebRTC video conferencing system, similar to Google Hangouts. This may not be fully functional, but is hoped to be in the near future.
416
 </p>
416
 </p>
417
 </div>
417
 </div>
418
 </div>
418
 </div>
419
 
419
 
420
-<div id="outline-container-orgb944eab" class="outline-2">
421
-<h2 id="orgb944eab">Koel</h2>
422
-<div class="outline-text-2" id="text-orgb944eab">
420
+<div id="outline-container-orgbad5922" class="outline-2">
421
+<h2 id="orgbad5922">KanBoard</h2>
422
+<div class="outline-text-2" id="text-orgbad5922">
423
+<p>
424
+A simple kanban system for managing projects or TODO lists.
425
+</p>
426
+
427
+<p>
428
+<a href="./app_kanboard.html">How to use it</a>
429
+</p>
430
+</div>
431
+</div>
432
+<div id="outline-container-org6529912" class="outline-2">
433
+<h2 id="org6529912">Koel</h2>
434
+<div class="outline-text-2" id="text-org6529912">
423
 <p>
435
 <p>
424
 Access your music collection from any internet connected device.
436
 Access your music collection from any internet connected device.
425
 </p>
437
 </p>
429
 </p>
441
 </p>
430
 </div>
442
 </div>
431
 </div>
443
 </div>
432
-<div id="outline-container-orgbbbba81" class="outline-2">
433
-<h2 id="orgbbbba81">Lychee</h2>
434
-<div class="outline-text-2" id="text-orgbbbba81">
444
+<div id="outline-container-orgc0eae1a" class="outline-2">
445
+<h2 id="orgc0eae1a">Lychee</h2>
446
+<div class="outline-text-2" id="text-orgc0eae1a">
435
 <p>
447
 <p>
436
 Make your photo albums available on the web.
448
 Make your photo albums available on the web.
437
 </p>
449
 </p>
441
 </p>
453
 </p>
442
 </div>
454
 </div>
443
 </div>
455
 </div>
444
-<div id="outline-container-org6ff2173" class="outline-2">
445
-<h2 id="org6ff2173">Mailpile</h2>
446
-<div class="outline-text-2" id="text-org6ff2173">
456
+<div id="outline-container-orga4bfc9d" class="outline-2">
457
+<h2 id="orga4bfc9d">Mailpile</h2>
458
+<div class="outline-text-2" id="text-orga4bfc9d">
447
 <p>
459
 <p>
448
 Modern email client which supports GPG encryption.
460
 Modern email client which supports GPG encryption.
449
 </p>
461
 </p>
453
 </p>
465
 </p>
454
 </div>
466
 </div>
455
 </div>
467
 </div>
456
-<div id="outline-container-orgbed2d4b" class="outline-2">
457
-<h2 id="orgbed2d4b">Matrix</h2>
458
-<div class="outline-text-2" id="text-orgbed2d4b">
468
+<div id="outline-container-org672b48e" class="outline-2">
469
+<h2 id="org672b48e">Matrix</h2>
470
+<div class="outline-text-2" id="text-org672b48e">
459
 <p>
471
 <p>
460
 Multi-user chat with some security and moderation controls.
472
 Multi-user chat with some security and moderation controls.
461
 </p>
473
 </p>
465
 </p>
477
 </p>
466
 </div>
478
 </div>
467
 </div>
479
 </div>
468
-<div id="outline-container-org35530e4" class="outline-2">
469
-<h2 id="org35530e4">Mediagoblin</h2>
470
-<div class="outline-text-2" id="text-org35530e4">
480
+<div id="outline-container-orgce218ca" class="outline-2">
481
+<h2 id="orgce218ca">Mediagoblin</h2>
482
+<div class="outline-text-2" id="text-orgce218ca">
471
 <p>
483
 <p>
472
 Publicly host video and audio files so that you don't need to use YouTube/Vimeo/etc.
484
 Publicly host video and audio files so that you don't need to use YouTube/Vimeo/etc.
473
 </p>
485
 </p>
477
 </p>
489
 </p>
478
 </div>
490
 </div>
479
 </div>
491
 </div>
480
-<div id="outline-container-org5500ed4" class="outline-2">
481
-<h2 id="org5500ed4">Mumble</h2>
482
-<div class="outline-text-2" id="text-org5500ed4">
492
+<div id="outline-container-orgb224245" class="outline-2">
493
+<h2 id="orgb224245">Mumble</h2>
494
+<div class="outline-text-2" id="text-orgb224245">
483
 <p>
495
 <p>
484
 The popular VoIP and text chat system. Say goodbye to old-fashioned telephony conferences with silly dial codes. Also works well on mobile.
496
 The popular VoIP and text chat system. Say goodbye to old-fashioned telephony conferences with silly dial codes. Also works well on mobile.
485
 </p>
497
 </p>
489
 </p>
501
 </p>
490
 </div>
502
 </div>
491
 </div>
503
 </div>
492
-<div id="outline-container-orgc0f99a0" class="outline-2">
493
-<h2 id="orgc0f99a0">NextCloud</h2>
494
-<div class="outline-text-2" id="text-orgc0f99a0">
504
+<div id="outline-container-org2786fbb" class="outline-2">
505
+<h2 id="org2786fbb">NextCloud</h2>
506
+<div class="outline-text-2" id="text-org2786fbb">
495
 <p>
507
 <p>
496
 Store files on your server and sync them with laptops or mobile devices. Includes many plugins including videoconferencing and collaborative document editing.
508
 Store files on your server and sync them with laptops or mobile devices. Includes many plugins including videoconferencing and collaborative document editing.
497
 </p>
509
 </p>
501
 </p>
513
 </p>
502
 </div>
514
 </div>
503
 </div>
515
 </div>
504
-<div id="outline-container-orga3e49f8" class="outline-2">
505
-<h2 id="orga3e49f8">PI-Hole</h2>
506
-<div class="outline-text-2" id="text-orga3e49f8">
516
+<div id="outline-container-orgaad15be" class="outline-2">
517
+<h2 id="orgaad15be">PI-Hole</h2>
518
+<div class="outline-text-2" id="text-orgaad15be">
507
 <p>
519
 <p>
508
 The black hole for web adverts. Block adverts at the domain name level within your local network. It can significantly reduce bandwidth, speed up page load times and protect your systems from being tracked by spyware.
520
 The black hole for web adverts. Block adverts at the domain name level within your local network. It can significantly reduce bandwidth, speed up page load times and protect your systems from being tracked by spyware.
509
 </p>
521
 </p>
513
 </p>
525
 </p>
514
 </div>
526
 </div>
515
 </div>
527
 </div>
516
-<div id="outline-container-org6d5133e" class="outline-2">
517
-<h2 id="org6d5133e">PostActiv</h2>
518
-<div class="outline-text-2" id="text-org6d5133e">
528
+<div id="outline-container-org0cb789f" class="outline-2">
529
+<h2 id="org0cb789f">PostActiv</h2>
530
+<div class="outline-text-2" id="text-org0cb789f">
519
 <p>
531
 <p>
520
 An alternative federated social networking system compatible with GNU Social. It includes some optimisations and fixes currently not available within the main GNU Social project.
532
 An alternative federated social networking system compatible with GNU Social. It includes some optimisations and fixes currently not available within the main GNU Social project.
521
 </p>
533
 </p>
525
 </p>
537
 </p>
526
 </div>
538
 </div>
527
 </div>
539
 </div>
528
-<div id="outline-container-org82cb46a" class="outline-2">
529
-<h2 id="org82cb46a">Profanity</h2>
530
-<div class="outline-text-2" id="text-org82cb46a">
540
+<div id="outline-container-org6b2db26" class="outline-2">
541
+<h2 id="org6b2db26">Profanity</h2>
542
+<div class="outline-text-2" id="text-org6b2db26">
531
 <p>
543
 <p>
532
 A shell based XMPP client which you can run on the Freedombone server via ssh.
544
 A shell based XMPP client which you can run on the Freedombone server via ssh.
533
 </p>
545
 </p>
537
 </p>
549
 </p>
538
 </div>
550
 </div>
539
 </div>
551
 </div>
540
-<div id="outline-container-org0544cbf" class="outline-2">
541
-<h2 id="org0544cbf">Riot Web</h2>
542
-<div class="outline-text-2" id="text-org0544cbf">
552
+<div id="outline-container-org4dea572" class="outline-2">
553
+<h2 id="org4dea572">Riot Web</h2>
554
+<div class="outline-text-2" id="text-org4dea572">
543
 <p>
555
 <p>
544
 A browser based user interface for the Matrix federated communications system, including WebRTC audio and video chat.
556
 A browser based user interface for the Matrix federated communications system, including WebRTC audio and video chat.
545
 </p>
557
 </p>
549
 </p>
561
 </p>
550
 </div>
562
 </div>
551
 </div>
563
 </div>
552
-<div id="outline-container-orga52c58b" class="outline-2">
553
-<h2 id="orga52c58b">SearX</h2>
554
-<div class="outline-text-2" id="text-orga52c58b">
564
+<div id="outline-container-org7e88433" class="outline-2">
565
+<h2 id="org7e88433">SearX</h2>
566
+<div class="outline-text-2" id="text-org7e88433">
555
 <p>
567
 <p>
556
 A metasearch engine for customised and private web searches.
568
 A metasearch engine for customised and private web searches.
557
 </p>
569
 </p>
561
 </p>
573
 </p>
562
 </div>
574
 </div>
563
 </div>
575
 </div>
564
-<div id="outline-container-org8f2b9fe" class="outline-2">
565
-<h2 id="org8f2b9fe">tt-rss</h2>
566
-<div class="outline-text-2" id="text-org8f2b9fe">
576
+<div id="outline-container-orgcfc1af4" class="outline-2">
577
+<h2 id="orgcfc1af4">tt-rss</h2>
578
+<div class="outline-text-2" id="text-orgcfc1af4">
567
 <p>
579
 <p>
568
 Private RSS reader. Pulls in RSS/Atom feeds via Tor and is only accessible via an onion address. Have "<i>the right to read</i>" without the Surveillance State knowing what you're reading. Also available with a user interface suitable for viewing on mobile devices via a browser such as OrFox.
580
 Private RSS reader. Pulls in RSS/Atom feeds via Tor and is only accessible via an onion address. Have "<i>the right to read</i>" without the Surveillance State knowing what you're reading. Also available with a user interface suitable for viewing on mobile devices via a browser such as OrFox.
569
 </p>
581
 </p>
573
 </p>
585
 </p>
574
 </div>
586
 </div>
575
 </div>
587
 </div>
576
-<div id="outline-container-org96317fb" class="outline-2">
577
-<h2 id="org96317fb">Syncthing</h2>
578
-<div class="outline-text-2" id="text-org96317fb">
588
+<div id="outline-container-org526d1e5" class="outline-2">
589
+<h2 id="org526d1e5">Syncthing</h2>
590
+<div class="outline-text-2" id="text-org526d1e5">
579
 <p>
591
 <p>
580
 Possibly the best way to synchronise files across all of your devices. Once it has been set up it "just works" with no user intervention needed.
592
 Possibly the best way to synchronise files across all of your devices. Once it has been set up it "just works" with no user intervention needed.
581
 </p>
593
 </p>
585
 </p>
597
 </p>
586
 </div>
598
 </div>
587
 </div>
599
 </div>
588
-<div id="outline-container-org6118146" class="outline-2">
589
-<h2 id="org6118146">Tahoe-LAFS</h2>
590
-<div class="outline-text-2" id="text-org6118146">
600
+<div id="outline-container-org43bcb4f" class="outline-2">
601
+<h2 id="org43bcb4f">Tahoe-LAFS</h2>
602
+<div class="outline-text-2" id="text-org43bcb4f">
591
 <p>
603
 <p>
592
 Robust and encrypted storage of files on one or more server.
604
 Robust and encrypted storage of files on one or more server.
593
 </p>
605
 </p>
597
 </p>
609
 </p>
598
 </div>
610
 </div>
599
 </div>
611
 </div>
600
-<div id="outline-container-org7850375" class="outline-2">
601
-<h2 id="org7850375">Tox</h2>
602
-<div class="outline-text-2" id="text-org7850375">
612
+<div id="outline-container-org29d522e" class="outline-2">
613
+<h2 id="org29d522e">Tox</h2>
614
+<div class="outline-text-2" id="text-org29d522e">
603
 <p>
615
 <p>
604
 Client and bootstrap node for the Tox chat/VoIP system.
616
 Client and bootstrap node for the Tox chat/VoIP system.
605
 </p>
617
 </p>
609
 </p>
621
 </p>
610
 </div>
622
 </div>
611
 </div>
623
 </div>
612
-<div id="outline-container-org37c0a88" class="outline-2">
613
-<h2 id="org37c0a88">Turtl</h2>
614
-<div class="outline-text-2" id="text-org37c0a88">
624
+<div id="outline-container-org71eba9a" class="outline-2">
625
+<h2 id="org71eba9a">Turtl</h2>
626
+<div class="outline-text-2" id="text-org71eba9a">
615
 <p>
627
 <p>
616
 A system for privately creating and sharing notes and images, similar to Evernote but without the spying.
628
 A system for privately creating and sharing notes and images, similar to Evernote but without the spying.
617
 </p>
629
 </p>
621
 </p>
633
 </p>
622
 </div>
634
 </div>
623
 </div>
635
 </div>
624
-<div id="outline-container-org6042f9a" class="outline-2">
625
-<h2 id="org6042f9a">Vim</h2>
626
-<div class="outline-text-2" id="text-org6042f9a">
636
+<div id="outline-container-org95cabfd" class="outline-2">
637
+<h2 id="org95cabfd">Vim</h2>
638
+<div class="outline-text-2" id="text-org95cabfd">
627
 <p>
639
 <p>
628
 If you use the Mutt client to read your email then this will set it up to use vim for composing new mail.
640
 If you use the Mutt client to read your email then this will set it up to use vim for composing new mail.
629
 </p>
641
 </p>
630
 </div>
642
 </div>
631
 </div>
643
 </div>
632
 
644
 
633
-<div id="outline-container-org51cc377" class="outline-2">
634
-<h2 id="org51cc377">XMPP</h2>
635
-<div class="outline-text-2" id="text-org51cc377">
645
+<div id="outline-container-org07897b8" class="outline-2">
646
+<h2 id="org07897b8">XMPP</h2>
647
+<div class="outline-text-2" id="text-org07897b8">
636
 <p>
648
 <p>
637
 Chat server which can be used together with client such as Gajim or Conversations to provide end-to-end content security and also onion routed metadata security. Includes advanced features such as <i>client state notification</i> to save battery power on your mobile devices, support for seamless roaming between networks and <i>message carbons</i> so that you can receive the same messages while being simultaneously logged in to your account on more than one device.
649
 Chat server which can be used together with client such as Gajim or Conversations to provide end-to-end content security and also onion routed metadata security. Includes advanced features such as <i>client state notification</i> to save battery power on your mobile devices, support for seamless roaming between networks and <i>message carbons</i> so that you can receive the same messages while being simultaneously logged in to your account on more than one device.
638
 </p>
650
 </p>