Skip to content

Commit

Permalink
Split service space (#90)
Browse files Browse the repository at this point in the history
* Added engineering garage as a service space

* Added config for app and made sure things are using it

* Removed deploy.rb

* Added more config

* Fixed error

* Removed maker request from engineering garage and updated nav bar

* Removed HRC stuff from non innovation studio spaces

* Removed tours from non innovation studio spaces

* Remove export from non innovation studio spaces

* Remove training docs from non innovation studio spaces

* Moved emails to template files

* Use config values

* Removed old font references, added npm to compile less

* Updated innovation studio css to main css, added cache busting to config

* Moved email templates to sub-folder, updated templates

* Make sure users are in this service space

* Split items per service space

* Added service space to studio spaces, email presets, and event presets

* Fix email template paths

* Fix color of tool reservation calendar block

* Added conditional if captcha site key is empty

* Added new event types and added displays for training and workshops

* Updated alerts and my alerts

* Updated footers

* Added email templates for engineering garage

* Fixed no toolbar view and removed unused erb file

* Fix announcement notice

* default config

* Updated DB dump and readme

* Fix config stuff

* Fix more config stuff

* Remove duplicate double slash

* Make sure to check the user has an email before sending it

* Updated readme

* Added section for email testing

* remove stank from readme file

* Remove Stank

* Fixed sample files

* Added missing require statements in scripts

* Fix logic for setting dates on load

* Added attended orientation email

* Added logic for active/inactive users and prevent inactive users from doing things

* Moved active to it's own DB column

* Remove active check for things
  • Loading branch information
tommyneu authored Aug 19, 2024
1 parent fc9bdc6 commit 47a8ed6
Show file tree
Hide file tree
Showing 115 changed files with 2,177 additions and 812 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
/public/wdn
/db/scripts/private/
.idea
node_modules

## Service start up configs
.config
Expand Down
2 changes: 1 addition & 1 deletion Guardfile
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
less_options = {
all_on_start: true,
all_after_change: true,
patterns: ['Guardfile', 'src/less/innovation_studio.less'],
patterns: ['Guardfile', 'src/less/main.less'],
output: 'public/css',
compress: true
}
Expand Down
101 changes: 37 additions & 64 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ UNL reservation system for schedule resources, classes, etc.

1. Service spaces refer to different silos of the University that will utilize resources. E.g. the math department, the Honors program, or University Communication.
2. Super Admins of a space can do anything, including giving others access and privileges to the space.
3. Resources are created, and then may be reserved by anyone who has the User Access privilege in the space.
3. Resources are created, and then may be reserved by anyone who has the User Access privilege in the space.
4. Events *may* include a resource reservation but do not have to.
5. Admins with the right privilege can set the *hours* of the space, which indicate when reservations can be made.
6. The agenda is a quick overview of the day for Admins to look at.
Expand All @@ -18,21 +18,37 @@ UNL reservation system for schedule resources, classes, etc.
2. Now using RVM, install the ruby with `rvm install 2.6.5`.
3. You probably do not have the `bundler` gem. Check with `bundle`. If not, install it with `gem install bundler`.
4. In the project root, install the gems using `bundle install`.
5. Create a mysql database you'd like to use, you can typically use one on your computer. `brew install mysql` if necessary.
6. `config/config.json` is a committed file, and a template for the configuration. Create a copy in the same directoy named `server.json` and edit it to match your database. You will also need to include your site keys for google reCaptcha which can be generated at https://www.google.com/recaptcha/ for the V2 checkbox.
7. Your database is currently blank. Run any sql queries in `./data` to install database and the updates to it.
5. Create a mysql database you'd like to use, you can typically use one on your computer. `brew install mysql` if necessary.
6. `config/config.json` is a committed file, and a template for the configuration. Create a copy in the same directory named `server.json` and edit it to match your database. You will also need to include your site keys for google reCaptcha which can be generated at [https://www.google.com/recaptcha/](https://www.google.com/recaptcha/) for the V2 checkbox.
7. Your database is currently blank. Install database schema by running `./data/db_2024_08_01.sql` and any updates greater than `0006`.
8. Install the WDN Framework into the `public/wdn` directory...see [WDN Documentation](http://wdn.unl.edu/documentation).
9. Start the server by going to the root directory and doing `bundle exec shotgun -o 0.0.0.0 -p 9393`. This launches the server on localhost port 9393, listening everywhere (you can use your iimlemburg.unl.edu or whichever), and the server will automatically update to new code. If you add gems to the bundle, you will need to re-execute this command.
10. Navigate to `localhost:9393/` or similar and begin!
11. In another terminal, type `bundle exec guard` in the project root to execute LESS compilation.

### Less

I couldn't get Guard to work for me locally so I also added a npm version of less complication

The traditional way to compile less `bundle exec guard`

The NPM way to compile less

1. Run `npm ci` to install less
2. Run `npm run less` to compile less

### Local Email Testing

A quick way to test emails without having to set up email stuff is to run a SMTP debug server in python

`sudo python -m smtpd -n -c DebuggingServer localhost:25`

## Installation on server

1. Run `sudo -u {user} -s` run commands as a user and navigate to your project's root
2. Run `cp ./config/config.json ./config/server.json` to copy config file and customize it to your environment
3. Run `ln -s {path to WDN Templates} {path to project root}/public/wdn` to symlink WDN Templates to your project
4. Run `/bin/bundler install` to install dependencies
5. Install database schema running files in `./data`
5. Install database schema by running `./data/db_2024_08_01.sql` and any updates greater than `0006`
6. You will need to get a service running for unicorn using systemd
1. Run `cp ./startup.sh.sample ./startup.sh` and customize file for your domain and sock
2. Run `cp ./unicorn.rb.sample ./unicorn.rb` and customize file for your domain and sock
Expand All @@ -41,72 +57,29 @@ UNL reservation system for schedule resources, classes, etc.
7. Run `systemctl --user start unicorn` to start the service
8. Run `systemctl --user enable unicorn` to start the service on boot

## Deploying Updates on Staging

1. Run these commands to restart the unicorn server.

``` bash
cat innovationstudio-manager-test.pid
sudo -u innovationstudio-test kill -9 [replace with PID from first command]
sudo -u innovationstudio-test ./startup.sh
```

2. After restarting the unicorn server make sure that there are only two scheduler processes running. The scheduler processes handle sending out automated emails on a daily basis. There should be one for the staging environment and one for the production environment. If more than 2 processes are running then users will receive duplicate emails. Run the command below to check if multiple processes are running. You should only get 2 process IDs back.

``` bash
pgrep ruby
```
## Deploying Updates on Production/Staging

3. If you get more than 2 processes IDs then you need to check which users started each process. There should be one process started by the innovationstudio-test user(the staging user) and one process started by the innovationstudio user. You can check the user of a process with this command where pid is the process ID.
1. SSH into server and switch to site's user `sudo -u {USER} -s`
2. Run `git pull origin master` to pull latest changes
3. Update database using SQL files in `./data/updates`
4. Update any gems using `bundle install`
5. Restart unicorn `systemctl --user restart unicorn`
6. Double check service is running `systemctl --user status unicorn`
7. Check for errors `journalctl --user -u unicorn -f`

``` bash
ps -o user= -p pid
```
### Other helpful commands

4. Once you determine which processes are extra (if any) then kill them with this command.

``` bash
sudo -u innovationstudio kill -9 pid
```

## Deploying Updates on Production

1. Run these commands to restart the unicorn server.

``` bash
sudo -u innovationstudio -s -H
systemctl --user restart unicorn
```

2. If the production environment fails to start after executing those commands then an error must have occurred. You can view the error log with the following command. This command will print the last 50 lines of the error log:

``` bash
cat error.log | tail -n 50
```

3. If the error log happens to say that the unicorn server cannot start because the process already exists (even though the server is still down) you can run the following commands to determine the process ID and to kill the processe. After killing the existing process and trying to restart the server you should get a more helpful error message in the error log if the server still fails to start.
Use this command to find the process ID. The process you're looking for should have this in the command column:
``` bash
unicorn master -l /run/httpd-local/innovationstudio.sock -E production -c /var/www/html/innovationstudio-manager.unl.edu/unicorn.rb
```
``` bash
ps aux
```
Use this command to kill the process ID
``` bash
sudo -u innovationstudio kill -9 pid
```
- Starting unicorn `systemctl --user start unicorn`
- Stopping unicorn `systemctl --user stop unicorn`
- Start unicorn on boot `systemctl --user enable unicorn`
- Don't start unicorn on boot `systemctl --user disable unicorn`
- Check if unicorn is enabled `systemctl --user is-enabled unicorn`
- Update systemctl when changes made to service file `systemctl --user daemon-reload`

## CRON

``` text
0 12 * * * ruby ././scripts/email_expiring_users.rb
0 12 * * * ruby ././scripts/email_unconfirmed_trainers.rb
0 22 * * * ruby ././scripts/email_expiring_users_vehicle_update.rb
#@reboot /var/www/html/innovationstudio-manager.unl.edu/startup.sh
```
49 changes: 44 additions & 5 deletions app.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

use Rack::Session::Cookie, :key => 'rack.session',
:path => '/',
:domain => (ENV['RACK_ENV'] == 'development' ? nil : 'innovationstudio-manager.unl.edu'),
:domain => CONFIG['app']['cookie_domain'],
:secret => 'averymanteroldfatherbesseyhamilton',
:old_secret => 'averymanteroldfatherbesseyhamilton',
:expire_after => 30*24*60*60
Expand All @@ -22,12 +22,14 @@ def flash(type, header, message)
}
end

SS_ID = ServiceSpace.where(:name => 'Innovation Studio').first.id
SS_ID = ServiceSpace.where(:id => CONFIG['app']['service_space_id']).first.id

before do
# site defaults
@inline_body_script_content = ''
@title = 'Innovation Studio Manager'
@affiliation = 'Nebraska Innovation Campus'
@affiliation_link = 'https://innovate.unl.edu/'
CONFIG['app']['title'] = 'Innovation Studio Manager'
@breadcrumbs = [
{
:href => 'https://www.unl.edu/',
Expand All @@ -40,10 +42,32 @@ def flash(type, header, message)
},
{
:href => '/',
:text => 'Innovation Studio Manager'
:text => CONFIG['app']['title']
}
]

if SS_ID == 8
@inline_body_script_content = ''
@affiliation = 'College of Engineering'
@affiliation_link = 'https://engineering.unl.edu/'
CONFIG['app']['title'] = 'Engineering Garage'
@breadcrumbs = [
{
:href => 'https://www.unl.edu/',
:text => 'Nebraska',
:title => 'University of Nebraska–Lincoln Home'
},
{
:href => 'https://engineering.unl.edu/',
:text => 'College of Engineering'
},
{
:href => '/',
:text => CONFIG['app']['title']
}
]
end

session[:init] = true

# check if the user is currently logged in
Expand Down Expand Up @@ -77,6 +101,21 @@ def require_login(redirect_after_login=nil)
end
end

def require_active(redirect_to=nil)
if !@user.nil? && !@user.is_active && !@user.is_super_user?
if SS_ID == 1
flash(:alert, 'You Must Be An Active User', 'That page requires you to be an active user. To activate your account please visit Innovation Studio.')
elsif SS_ID == 8
flash(:alert, 'You Must Be An Active User', 'That page requires you to be an active user. To activate your account please visit the Engineering Garage.')
end
if redirect_to.nil?
redirect '/'
else
redirect redirect_to
end
end
end

def drupal_link_lookup(key)
# Leading and Trailing Slash IMPORTANT
nodes = {
Expand All @@ -103,7 +142,7 @@ def drupal_link_lookup(key)
end

get '/images/user/:user_id/?' do
user = User.find_by(:id => params[:user_id])
user = User.find_by(:id => params[:user_id], :service_space_id => SS_ID)
if user.nil? || user.imagedata.nil?
raise Sinatra::NotFound
end
Expand Down
17 changes: 10 additions & 7 deletions classes/emailer.rb
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ def self.mail(to, subject, body, bcc = "", attachments = nil)
:bcc => bcc_group,
:subject => subject,
:html_body => body,
:from => '[email protected]',
:from => CONFIG['app']['email_from'],
:via => self.method,
:via_options => self.method_options,
:attachments => attachments
Expand All @@ -40,7 +40,7 @@ def self.mail(to, subject, body, bcc = "", attachments = nil)
:bcc => bcc,
:subject => subject,
:html_body => body,
:from => '[email protected]',
:from => CONFIG['app']['email_from'],
:via => self.method,
:via_options => self.method_options,
:attachments => attachments
Expand Down Expand Up @@ -69,18 +69,21 @@ def self.breakup_recipient(recipient)

def self.method
if ENV['RACK_ENV'] == 'development'
:sendmail
# :smtp
if CONFIG['email']['via'] == ":smtp"
:smtp
else
:sendmail
end
else
:sendmail
end
end

def self.method_options
if ENV['RACK_ENV'] == 'development'
if ENV['RACK_ENV'] == 'development' && !CONFIG['email']['via_address'].empty?
{
:address => '127.0.0.1',
:port => '1025'
:address => CONFIG['email']['via_address'],
:port => CONFIG['email']['via_port']
}
else
{}
Expand Down
5 changes: 2 additions & 3 deletions config.ru
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,10 @@ require 'utils/database'
require 'sinatra'
require 'app'

if ENV['RACK_ENV'] == 'development'
# weird workaround for localhost cookie things
if CONFIG['app']['cookie_domain'].empty?
set :cookie_options, :domain => nil
else
set :cookie_options, :domain => 'innovationstudio-manager.unl.edu'
set :cookie_options, :domain => CONFIG['app']['cookie_domain']
end

# start scheduler on new thread so program doesn't hang waiting for it to finish
Expand Down
12 changes: 12 additions & 0 deletions config/config.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,17 @@
"reCaptcha" : {
"site_key" : "",
"secret_key" : ""
},
"app" : {
"service_space_id": "1",
"URL": "https://innovationstudio-manager.unl.edu/",
"cookie_domain": "innovationstudio-manager.unl.edu",
"email_from": "[email protected]",
"cb_version": "2024022701"
},
"email" : {
"via": ":smtp",
"via_address": "localhost",
"via_port": "25"
}
}
43 changes: 28 additions & 15 deletions data/db_2024_02_15.sql → data/db_2024_08_01.sql

Large diffs are not rendered by default.

21 changes: 21 additions & 0 deletions data/updates/0006_engineering_garage.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
INSERT INTO `service_spaces` (`id`, `name`, `url_name`, `imagedata`, `imagemime`) VALUES
(8, 'Engineering Garage', NULL, NULL, NULL);

ALTER TABLE `preset_events` ADD COLUMN `service_space_id` int(11) DEFAULT 1;
ALTER TABLE `preset_emails` ADD COLUMN `service_space_id` int(11) DEFAULT 1;
ALTER TABLE `studio_spaces` ADD COLUMN `service_space_id` int(11) DEFAULT 1;

INSERT INTO `studio_spaces` (`name`, `service_space_id`) VALUES
('Engineering Garage', 8);

INSERT INTO `event_types` (`id`, `description`, `service_space_id`) VALUES
(12, 'New Membership Orientation', 8);

INSERT INTO `event_types` (`id`, `description`, `service_space_id`) VALUES
(13, 'Machine Training', 8);

INSERT INTO `event_types` (`id`, `description`, `service_space_id`) VALUES
(14, 'General Workshop', 8);

ALTER TABLE `users` ADD COLUMN `active` tinyint(1) DEFAULT 0;
UPDATE `users` SET `active` = 1;
45 changes: 0 additions & 45 deletions deploy.rb

This file was deleted.

Loading

0 comments on commit 47a8ed6

Please sign in to comment.