Skip to content
This repository has been archived by the owner on Apr 10, 2018. It is now read-only.

Commit

Permalink
Merge 8e0ae4f into 1a4fd31
Browse files Browse the repository at this point in the history
  • Loading branch information
Masayuki IZUMI committed May 27, 2015
2 parents 1a4fd31 + 8e0ae4f commit 7140e31
Show file tree
Hide file tree
Showing 44 changed files with 961 additions and 199 deletions.
6 changes: 6 additions & 0 deletions app/controllers/api/klasses_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,10 @@ def require_resources
def require_resource
@resource = Klass.friendly.find(params[:id])
end

def timetable
require_resource
@resources = Timetable.create_from_klass(@resource)
respond_with @resources
end
end
5 changes: 5 additions & 0 deletions app/models/period_time.rb
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,11 @@ class PeriodTime < ActiveRecord::Base
validates :start_time, presence: true, uniqueness: { scope: [:end_time] }
validates :end_time, presence: true

include Garage::Representer

property :start_time
property :end_time

include Comparable

def is?(params)
Expand Down
107 changes: 58 additions & 49 deletions app/models/timetable.rb
Original file line number Diff line number Diff line change
@@ -1,61 +1,70 @@
class Timetable
BEGINNING_OF_DAY = Settings.timetable.beginning_of_day
END_OF_DAY = Settings.timetable.end_of_day

attr_reader :rows

def initialize(lectures)
@rows = {}
lectures.each do |lecture|
lecture.periods.each do |period|
wday = period.wday
@rows[wday] ||= Row.new
@rows[wday] << Cell.new(lecture: lecture, period_time: period.period_time)
end
end
@rows.each { |wday, row| row.layered! }
include ActiveModel::Model
attr_accessor :cells, :all_week

include Garage::Representer

collection :cells
property :beginning_of_week
property :end_of_week

class Cell
include ActiveModel::Model
attr_accessor :lecture, :category, :scheduled_on, :period_time, :rescheduling

include Garage::Representer

property :category
property :scheduled_on
property :period_time, as: :period
property :lecture
property :rescheduling_id

delegate :id, to: :rescheduling, prefix: true, allow_nil: true
end

class Row
attr_reader :cells
def initialize
@cells = []
end
def beginning_of_week
all_week.first
end

def <<(cell)
@cells << cell
end
def end_of_week
all_week.last
end

def self.create_from_klass(klass, all_week = Date.today.all_week)
lectures = klass.lectures.current_term.includes(:periods)
create_from_lectures(lectures, all_week)
end

def self.create_from_lecturer(lecturer, all_week = Date.today.all_week)
lectures = lecturer.lectures.current_term.includes(:periods)
create_from_lectures(lectures, all_week)
end

def layered!
@cells.each.with_index do |cell, i|
@cells.each.with_index do |other_cell, j|
next if i == j
if cell.range.overlaps?(other_cell.range)
cell.layer_count += 1
if cell.layer_index <= other_cell.layer_index
cell.layer_index = other_cell.layer_index + 1
end
end
end
cell.layer_index = 0 if cell.layer_index == -1
private

def self.create_from_lectures(lectures, all_week)
cells = all_week.inject([]) do |cells, date|
cells + create_cells_from_lectures_by_date(lectures, date)
end
end
Timetable.new(cells: cells, all_week: all_week)
end

class Cell
include ActiveModel::Model
attr_accessor :lecture, :period_time, :range, :layer_count, :layer_index
delegate :start_time, :end_time, to: :period_time
def initialize(*args)
super(*args)
base = time_to_i(BEGINNING_OF_DAY)
@range = (time_to_i(start_time) - base)...(time_to_i(end_time) - base)
@layer_count = 1
@layer_index = -1
end
def self.create_cells_from_lectures_by_date(lectures, date)
lectures.where(periods: { wday: date.wday }).map { |lecture|
create_cells_from_lecture_by_date(lecture, date)
}.flatten
end

def time_to_i(time_str)
Time.parse(time_str).to_i
def self.create_cells_from_lecture_by_date(lecture, date)
periods = lecture.periods.select { |period| period.wday == date.wday }
periods.map do |period|
Timetable::Cell.new(
lecture: lecture,
category: 'normal',
scheduled_on: date,
period_time: period.period_time
)
end
end
end
4 changes: 3 additions & 1 deletion config/routes.rb
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,9 @@
namespace :api do
scope :v1 do
resources :lectures, only: %i(index show)
resources :klasses, only: %i(index show), path: :classes
resources :klasses, only: %i(index show), path: :classes do
get :timetable, on: :member
end
resources :reschedulings, only: %i(index)
end

