settings.html 18.8 KB
Newer Older
1
<!DOCTYPE html>
2 3
<!--
Copyright (C) 2015 GRNET S.A.
4 5 6 7 8 9 10 11 12 13 14 15

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
16 17
along with this program.  If not, see <http://www.gnu.org/licenses/>.
-->
18 19 20 21 22 23 24
<html>
    <head>
        <title>User Settings</title>
        <link rel="stylesheet" href="static/stylesheets/main.css" />
        <script src="static/js/jquery.js"></script>
        <script src="settings.js"></script>
        <script type="text/javascript">
25 26
            var path = require('path');
            var fs = require('fs');
27
            var LANG = JSON.parse(fs.readFileSync(path.join('..', 'ui_data/languages.json')));
28

29 30
            var errors = {
                cloud_url_empty: 'Provide a Cloud Authentication URL',
31
                cloud_inaccessible: 'Cloud URL did not respond as expected',
32
                token_empty: 'Provide a user token (Login to retrieve token)',
33 34
                token_error: 'Failed to authenticate',
                token_cloudless: 'No cloud to try this token against',
35 36
                container_empty: 'Provide the name of the remote container',
                dir_not_chosen: 'Select the local directory'
37
            }
38
            var settings = {};
39

40 41
            var fs = require('fs');
            var exclude = null;
42
            var cur_lang = 'en';
43
            $(document).ready(function() {
44 45 46 47 48
                var url = get_setting('url')
                if (url) {
                    url = url.replace(/\/+$/, '');
                    $('#cloud-url').val(url);
                }
49
                settings['url'] = url;
50 51
                var token = get_setting('token');
                if (token) $('#token').val(token);
52
                settings['token'] = token;
53 54
                var container = get_setting('container');
                if (container) $('#container').val(container);
55
                settings['container'] = container;
56 57
                var directory = get_setting('directory');
                if (directory) $('#directory').html(directory);
58
                settings['directory'] = directory
59 60
                var exclude = get_setting('exclude');
                if (exclude) try {
61 62
                    $('#exclude').val(
                        fs.readFileSync(exclude, encoding='utf-8'));
63
                } catch (err) {console.log(err);}
64 65 66
                if (!get_setting('language')) set_setting('language', cur_lang);
                if (get_setting('sync_on_start')) $('#start_sync_box').click();

67
            });
68 69
            cur_lang = get_setting('language');

70 71 72 73 74 75 76 77 78 79 80
            function update_exclude(new_content) {
                if (exclude) fs.writeFile(exclude, new_content);
            }
            function extract_credentials(cookie) {
                var credentials = cookie.value.split('%7C');
                var uuid = credentials[0];
                var token = credentials[1];
                //$('#uuid').html(uuid);
                $('#token').val(token);
                $('#token').trigger('change');
            }
81 82 83 84 85 86 87 88 89 90
            function remove_cookies(win, url) {
                var removed_at_least_one = false
                win.cookies.getAll({url: url}, function(cookies) {
                    $.each(cookies, function(i, cookie) {
                        win.cookies.remove({url: url, name: cookie.name} );
                        removed_at_least_one = true;
                    });
                });
                return removed_at_least_one;
            }
91
            var gui = require('nw.gui');
92 93 94 95
            var cred_win = null;
            var logout_win = null;
            var got_cookie = false;
            var show_creds = true;
96 97 98 99 100 101 102 103 104 105 106 107

            function creds_on() {
                $('#get_creds').removeClass("off");
                $('#get_creds').addClass("on");

            }

            function creds_off() {
                $('#get_creds').removeClass("on");
                $('#get_creds').addClass("off");
            }

