Skip to content

Commit

Permalink
Merge branch 'release/2.1.0' into master
Browse files Browse the repository at this point in the history
  • Loading branch information
adufr committed Oct 12, 2020
2 parents 10e92c6 + ec35ab3 commit 849e884
Show file tree
Hide file tree
Showing 18 changed files with 611 additions and 175 deletions.
3 changes: 3 additions & 0 deletions .jshintrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"esversion": 6
}
6 changes: 4 additions & 2 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,10 @@ before_script:
- cp -a .env.example .env

before_install:
- openssl aes-256-cbc -K $encrypted_d810adeb7664_key -iv $encrypted_d810adeb7664_iv
-in .travis/deploy_key.enc -out .travis/deploy_key -d
- if [ "$TRAVIS_BRANCH" == "master" ]; then
openssl aes-256-cbc -K $encrypted_d810adeb7664_key -iv $encrypted_d810adeb7664_iv
-in .travis/deploy_key.enc -out .travis/deploy_key -d;
fi

install: npm install

Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ L'API de calendz est développée avec les frameworks et outils suivants* :

| Librairie | Version | Description |
| ---------------- | ---------- | ------------------------------------------------------------------------------------------------ |
| [Node.js] | 12.16.0 | Node.js® is a JavaScript runtime built on Chrome's V8 JavaScript engine. |
| [Node.js] | 12.18.3 | Node.js® is a JavaScript runtime built on Chrome's V8 JavaScript engine. |
| [Adonis.js] | 4.1 | The Node.js Framework highly focused on developer ergonomics, stability and confidence. |
| [Cheerio] | 1.0.0-rc.3 | Fast, flexible, and lean implementation of core jQuery designed specifically for the server. |

Expand All @@ -36,7 +36,7 @@ L'API de calendz est développée avec les frameworks et outils suivants* :

### Pré-requis

* Installer Node 12.16.0
* Installer Node 12.18.3
* Créer un fichier `.env` à la source de ce repository contenant les valeurs suivantes (modifiables selon vos besoins)

NODE_ENV=development
Expand Down
57 changes: 57 additions & 0 deletions app/Controllers/Http/MonthController.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
'use strict'

const moment = require('moment')
const Cache = use('Cache')
const Scrapper = use('Scrapper')
const ScrappingException = use('App/Exceptions/ScrappingException')

const numberOfWeekByMonth = 4

class MonthController {
/**
* Get courses of the current month
*/
async getCurrent ({ request }) {
const { firstname, lastname, ignoreCache } = request.only(['firstname', 'lastname', 'ignoreCache'])

const result = []

for (let i = 0; i < numberOfWeekByMonth; i++) {
let cacheUsed = false
// get current date (+ i * 7 days) and format with moment
const date = moment(new Date()).add(i * 7, 'd').format('MM/DD/YY')

// ---------------------------------------------------
// Use cache (or at least, try to)

if (!ignoreCache) {
// Get data from cache
const data = await Cache.getWeek(firstname, lastname, date)
if (data) {
cacheUsed = true
result.push(data)
}
}

// ---------------------------------------------------
// Data not in cache: scrapping

if (ignoreCache || !cacheUsed) {
// if not cached, scrap it
const data = await Scrapper.fetchWeek(firstname, lastname, date)
.catch(() => { /* istanbul ignore next */ throw new ScrappingException() })

result.push(data)

// set scrap result in cache
await Cache.setWeek(firstname, lastname, date, data)
// indicate to not restart scrapping today
await Cache.setIsDailyScrapped(firstname, lastname, date)
}
}

return result
}
}

module.exports = MonthController
20 changes: 20 additions & 0 deletions app/Controllers/Http/TeamsController.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
'use strict'

const Scrapper = use('Scrapper')
const ScrappingException = use('App/Exceptions/ScrappingException')

class TeamsController {
/**
* Get Microsoft Teams current links
*/
async get ({ request }) {
const { firstname, lastname } = request.only(['firstname', 'lastname'])

const result = await Scrapper.fetchTeamsLinks(firstname, lastname)
.catch(() => { /* istanbul ignore next */ throw new ScrappingException() })

return result
}
}

module.exports = TeamsController
58 changes: 54 additions & 4 deletions app/Controllers/Http/WeekController.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,9 @@ const InvalidDateException = use('App/Exceptions/InvalidDateException')