Expand Down
172 changes: 142 additions & 30 deletions doc/api.json
Original file line number Diff line number Diff line change
Expand Up @@ -117,35 +117,6 @@
"string"
]
},
"period": {
"description": "the preriod that lecture has taken",
"type": [
"object"
],
"properties": {
"start_time": {
"description": "time when the period start",
"example": "09:00:00+09:00",
"type": [
"string"
]
},
"end_time": {
"description": "time when the period end",
"example": "10:30:00+09:00",
"type": [
"string"
]
},
"wday": {
"description": "wday when the period taken",
"example": 1,
"type": [
"integer"
]
}
}
},
"lecturer": {
"description": "name of the lecture",
"example": "新井 イスマイル",
Expand Down Expand Up @@ -194,7 +165,7 @@
"array"
],
"items": {
"$ref": "#/definitions/lecture/definitions/period"
"$ref": "#/definitions/period"
}
},
"lecturers": {
Expand All @@ -213,6 +184,55 @@
"object"
]
},
"period": {
"$schema": "http://json-schema.org/draft-04/hyper-schema",
"title": "Period",
"definitions": {
"period_time": {
"description": "the time when the lecture will be start/end",
"type": [
"object"
],
"properties": {
"start_time": {
"description": "time when the period start",
"example": "09:00:00+09:00",
"type": [
"string"
]
},
"end_time": {
"description": "time when the period end",
"example": "10:30:00+09:00",
"type": [
"string"
]
}
}
},
"wday": {
"description": "wday when the period taken",
"example": 1,
"type": [
"integer"
]
}
},
"properties": {
"start_time": {
"$ref": "#/definitions/period/definitions/period_time/properties/start_time"
},
"end_time": {
"$ref": "#/definitions/period/definitions/period_time/properties/end_time"
},
"wday": {
"$ref": "#/definitions/period/definitions/wday"
}
},
"type": [
"object"
]
},
"rescheduling": {
"$schema": "http://json-schema.org/draft-04/hyper-schema",
"title": "Rescheduling",
Expand Down Expand Up @@ -293,6 +313,92 @@
"type": [
"object"
]
},
"timetable": {
"$schema": "http://json-schema.org/draft-04/hyper-schema",
"title": "Timetable",
"definitions": {
"category": {
"description": "variations of this period(normal, addition, cancel)",
"example": "change",
"type": [
"string"
]
},
"scheduled_on": {
"description": "date when the period scheduled on",
"example": "2014-12-16",
"type": [
"string"
]
},
"beginning_of_week": {
"description": "the date representing the start this week",
"example": "2014-12-15",
"type": [
"string"
]
},
"end_of_week": {
"description": "the date representing the end this week",
"example": "2014-12-19",
"type": [
"string"
]
}
},
"links": [
{
"description": "List class' timetables.",
"href": "/api/v1/classes/{(%23%2Fdefinitions%2Fclass%2Fdefinitions%2Fid)}/timetable",
"method": "GET",
"rel": "Info",
"title": "Class' timetable"
}
],
"properties": {
"cells": {
"type": [
"array"
],
"items": {
"properties": {
"category": {
"$ref": "#/definitions/timetable/definitions/category"
},
"scheduled_on": {
"$ref": "#/definitions/timetable/definitions/scheduled_on"
},
"lecture": {
"$ref": "#/definitions/lecture"
},
"period": {
"$ref": "#/definitions/period/definitions/period_time"
},
"rescheduling_id": {
"example": 1,
"anyOf": [
{
"$ref": "#/definitions/rescheduling/definitions/id"
},
{
"type": null
}
]
}
}
}
},
"beginning_of_week": {
"$ref": "#/definitions/timetable/definitions/beginning_of_week"
},
"end_of_week": {
"$ref": "#/definitions/timetable/definitions/end_of_week"
}
},
"type": [
"object"
]
}
},
"properties": {
Expand All @@ -302,8 +408,14 @@
"lecture": {
"$ref": "#/definitions/lecture"
},
"period": {
"$ref": "#/definitions/period"
},
"rescheduling": {
"$ref": "#/definitions/rescheduling"
},
"timetable": {
"$ref": "#/definitions/timetable"
}
},
"type": [
Expand Down

0 comments on commit 7140e31

Please sign in to comment.