Skip to content

Commit

Permalink
Merge branch 'dev'
Browse files Browse the repository at this point in the history
  • Loading branch information
Lionel Laské committed Oct 11, 2020
2 parents 6319475 + aa9b3d2 commit 28bdf4c
Show file tree
Hide file tree
Showing 90 changed files with 8,137 additions and 5,970 deletions.
4 changes: 3 additions & 1 deletion .eslintignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ dashboard/public/js/bootstrap-tour.min.js
dashboard/public/js/bootstrap.min.js
dashboard/public/js/Chart.min.js
dashboard/public/js/jquery-3.1.0.min.js
dashboard/public/js/jquery-sortable.js
dashboard/public/js/jquery-ui-1-11-4.js
dashboard/public/js/jquery.ui.sortable-animation.js
dashboard/public/js/jquery.multi-select.js
dashboard/public/js/jquery.searchable.js
dashboard/public/js/l10n.js
Expand All @@ -13,6 +13,8 @@ dashboard/public/js/material.min.js
dashboard/public/js/moment.min.js
dashboard/public/js/noty.js
dashboard/public/js/pace.min.js
dashboard/public/js/qrcodegen.js
dashboard/public/js/FileSaver.js
dashboard/public/js/select2.min.js

docs/
Expand Down
5 changes: 4 additions & 1 deletion .eslintrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,10 @@
"url": "writable",
"headers": "writable",
"icon": "readonly",
"Chart": "readonly"
"Chart": "readonly",
"QRCode": "readonly",
"saveAs": "readonly",
"Uint8Array": "readonly"
}
},
{
Expand Down
35 changes: 35 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,41 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).

## [1.3.0] - 2020-10-11
### Added
- Provide a way to remove multiple users at the same time #217
- Allow teachers to connect to Sugarizer client #222
- Add a download icon in Dashboard Journal view #220
- Show the right icon in Dashboard for TXT/ODT/DOC/PDF #226
- Allow opening PDF content in dashboard #227
- Add an upload button in Dashboard Journal view #221
- Added tutorial for User Edit and Profile view
- Added title to charts in statistics view
- Add multiple actions to Journal and Users view #245
- Added All Classrooms option in Users View
- Added multi-delete in classroom view
- Documentation to deploy on GCP with ansible #256
- Allow signup function to validate if name exist
- Replicaset parameter for MongoDB

### Changed
- Change edit classroom screen to handle large number of students
- Replace deprecated node library request by superagent #254

### Fixed
- Package vulnerability fix
- Fixed button position in Users View
- Server crash when dashboard call with several thousand of entries #208
- Classroom name could be null or could already exist
- Shared journal content is incorrect in dashboard #219
- Activity list doesn't scroll while reordering, causes multiple server calls. #235
- Overflow on opening any dropbox #238
- Selected option's text isn't localized #240
- Page navigation problem on language switching #142
- Popup is not displayed when Add/Edit/Delete a Chart
- Fix tutorial restart on views


