playerList.js 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159
  1. import fs from 'fs'
  2. import Excel from './excel'
  3. import Player from '../models/player'
  4. import PlayerList from '../models/playerList'
  5. import moment from 'moment'
  6. import { normalize, normalizePhone } from './helpers'
  7. import { session } from '../index'
  8. import { configDb } from '../../api'
  9. async function getPlayerLists (req, res) {
  10. try {
  11. const playerLists = await PlayerList.find().select({_id: 1, imported: 1, file: 1, filesize: 1})
  12. return res.json(playerLists)
  13. } catch (error) {
  14. return res.status(400).json({ msg: error.toString() })
  15. }
  16. }
  17. async function getPlayerList (req, res) {
  18. try {
  19. const key = req.query.playerlistId ? { _id: req.query.playerlistId } : {}
  20. const playerList = await PlayerList.findOne(key).sort({ imported: -1 }).populate('players')
  21. return res.json(playerList)
  22. } catch (error) {
  23. return res.status(400).json({ msg: error.toString() })
  24. }
  25. }
  26. async function downloadPlayerList (req, res) {
  27. try {
  28. const tournament = req.query.tournament || configDb.tournamentId.value
  29. if (!tournament) {
  30. throw Error('No tournament given.')
  31. }
  32. const filename = `PlayerList-${tournament}-${moment().format('YYYYMMDDTHHmmss')}.xls`
  33. const playerListFile = fs.createWriteStream(`swisstennis_files/${filename}`)
  34. const playerList = await session.get(`https://comp.swisstennis.ch/advantage/servlet/PlayerList.xls?tournament=Id${tournament}&lang=D`, {stream: true})
  35. playerList.pipe(playerListFile)
  36. const streamDone = new Promise((resolve, reject) => {
  37. playerListFile.on('finish', resolve)
  38. playerListFile.on('error', reject)
  39. })
  40. await streamDone
  41. const stats = fs.statSync(`swisstennis_files/${filename}`)
  42. return res.json({ filename, size: stats.size, mtime: stats.mtime })
  43. } catch (error) {
  44. return res.status(400).json({ msg: error.toString() })
  45. }
  46. }
  47. async function parsePlayerList (req, res) {
  48. try {
  49. console.log('Parsing file', req.params.filename)
  50. const filePath = `swisstennis_files/${req.params.filename}`
  51. const dateString = req.params.filename.match(/(\d{4}\d{2}\d{2}T\d{2}\d{2}\d{2})/)[1]
  52. const fileDate = moment(dateString)
  53. const stat = fs.statSync(filePath)
  54. const fileNewer = await PlayerList.find({ imported: { $gte: fileDate.toDate() } })
  55. if (fileNewer.length) {
  56. throw Error('File has to be newer.')
  57. }
  58. console.log('About to read the player list.', filePath)
  59. const worksheets = await Excel.readWorkbook(filePath)
  60. const worksheet = worksheets.Players
  61. if (worksheet[4].length !== 32 & worksheet[3][0] !== 'Konkurrenz' & worksheet[3][31] !== 'bezahlt') {
  62. throw Error(`Wrong file structure. Length: ${worksheet[4].length} (expected 32), Column A name: ${worksheet[3][0]} (expected Konkurrenz).`)
  63. }
  64. const headers = worksheet.slice(3, 4)
  65. const allPlayers = await Promise.all(worksheet.slice(4, worksheet.length).map(async data => {
  66. const filePlayer = {
  67. created: fileDate.toDate(),
  68. category: normalize(data[0]),
  69. licenseNr: normalize(data[2]),
  70. name: normalize(data[5]),
  71. firstName: normalize(data[6]),
  72. nameDP: normalize(data[24]),
  73. firstNameDP: normalize(data[25]),
  74. birthDate: data[7] || null,
  75. email: normalize(data[16]),
  76. ranking: normalize(data[17]),
  77. licenseNrDP: normalize(data[23]),
  78. phonePrivate: normalizePhone(data[13]),
  79. phoneWork: normalizePhone(data[14]),
  80. phoneMobile: normalizePhone(data[15]),
  81. birthDateDP: data[26] || null,
  82. rankingDP: normalize(data[27]),
  83. confirmed: !!data[29],
  84. paid: !!data[31],
  85. }
  86. filePlayer.gender = filePlayer.category ?
  87. filePlayer.category[0] === 'M' ? 'm' :
  88. filePlayer.category[0] === 'W' ?
  89. 'w' :
  90. null :
  91. null,
  92. filePlayer.doubles = !!filePlayer.category.match(/DM.*|[MW]D.*/)
  93. filePlayer.junior = filePlayer.birthDate ?
  94. filePlayer.birthDate.getTime() >= (new Date((new Date()).getFullYear() - 19, 11, 31, 23, 59, 59, 999)).getTime() :
  95. false
  96. filePlayer.fullName = filePlayer.doubles ?
  97. `${filePlayer.name} ${filePlayer.firstName} / ${filePlayer.nameDP} ${filePlayer.firstNameDP}` :
  98. `${filePlayer.name} ${filePlayer.firstName}`
  99. filePlayer.idString = `${filePlayer.category} % ${filePlayer.fullName}`
  100. filePlayer.phone = null
  101. const reMobile = /^\+417/
  102. if (filePlayer.phoneWork && filePlayer.phoneWork.match(reMobile)) {
  103. filePlayer.phone = filePlayer.phoneWork
  104. } else if (filePlayer.phonePrivate && filePlayer.phonePrivate.match(reMobile)) {
  105. filePlayer.phone = filePlayer.phonePrivate
  106. } else if (filePlayer.phoneMobile && filePlayer.phoneMobile.match(reMobile)) {
  107. filePlayer.phone = filePlayer.phoneMobile
  108. }
  109. const player = new Player(filePlayer)
  110. player.save()
  111. return player._id
  112. }))
  113. const playerList = new PlayerList({
  114. imported: fileDate,
  115. file: req.params.filename,
  116. fileSize: stat.size,
  117. players: allPlayers
  118. })
  119. await playerList.save()
  120. return res.json({playerList})
  121. } catch (error) {
  122. return res.status(400).json({ msg: error.toString() })
  123. }
  124. }
  125. async function deletePlayerList (req, res) {
  126. try {
  127. const { playerlistId } = req.params
  128. if (!playerlistId) {
  129. throw Error('No playerlistId given.')
  130. }
  131. const playerList = await PlayerList.findOne({ _id: playerlistId })
  132. if (!playerList) {
  133. throw Error('PlayerList not found.')
  134. }
  135. playerList.remove()
  136. return res.json({ _id: playerlistId })
  137. } catch (error) {
  138. return res.status(400).json({ msg: error.toString() })
  139. }
  140. }
  141. export default { getPlayerLists, getPlayerList, downloadPlayerList, parsePlayerList, deletePlayerList }