1
0
mirror of https://github.com/LaCasemate/fab-manager.git synced 2025-01-17 06:52:27 +01:00

Merge branch '2-0-rc1' into tests

This commit is contained in:
Sylvain 2016-04-13 14:03:28 +02:00
commit eb2bc54cec
15 changed files with 173 additions and 131 deletions

View File

@ -1,4 +1,4 @@
FROM ruby:2.2
FROM ruby:2.3
MAINTAINER peng@sleede.com
# cf: nginx Dockerfile : https://github.com/nginxinc/docker-nginx
@ -23,7 +23,7 @@ RUN bundle config --global frozen 1
WORKDIR /tmp
COPY Gemfile /tmp/
COPY Gemfile.lock /tmp/
RUN bundle install
RUN bundle install --binstubs
# Clean up APT when done.
#RUN apt-get clean && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*

View File

@ -6,26 +6,27 @@ FabManager is the FabLab management solution. It is web-based, open-source and t
##### Table of Contents
1. [Software stack](#software-stack)
2. [Contributing](#contributing)
3. [Setup a development environment](#setup-a-development-environment)<br/>
3.1. [General Guidelines](#general-guidelines)<br/>
3.2. [Environment Configuration](#environment-configuration)
4. [PostgreSQL](#postgresql)<br/>
4.1. [Install PostgreSQL 9.4 on Ubuntu/Debian](#postgresql-on-debian)<br/>
4.2. [Install and launch PostgreSQL on MacOS X](#postgresql-on-macosx)<br/>
4.3. [Setup the FabManager database in PostgreSQL](#setup-fabmanager-in-postgresql)
5. [ElasticSearch](#elasticsearch)<br/>
5.1. [Install ElasticSearch on Ubuntu/Debian](#elasticsearch-on-debian)<br/>
5.2. [Install ElasticSearch on MacOS X](#elasticsearch-on-macosx)<br/>
5.3. [Setup ElasticSearch for the FabManager](#setup-fabmanager-in-elasticsearch)
6. [Internationalization (i18n)](#i18n)<br/>
6.1. [Translation](#i18n-translation)<br/>
6.1.1. [Front-end translations](#i18n-translation-front)<br/>
6.1.2. [Back-end translations](#i18n-translation-back)<br/>
6.2. [Configuration](#i18n-configuration)<br/>
6.2.1. [Settings](#i18n-settings)<br/>
6.2.2. [Applying changes](#i18n-apply)
7. [Known issues](#known-issues)
8. [Related Documentation](#related-documentation)
3. [Setup a production environment with Docker and CoreOS](#setup-a-production-environment)<br/>
4. [Setup a development environment](#setup-a-development-environment)<br/>
4.1. [General Guidelines](#general-guidelines)<br/>
4.2. [Environment Configuration](#environment-configuration)
5. [PostgreSQL](#postgresql)<br/>
5.1. [Install PostgreSQL 9.4 on Ubuntu/Debian](#postgresql-on-debian)<br/>
5.2. [Install and launch PostgreSQL on MacOS X](#postgresql-on-macosx)<br/>
5.3. [Setup the FabManager database in PostgreSQL](#setup-fabmanager-in-postgresql)
6. [ElasticSearch](#elasticsearch)<br/>
6.1. [Install ElasticSearch on Ubuntu/Debian](#elasticsearch-on-debian)<br/>
6.2. [Install ElasticSearch on MacOS X](#elasticsearch-on-macosx)<br/>
6.3. [Setup ElasticSearch for the FabManager](#setup-fabmanager-in-elasticsearch)
7. [Internationalization (i18n)](#i18n)<br/>
7.1. [Translation](#i18n-translation)<br/>
7.1.1. [Front-end translations](#i18n-translation-front)<br/>
7.1.2. [Back-end translations](#i18n-translation-back)<br/>
7.2. [Configuration](#i18n-configuration)<br/>
7.2.1. [Settings](#i18n-settings)<br/>
7.2.2. [Applying changes](#i18n-apply)
8. [Known issues](#known-issues)
9. [Related Documentation](#related-documentation)
@ -49,6 +50,11 @@ Contributions are welcome. Please read [the contribution guidelines](CONTRIBUTIN
**IMPORTANT**: **do not** update Arshaw/fullCalendar.js as it contains a hack for the remove-event cross.
<a name="setup-a-production-environment"></a>
## Setup a production environment with Docker and CoreOS
[Docker Readme](docker/README.md)
<a name="setup-a-development-environment"></a>
## Setup a development environment
@ -561,7 +567,7 @@ After modifying any values concerning the localisation, restart the application
<a name="related-documentation"></a>
## Related Documentation
- [Ruby 2.2.3](http://ruby-doc.org/core-2.2.3/)
- [Ruby 2.3.0](http://ruby-doc.org/core-2.3.0/)
- [Ruby on Rails](http://api.rubyonrails.org)
- [AngularJS](https://docs.angularjs.org/api)
- [Angular-Bootstrap](http://angular-ui.github.io/bootstrap/)

View File

@ -172,7 +172,7 @@ Application.Controllers.controller "StatisticsController", ["$scope", "$state",
if sex == 'male'
return _t('man')
if sex == 'female'
return t('woman')
return _t('woman')

View File

@ -79,6 +79,8 @@ Application.Controllers.controller "EditProfileController", ["$scope", "$rootSco
$scope.selectGroup = ->
Member.update {id: $scope.user.id}, {user: {group_id: $scope.userGroup}}, (user) ->
$scope.user = user
$rootScope.currentUser = user
Auth._currentUser.group_id = user.group_id
$scope.group.change = false
growl.success(_t('your_group_has_been_successfully_changed'))
, (err) ->

View File

@ -1,7 +1,7 @@
'use strict'
Application.Controllers.controller "PlansIndexController", ["$scope", "$state", '$uibModal', 'Auth', 'dialogs', 'growl', 'plansPromise', 'groupsPromise', 'Subscription', 'Member', 'subscriptionExplicationsPromise', '_t'
, ($scope, $state, $uibModal, Auth, dialogs, growl, plansPromise, groupsPromise, Subscription, Member, subscriptionExplicationsPromise, _t) ->
Application.Controllers.controller "PlansIndexController", ["$scope", "$rootScope", "$state", '$uibModal', 'Auth', 'dialogs', 'growl', 'plansPromise', 'groupsPromise', 'Subscription', 'Member', 'subscriptionExplicationsPromise', '_t'
, ($scope, $rootScope, $state, $uibModal, Auth, dialogs, growl, plansPromise, groupsPromise, Subscription, Member, subscriptionExplicationsPromise, _t) ->
@ -11,10 +11,10 @@ Application.Controllers.controller "PlansIndexController", ["$scope", "$state",
$scope.groups = groupsPromise
## default : do not show the group changing form
$scope.changeGroup = false
## group ID of the current/selected user
$scope.userGroup = null
$scope.group =
change: false
id: null
## list of plans, classified by group
$scope.plansClassifiedByGroup = []
@ -45,8 +45,8 @@ Application.Controllers.controller "PlansIndexController", ["$scope", "$state",
$scope.updateMember = ->
$scope.selectedPlan = null
$scope.paidPlan = null
$scope.userGroup = $scope.ctrl.member.group_id
$scope.changeGroup = false
$scope.group.id = $scope.ctrl.member.group_id
$scope.group.change = false
@ -77,24 +77,25 @@ Application.Controllers.controller "PlansIndexController", ["$scope", "$state",
##
# Return the group object, identified by the ID set in $scope.userGroup
# Return the group object, identified by the ID set in $scope.group.id
##
$scope.getUserGroup = ->
for group in $scope.groups
if group.id == $scope.userGroup
if group.id == $scope.group.id
return group
##
# Change the group of the current/selected user to the one set in $scope.userGroup
# Change the group of the current/selected user to the one set in $scope.group.id
##
$scope.selectGroup = ->
Member.update {id: $scope.ctrl.member.id}, {user: {group_id: $scope.userGroup}}, (user) ->
Member.update {id: $scope.ctrl.member.id}, {user: {group_id: $scope.group.id}}, (user) ->
$scope.ctrl.member = user
$scope.changeGroup = false
$scope.group.change = false
if $scope.currentUser.role isnt 'admin'
$scope.currentUser = user
$rootScope.currentUser = user
Auth._currentUser.group_id = user.group_id
growl.success(_t('your_group_was_successfully_changed'))
else
growl.success(_t('the_user_s_group_was_successfully_changed'))
@ -112,7 +113,7 @@ Application.Controllers.controller "PlansIndexController", ["$scope", "$state",
# @return {string} 'male' or 'female'
##
$scope.getGender = (user) ->
if user.profile
if user and user.profile
if user.profile.gender == "true" then 'male' else 'female'
else 'other'
@ -128,7 +129,7 @@ Application.Controllers.controller "PlansIndexController", ["$scope", "$state",
if $scope.currentUser.role isnt 'admin'
$scope.ctrl.member = $scope.currentUser
$scope.paidPlan = $scope.currentUser.subscribed_plan
$scope.userGroup = $scope.currentUser.group_id
$scope.group.id = $scope.currentUser.group_id
else
Member.query {requested_attributes:'[subscription]'}, (members) ->
membersNoPlan = []

View File

@ -91,19 +91,19 @@
<h3 ng-show="currentUser.role === 'admin'" translate translate-values="{GENDER:getGender(currentUser)}" translate-interpolation="messageformat">{{ 'his_group' }}</h3>
</div>
<div class="widget-content no-bg auto wrapper">
<div ng-show="!changeGroup">
<div ng-show="!group.change">
<div class="well well-warning">
<strong>{{getUserGroup().name}}</strong>
</div>
<button class="btn btn-default m-t"
ng-click="changeGroup = !changeGroup"
ng-click="group.change = !group.change"
ng-show="(!selectedPlan && ctrl.member && !ctrl.member.subscribed_plan && ctrl.member.subscription) || (!paidPlan)"
translate
translate-values="{ROLE:currentUser.role}"
translate-interpolation="messageformat">{{ 'he_wants_to_change_group' }}</button>
</div>
<div ng-show="changeGroup">
<select class="form-control" ng-options="g.id as g.name for g in groups" ng-model="userGroup"></select>
<div ng-show="group.change">
<select class="form-control" ng-options="g.id as g.name for g in groups" ng-model="group.id"></select>
<button class="btn btn-success m-t"
ng-click="selectGroup()"
translate

View File

@ -5,6 +5,10 @@ class AuthProvider < ActiveRecord::Base
def providable_type
DatabaseProvider.name
end
def name
'DatabaseProvider::SimpleAuthProvider'
end
end
PROVIDABLE_TYPES = %w(DatabaseProvider OAuth2Provider)
@ -39,6 +43,9 @@ class AuthProvider < ActiveRecord::Base
## Get the provider matching the omniAuth strategy name
def self.from_strategy_name(strategy_name)
if strategy_name.blank? or all.empty?
return SimpleAuthProvider.new
end
parsed = /^([^-]+)-(.+)$/.match(strategy_name)
ret = nil
all.each do |strategy|

View File

@ -13,8 +13,7 @@ class Event < ActiveRecord::Base
attr_accessor :recurrence, :recurrence_end_at
after_create :event_recurrence
before_save :set_nb_free_places
before_update :update_nb_free_places, if: :nb_total_places_changed?
before_save :update_nb_free_places
def name
title
@ -33,6 +32,10 @@ class Event < ActiveRecord::Base
end
end
def reservations
Reservation.where(reservable: self)
end
private
def event_recurrence
if recurrence.present? and recurrence != 'none'
@ -79,14 +82,12 @@ class Event < ActiveRecord::Base
end
end
def set_nb_free_places
if nb_free_places.nil?
self.nb_free_places = nb_total_places
def update_nb_free_places
if nb_total_places.nil?
self.nb_free_places = nil
else
reserved_places = reservations.map{|r| r.nb_reserve_places + r.nb_reserve_reduced_places}.inject(0){|sum, t| sum + t }
self.nb_free_places = (nb_total_places - reserved_places)
end
end
def update_nb_free_places
diff = nb_total_places - nb_total_places_was
self.nb_free_places += diff
end
end

View File

@ -2,7 +2,7 @@ development:
adapter: postgresql
host: localhost
encoding: unicode
database: fablab_development
database: fabmanager_development
pool: 25
username: sleede
password: sleede
@ -14,7 +14,7 @@ test:
adapter: postgresql
host: localhost
encoding: unicode
database: fablab_test
database: fabmanager_test
pool: 25
username: sleede
password: sleede
@ -23,7 +23,7 @@ staging:
adapter: postgresql
host: localhost
encoding: unicode
database: fablab_development
database: fabmanager_development
pool: 25
username: sleede
password: sleede
@ -33,7 +33,7 @@ production:
adapter: postgresql
host: localhost
encoding: unicode
database: fablab_development
database: fabmanager_development
pool: 25
username: sleede
password: sleede

View File

@ -92,7 +92,9 @@ Rails.application.configure do
:address => Rails.application.secrets.smtp_address,
:port => Rails.application.secrets.smtp_port,
:user_name => Rails.application.secrets.smtp_user_name,
:password => Rails.application.secrets.smtp_password
:password => Rails.application.secrets.smtp_password,
:authentication => 'plain',
:enable_starttls_auto => true
}
# use :smtp for switch prod

View File

@ -1,14 +1,50 @@
# full procedure to put into production a fabmanager app with Docker
## Docker
This README tries to describe all steps to put a fabmanager app into production on a server, based on a solution using Docker and DigitalOcean.
In order to make all this stuff working, please use the same directories structure as described in this guide in your fabmanager app folder.
Docker is an application deployment software.
### docker/env
## PREPARE HOST COREOS
Install VPS WITH Version coreOS STABLE (Ex : on DigitalOcean)
Make a copy of the **env.example** and use it as a starting point.
List all the environment variables needed by your application.
### Creating Swap File in CoreOS
### docker/nginx_with_ssl.conf.example
* Use nginx.conf.example especially if you are not using **SSL**
* Replace **MAIN_DOMAIN** (example: fab-manager.com).
* Replace **URL_WITH_PROTOCOL_HTTPS** (example: https://www.fab-manager.com).
* Replace **ANOTHER_URL_1**, **ANOTHER_URL_2** (example: .fab-manager.fr)
## Things are getting serious, starting deployment process guys
### setup the server
Go to **DigitalOcean** and create a Droplet with operating system coreOS **stable**.
You need at least 2GB of addressable memory (RAM + swap) to install and use FabManager!.
Choose datacenter. Set hostname as your domain name.
### Buy domain name and link it with the droplet
1. Buy a domain name on OVH
2. Replace IP of the domain with droplet's IP (you can enable the flexible ip and use it)
3. **Do not** fuck up trying to access your domain name right away, DNS are not aware of the change yet so **WAIT** and be patient.
### Connect to the droplet via SSH
You can already connect to the server with this command: `ssh core@droplet-ip`. When DNS propagation will be done, you will be able to
connect to the server with `ssh core@your-domain-name`.
### Create SWAP file in coreOS
Firstly, switch to sudo and create swap file
```bash
sudo -i
touch /2GiB.swap
@ -18,7 +54,8 @@ chmod 600 /2GiB.swap
mkswap /2GiB.swap
```
Create file /etc/systemd/system/swap.service with
Create file **/etc/systemd/system/swap.service**, filling it with the lines:
```bash
[Unit]
Description=Turn on swap
@ -35,43 +72,44 @@ WantedBy=multi-user.target
```
Then add service and start:
```bash
systemctl enable /etc/systemd/system/swap.service
systemctl start swap
systemctl start swap
exit
```
## PREPARE FOLDERS AND ENV CONFIG ON HOST
### Setup folders and env file
```bash
mkdir -p /home/core/fabmanager/config
MOVE docker/env.example to /home/core/fabmanager/config/env
CUSTOM ENV
```
Copy the previously customized `env` file as `/home/core/fabmanager/config/env`.
```bash
mkdir -p /home/core/fabmanager/config/nginx
MOVE docker/nginx.conf.example to /home/core/fabmanager/config/nginx/fabmanager.conf
CUSTOM fabmanager.conf
```
IF SSL
mkdir -p /home/core/fabmanager/config/nginx/ssl
Move your crt and deprotected key
MOVE docker/nginx_with_ssl.conf.example to /home/core/fabmanager/config/nginx/fabmanager.conf
CUSTOM fabmanager.conf
Copy the previously customized `nginx.conf` as `/home/core/fabmanager/config/nginx/fabmanager.conf`.
## DEPLOY DOCKERS CONTAINERS ON HOST
### Deploy dockers containers on host
```bash
docker pull redis:3.0
docker pull postgres:9.4
docker pull elasticsearch:1.7
docker pull sleede/fabmanager
docker pull sleede/fab-manager
docker run --restart=always -d --name=fabmanager-postgres -v /home/core/fabmanager/postgresql:/var/lib/postgresql/data postgres:9.4
docker run --restart=always -d --name=fabmanager-redis -v /home/core/fabmanager/redis:/data redis:3.0
docker run --restart=always -d --name=fabmanager-elastic -v /home/core/fabmanager/elasticsearch:/usr/share/elasticsearch/data elasticsearch:1.7
```
### DB CREATE
### Rails specific commands
#### DB CREATE
```bash
docker run --rm \
@ -80,11 +118,11 @@ docker run --rm \
--link=fabmanager-elastic:elasticsearch \
-e RAILS_ENV=production \
--env-file /home/core/fabmanager/config/env \
sleede/fabmanager \
sleede/fab-manager \
bundle exec rake db:create
```
### DB MIGRATE
#### DB MIGRATE
```bash
docker run --rm \
@ -93,11 +131,11 @@ docker run --rm \
--link=fabmanager-elastic:elasticsearch \
-e RAILS_ENV=production \
--env-file /home/core/fabmanager/config/env \
sleede/fabmanager \
sleede/fab-manager \
bundle exec rake db:migrate
```
### DB SEED
#### DB SEED
```bash
docker run --rm \
@ -106,12 +144,12 @@ docker run --rm \
--link=fabmanager-elastic:elasticsearch \
-e RAILS_ENV=production \
--env-file /home/core/fabmanager/config/env \
sleede/fabmanager \
sleede/fab-manager \
bundle exec rake db:seed
```
### PREPARE ELASTIC
#### PREPARE ELASTIC
```bash
docker run --rm \
@ -121,27 +159,12 @@ docker run --rm \
--link=fabmanager-elastic:elasticsearch \
-e RAILS_ENV=production \
--env-file /home/core/fabmanager/config/env \
sleede/fabmanager \
sleede/fab-manager \
bundle exec rake fablab:es_build_stats
```
### recreate every versions of images
```bash
docker run --rm \
--link=fabmanager-postgres:postgres \
--link=fabmanager-redis:redis \
--link=fabmanager-elastic:elasticsearch \
-e RAILS_ENV=production \
--env-file /home/core/fabmanager/config/env \
-v /home/core/fabmanager/public/uploads:/usr/src/app/public/uploads \
sleede/fabmanager \
bundle exec rake fablab:build_images_versions
```
### BUILD ASSETS
#### BUILD ASSETS
```bash
docker run --rm \
@ -151,16 +174,12 @@ docker run --rm \
-e RAILS_ENV=production \
--env-file /home/core/fabmanager/config/env \
-v /home/core/fabmanager/public/assets:/usr/src/app/public/assets \
sleede/fabmanager \
sleede/fab-manager \
bundle exec rake assets:precompile
docker run --rm -v /home/core/fabmanager/public/assets:/usr/src/app/public/assets sleede/fabmanager cp vendor/assets/components/select2/select2.png public/assets/select2.png
docker run --rm -v /home/core/fabmanager/public/assets:/usr/src/app/public/assets sleede/fabmanager cp vendor/assets/components/select2/select2x2.png public/assets/select2x2.png
docker run --rm -v /home/core/fabmanager/public/assets:/usr/src/app/public/assets sleede/fabmanager cp vendor/assets/components/select2/select2-spinner.gif public/assets/select2-spinner.gif
```
### RUN APP
#### RUN APP
```bash
docker run --restart=always -d --name=fabmanager \
@ -177,19 +196,22 @@ docker run --restart=always -d --name=fabmanager \
-v /home/core/fabmanager/public/uploads:/usr/src/app/public/uploads \
-v /home/core/fabmanager/invoices:/usr/src/app/invoices \
-v /home/core/fabmanager/log:/var/log/supervisor \
sleede/fabmanager
sleede/fab-manager
```
### for debug
```bash
docker run --rm -it \
--link=fabmanager-postgres:postgres \
--link=fabmanager-redis:redis \
--link=fabmanager-elastic:elasticsearch \
-e RAILS_ENV=production \
--env-file /home/core/fabmanager/config/env \
sleede/fabmanager \
bash
```
### Dockers utils
#### Restart app
`docker restart fabmanager-app`
#### Remove app
`docker rm -f fabmanager-app`
#### Open a bash in the app context
`docker exec -it fabmanager-app bash`

View File

@ -6,7 +6,7 @@ SECRET_KEY_BASE=
STRIPE_API_KEY=
STRIPE_PUBLISHABLE_KEY=
STRIPE_CURRENCY=
STRIPE_CURRENCY=eur
INVOICE_PREFIX=Demo-FabLab-facture
FABLAB_WITHOUT_PLANS=false
@ -16,9 +16,9 @@ DEFAULT_HOST=demo.fab-manager.com
DEFAULT_PROTOCOL=http
DELIVERY_METHOD=smtp
SMTP_ADDRESS=smtp.sparkpostmail.com
SMTP_ADDRESS=smtp.mailgun.org
SMTP_PORT=587
SMTP_USER_NAME=SMTP_Injection
SMTP_USER_NAME=
SMTP_PASSWORD=
GA_ID=
@ -42,4 +42,5 @@ ELASTICSEARCH_LANGUAGE_ANALYZER=french
TIME_ZONE=Paris
WEEK_STARTING_DAY=monday
D3_DATE_FORMAT=%d/%m/%y
D3_DATE_FORMAT=%d/%m/%y
UIB_DATE_FORMAT=dd/MM/yyyy

View File

@ -4,7 +4,7 @@ upstream puma {
server {
listen 80;
server_name demo.fab-manager.com;
server_name MAIN_DOMAIN;
root /usr/src/app/public;
location ^~ /assets/ {

View File

@ -4,11 +4,11 @@ upstream puma {
server {
listen 443 ssl;
server_name demo.fab-manager.com;
server_name MAIN_DOMAIN;
root /usr/src/app/public;
ssl on;
ssl_certificate /etc/nginx/conf.d/ssl/fab-manager.crt;
ssl_certificate_key /etc/nginx/conf.d/ssl/fab-manager.deprotected.key;
ssl_certificate /etc/nginx/conf.d/ssl/MAIN_DOMAIN.crt;
ssl_certificate_key /etc/nginx/conf.d/ssl/MAIN_DOMAIN.deprotected.key;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers 'EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH';
ssl_prefer_server_ciphers on;
@ -58,6 +58,6 @@ server {
server {
listen 80;
server_name demo.fab-manager.com;
rewrite ^ https://demo.fab-manager.com$request_uri? permanent;
server_name MAIN_DOMAIN ANOTHER_DOMAIN_1 ANOTHER_DOMAIN_2;
rewrite ^ URL_WITH_PROTOCOL_HTTPS$request_uri? permanent;
}

View File

@ -5,7 +5,7 @@ file=/var/run/supervisor.sock ; path to your socket file
nodaemon=true ; dont run supervisord as a daemon
logfile=/var/log/supervisor/supervisord.log ; supervisord log file
logfile_maxbytes=10MB ; maximum size of logfile before rotation
logfile_backups=10 ; number of backed up logfiles
logfile_backups=100 ; number of backed up logfiles
loglevel=info ; info, debug, warn, trace
pidfile=/var/run/supervisord.pid ; pidfile location
user=root ; default user