## [1.2.0] - 2019-12-01
### Added
- Teacher profile
Expand Down
8 changes: 4 additions & 4 deletions Gruntfile.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,9 @@ module.exports = function(grunt) {
'* Copyright (c) <%= grunt.template.today("yyyy") %> <%= pkg.author %>;' +
' Licensed <%= pkg.license %> */\n',
// Task configuration.
uglify: {
terser: {
options: {
banner: '<%= banner %>'
keep_fnames: true
},
dynamic_mappings: {
expand: true,
Expand Down Expand Up @@ -47,11 +47,11 @@ module.exports = function(grunt) {
});

// These plugins provide necessary tasks.
grunt.loadNpmTasks('grunt-contrib-uglify');
grunt.loadNpmTasks('grunt-terser');
grunt.loadNpmTasks('grunt-contrib-imagemin');
grunt.loadNpmTasks('grunt-contrib-cssmin');

// Default task.
grunt.registerTask('default', ['uglify', 'imagemin', 'cssmin']);
grunt.registerTask('default', ['terser', 'imagemin', 'cssmin']);

};
393 changes: 202 additions & 191 deletions LICENSE

Large diffs are not rendered by default.

13 changes: 13 additions & 0 deletions NOTICE
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
Copyright 2014 Lionel Laské

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
61 changes: 32 additions & 29 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

[Sugarizer](https://github.com/llaske/sugarizer) is the open source learning platform based on Sugar that began in the famous One Laptop Per Child project.

Sugarizer Server allow deployment of Sugarizer on a local server, for example on a school server, so expose locally Sugarizer as a Web Application. Sugarizer Server can also be used to provide collaboration features for Sugarizer Application on the network. Sugarizer Server could be deployed in a Docker container or on any computer with Node.js 6+ and MongoDB 2.6+.
Sugarizer Server allows the deployment of Sugarizer on a local server, for example on a school server, so expose locally Sugarizer as a Web Application. Sugarizer Server can also be used to provide collaboration features for Sugarizer Application on the network. Sugarizer Server could be deployed in a Docker container or on any computer with Node.js 6+ and MongoDB 2.6+.


## Running Sugarizer Server
Expand Down Expand Up @@ -59,6 +59,7 @@ Following is the typical content of Sugarizer Server settings file:
port = 27018
name = sugarizer
waitdb = 1
replicaset = false

[collections]
users = users
Expand All @@ -81,27 +82,27 @@ Following is the typical content of Sugarizer Server settings file:

The **[information]** section is for describing your server. It could be useful for clients connected to the server.

The **[web]** section describe the settings of the node.js process. By default, the web server is on the port 8080.
The **[web]** section describes the settings of the node.js process. By default, the web server is on the port 8080.

The **[security]** section regroup security settings. `min_password_size` is the minimum number of characters for the password. `max_age` is the expiration time in milliseconds of a session with the client. At the expiration of the session, the client should reenter its password. Default time is 172800000 (48 hours). Parameters `https`, `certificate_file`, `key_file` and `strict_ssl` are explain above.
It `no_signup_mode` is true, account creation is allowed only by an administrator or a teacher (no direct sign-up allowed by a student).

The **[client]** indicate the place where is located Sugarizer Client. Sugarizer Client is need by the server.

The **[presence]** section describe the settings of the presence server. By default, a web socket is created on port 8039. You need to change this value if you want to use another port.
The **[presence]** section describes the settings of the presence server. By default, a web socket is created on port 8039. You need to change this value if you want to use another port.

The **[database]** and **[collections]** sections are for MongoDB settings. You could update the server name (by default MongoDB run locally) and the server port. Names of the database and collections had no reason to be changed. The `waitdb` parameter allow you to force server to wait for the database.
The **[database]** and **[collections]** sections are for MongoDB settings. You could update the server name (by default MongoDB run locally) and the server port. Names of the database and collections had no reason to be changed. The `waitdb` parameter allow you to force server to wait for the database. Optionally, the `replicaset` parameter can be set to `true` to enable MongoDB Replicaset support, in this case the server name becomes the replicaset connection string.

The **[statistics]** section indicate if the server will log client usage.

The **[log]** section indicate how the server log access. If `level` value is greater than 0 or is not present, Sugarizer Server will log all access to the server on the command line.

The **[activities]** section describe information on where to find embedded activities. The favorites value list ids of activities that Web Application users will find by default on the home page. All values are self explained and had no reason to be changed.
The **[activities]** section describes information on where to find embedded activities. The favorites value list ids of activities that Web Application users will find by default on the home page. All values are self explained and had no reason to be changed.


## Dashboard

Sugarizer Server Dashboard is an admin tool for teachers and deployment administrator. This dashboard can be used to control and manage the work of learners and manage and analyze all activities on a Sugarizer Server. The Dashboard have following features:
Sugarizer Server Dashboard is an admin tool for teachers and deployment administrator. This dashboard can be used to control and manage the work of learners and manage and analyze all activities on a Sugarizer Server. The Dashboard has following features:

* Users: how many users have been registered on the server, recent users, top users on the server, create/edit/remove a user.
* Journal: how many Journals and how many entries in Journal on the server, last Journal, and last entries, edit a journal (see/update/remove) entries.
Expand All @@ -113,15 +114,15 @@ To login to the Dashboard the first time, you will have to create an admin accou

sh add-admin.sh admin password http://127.0.0.1:8080/auth/signup

Note: For security reason, the script should be launched from the local machine. On Docker, attach a new shell to the container and launch the script from this shell - in that case the port to use should be 80, not 8080.
Note: For security reasons, the script should be launched from the local machine. On Docker, attach a new shell to the container and launch the script from this shell - in that case the port to use should be 80, not 8080.

Where **admin** is the login for the new admin account and **password** is the password.

Once the admin account is created, you could access Sugarizer Dashboard on http://127.0.0.1:8080/dashboard.

## Server API

To implement the above functionalities, the sugarizer backend expose an API. The API routes look as follows:
To implement the above functionalities, the sugarizer backend exposes an API. The API routes look as follows:


#### INFORMATION ROUTE
Expand Down Expand Up @@ -207,43 +208,45 @@ To generate docs, run the following command in `terminal`.
apidoc -i api/controller -i dashboard/helper -o docs/www/


## Import users from a CSV file
## Import/Delete users using a CSV file

Sugarizer Server comes with a script to import a set of students, administrators and classrooms from a CSV file.
Sugarizer Server comes with a script to import/delete a set of students, teachers, administrators and classrooms from a CSV file.

To launch it, run the command line:

cd sugarizer-server
export NODE_ENV=settings
node scripts/seed_users.js filename.csv

Where `settings` is the name of the .ini file to use for settings (default is `sugarizer`). `filename.csv` is the CSV who contains items to create. Here's an example of CSV file:
Where `settings` is the name of the .ini file to use for settings (default is `sugarizer`). `filename.csv` is the CSV who contains items to create/delete. Here's an example of CSV file:

name,type,language,color,password,classroom
Lionel,admin,fr,"{""stroke"":""#F8E800"",""fill"":""#FF8F00""}",aaaa,
Nikhil,student,,,,CM2
name,type,language,stroke,fill,password,classroom
Lionel,admin,fr,#BCCDFF,#FF8F00,aaaa,
Nikhil,student,,,,,CM2

Note that the header line is needed.

The signification of each field is:

* `name` is the name of the account to create.
* `type` is the type of account. Should be `student` or `admin`.
* `type` is the type of account. Should be `student`, `teacher`, `admin` or `delete`. If the type of set to `delete`, the user with that `name` will be deleted.
* `language` is the language for the account. If missing, the default is `en`.
* `color` is the color for the account. If missing, it's generated randomly.
* `stroke` is the stroke color for the account. If missing, it's generated randomly.
* `fill` is the fill color for the account. If missing, it's generated randomly.
* `password` is the password for the account. If missing, it's generated randomly.
* `classroom` is the classroom for the student. If a classroom with this name exist, the student is add to the classroom. If a classroom don't exist, the classroom is created first. If missing, the student is let without classroom.
* `classroom` is the classroom for the student. If a classroom with this name exists, the student is added to the classroom. If a classroom doesn't exist, the classroom is created first. If missing, the student is let without classroom.

At the end of the script a new CSV file named `output.csv` is generated. The output file has the same format than the input field with two more fields:
At the end of the script, a new CSV file named `output.csv` is generated. The output file has the same format than the input field with three more fields:

* `status` is 1 if item created, 0 if an error happened.
* `status` is 1 if item created, 2 if item deleted, 0 if an error happened.
* `comment` is the detail of action done.
* `_id` is the ObjectId of the created account.

Here's an example of output file:

name,type,language,color,password,classroom,status,comment
Lionel,admin,fr,"{""stroke"":""#F8E800"",""fill"":""#FF8F00""}",aaaa,,1,
Nikhil,student,en,"{""stroke"":""#807500"",""fill"":""#FF8F00""}",l0dU,CM2,1,Given password was invalid (Generated random password).
status,comment,_id,name,type,language,stroke,fill,password,classroom
1,,5d30162ced7ee117b842ad4a,Lionel,admin,fr,#BCCDFF,#FF8F00,aaaa,
1,Given password was invalid (Generated random password).,5d30162ced7ee117b842ad57,Nikhil,student,en,#D1A3FF,#AC32FF,l0dU,CM2

Note: For security reason, the script should be launched from the local machine. On Docker, attach a new shell to the container and launch the script from this shell - in that case the port to use should be 80, not 8080.

Expand All @@ -255,7 +258,7 @@ Few parameters in the **[security]** section of the setting file are dedicated t

* To run the server securely set `https` parameter to `true`.
* `certificate_file` and `key_file` are path to certificate and key file to sign requests.
* `strict_ssl` should be set to `false` if your certificate is a self signed certificate or is a certificate not signed by a trusted authority.
* `strict_ssl` should be set to `false` if your certificate is a self-signed certificate or is a certificate not signed by a trusted authority.


## Unit testing
Expand All @@ -271,27 +274,27 @@ Note that settings for unit testing are defined in [env/test.ini](env/test.ini).

# Optimize performance

If you want to optimize JavaScript performance, you could generate an optimized version of Sugarizer and Sugarizer-Server with [Grunt](http://gruntjs.com). This optimized version will minimize and reduce size of the public resources.
If you want to optimize JavaScript performance, you could generate an optimized version of Sugarizer and Sugarizer-Server with [Grunt](http://gruntjs.com). This optimized version will minimize and reduce the size of the public resources.

First ensure than Node.js and npm is installed on your machine. See [here](http://nodejs.org/) for more information.
First, ensure that Node.js and npm are installed on your machine. See [here](http://nodejs.org/) for more information.

The Gruntfile.js contains tasks settings to build an optimized version of Sugarizer and Sugarizer-Server. To do that, ensure first that Grunt is installed:
The Gruntfile.js contains task settings to build an optimized version of Sugarizer and Sugarizer-Server. To do that, ensure first that Grunt is installed:

npm install -g grunt-cli

Then navigate to Sugarizer directory install specific component for Sugarizer by running:
Then navigate to Sugarizer directory install the specific component for Sugarizer by running:

npm install

Then launch Grunt task to minify Sugarizer JavaScript files:

grunt -v

After minification, the `build` directory will contain the optimized version of each file in a same directory that the initial one, so you could just copy files:
After minification, the `build` directory will contain the optimized version of each file in the same directory as the initial one, so you could just copy files:

cp -r build/* .

Then navigate to Sugarizer-Server directory install specific component for Sugarizer-Server by running:
Then navigate to Sugarizer-Server directory install the specific component for Sugarizer-Server by running:

npm install

Expand Down
44 changes: 44 additions & 0 deletions ansible/deploy-to-gcp/create-gce-instance.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
# creates the vm instance

- hosts: localhost
tasks:
- name: Creating Disk for VM instance
gcp_compute_disk:
name: sugarizer-disk
size_gb: "{{ disk_size_gb }}"
source_image: "{{ image }}"
zone: "{{ zone }}"
project: "{{ project_id }}"
auth_kind: serviceaccount
service_account_file: "{{ credentials_file }}"
state: present
register: disk

- include_vars:
file: gcp-start-script.yml

- name: Creating GCP VM instance
gcp_compute_instance:
name: "{{ instance_names }}"
zone: "{{ zone }}"
machine_type: "{{ machine_type }}"
disks:
- auto_delete: 'true'
boot: 'true'
source: "{{ disk }}"
network_interfaces:
- network: null
access_configs:
- name: External NAT
type: ONE_TO_ONE_NAT
state: present
metadata:
startup-script: "{{ script }}"
auth_kind: serviceaccount
service_account_file: "{{ credentials_file }}"
project: "{{ project_id }}"
register: gce

- name: Getting External IPs of hosts
debug:
msg: "ExternalIP = {{ gce.networkInterfaces[0].accessConfigs[0].natIP }}"
15 changes: 15 additions & 0 deletions ansible/deploy-to-gcp/create-gcp-firewall.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# creates the firewall rule

- name: create a firewall
hosts: localhost
tasks:
- gcp_compute_firewall:
name: firewall-role
allowed:
- ip_protocol: tcp
project: "{{ project_id }}"
priority: "65534"
direction: "INGRESS"
auth_kind: serviceaccount
service_account_file: "{{ credentials_file }}"
state: present
11 changes: 11 additions & 0 deletions ansible/deploy-to-gcp/gcp-start-script.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
script: 'apt update;
apt install -y git;
git clone https://github.com/llaske/sugarizer;
git clone https://github.com/llaske/sugarizer-server;
curl -fsSL https://get.docker.com/ | sh;
curl -L "https://github.com/docker/compose/releases/download/1.8.1/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose;
chmod +x /usr/local/bin/docker-compose;
cd sugarizer-server;
sh generate-docker-compose.sh;
sleep 30s;
docker-compose up -d'
16 changes: 16 additions & 0 deletions ansible/deploy-to-gcp/get-package.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
USER=ksraj123
BRANCH=patch-1

REPO=sugarizer-server
RELPATH=./ansible/deploy-to-gcp

sudo apt-get update
sudo apt-get install -y subversion
svn export https://github.com/$USER/$REPO/branches/$BRANCH/$RELPATH

# Installing Ansible and other dependencies throug pip
curl https://bootstrap.pypa.io/get-pip.py -o get-pip.py
python get-pip.py --user
pip install --user ansible
pip install requests google-auth
rm get-pip.py
16 changes: 16 additions & 0 deletions ansible/deploy-to-gcp/host_vars/localhost.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# Enter name of service account key file
credentials_file:

# Enter Project id
project_id:

# Modify project zone
zone: "us-central1-a"

# Modify name of the instance
instance_names: "sugarizer-server"


machine_type: "n1-standard-1"
disk_size_gb: 20
image: "projects/debian-cloud/global/images/family/debian-9"
4 changes: 4 additions & 0 deletions ansible/deploy-to-gcp/site.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# master playbook

- import_playbook: create-gcp-firewall.yml
- import_playbook: create-gce-instance.yml
Loading

0 comments on commit 28bdf4c

Please sign in to comment.