Schedule serverside
This commit is contained in:
1 parent
06b3f481bd
commit
fcf45614a3
11 files changed
+311
-107
No files matched your search
+1
-12
@@ -82,18 +82,7 @@ app.config(($locationProvider, $routeProvider) => {
|
||||
}
|
||||
}))
|
||||
|
||||
let routers = [
|
||||
{
|
||||
name: '/schedule/:period?/:semester?',
|
||||
template: '<page-schedule schedules="$resolve.list"></page-schedule>',
|
||||
title: 'Расписание',
|
||||
resolve: {
|
||||
list: api => api.schedule
|
||||
.list()
|
||||
.then(i => i.data)
|
||||
}
|
||||
}
|
||||
]
|
||||
let routers = []
|
||||
.concat(pages)
|
||||
.map(i => {
|
||||
let path = i.name
|
||||
|
||||
@@ -0,0 +1,130 @@
|
||||
const React = require('react')
|
||||
|
||||
import {getDates} from '../utils/date'
|
||||
import {shortName} from '../models/collective'
|
||||
|
||||
const now = new Date()
|
||||
const dates = getDates(now);
|
||||
|
||||
const days = ['mon', 'tue', 'wed', 'thu', 'fri', 'sat', 'sun'];
|
||||
const isToday = weekDayIndex => (now.getDay() - 1) === weekDayIndex;
|
||||
const weekDay = weekDayIndex => dates[weekDayIndex];
|
||||
const short = shortName;
|
||||
|
||||
const todayClass = i => isToday(i)
|
||||
? 'current'
|
||||
: ''
|
||||
|
||||
const HeadDay = ({i, children}) => (
|
||||
<div className={`${todayClass(i)}`}>
|
||||
<p className="day">{children}</p>
|
||||
<p className="date">{weekDay(i)}</p>
|
||||
</div>
|
||||
)
|
||||
|
||||
const days2 = [
|
||||
'Понедельник',
|
||||
'Вторник',
|
||||
'Среда',
|
||||
'Четверг',
|
||||
'Пятница',
|
||||
'Суббота',
|
||||
]
|
||||
|
||||
const Schedule = ({groups}) => (
|
||||
<div className="schedule-table">
|
||||
<div className="schedule-table__head">
|
||||
<div className="group">Гр.</div>
|
||||
|
||||
{days2.map((day, index) => (
|
||||
<HeadDay key={index} i={index}>{day}</HeadDay>
|
||||
))}
|
||||
</div>
|
||||
|
||||
<div className="schedule-table__body">
|
||||
{groups.map((group, index) => (
|
||||
<GroupRow key={index} {...group}/>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
|
||||
const GroupRow = ({name, time, week}) => (
|
||||
<div className="schedule-table__body-row">
|
||||
<div className="schedule-table__body-group">
|
||||
<p className="name">{name}</p>
|
||||
<p className="time">{time}</p>
|
||||
</div>
|
||||
|
||||
{week.map((day, index) => (
|
||||
<Group key={index} day={day} dayIndex={index}/>
|
||||
))}
|
||||
</div>
|
||||
)
|
||||
|
||||
const Group = ({day, dayIndex}) => (
|
||||
<div className={`schedule-table__record ${todayClass(dayIndex)}`}>
|
||||
{day.map((lesson, index) => (
|
||||
<Cell key={index} {...lesson}/>
|
||||
))}
|
||||
</div>
|
||||
)
|
||||
|
||||
const Cell = ({course, teacher, time}) => (
|
||||
<div className="schedule-table__course">
|
||||
|
||||
{
|
||||
console.log(time)
|
||||
}
|
||||
|
||||
<Lesson {...course}/>
|
||||
|
||||
<Teacher {...teacher}/>
|
||||
|
||||
{time
|
||||
.map(range => ({range}))
|
||||
.map((range, index) => (
|
||||
<TimeRange key={index} {...range}/>
|
||||
))}
|
||||
</div>
|
||||
)
|
||||
|
||||
const Lesson = ({title, url}) => (
|
||||
<p className="lesson">
|
||||
{url
|
||||
? (
|
||||
<a href={url}>
|
||||
{title}
|
||||
</a>
|
||||
)
|
||||
: (
|
||||
<span>
|
||||
{title}
|
||||
</span>
|
||||
)
|
||||
}
|
||||
</p>
|
||||
)
|
||||
|
||||
const Teacher = ({name, url}) => (
|
||||
<p className="teacher">
|
||||
{url
|
||||
? (
|
||||
<a href={url}>
|
||||
{short(name)}
|
||||
</a>
|
||||
)
|
||||
: (
|
||||
<span>
|
||||
{short(name)}
|
||||
</span>
|
||||
)
|
||||
}
|
||||
</p>
|
||||
)
|
||||
|
||||
const TimeRange = ({range}) => (
|
||||
<p className="time">{(range || []).join(' — ')}</p>
|
||||
)
|
||||
|
||||
module.exports = Schedule
|
||||
@@ -0,0 +1,20 @@
|
||||
const React = require('react')
|
||||
const text = require('../core/schedule').text
|
||||
|
||||
const ScheduleList = ({schedules}) => (
|
||||
<div className="schedule-selector">
|
||||
<ul>
|
||||
{schedules.map((s, index) => (
|
||||
<Schedule key={index} {...s}/>
|
||||
))}
|
||||
</ul>
|
||||
</div>
|
||||
)
|
||||
|
||||
const Schedule = ({url, semester, period}) => (
|
||||
<li>
|
||||
<a href={url}>{text({semester, period})}</a>
|
||||
</li>
|
||||
)
|
||||
|
||||
module.exports = ScheduleList
|
||||
+62
-30
@@ -1,18 +1,20 @@
|
||||
import {c} from '../core/db'
|
||||
import {select} from '../utils/fn'
|
||||
import {createMap} from '../utils/common'
|
||||
import {getCollective} from './collective'
|
||||
|
||||
import {scheduleDate, getPeriod as schedulePeriod} from '../models/schedule'
|
||||
import {scheduleDate, getPeriod as schedulePeriod, getPeriodString} from '../models/schedule'
|
||||
import {getCourse} from '../models/course'
|
||||
|
||||
const last = require('../lib/array').last
|
||||
const sortBy = require('../lib/sort').sortBy
|
||||
|
||||
const SCHEDULES = 'schedules'
|
||||
|
||||
export async function getSchedule(period, semester) {
|
||||
async function findSchedule(period, semester) {
|
||||
const schedule = await c(SCHEDULES).findOne({
|
||||
$or: [
|
||||
{period: period},
|
||||
{period: schedulePeriod(period)}
|
||||
{period: period},
|
||||
{period: schedulePeriod(period)}
|
||||
],
|
||||
semester: semester
|
||||
})
|
||||
@@ -20,19 +22,44 @@ export async function getSchedule(period, semester) {
|
||||
return schedule ? migrate(schedule) : null
|
||||
}
|
||||
|
||||
export async function getSchedules(fields = ['_id', 'id', 'period', 'semester']) {
|
||||
const list = await c(SCHEDULES)
|
||||
.find({})
|
||||
.toArray()
|
||||
async function findAllScheduleParams() {
|
||||
const schedules = await c(SCHEDULES)
|
||||
.find({}, {
|
||||
period: 1,
|
||||
semester: 1,
|
||||
_id: 0,
|
||||
})
|
||||
.toArray()
|
||||
|
||||
const schedules = await Promise.all(list.map(migrate))
|
||||
return schedules
|
||||
.sort((a, b) => {
|
||||
const ad = scheduleDate(a).getTime()
|
||||
const bd = scheduleDate(b).getTime()
|
||||
return ad - bd
|
||||
})
|
||||
.map(select(fields))
|
||||
.map(i => ({
|
||||
...i,
|
||||
period: schedulePeriod(i.period),
|
||||
}))
|
||||
.sort(sortBy(
|
||||
i => scheduleDate(i).getTime(),
|
||||
true,
|
||||
))
|
||||
}
|
||||
|
||||
async function findDefaultScheduleParams() {
|
||||
const schedules = await findAllScheduleParams()
|
||||
return last(schedules
|
||||
.map(i => ({
|
||||
...i,
|
||||
period: getPeriodString(i.period),
|
||||
}))
|
||||
)
|
||||
}
|
||||
|
||||
function text({semester, period}) {
|
||||
const word = semester => [['spring', 'Весна'], ['autumn', 'Осень']]
|
||||
.find(i => i[0] === semester)
|
||||
[1]
|
||||
const periodIndex = semester === 'spring' ? 1 : 0
|
||||
const year = period[periodIndex]
|
||||
|
||||
return `${word(semester)} ${year} года`
|
||||
}
|
||||
|
||||
async function migrate(schedule) {
|
||||
@@ -49,7 +76,7 @@ async function migrate(schedule) {
|
||||
function migrate10to20(schedule) {
|
||||
const dayNames = ['mon', 'tue', 'wed', 'thu', 'fri', 'sat', 'sun']
|
||||
const time = time => time
|
||||
.map(i => i.split(' '))
|
||||
.map(i => i.split(' '))
|
||||
|
||||
const week = days => days.reduce((week, lesson, index) => {
|
||||
if (lesson) {
|
||||
@@ -66,23 +93,23 @@ function migrate10to20(schedule) {
|
||||
version: '2.0',
|
||||
period: schedulePeriod(schedule.period),
|
||||
groups: schedule.schedule
|
||||
.map(group => ({
|
||||
name: group.group,
|
||||
time: group.time,
|
||||
week: week(group.week)
|
||||
}))
|
||||
.map(group => ({
|
||||
name: group.group,
|
||||
time: group.time,
|
||||
week: week(group.week)
|
||||
}))
|
||||
})
|
||||
}
|
||||
|
||||
async function migrate20to30(schedule) {
|
||||
const days = ['mon', 'tue', 'wed', 'thu', 'fri', 'sat', 'sun']
|
||||
const days = ['mon', 'tue', 'wed', 'thu', 'fri', 'sat']//, 'sun']
|
||||
|
||||
const persons = await getCollective()
|
||||
const person = createMap(i => i.id, persons)
|
||||
|
||||
const week = week => days
|
||||
.map(day => week[day] || [])
|
||||
.map(lessons => lessons.map(lesson))
|
||||
.map(day => week[day] || [])
|
||||
.map(lessons => lessons.map(lesson))
|
||||
|
||||
const lesson = i => ({
|
||||
time: i.time,
|
||||
@@ -107,10 +134,15 @@ async function migrate20to30(schedule) {
|
||||
return Object.assign(schedule, {
|
||||
version: '3.0',
|
||||
groups: schedule.groups
|
||||
.map(group => ({
|
||||
name: group.name,
|
||||
time: group.time,
|
||||
week: week(group.week)
|
||||
}))
|
||||
.map(group => ({
|
||||
name: group.name,
|
||||
time: group.time,
|
||||
week: week(group.week)
|
||||
}))
|
||||
})
|
||||
}
|
||||
|
||||
exports.findSchedule = findSchedule
|
||||
exports.findAllScheduleParams = findAllScheduleParams
|
||||
exports.findDefaultScheduleParams = findDefaultScheduleParams
|
||||
exports.text = text
|
||||
@@ -9,4 +9,18 @@ function splitBy(key) {
|
||||
}
|
||||
}
|
||||
|
||||
function head(list) {
|
||||
return Array.isArray(list) && list.length
|
||||
? list[0]
|
||||
: null
|
||||
}
|
||||
|
||||
function last(list) {
|
||||
return Array.isArray(list) && list.length
|
||||
? list[list.length - 1]
|
||||
: null
|
||||
}
|
||||
|
||||
exports.splitBy = splitBy
|
||||
exports.head = head
|
||||
exports.last = last
|
||||
+7
-3
@@ -10,9 +10,13 @@ export default [
|
||||
],
|
||||
},
|
||||
{
|
||||
'text': 'Расписание',
|
||||
'url': '/schedule',
|
||||
'color': 'green'
|
||||
text: 'Расписание',
|
||||
url: '/schedule',
|
||||
color: 'green',
|
||||
items: [
|
||||
{url: '*', text: ''},
|
||||
]
|
||||
|
||||
},
|
||||
{
|
||||
'text': 'Поступление',
|
||||
|
||||
@@ -28,3 +28,19 @@ export function getPeriod(i){
|
||||
|
||||
return i.map(Number);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* f("2012-2015") -> "2012-2015"
|
||||
* f(["2012", "2015"]) -> "2012-2015"
|
||||
* f([2012, 2015]) -> "2012-2015"
|
||||
*
|
||||
* @param i
|
||||
* @returns {*}
|
||||
*/
|
||||
function getPeriodString(i) {
|
||||
return getPeriod(i)
|
||||
.join('-')
|
||||
}
|
||||
|
||||
exports.getPeriodString = getPeriodString
|
||||
@@ -1,24 +0,0 @@
|
||||
import route from 'koa-route';
|
||||
import {json} from './';
|
||||
import {sortByPattern} from '../utils/sort';
|
||||
import db from '../core/db';
|
||||
|
||||
let split = d => s => s.split(d);
|
||||
let toArray = split(',');
|
||||
|
||||
export default function () {
|
||||
return route.get('/collective', json(
|
||||
function *() {
|
||||
this.type = 'application/json';
|
||||
let pattern = toArray(this.query.sort || '');
|
||||
|
||||
let data = yield db.c('collective').find();
|
||||
if (!data) {
|
||||
this.status = 404;
|
||||
return;
|
||||
}
|
||||
|
||||
this.body = sortByPattern(data, pattern, i => i.id);
|
||||
}
|
||||
))
|
||||
};
|
||||
@@ -6,14 +6,10 @@ import {map, assign} from '../utils/common'
|
||||
import {index as indexFile} from '../config'
|
||||
|
||||
import sitemap from './sitemap'
|
||||
import schedule from './schedule'
|
||||
import pages from './pages'
|
||||
|
||||
export function routes(store) {
|
||||
return compose([
|
||||
sitemap(),
|
||||
schedule(),
|
||||
pages(),
|
||||
])
|
||||
}
|
||||
|
||||
|
||||
+59
-34
@@ -1,40 +1,65 @@
|
||||
import compose from 'koa-compose';
|
||||
import route from 'koa-route';
|
||||
import {json} from './';
|
||||
const React = require('react')
|
||||
const Share = require('../components/Share')
|
||||
const Schedule = require('../components/Schedule')
|
||||
const ScheduleList = require('../components/ScheduleList')
|
||||
const {render} = require('../lib/render')
|
||||
const getPeriodString = require('../models/schedule').getPeriodString
|
||||
const getPathWithNoTrailingSlash = require('../lib/url').getPathWithNoTrailingSlash
|
||||
const {get} = require('koa-route')
|
||||
|
||||
import {getSchedule, getSchedules} from '../core/schedule';
|
||||
const {findSchedule, findDefaultScheduleParams, findAllScheduleParams} = require('../core/schedule')
|
||||
const text = require('../core/schedule').text
|
||||
|
||||
export default function () {
|
||||
return compose([
|
||||
list(),
|
||||
schedule()
|
||||
]);
|
||||
};
|
||||
|
||||
function list() {
|
||||
return route.get('/schedule/list', json(
|
||||
async(ctx) => {
|
||||
ctx.type = 'application/json';
|
||||
const data = await getSchedules();
|
||||
|
||||
if (!data) ctx.status = 404;
|
||||
else ctx.body = data;
|
||||
}
|
||||
));
|
||||
function getMeta(schedule) {
|
||||
const t = text(schedule)
|
||||
return {
|
||||
title: t,
|
||||
description: t,
|
||||
}
|
||||
}
|
||||
|
||||
function schedule() {
|
||||
return route.get('/schedule/:period?/:semester?', json(
|
||||
async(ctx, period, semester) => {
|
||||
ctx.type = 'application/json';
|
||||
function getSchedule() {
|
||||
return get('/schedule/:period?/:semester?', async (ctx, period, semester) => {
|
||||
const useRoute = Boolean(period) && Boolean(semester)
|
||||
if (useRoute) {
|
||||
const path = getPathWithNoTrailingSlash(ctx.path)
|
||||
|
||||
let data = await getSchedule(period, semester);
|
||||
if (!data) {
|
||||
ctx.status = 404;
|
||||
return;
|
||||
}
|
||||
const data = await findSchedule(period, semester)
|
||||
if (data) {
|
||||
|
||||
ctx.body = data;
|
||||
}
|
||||
))
|
||||
}
|
||||
//let schedules = await findAllScheduleParams()
|
||||
//schedules = schedules.map(({semester, period}) => ({
|
||||
// period,
|
||||
// semester,
|
||||
// url: `/schedule/${getPeriodString(period)}/${semester}`,
|
||||
//}))
|
||||
|
||||
const Component = (
|
||||
<div className="content content_full">
|
||||
{/*<ScheduleList schedules={schedules}/>*/}
|
||||
|
||||
<Schedule {...data}/>
|
||||
|
||||
<Share/>
|
||||
</div>
|
||||
)
|
||||
|
||||
ctx.type = 'text/html'
|
||||
ctx.body = await render(path, Component, getMeta(data))
|
||||
} else {
|
||||
ctx.status = 404
|
||||
}
|
||||
} else {
|
||||
const route = await findDefaultScheduleParams()
|
||||
|
||||
if (route) {
|
||||
const {period, semester} = route
|
||||
ctx.redirect(`/schedule/${period}/${semester}`)
|
||||
} else {
|
||||
ctx.status = 404
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
exports.getSchedule = getSchedule
|
||||
@@ -27,6 +27,7 @@ const gallery = require('./routes/gallery')
|
||||
const teachers = require('./routes/teachers')
|
||||
const documents = require('./routes/documents')
|
||||
const document = require('./routes/document')
|
||||
const schedule = require('./routes/schedule')
|
||||
|
||||
const dirPublic = path.join(__dirname, '../public')
|
||||
const dirTemplates = path.join(__dirname, 'templates')
|
||||
@@ -74,6 +75,7 @@ export default function (store) {
|
||||
app.use(teachers.getTeacher())
|
||||
app.use(documents.getDocuments())
|
||||
app.use(document.getDocument())
|
||||
app.use(schedule.getSchedule())
|
||||
app.use(routes(store))
|
||||
|
||||
return Server(app.callback())
|
||||
|
||||
Reference in new issue
Block a user