123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176 |
- import fs from 'fs'
- import Excel from './excel'
- import Draw from '../models/draw'
- import MatchList from '../models/matchList'
- import PlayerList from '../models/playerList'
- import moment from 'moment'
- import { normalize } from './helpers'
- import { session } from '../index'
- function initials (player) {
- const fnInitials = player.firstName
- .split('-')
- .map(element=>element
- .split(' ')
- .map(element => element[0]+'.')
- .join(' ')
- ).join('-')
- const fnInitialsDP = player.firstNameDP
- .split('-')
- .map(element=>element
- .split(' ')
- .map(element => element[0]+'.')
- .join(' ')
- ).join('-')
- return player.doubles ? `${player.name} ${fnInitials} / ${player.nameDP} ${fnInitialsDP}` : `${name} ${fnInitials}`
- }
- async function getDraws (req, res) {
- try {
- const draws = await Draw.find()
- return res.json(draws)
- } catch (error) {
- return res.status(400).json({ msg: error.toString() })
- }
- }
- async function getDraw (req, res) {
- try {
- const key = req.query.drawId ? { _id: req.query.drawId } : {}
- const draw = await MatchList.findOne(key).sort({ imported: -1 })
- return res.json(draw)
- } catch (error) {
- return res.status(400).json({ msg: error.toString() })
- }
- }
- async function downloadDraw (req, res) {
- try {
- const { drawId } = req.params
-
- const filename = `DisplayDraw-${drawId}-${moment().format('YYYYMMDDTHHmmss')}.xls`
- const drawFile = fs.createWriteStream(`swisstennis_files/${filename}`)
- const drawDisplay = await session.get(`https://comp.swisstennis.ch/advantage/servlet/DisplayDraw.xls?eventId=${drawId}&lang=D`, {stream: true})
- await drawDisplay.pipe(drawFile)
- const streamDone = new Promise((resolve, reject) => {
- drawFile.on('finish', resolve)
- drawFile.on('error', reject)
- })
- await streamDone
- const stats = fs.statSync(`swisstennis_files/${filename}`)
- return res.json({ filename, size: stats.size, mtime: stats.mtime })
- } catch (error) {
- return res.status(400).json({ msg: error.toString() })
- }
- }
- async function parseDraw (req,res) {
- try {
- console.log('Parsing file', req.params.filename)
-
- const filePath = `swisstennis_files/${req.params.filename}`
- const dateString = req.params.filename.match(/(\d{4}\d{2}\d{2}T\d{2}\d{2}\d{2})/)[1]
- const fileDate = moment(dateString)
- const stat = fs.statSync(filePath)
-
- const fileNewer = await Draw.find({ imported: { $gte: fileDate } })
- if (fileNewer.length) {
- throw Error('File has to be newer.')
- }
-
- console.log('About to read the draw.')
- const worksheets = await Excel.readWorkbook(`swisstennis_files/${req.params.filename}`)
- const worksheet = worksheets.Tableaux
- if (worksheet[0].length !== 1 || worksheet[1].length !== 1 || worksheet[2].length !== 1 || worksheet[3].length !== 0) {
- throw Error(`Wrong file structure.`)
- }
- const category = normalize(worksheet[2][0])
- const doubles = !!category.match(/DM.*|[MW]D.*/)
- const drawSize = ( worksheet.length - 4 + 1 ) / 2 // 4 header lines, 1 empty line between each player (n-1)
- const draw = worksheet.slice(4)
- const rounds = Math.log2(drawSize)
- const playerList = await PlayerList.findOne().sort({imported: -1}).populate('players')
- const players = playerList.players.filter(player => player.category === category)
- const matchList = await MatchList.findOne().sort({imported: -1}).populate('matches')
- const matches = matchList.matches
-
- const drawMatches = []
- for (var round = 0; round < rounds; round += 1) {
- const matchPositionOffset = Math.pow(2, round)
- const playerOffset = 2 * matchPositionOffset
- const roundOffset = playerOffset/2 - 1
- const matchIncrement = 2 * playerOffset
- for (var seq = 0; seq < drawSize / Math.pow(2, round + 1); seq += 1) {
- const matchPosition = roundOffset + seq * matchIncrement
- // Data from spreadsheet cells
- const player1String = normalize(draw[matchPosition][round])
- const player2String = normalize(draw[matchPosition + playerOffset][round])
- const winnerString = normalize(draw[matchPositionOffset + matchPosition][round + 1])
- const timePlaceResultString = normalize(draw[matchPositionOffset + matchPosition + 1][round + 1])
- const drawPlayerRegex = /^(?:\((\d+)\))?\s*\(([RN]\d\s?(?:\d+)?|NC)\) (.+)$/
- const drawDoubleRegex = /^(?:\((\d+)\))?\s*\(([RN]\d\s?(?:\d+)?|NC)\/([RN]\d\s?(?:\d+)?|NC)\) ([^\/]+)\s*\/\s*([^\/]+)$/
-
- const player1Match = doubles ? player1String.match(drawDoubleRegex) : player1String.match(drawDoubleRegex)
- const player2Match = doubles ? player2String.match(drawDoubleRegex) : player2String.match(drawDoubleRegex)
-
- console.log(player1Match, player2Match)
- const player1 = (round === 0) ?
- players.find(player => player1Match && (category === player.category) && (player1Match[3] === player.fullName)) :
- players.find(player => (category === player.category) && (player1String === initials(player)))
-
- const player2 = (round === 0) ?
- players.find(player => player2Match && (category === player.category) && (player2Match[3] === player.fullName)) :
- players.find(player => (category === player.category) && (player2String === initials(player)))
-
- const timePlace = timePlaceResultString.match(/^(\d{2}\/\d{2}\/\d{2})?\s+(\d{2}:\d{2})?\s*\(([^\)]+)\)?$/)
- const result = normalize(draw[matchPosition + playerOffset/2 + 1][round + 1]).match(/^((?:WO)?\s*(?:\d+\/\d+\s*)*)$/)
- const winner = winnerString
- const idString = (player1 && player2)
- const match = {
- created: new Date(),
- idString: '',
- category,
- place: timePlace && timePlace[3] || null,
- date: timePlace && timePlace[1] && timePlace[2] && moment(`${timePlace[1]} ${timePlace[2]}`, 'DD/MM/YY HH:mm') || null,
- round: round + 1,
- player1: player1 && player1._id || null,
- player2: player2 && player2._id || null,
- winner: winner || null,
- result: result && result[0] || null,
- doubles
- }
- drawMatches.push(match)
- }
- }
- console.log('matches:', drawMatches.length)
- return res.json({ drawMatches })
- } catch (error) {
- res.status(400).json({ msg: error.toString() })
- }
- }
- async function deleteDraw (req, res) {
- try {
- const { drawId } = req.params
-
- if (!drawId) {
- throw Error('No drawId given.')
- }
- const draw = await MatchList.findOne({ _id: drawId })
- if (!draw) {
- throw Error('Draw not found.')
- }
- draw.remove()
- return res.json({ _id: drawId })
- } catch (error) {
- return res.status(400).json({ msg: error.toString() })
- }
- }
- export default { getDraws, getDraw, downloadDraw, parseDraw, deleteDraw }
|