Skip to content

Commit

Permalink
Merge pull request #12 from benjavicente/small-improvements
Browse files Browse the repository at this point in the history
Small improvements
  • Loading branch information
benjavicente authored Dec 24, 2020
2 parents 9a567a0 + b7ed4d5 commit a97cb45
Show file tree
Hide file tree
Showing 19 changed files with 327 additions and 370 deletions.
6 changes: 6 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -23,3 +23,9 @@ yarn-debug.log*

# Test files
.rspec

# Debug
.byebug*

# Other files
docs/*
134 changes: 111 additions & 23 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,33 @@
# UCalendar

Implementación en Rails de [uc-nrc-icalendar](https://github.com/benjavicente/uc-nrc-icalendar).
Implementación en Rails de [uc-nrc-icalendar][uc-nrc-icalendar].

## SetUp
Aplicación web que obtiene los cursos de [Busca Cursos][buscacursosuc]
y crea un calendario en formato [iCalendar][iCal] que luego puede ser
importado a Google Calendar.

[Deploy en Heroku][deploy-page]


## Uso

1. Seleccionar el semestre académico.
2. Ingresar los códigos del curso junto a su sección (`EJM1230-1`) o
el NRC de cada uno.
3. Descargar el calendario `ics` o copiar el `url` de descarga.
4. Agregar el calendario a la aplicación de calenadrio con el
acrhivo `ics` (en [google][gc-by-ics])
o con el `url` (en [google][gc-by-url]).


## Set-Up

Antes de crear la base de datos, crear un archivo`.env` con la clave
de postgres:

```env
POSTGRES_PASSWORD=
```

Para crear el entorno de desarrollo:

Expand All @@ -12,40 +37,103 @@ yarn install
rails db:setup
```

Crear un archivo `.env` con:
Para iniciar el servidor

```env
POSTGRES_PASSWORD=
```bash
sudo service postgresql start
rails s
```

## Administración

Para que se pueda obtener los cursos, primero se tiene que crear un
periodo en la base de datos. Para hacer esto se puede usar la página
de administración (`/admin`), y crear uno en la sección _Terms_.
### Administración

## Creación de calendarios
Para que se pueda obtener los cursos, tiene que existir un periodo
académico (_term_) en la base de datos. Tambíen, para que no se creen
eventos en feriados deben crearse estos feriados (_holidays_).

Estos se pueden crear con las _seeds_ o en el interfaz de
administración (`/admin`).

TODO

## Obtener los calendarios externamente

```js
`HOST/term/${year}/${period}/schedule.ics?cs[]=${course_section}&nrc[]=${nrc}`
HOST = 'https://ucalendar.herokuapp.com'
```

Donde `year` es el año, `period` el periodo (`1`, `2` o `tav`),
`course_section` es el curso con su sección (ej `MAT1610-1`) y
`nrc` el `nrc` del curso (ej `14778`).
### Directo

```js
`${HOST}/term/${year}/${period}/schedule.ics?cs[]=${cs}&nrc[]=${nrc}`
```

- `year`: año buscado, requerido
- `period`: periodo buscado, requerido
- `cs[]`: curso con su sección (ej `MAT1610-1`), opcional, acepta multiples valores
- `nrc[]`: ncr del curso, opcional, acepta multiples valores

Ejemplo:

```url
https://ucalendar.herokuapp.com/term/2021/1/schedule.ics?cs[]=MAT1640-1&cs[]=MAT1630-1
```

### Versíon corta

```js
`${HOST}?s.ics?year=${year}&period=${period}&cs=${course_section}&nrc=${nrc}`
```

Acepta los mismos parámetros de el `GET`, pero `year` y `period` son
opcionales, si no están presentes obtienen los datos de la el periodo
académico.

Además, acepta:

- `cs`: cursos coon su sección separados por comas
- `nrc`: nrc de los cursos separados por comas

Ejemplos (formato HTML):

```url
https://ucalendar.herokuapp.com/s.ics?cs=MAT1640-1,MAT1630-1
```

### Ver periodos

```js
`${HOST}/terms.json`
```

Obtiene una lista de los periodos académicos en formato `JSON`.


## GH Pages (Página estática)

Ya que se utiliza una vista con AJAX, esta puede ser compilada a
una [página estática]. Para esto se usa la rama `gh-pages`, que es
creada con la página con el comando `rake gh_pages:compile`.

Página en [github.io][gh-page].


## Links adicionales

## Links de interés
- Página con documentación de icalendar: [icalendar.org]
- Diagrama de la base de datos en: [dbdiagram.io]

- [Busca Cursos](http://buscacursos.uc.cl/)
- [dbdiagram.io database](https://dbdiagram.io/d/5fd964db9a6c525a03bb3aee)
- [Percent-encoding](https://en.wikipedia.org/wiki/Percent-encoding)

### Icalendar
<!-- Links -->

- [Icalendar.org](https://icalendar.org/)
- [icalendar recurrence](https://icalendar.org/iCalendar-RFC-5545/3-3-10-recurrence-rule.html)
- [icalendar ex-dates](https://icalendar.org/iCalendar-RFC-5545/3-8-5-1-exception-date-times.html)
[buscacursosuc]: http://buscacursos.uc.cl/
[uc-nrc-icalendar]: https://github.com/benjavicente/uc-nrc-icalendar
[ical]: https://es.wikipedia.org/wiki/ICalendar
[icalendar.org]: https://icalendar.org/
[dbdiagram.io]: https://dbdiagram.io/d/5fd964db9a6c525a03bb3aee
[página estática]: https://es.wikipedia.org/wiki/P%C3%A1gina_web_est%C3%A1tica
[gc-by-ics]: https://calendar.google.com/calendar/u/0/r/settings/export
"Importar en Google Calendar con archivo ICS"
[gc-by-url]: https://calendar.google.com/calendar/u/0/r/settings/addbyurl
"Importar en Google Calendar con URL del calendario"
[gh-page]: https://benjavicente.github.io/ucalendar/
[deploy-page]: https://ucalendar.herokuapp.com/
2 changes: 1 addition & 1 deletion app/admin/holidays.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# frozen_string_literal: true

ActiveAdmin.register Holiday do
permit_params :day, :name, :every_yeat
permit_params :day, :name, :every_year
end
1 change: 1 addition & 0 deletions app/assets/stylesheets/schedule.scss
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@
text-align: center;
select {
border: none;
background: none;
font-size: inherit;
font-weight: inherit;
}
Expand Down
3 changes: 3 additions & 0 deletions app/controllers/schedule_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,9 @@ def ics_format
calendar.add_event(event)
end
end
calendar.prodid = 'benjavicente/ucalendar'
calendar.append_custom_property('X-WR-CALNAME', I18n.t('schedule'))
calendar.append_custom_property('X-WR-TIMEZONE', 'America/Santiago')
calendar.to_ical
end

Expand Down
2 changes: 1 addition & 1 deletion app/lib/date_time.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
class DateTime
# Cambia el día de semana a la entregada,
# solo considerando el dia actual y posteriores
def change_to_next_wday(week_day)
def change_wday(week_day)
self + (week_day - wday) % 7
end
end
2 changes: 1 addition & 1 deletion app/models/academic_unit.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# frozen_string_literal: true

class AcademicUnit < ApplicationRecord
has_many :courses
has_many :courses, dependent: :destroy
end
2 changes: 1 addition & 1 deletion app/models/application_record.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ def self.sample(amount = nil)

# https://stackoverflow.com/a/36335591
def self.human_enum_name(enum_name, enum_value)
I18n.t("activerecord.attributes.#{model_name.i18n_key}.#{enum_name.to_s.pluralize}.#{enum_value}")
I18n.t("activerecord.attributes.#{model_name.i18n_key}.#{enum_name.to_s.pluralize}.long_name.#{enum_value}")
end

def self.short_enum_name(enum_name, enum_value)
Expand Down
2 changes: 1 addition & 1 deletion app/models/campus.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# frozen_string_literal: true

class Campus < ApplicationRecord
has_many :courses
has_many :courses, dependent: :destroy
end
9 changes: 5 additions & 4 deletions app/models/schedule.rb
Original file line number Diff line number Diff line change
Expand Up @@ -79,12 +79,12 @@ def create_icalendar_events
@expandable_events.map do |event|
# Info
fist_day = course.term.first_day
until_date = course.term.last_day
until_date = course.term.last_day.advance(days: 1)
days = event.days.map { |e| ICALENDAR_DAYS[e] }.join(',')
event_start = fist_day.to_datetime.change(MODULES_TIME[event.modules.min])
event_start = event_start.change_to_next_wday(event.days.max_by { |d| (fist_day.day - d - 2) % 7 } + 1)
event_start = event_start.change_wday(event.days.max_by { |d| (fist_day.day - d - 2) % 7 } + 1)
event_end = fist_day.to_datetime.change(MODULES_TIME[event.modules.max])
event_end = event_end.change_to_next_wday(event.days.max_by { |d| (fist_day.day - d - 2) % 7 } + 1)
event_end = event_end.change_wday(event.days.max_by { |d| (fist_day.day - d - 2) % 7 } + 1)
# Calendar
icalendar_event = Icalendar::Event.new
icalendar_event.summary = ErbTemplate.new('event/summary').render(binding)
Expand All @@ -93,7 +93,8 @@ def create_icalendar_events
icalendar_event.dtstart = event_start
icalendar_event.dtend = event_end + MODULE_LENGH
exdates = Holiday.all.filter_map do |holiday|
hday = holiday.every_yeat ? holiday.day.change(year: course.term.first_day.year) : holiday.day
hday = holiday.every_year ? holiday.day.change(year: course.term.first_day.year) : holiday.day
hday = hday.to_datetime.change(hour: event_start.hour, min: event_start.min)
course.term.first_day < hday && hday < course.term.last_day ? hday : nil
end
icalendar_event.exdate = exdates
Expand Down
4 changes: 2 additions & 2 deletions app/models/term.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@

# Periodo de clases
class Term < ApplicationRecord
enum period: %i[tav 1 2] # TODO: tav debería ser 3 en el enum
default_scope { order(year: :desc, period: :asc) }
enum period: %i[1 2 tav]
default_scope { order(year: :desc, period: :desc) }

has_many :courses, dependent: :destroy

Expand Down
2 changes: 1 addition & 1 deletion app/views/schedule/show.html.erb
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<% unless @term.nil? %>
<% unless @term.nil? || @courses.empty? %>
<% provide :description, t('schedule_of', subjects_names: @courses.map(&:subject).map(&:name).to_sentence) %>
<% end %>
Expand Down
77 changes: 63 additions & 14 deletions config/locales/es.yml
Original file line number Diff line number Diff line change
@@ -1,31 +1,80 @@
es:
page_description: Obtiene el horario de los cursos y guardalos en tu calendario.
with: con
schedule_of: "Horario de %{subjects_names}"
course_form_instrucions: Busca cursos por Código-Sección o por NRC
courses: Cursos
download_schedule: Descargar horario
schedule: "Horario"
page_description: Obtiene el horario de los cursos y guardalos en tu calendario.
period_not_found: "Periodo no encontrado %{year}-%{period}"
courses: Cursos
course_form_instrucions: Busca cursos por Código-Sección o por NRC
schedule_of: "Horario de %{subjects_names}"
schedule: Horario
with: con
date:
day_names: ["Domingo", "Lunes", "Martes", "Miércoles", "Jueves", "Viernes", "Sábado"]
support:
array:
words_connector: ", "
two_words_connector: " y "
last_word_connector: " y "
# Rails Active Record
# https://guides.rubyonrails.org/i18n.html#translations-for-active-record-models
attributes:
year: Año
period: Periodo
fist_day: Primer día
last_day: Último día
academic_unit: Unidad académica
campus: Campus
course: Curso
category: Categoria
created_at: Creado en
name: Nombre
day: Día
schedule: Horario
every_year: Cada año
subject: Ramo
teacher: Profesor
term: Semestre académico
updated_at: Actualizado en
classroom: Sala
module: Módulo
activerecord:
models:
academic_unit: Unidad académica
campus: Campus
course: Curso
exam: Prueba
holiday: Feriado
schedule_event:
one: Módulo de un curso
other: Módulos de cursos
schedule: Horario
subject: Ramo
teacher: Profesor
term: Semestre académico
user: Usuario
attributes:
course:
section: Sección
format: Formato
total_vacancy: Cupos
"withdrawal?": Permite retiro
"english?": Se dicta en ingles
"require_special_approval?": Requiere aprob. especial
subject:
code: Código
credits: Creditos
fr_area: Área FG
category: Categoria
schedule_event:
categories:
class: "Clase"
assis: "Ayudantía"
lab: "Laboratorio"
workshop: "Taller"
field: "Terreno"
practice: "Práctica"
tesis: "Tesis"
other: "Otro"
long_name:
class: "Clase"
assis: "Ayudantía"
lab: "Laboratorio"
workshop: "Taller"
field: "Terreno"
practice: "Práctica"
tesis: "Tesis"
other: "Otro"
short_name:
class: "Clas"
assis: "Ayd"
Expand Down
2 changes: 1 addition & 1 deletion config/routes.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
devise_for :users, ActiveAdmin::Devise.config
ActiveAdmin.routes(self)
root 'schedule#show_short'
get 't/s', to: 'schedule#show_short', as: 'schedule_short'
get 's', to: 'schedule#show_short', as: 'schedule_short'
get 'term/:year/:period/schedule', to: 'schedule#show', as: 'schedule'
get 'terms', to: 'terms#show', as: 'terms'
end
4 changes: 2 additions & 2 deletions db/migrate/20201216004221_init_app_db.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ def change
t.timestamps
t.date :day, null: false
t.string :name, null: false
t.boolean :every_yeat, default: false, null: false
t.boolean :every_year, default: false, null: false
end

create_table :teachers do |t|
Expand Down Expand Up @@ -37,7 +37,7 @@ def change
t.string :code, null: false
t.string :name, null: false
t.integer :credits
t.string :fr_area
t.string :fg_area
t.string :category
end
add_index :subjects, :code, unique: true
Expand Down
Loading

0 comments on commit a97cb45

Please sign in to comment.