2021-09-30 07:29:25 -04:00
|
|
|
import getMeta from '../../../utils/meta'
|
|
|
|
import HumanReadableLogs from '../../../ide/human-readable-logs/HumanReadableLogs'
|
|
|
|
import BibLogParser from '../../../ide/log-parser/bib-log-parser'
|
|
|
|
import { buildFileList } from './file-list'
|
|
|
|
|
|
|
|
const searchParams = new URLSearchParams(window.location.search)
|
|
|
|
|
|
|
|
export const handleOutputFiles = async (projectId, data) => {
|
|
|
|
const result = {}
|
|
|
|
|
|
|
|
const outputFiles = new Map()
|
|
|
|
|
|
|
|
for (const outputFile of data.outputFiles) {
|
|
|
|
outputFiles.set(outputFile.path, outputFile)
|
|
|
|
}
|
|
|
|
|
|
|
|
const outputFile = outputFiles.get('output.pdf')
|
|
|
|
|
|
|
|
if (outputFile) {
|
|
|
|
// build the URL for viewing the PDF in the preview UI
|
|
|
|
const params = new URLSearchParams({
|
|
|
|
compileGroup: data.compileGroup,
|
|
|
|
})
|
|
|
|
|
|
|
|
if (data.clsiServerId) {
|
|
|
|
params.set('clsiserverid', data.clsiServerId)
|
|
|
|
}
|
|
|
|
|
|
|
|
if (searchParams.get('verify_chunks') === 'true') {
|
|
|
|
// Instruct the serviceWorker to verify composed ranges.
|
|
|
|
params.set('verify_chunks', 'true')
|
|
|
|
}
|
|
|
|
|
|
|
|
if (getMeta('ol-enablePdfCaching')) {
|
|
|
|
// Tag traffic that uses the pdf caching logic.
|
|
|
|
params.set('enable_pdf_caching', 'true')
|
|
|
|
}
|
|
|
|
|
|
|
|
result.pdfUrl = `${data.pdfDownloadDomain}${outputFile.url}?${params}`
|
|
|
|
|
|
|
|
// build the URL for downloading the PDF
|
|
|
|
params.set('popupDownload', 'true') // save PDF download as file
|
|
|
|
|
|
|
|
result.pdfDownloadUrl = `/download/project/${projectId}/build/${outputFile.build}/output/output.pdf?${params}`
|
|
|
|
}
|
|
|
|
|
|
|
|
const params = new URLSearchParams({
|
|
|
|
compileGroup: data.compileGroup,
|
|
|
|
})
|
|
|
|
|
|
|
|
if (data.clsiServerId) {
|
|
|
|
params.set('clsiserverid', data.clsiServerId)
|
|
|
|
}
|
|
|
|
|
|
|
|
result.logEntries = {
|
|
|
|
errors: [],
|
|
|
|
warnings: [],
|
|
|
|
typesetting: [],
|
|
|
|
}
|
|
|
|
|
|
|
|
function accumulateResults(newEntries, type) {
|
|
|
|
for (const key in result.logEntries) {
|
|
|
|
if (newEntries[key]) {
|
|
|
|
for (const entry of newEntries[key]) {
|
|
|
|
if (type) {
|
|
|
|
entry.type = newEntries.type
|
|
|
|
}
|
|
|
|
if (entry.file) {
|
|
|
|
entry.file = normalizeFilePath(entry.file)
|
|
|
|
}
|
|
|
|
entry.key = `${entry.file}:${entry.line}:${entry.column}:${entry.message}`
|
|
|
|
}
|
|
|
|
result.logEntries[key].push(...newEntries[key])
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
const logFile = outputFiles.get('output.log')
|
|
|
|
|
|
|
|
if (logFile) {
|
2021-10-21 04:10:56 -04:00
|
|
|
const response = await fetch(
|
|
|
|
`${data.pdfDownloadDomain}${logFile.url}?${params}`
|
|
|
|
)
|
2021-09-30 07:29:25 -04:00
|
|
|
|
|
|
|
const log = await response.text()
|
|
|
|
|
|
|
|
result.log = log
|
|
|
|
|
|
|
|
const { errors, warnings, typesetting } = HumanReadableLogs.parse(log, {
|
|
|
|
ignoreDuplicates: true,
|
|
|
|
})
|
|
|
|
|
|
|
|
accumulateResults({ errors, warnings, typesetting })
|
|
|
|
}
|
|
|
|
|
|
|
|
const blgFile = outputFiles.get('output.blg')
|
|
|
|
|
|
|
|
if (blgFile) {
|
2021-10-21 04:10:56 -04:00
|
|
|
const response = await fetch(
|
|
|
|
`${data.pdfDownloadDomain}${blgFile.url}?${params}`
|
|
|
|
)
|
2021-09-30 07:29:25 -04:00
|
|
|
|
|
|
|
const log = await response.text()
|
|
|
|
|
2021-11-25 05:23:16 -05:00
|
|
|
try {
|
|
|
|
const { errors, warnings } = new BibLogParser(log, {}).parse()
|
|
|
|
accumulateResults({ errors, warnings }, 'BibTeX:')
|
|
|
|
} catch (e) {
|
|
|
|
// BibLog parsing errors are ignored
|
|
|
|
}
|
2021-09-30 07:29:25 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
result.fileList = buildFileList(outputFiles, data.clsiServerId)
|
|
|
|
|
2021-11-25 05:24:25 -05:00
|
|
|
result.logEntries.all = [
|
|
|
|
...result.logEntries.errors,
|
|
|
|
...result.logEntries.warnings,
|
|
|
|
...result.logEntries.typesetting,
|
|
|
|
]
|
|
|
|
|
2021-09-30 07:29:25 -04:00
|
|
|
return result
|
|
|
|
}
|
|
|
|
|
|
|
|
export function buildLogEntryAnnotations(entries, fileTreeManager) {
|
|
|
|
const rootDocDirname = fileTreeManager.getRootDocDirname()
|
|
|
|
|
|
|
|
const logEntryAnnotations = {}
|
|
|
|
|
|
|
|
for (const entry of entries) {
|
|
|
|
if (entry.file) {
|
|
|
|
entry.file = normalizeFilePath(entry.file, rootDocDirname)
|
|
|
|
|
|
|
|
const entity = fileTreeManager.findEntityByPath(entry.file)
|
|
|
|
|
|
|
|
if (entity) {
|
|
|
|
if (!(entity.id in logEntryAnnotations)) {
|
|
|
|
logEntryAnnotations[entity.id] = []
|
|
|
|
}
|
|
|
|
|
|
|
|
logEntryAnnotations[entity.id].push({
|
|
|
|
row: entry.line - 1,
|
|
|
|
type: entry.level === 'error' ? 'error' : 'warning',
|
|
|
|
text: entry.message,
|
|
|
|
source: 'compile',
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return logEntryAnnotations
|
|
|
|
}
|
|
|
|
|
|
|
|
function normalizeFilePath(path, rootDocDirname) {
|
|
|
|
path = path.replace(
|
|
|
|
/^.*\/compiles\/[0-9a-f]{24}(-[0-9a-f]{24})?\/(\.\/)?/,
|
|
|
|
''
|
|
|
|
)
|
|
|
|
|
|
|
|
path = path.replace(/^\/compile\//, '')
|
|
|
|
|
|
|
|
if (rootDocDirname) {
|
|
|
|
path = path.replace(/^\.\//, rootDocDirname + '/')
|
|
|
|
}
|
|
|
|
|
|
|
|
return path
|
|
|
|
}
|