108
            function get_credentials() {
109
                var cookie_name = '_pithos2_a';
110 111
                var lurl = get_account_ui() + '/logout?next=' + get_pithos_ui()
                show_creds = false;
112
                creds_off();
113 114 115
                got_cookie = false;
                cred_win = gui.Window.open(lurl, {
                    focus: true, width: 820, height: 580, toolbar: false
116
                });
117
                cred_win.cookies.onChanged.addListener(function(info) {
118 119 120
                    if (info.cookie.name === cookie_name) {
                        console.log('Succesfully logged in');
                        extract_credentials(info.cookie);
121
                        got_cookie = true;
122 123
                    }
                });
124 125 126 127 128 129 130 131 132 133 134 135 136 137
                cred_win.on('loaded', function() {
                    if (got_cookie) cred_win.close();
                });
                cred_win.on('closed', function() {
                    logout_win = gui.Window.open(
                        get_account_ui() + '/logout',
                        {focus: true, width:20, height: 20 });
                    logout_win.hide();
                    logout_win.on('loaded', function() {
                        while(remove_cookies(logout_win, get_pithos_ui())) {}
                        logout_win.close();
                        show_creds = true;
                    });
                });
138
            }
139 140

            function check_cloud_url() {
141

142 143
                var url = $('#cloud-url').val().replace(/\/+$/, '');
                if(!url) {
144 145
                    $('#cloud-error small').text(errors.cloud_url_empty);
                    $('#cloud-error').addClass('error');
146
                    creds_off();
147
                    return false;
148
                } else {
149
                    refresh_endpoints(url);
150 151 152 153 154 155 156 157
                    if (!get_pithos_ui()) {
                        $('#cloud-error small').text(errors.cloud_inaccessible
                            + ' [' + get_url_error() + ']');
                        $('#cloud-error').addClass('error');
                        return false;
                    }
                }
                $('#cloud-error').removeClass('error');
158 159 160 161 162 163 164 165
                return true;
            }

            function check_token() {
                if (!$('#token').val()) {
                    $('#token-error small').text(errors.token_empty);
                    $('#token-error').addClass('error');
                    return false;
166
                } else{
167 168 169
                    var url = $('#cloud-url').val().replace(/\/+$/, '');
                    if (get_pithos_ui() && url) {
                        check_auth(url, $('#token').val());
170 171 172 173 174 175 176 177 178 179 180 181 182 183
                        var auth_error = get_auth_error();
                        if (auth_error) {
                            $('#token-error small').text(
                                errors.token_error + ' [' + auth_error + ']');
                            $('#token-error').addClass('error');
                            return false;
                        }
                    } else {
                        $('#token-error small').text(errors.token_cloudless);
                        $('#token-error').addClass('error');
                        return false;
                    }
                }
                $('#token-error').removeClass('error');
184 185 186 187 188 189 190 191 192 193 194 195
                return true;
            }

            function check_container() {
                if (!$('#container').val()) {
                    $('#container-error small').text(errors.container_empty);
                    $('#container-error').addClass('error');
                    return false;
                } else $('#container-error').removeClass('error');
                return true;
            }

196 197 198 199 200 201 202 203 204
            function check_directory() {
                if(!$('#directory').html()) {
                    $('#directory-error small').text(errors.dir_not_chosen);
                    $('#directory-error').addClass('error');
                    return false;
                } else $('#directory-error').removeClass('error');
                return true;
            }

205 206 207 208
            function check_fields() {
                var cloud = check_cloud_url();
                var token = check_token();
                var container = check_container();
209 210
                var directory = check_directory();
                return cloud && token && container && directory;
211
            }
212

