output-files.js 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155
  1. import getMeta from '../../../utils/meta'
  2. import HumanReadableLogs from '../../../ide/human-readable-logs/HumanReadableLogs'
  3. import BibLogParser from '../../../ide/log-parser/bib-log-parser'
  4. import { buildFileList } from './file-list'
  5. const searchParams = new URLSearchParams(window.location.search)
  6. export const handleOutputFiles = async (projectId, data) => {
  7. const result = {}
  8. const outputFiles = new Map()
  9. for (const outputFile of data.outputFiles) {
  10. outputFiles.set(outputFile.path, outputFile)
  11. }
  12. const outputFile = outputFiles.get('output.pdf')
  13. if (outputFile) {
  14. // build the URL for viewing the PDF in the preview UI
  15. const params = new URLSearchParams({
  16. compileGroup: data.compileGroup,
  17. })
  18. if (data.clsiServerId) {
  19. params.set('clsiserverid', data.clsiServerId)
  20. }
  21. if (searchParams.get('verify_chunks') === 'true') {
  22. // Instruct the serviceWorker to verify composed ranges.
  23. params.set('verify_chunks', 'true')
  24. }
  25. if (getMeta('ol-enablePdfCaching')) {
  26. // Tag traffic that uses the pdf caching logic.
  27. params.set('enable_pdf_caching', 'true')
  28. }
  29. result.pdfUrl = `${data.pdfDownloadDomain}${outputFile.url}?${params}`
  30. // build the URL for downloading the PDF
  31. params.set('popupDownload', 'true') // save PDF download as file
  32. result.pdfDownloadUrl = `/download/project/${projectId}/build/${outputFile.build}/output/output.pdf?${params}`
  33. }
  34. const params = new URLSearchParams({
  35. compileGroup: data.compileGroup,
  36. })
  37. if (data.clsiServerId) {
  38. params.set('clsiserverid', data.clsiServerId)
  39. }
  40. result.logEntries = {
  41. all: [],
  42. errors: [],
  43. warnings: [],
  44. typesetting: [],
  45. }
  46. function accumulateResults(newEntries, type) {
  47. for (const key in result.logEntries) {
  48. if (newEntries[key]) {
  49. for (const entry of newEntries[key]) {
  50. if (type) {
  51. entry.type = newEntries.type
  52. }
  53. if (entry.file) {
  54. entry.file = normalizeFilePath(entry.file)
  55. }
  56. entry.key = `${entry.file}:${entry.line}:${entry.column}:${entry.message}`
  57. }
  58. result.logEntries[key].push(...newEntries[key])
  59. result.logEntries.all.push(...newEntries[key])
  60. }
  61. }
  62. }
  63. const logFile = outputFiles.get('output.log')
  64. if (logFile) {
  65. const response = await fetch(`${logFile.url}?${params}`)
  66. const log = await response.text()
  67. result.log = log
  68. const { errors, warnings, typesetting } = HumanReadableLogs.parse(log, {
  69. ignoreDuplicates: true,
  70. })
  71. accumulateResults({ errors, warnings, typesetting })
  72. }
  73. const blgFile = outputFiles.get('output.blg')
  74. if (blgFile) {
  75. const response = await fetch(`${blgFile.url}?${params}`)
  76. const log = await response.text()
  77. const { errors, warnings } = new BibLogParser(log, {}).parse()
  78. accumulateResults({ errors, warnings }, 'BibTeX:')
  79. }
  80. result.fileList = buildFileList(outputFiles, data.clsiServerId)
  81. return result
  82. }
  83. export function buildLogEntryAnnotations(entries, fileTreeManager) {
  84. const rootDocDirname = fileTreeManager.getRootDocDirname()
  85. const logEntryAnnotations = {}
  86. for (const entry of entries) {
  87. if (entry.file) {
  88. entry.file = normalizeFilePath(entry.file, rootDocDirname)
  89. const entity = fileTreeManager.findEntityByPath(entry.file)
  90. if (entity) {
  91. if (!(entity.id in logEntryAnnotations)) {
  92. logEntryAnnotations[entity.id] = []
  93. }
  94. logEntryAnnotations[entity.id].push({
  95. row: entry.line - 1,
  96. type: entry.level === 'error' ? 'error' : 'warning',
  97. text: entry.message,
  98. source: 'compile',
  99. })
  100. }
  101. }
  102. }
  103. return logEntryAnnotations
  104. }
  105. function normalizeFilePath(path, rootDocDirname) {
  106. path = path.replace(
  107. /^.*\/compiles\/[0-9a-f]{24}(-[0-9a-f]{24})?\/(\.\/)?/,
  108. ''
  109. )
  110. path = path.replace(/^\/compile\//, '')
  111. if (rootDocDirname) {
  112. path = path.replace(/^\.\//, rootDocDirname + '/')
  113. }
  114. return path
  115. }