class WeekController {
/**
* ==============================================================
* Get courses of the current week
* ==============================================================
*/
async getCurrent ({ request }) {
const { firstname, lastname, ignoreCache } = request.only(['firstname', 'lastname', 'ignoreCache'])
Expand Down Expand Up @@ -37,22 +39,34 @@ class WeekController {
}

/**
* ==============================================================
* Get courses of a given week
* ==============================================================
*/
async getByDate ({ request, params }) {
const { firstname, lastname, ignoreCache } = request.only(['firstname', 'lastname', 'ignoreCache'])

// check if date is valid, if yes format it
if (!DateUtils.isValid(params.date)) throw new InvalidDateException()
const date = moment(params.date, 'MM-DD-YYYY').format('MM/DD/YY')
const translatedDate = DateUtils.getWeekNumber(date)

// ---------------------------------------------------
// Use cache (or at least, try to)

// try to retrieve and return data from cache/redis
if (!ignoreCache) {
// Get data from cache
const data = await Cache.getWeek(firstname, lastname, date)
if (data) return data
if (data) {
const scrappedToday = await Cache.getIsDailyScrapped(firstname, lastname, date)
return { ...data, scrappedToday }
}
}

// if not cached, scrap it
// ---------------------------------------------------
// Data not in cache: scrapping

// start scrapping
const result = await Scrapper.fetchWeek(firstname, lastname, date)
.catch(() => {
/* istanbul ignore next */
Expand All @@ -61,8 +75,44 @@ class WeekController {

// set scrap result in cache
await Cache.setWeek(firstname, lastname, date, result)
// indicate to not restart scrapping today
await Cache.setIsDailyScrapped(firstname, lastname, date)

return result
return { ...result, scrappedToday: true, weekNumber: translatedDate.number }
}

/**
* ==============================================================
* Route used by Calendz for background actualization
* ==============================================================
*/
async updateByDate ({ request, params }) {
const { firstname, lastname } = request.only(['firstname', 'lastname'])

// check if date is valid, if yes format it
if (!DateUtils.isValid(params.date)) throw new InvalidDateException()
const date = moment(params.date, 'MM-DD-YYYY').format('MM/DD/YY')
const translatedDate = DateUtils.getWeekNumber(date)

// ---------------------------------------------------
// Get both CACHED and SCRAPPED data

const cachedData = await Cache.getWeek(firstname, lastname, date)

let scrappedData = await Scrapper.fetchWeek(firstname, lastname, date)
.catch(() => {
/* istanbul ignore next */
throw new ScrappingException()
})
scrappedData = { ...scrappedData, weekNumber: translatedDate.number }
await Cache.setIsDailyScrapped(firstname, lastname, date)

// ---------------------------------------------------
// Compare data

return JSON.stringify(scrappedData) === JSON.stringify(cachedData)
? { update: false }
: { update: true, ...scrappedData }
}
}

Expand Down
55 changes: 55 additions & 0 deletions app/Middleware/ConvertIcal.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
/* istanbul ignore file */
'use strict'

const ical = require('ical-generator')
const moment = require('moment')

class ConvertIcal {
async handle ({ response, request }, next) {
await next()

const format = request.input('format')

if (format === 'icalendar') {
const cal = ical()

const events = findValuesHelper(response._lazyBody, 'date', [])

events.forEach(event => {
cal.createEvent({
start: moment(event.date + ' ' + event.start, 'DD/MM/YYYY hh:mm').toDate(),
end: moment(event.date + ' ' + event.end, 'DD/MM/YYYY hh:mm').toDate(),
summary: event.subject,
description: event.professor,
location: event.room
})
})

response._lazyBody.content = cal.toString()
response.safeHeader('Content-type', 'text/calendar')
}
}
}

function findValuesHelper (obj, key, list) {
if (!obj) return list
if (obj instanceof Array) {
for (var i in obj) {
list = list.concat(findValuesHelper(obj[i], key, []))
}
return list
}
if (obj[key]) list.push(obj)

if ((typeof obj === 'object') && (obj !== null)) {
var children = Object.keys(obj)
if (children.length > 0) {
for (i = 0; i < children.length; i++) {
list = list.concat(findValuesHelper(obj[children[i]], key, []))
}
}
}
return list
}

module.exports = ConvertIcal
10 changes: 0 additions & 10 deletions app/Middleware/ForceJson.js

This file was deleted.

Loading

0 comments on commit 849e884

Please sign in to comment.