213 214 215 216 217 218 219 220 221
            function check_start_sync() {
                settings['sync_on_start'] = $('#start_sync_box').is(':checked');
            }

            function localize() {
                settings['language'] = cur_lang;
                var COMMON = JSON.parse(
                fs.readFileSync(path.join('..', 'ui_data/common_' + cur_lang + '.json')));
                var SETTINGS = COMMON.SETTINGS;
222
                document.title = SETTINGS.TITLE;
223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243
                errors = {
                    cloud_url_empty: SETTINGS["CLOUD URL IS EMPTY"] || 'Provide a Cloud Authentication URL',
                    cloud_inaccessible: SETTINGS["CLOUD URL UNEXPECTED RESPONSE"] || 'Cloud URL did not respond as expected',
                    token_empty: SETTINGS["TOKEN IS EMPTY"] || 'Provide a user token (Login to retrieve token)',
                    token_error: SETTINGS["AUTHENTICATION FAILED"] || 'Failed to authenticate',
                    token_cloudless: SETTINGS["TOKEN WITHOUT CLOUD"] || 'No cloud to try this token against',
                    container_empty: SETTINGS["PROVIDE CONTAINER"] || 'Provide the name of the remote container',
                    dir_not_chosen: SETTINGS["SELECT DIRECTORY"] || 'Select the local directory'
                }
                document.getElementById('title').innerHTML = SETTINGS.TITLE || "Settings";
                document.getElementById('appearance_label').innerHTML = SETTINGS.GENERAL || "General";
                document.getElementById('language_label').innerHTML = SETTINGS.LANGUAGE || "Language";
                document.getElementById('start_sync_label').innerHTML = SETTINGS.SYNCONSTART || "Sync on Start";
                document.getElementById('cloud_label').innerHTML = SETTINGS.CLOUD || "Cloud";
                document.getElementById('url_label').innerHTML = SETTINGS.URL || "URL";
                document.getElementById('token_label').innerHTML = SETTINGS.TOKEN || "Token";
                document.getElementById('get_creds').innerHTML = SETTINGS.RETRIEVE || "Retrieve token";
                document.getElementById('sync_label').innerHTML = SETTINGS.SYNC || "Sync pair";
                document.getElementById('container_label').innerHTML = SETTINGS.CONTAINER || "Container";
                document.getElementById('directory_label').innerHTML = SETTINGS.DIRECTORY || "Directory";
                document.getElementById('dirdialogue_label').innerHTML = SETTINGS.DIRDIALOGUE || "Select directory";
244
                document.getElementById('sync_button').innerHTML = SETTINGS.SAVE;
245 246
                document.getElementById('explain_cloud').innerHTML = SETTINGS["EXPLAIN CLOUD"] || "Go to the cloud site, login, click API ACCESS and copy the Authentication URL in the first box.";
                document.getElementById('explain_sync').innerHTML = SETTINGS["EXPLAIN SYNC"] || "Pair a remote Pithos+ container with a local directory";
247

248 249 250 251 252 253 254
                var cloud_placeholder = SETTINGS["CLOUD URL PLACEHOLDER"] || "Authentication URL";
                $('#cloud-url').attr('placeholder', cloud_placeholder);
                var token_placeholder = SETTINGS["TOKEN PLACEHOLDER"] || "User Token";
                $('#token').attr('placeholder', token_placeholder);
                var container_placeholder = SETTINGS["CONTAINER PLACEHOLDER"] || "Container";
                $('#container').attr('placeholder', container_placeholder)

255 256 257 258 259
                var lang_code = '';
                for (key in LANG) {
                    var lang = LANG[key];
                    var checked = ''
                    if (key === cur_lang) checked = 'checked'
260 261 262
                    lang_code += '<div class="lang">'
                        + '<input type="radio" name="language" '
                        + 'id="button_' + key+ '" value="' + key + '" '
263 264
                        + checked
                        + ' onclick="cur_lang=\'' + key + '\'; localize();">'
265 266
                        + '<label for="button_' + key + '">' + lang.name
                        + ' <img src="' + lang.icon + '"/></label></input></div>';
267 268 269 270
                }
                document.getElementById('language_space').innerHTML = lang_code;
            }

271 272 273
            window.setInterval(function() {
                // Refresh get_creds visibility, until refresh_endpoints
                // changes are in effect
274 275
                if (get_pithos_ui() && show_creds) creds_on();
                else creds_off();
276 277 278
                check_cloud_url();
                check_token();
            }, 500);
279 280 281
        </script>
    </head>
    <body>
282
        <div class="wrapper">
283
            <header>
284
                <h2><img src="static/images/about.png"/> <span id="title">User Settings</span></h2>
285 286
            </header>
            <form>
