1 /*
2  * NotebookOutput.hpp
3  *
4  * Copyright (C) 2021 by RStudio, PBC
5  *
6  * Unless you have received this program directly from RStudio pursuant
7  * to the terms of a commercial license agreement with RStudio, then
8  * this program is licensed to you under the terms of version 3 of the
9  * GNU Affero General Public License. This program is distributed WITHOUT
10  * ANY EXPRESS OR IMPLIED WARRANTY, INCLUDING THOSE OF NON-INFRINGEMENT,
11  * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Please refer to the
12  * AGPL (http://www.gnu.org/licenses/agpl-3.0.txt) for more details.
13  *
14  */
15 
16 
17 #ifndef SESSION_NOTEBOOK_OUTPUT_HPP
18 #define SESSION_NOTEBOOK_OUTPUT_HPP
19 
20 #include <string>
21 
22 #include <shared_core/json/Json.hpp>
23 
24 #define kChunkOutputType     "output_type"
25 #define kChunkOutputValue    "output_val"
26 #define kChunkOutputOrdinal  "output_ordinal"
27 #define kChunkOutputMetadata "output_metadata"
28 #define kChunkUrl            "url"
29 #define kChunkId             "chunk_id"
30 #define kChunkDocId          "doc_id"
31 
32 #define kChunkOutputPath   "chunk_output"
33 
34 enum ChunkOutputType
35 {
36    ChunkOutputNone    = 0,
37    ChunkOutputText    = 1,
38    ChunkOutputPlot    = 2,
39    ChunkOutputHtml    = 3,
40    ChunkOutputError   = 4,
41    ChunkOutputOrdinal = 5,
42    ChunkOutputData    = 6
43 };
44 
45 #define kChunkConsoleInput  0
46 #define kChunkConsoleOutput 1
47 #define kChunkConsoleError  2
48 
49 #define kChunkLibDir "lib"
50 
51 namespace rstudio {
52 namespace core {
53    class FilePath;
54    class Error;
55 }
56 }
57 
58 namespace rstudio {
59 namespace session {
60 namespace modules {
61 namespace rmarkdown {
62 namespace notebook {
63 
64 // forms for requesting the chunk output folder
65 enum ChunkOutputContext
66 {
67    ContextExact = 0,   // always use the requested context
68    ContextSaved        // fall back to saved context if exact doesn't exist
69 };
70 
71 struct OutputPair
72 {
OutputPairrstudio::session::modules::rmarkdown::notebook::OutputPair73    OutputPair() :
74       outputType(ChunkOutputNone), ordinal(1)
75    {}
OutputPairrstudio::session::modules::rmarkdown::notebook::OutputPair76    OutputPair(ChunkOutputType type, unsigned ord):
77       outputType(type), ordinal(ord)
78    {}
79    ChunkOutputType outputType;
80    unsigned ordinal;
81 };
82 
83 // given a document ID and a chunk ID, discover the last output the chunk had
84 OutputPair lastChunkOutput(const std::string& docId,
85                            const std::string& chunkId,
86                            const std::string& nbCtxId);
87 
88 void updateLastChunkOutput(const std::string& docId,
89                            const std::string& chunkId,
90                            const OutputPair& pair);
91 
92 // compute chunk output folder paths for specific contexts
93 core::FilePath chunkOutputPath(
94       const std::string& docPath, const std::string& docId,
95       const std::string& chunkId, const std::string& nbCtxId,
96       ChunkOutputContext ctxType);
97 core::FilePath chunkOutputPath(const std::string& docId,
98       const std::string& chunkId, const std::string& nbCtxId,
99       ChunkOutputContext ctxType);
100 core::FilePath chunkOutputPath(const std::string& docId,
101       const std::string& chunkId, ChunkOutputContext ctxType);
102 
103 // compute individual chunk output unit paths
104 core::FilePath chunkOutputFile(const std::string& docId,
105       const std::string& chunkId, const std::string& nbCtxId,
106       const OutputPair& output);
107 
108 core::FilePath chunkOutputFile(const std::string& docId,
109       const std::string& chunkId, const std::string& nbCtxId,
110       ChunkOutputType outputType);
111 
112 core::Error cleanChunkOutput(const std::string& docId,
113       const std::string& chunkId, const std::string& nbCtxId,
114       bool preserveFolder);
115 
116 // helper for emitting console data to file
117 core::Error appendConsoleOutput(int chunkConsoleOutputType,
118                                 const std::string& output,
119                                 const core::FilePath& filePath);
120 
121 core::Error writeConsoleOutput(int chunkConsoleOutputType,
122                                const std::string& output,
123                                const core::FilePath& filePath,
124                                bool truncate);
125 
126 
127 // send chunk output to client
128 void enqueueChunkOutput(const std::string& docId,
129       const std::string& chunkId, const std::string& nbCtxId,
130       unsigned ordinal, ChunkOutputType outputType, const core::FilePath& path);
131 void enqueueChunkOutput(const std::string& docId,
132       const std::string& chunkId, const std::string& nbCtxId,
133       unsigned ordinal, ChunkOutputType outputType, const core::FilePath& path,
134       const core::json::Value& metadata);
135 core::Error enqueueChunkOutput(
136       const std::string& docPath, const std::string& docId,
137       const std::string& chunkId, const std::string& nbCtxId,
138       const std::string& requestId);
139 
140 core::Error initOutput();
141 
142 } // namespace notebook
143 } // namespace rmarkdown
144 } // namespace modules
145 } // namespace session
146 } // namespace rstudio
147 
148 #endif
149