287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305
                <fieldset>
                    <legend id="appearance_label">Appearance</legend>
                    <div class="clearfix">
                        <div class="small-3 columns">
                            <label id="language_label" for="language_space" class="right inline">Language</label>
                        </div>
                        <div class="small-9 columns" id="language_space">
                        <!-- This will be filled by scripts -->
                        </div>
                    </div>
                    <div class="clearfix">
                        <div class="small-3 columns">
                            <label id="start_sync_label" for="start_sync" class="right inline">Sync on start up</label>
                        </div>
                        <div class="small-9 columns" id="start_sync">
                            <input type="checkbox" name="start_sync_box" id="start_sync_box" onchange="check_start_sync();"/>
                        </div>
                    </div>
                </fieldset>
306
                <fieldset>
307
                    <legend id="cloud_label">Cloud</legend>
308
                    <div id="explain_cloud" class="row clearfix explain"> &nbsp; </div>
309
                    <div class="clearfix">
310
                        <div class="small-3 columns">
311
                            <label id="url_label" for="cloud-url" class="right inline">Cloud URL</label>
312
                        </div>
313
                        <div class="small-9 columns" id="cloud-error">
314
                            <input type="text" id="cloud-url" placeholder="Authentication URL"
315 316
                            onchange="
                            var identity_url = $(this).val().replace(/\/+$/, '');
317 318
                            settings['url'] = identity_url;
                            refresh_endpoints(identity_url);
319
                            check_cloud_url();">
320 321
                            <small>Invalid entry</small>
                        </div>
322 323
                    </div>

324 325
                    <div class="clearfix">
                        <div class="small-3 columns">
326
                            <label id="token_label" for="token" class="right inline">User token</label>
327
                        </div>
328
                        <div class="small-9 columns" id="token-error">
329
                            <input type="text" id="token" placeholder="User token"
330
                            onchange="settings['token'] = $(this).val(); check_token();">
331 332 333 334 335
                            <small>Invalid entry</small>
                        </div>
                     </div>

                    <div class="clearfix">
336
                        <div class="small-9 columns"></div>
337
                       <a id="get_creds"
338
                            class="small-3 columns button right off"
339
                            onclick="get_credentials();">Login to retrieve token</a>
340
                    </div>
341

342 343
                </fieldset>
                <fieldset>
344
                    <legend id="sync_label">What to sync</legend>
345
                    <div id="explain_sync" class="row clearfix explain"> &nbsp; </div>
346 347
                    <div class="row clearfix">
                        <div class="small-3 columns">
348
                            <label id="container_label" for="container" class="right inline">Remote container</label>
349
                        </div>
350
                        <div class="small-9 columns" id="container-error">
351
                            <input type="text" id="container" placeholder="Pithos+ container"
352
                            onchange="settings['container']=$(this).val(); check_container();">
353
                            <small>Invalid entry</small>
354 355
                        </div>
                    </div>
356
                    <div class="row clearfix">
357
                        <div class="small-3 columns">
358
                            <label id="directory_label" for="directory" class="right">
359
                            Local directory</label>
360
                        </div>
361
                        <div id="directory" class="small-6 columns"></div>
362
                        <div id="dirdialogue_label" onclick="$('#choose-dir').trigger('click');"
363
                            class="small-3 columns pickdir" id="dirpick">
364 365 366 367 368 369
                            Select</div>
                    </div>
                    <div class="row clearfix">
                        <div id="directory-error" class="small-6 columns">
                            <small>Invalid entry</small>
                        </div>
370
                    </div>
371 372

                    <input type="file" id="choose-dir" nwdirectory
373
                        style="display:none;"
374
                        onchange="$('#directory').html($(this).val());
375 376
                            settings['directory'] = $(this).val();
                            check_directory();" />
377 378 379
                </fieldset>
                <div class="clearfix">
                    <a id="sync_button" class="button right"
380 381 382 383 384 385 386
                        onclick="if(check_fields() || confirm(
                                'There are some concerns about your settings.\n'
                                + 'To fix the errors: Cancel\n'
                                + 'To save anyway: OK')) {
                            export_settings(settings);
                            window.close();
                        }">Save</a>
387 388 389
                </div>
            </form>
        </div>
390
        <script type="text/javascript">
391
            localize();
392
        </script>
393 394
    </body>
</html>