Store program output
This commit is contained in:
parent
b3a473bef7
commit
1bb1782eea
|
@ -18,7 +18,7 @@ class Editor {
|
||||||
currentLanguage: string | null = null
|
currentLanguage: string | null = null
|
||||||
abortEval: AbortController | null = null
|
abortEval: AbortController | null = null
|
||||||
|
|
||||||
async initialize(form) {
|
initialize(form) {
|
||||||
this.languageSelector = form.querySelector('#language')
|
this.languageSelector = form.querySelector('#language')
|
||||||
this.wrapperButtons = new WrapperButtons(form.querySelector('#wrapper-buttons'), this.run.bind(this))
|
this.wrapperButtons = new WrapperButtons(form.querySelector('#wrapper-buttons'), this.run.bind(this))
|
||||||
this.codeElement = form.querySelector('#code')
|
this.codeElement = form.querySelector('#code')
|
||||||
|
@ -26,16 +26,45 @@ class Editor {
|
||||||
onChange(editor => this.changeEditor(editor))
|
onChange(editor => this.changeEditor(editor))
|
||||||
this.initConfiguredEditor()
|
this.initConfiguredEditor()
|
||||||
this.output = new Output(form.querySelector('#output'))
|
this.output = new Output(form.querySelector('#output'))
|
||||||
|
const stdout = document.querySelector<HTMLInputElement>('#dbstdout')
|
||||||
|
if (stdout) {
|
||||||
|
this.output.display({}, {
|
||||||
|
stdout: stdout.value,
|
||||||
|
stderr: document.querySelector<HTMLInputElement>('#dbstderr').value,
|
||||||
|
status: +document.querySelector<HTMLInputElement>('#dbstatus')?.value,
|
||||||
|
})
|
||||||
|
}
|
||||||
this.autodeleteText = form.querySelector('#autodelete-text')
|
this.autodeleteText = form.querySelector('#autodelete-text')
|
||||||
this.autodeleteCheckbox = form.querySelector('#automatically-hidden-label')
|
this.autodeleteCheckbox = form.querySelector('#automatically-hidden-label')
|
||||||
this.submit = form.querySelector('[type=submit]')
|
this.submit = form.querySelector('[type=submit]')
|
||||||
this.submit.disabled = true
|
this.submit.disabled = true
|
||||||
|
form.addEventListener('submit', () => {
|
||||||
|
if (this.output.json && !this.output.wrapper.isFormatter) {
|
||||||
|
for (const name of ['stdout', 'stderr', 'status']) {
|
||||||
|
const elem = form.querySelector(`#${name}`) || document.createElement('input')
|
||||||
|
elem.type = 'hidden'
|
||||||
|
elem.name = name
|
||||||
|
elem.value = this.output.json[name]
|
||||||
|
form.append(elem)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
this.stdinElement.value = ''
|
||||||
|
}
|
||||||
|
})
|
||||||
this.detailsElement = document.createElement('details')
|
this.detailsElement = document.createElement('details')
|
||||||
const summary = document.createElement('summary')
|
const summary = document.createElement('summary')
|
||||||
summary.textContent = 'Standard input'
|
summary.textContent = 'Standard input'
|
||||||
this.stdinElement = document.createElement('textarea')
|
this.stdinElement = document.createElement('textarea')
|
||||||
|
this.stdinElement.name = 'stdin'
|
||||||
|
this.stdinElement.addEventListener('change', () => this.changeToLookLikeNewPaste())
|
||||||
this.detailsElement.append(summary, this.stdinElement)
|
this.detailsElement.append(summary, this.stdinElement)
|
||||||
this.detailsElement.style.display = 'none'
|
const dbStdin = document.querySelector<HTMLInputElement>('#dbstdin')?.value
|
||||||
|
if (dbStdin) {
|
||||||
|
this.stdinElement.value = dbStdin
|
||||||
|
this.detailsElement.open = true
|
||||||
|
} else {
|
||||||
|
this.detailsElement.style.display = 'none'
|
||||||
|
}
|
||||||
form.querySelector('#buttons').append(this.detailsElement)
|
form.querySelector('#buttons').append(this.detailsElement)
|
||||||
if (this.autodeleteText) {
|
if (this.autodeleteText) {
|
||||||
this.autodeleteCheckbox.style.display = 'none'
|
this.autodeleteCheckbox.style.display = 'none'
|
||||||
|
@ -71,6 +100,7 @@ class Editor {
|
||||||
this.autodeleteCheckbox.style.display = ''
|
this.autodeleteCheckbox.style.display = ''
|
||||||
}
|
}
|
||||||
this.submit.disabled = false
|
this.submit.disabled = false
|
||||||
|
this.output.clear()
|
||||||
}
|
}
|
||||||
|
|
||||||
assignEvents() {
|
assignEvents() {
|
||||||
|
@ -134,5 +164,5 @@ class Editor {
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function createEditor(form) {
|
export default function createEditor(form) {
|
||||||
return new Editor().initialize(form)
|
new Editor().initialize(form)
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,19 +4,13 @@ const filterRegex = /(?:\t\.(?:text|file|section|globl|p2align|type|cfi_.*|size|
|
||||||
|
|
||||||
export default class Output {
|
export default class Output {
|
||||||
output: HTMLDivElement
|
output: HTMLDivElement
|
||||||
filterAsm: HTMLLabelElement
|
filterAsm = document.createElement('label')
|
||||||
filterAsmCheckbox: HTMLInputElement
|
filterAsmCheckbox = document.createElement('input')
|
||||||
wrapper: Wrapper
|
wrapper: Wrapper | null = null
|
||||||
json: {
|
json: { stdout: string, stderr: string, status: number | null } | null = null
|
||||||
stdout: string,
|
|
||||||
stderr: string,
|
|
||||||
status: number | null,
|
|
||||||
}
|
|
||||||
|
|
||||||
constructor(output) {
|
constructor(output) {
|
||||||
this.output = output
|
this.output = output
|
||||||
this.filterAsm = document.createElement('label')
|
|
||||||
this.filterAsmCheckbox = document.createElement('input')
|
|
||||||
this.filterAsmCheckbox.type = 'checkbox'
|
this.filterAsmCheckbox.type = 'checkbox'
|
||||||
this.filterAsmCheckbox.checked = true
|
this.filterAsmCheckbox.checked = true
|
||||||
this.filterAsmCheckbox.addEventListener('change', () => this.update())
|
this.filterAsmCheckbox.addEventListener('change', () => this.update())
|
||||||
|
@ -24,6 +18,7 @@ export default class Output {
|
||||||
}
|
}
|
||||||
|
|
||||||
clear() {
|
clear() {
|
||||||
|
this.json = null
|
||||||
this.output.textContent = ''
|
this.output.textContent = ''
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
ALTER TABLE pastes
|
||||||
|
DROP COLUMN stdin,
|
||||||
|
DROP COLUMN exit_code,
|
||||||
|
DROP COLUMN stdout,
|
||||||
|
DROP COLUMN stderr;
|
|
@ -0,0 +1,5 @@
|
||||||
|
ALTER TABLE pastes
|
||||||
|
ADD COLUMN stdin text NOT NULL DEFAULT '',
|
||||||
|
ADD COLUMN exit_code integer,
|
||||||
|
ADD COLUMN stdout text,
|
||||||
|
ADD COLUMN stderr text;
|
6
package-lock.json
generated
6
package-lock.json
generated
|
@ -4061,9 +4061,9 @@
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"typescript": {
|
"typescript": {
|
||||||
"version": "3.6.4",
|
"version": "3.7.2",
|
||||||
"resolved": "https://registry.npmjs.org/typescript/-/typescript-3.6.4.tgz",
|
"resolved": "https://registry.npmjs.org/typescript/-/typescript-3.7.2.tgz",
|
||||||
"integrity": "sha512-unoCll1+l+YK4i4F8f22TaNVPRHcD9PA3yCuZ8g5e0qGqlVlJ/8FSateOLLSagn+Yg5+ZwuPkL8LFUc0Jcvksg==",
|
"integrity": "sha512-ml7V7JfiN2Xwvcer+XAf2csGO1bPBdRbFCkYBczNZggrBZ9c7G3riSUeJmqEU5uOtXNPMhE3n+R4FA/3YOAWOQ==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"union-value": {
|
"union-value": {
|
||||||
|
|
|
@ -12,7 +12,7 @@
|
||||||
"prismjs": "^1.17.1",
|
"prismjs": "^1.17.1",
|
||||||
"style-loader": "^1.0.0",
|
"style-loader": "^1.0.0",
|
||||||
"ts-loader": "^6.2.0",
|
"ts-loader": "^6.2.0",
|
||||||
"typescript": "^3.6.4",
|
"typescript": "^3.7.2",
|
||||||
"webpack": "^4.40.2",
|
"webpack": "^4.40.2",
|
||||||
"webpack-cli": "^3.3.9",
|
"webpack-cli": "^3.3.9",
|
||||||
"webpack-stats-plugin": "^0.3.0"
|
"webpack-stats-plugin": "^0.3.0"
|
||||||
|
|
|
@ -18,6 +18,10 @@ pub struct Paste {
|
||||||
pub language_id: i32,
|
pub language_id: i32,
|
||||||
pub delete_at: Option<DateTime<Utc>>,
|
pub delete_at: Option<DateTime<Utc>>,
|
||||||
pub identifier: String,
|
pub identifier: String,
|
||||||
|
pub stdin: String,
|
||||||
|
pub exit_code: Option<i32>,
|
||||||
|
pub stdout: Option<String>,
|
||||||
|
pub stderr: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Paste {
|
impl Paste {
|
||||||
|
@ -42,6 +46,10 @@ struct InsertPaste {
|
||||||
delete_at: Option<DateTime<Utc>>,
|
delete_at: Option<DateTime<Utc>>,
|
||||||
language_id: i32,
|
language_id: i32,
|
||||||
paste: String,
|
paste: String,
|
||||||
|
stdin: String,
|
||||||
|
stdout: Option<String>,
|
||||||
|
stderr: Option<String>,
|
||||||
|
exit_code: Option<i32>,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn insert(
|
pub fn insert(
|
||||||
|
@ -49,6 +57,10 @@ pub fn insert(
|
||||||
delete_at: Option<DateTime<Utc>>,
|
delete_at: Option<DateTime<Utc>>,
|
||||||
language: &str,
|
language: &str,
|
||||||
paste: String,
|
paste: String,
|
||||||
|
stdin: String,
|
||||||
|
stdout: Option<String>,
|
||||||
|
stderr: Option<String>,
|
||||||
|
exit_code: Option<i32>,
|
||||||
) -> Result<String, Rejection> {
|
) -> Result<String, Rejection> {
|
||||||
let mut rng = rand::thread_rng();
|
let mut rng = rand::thread_rng();
|
||||||
let identifier: String = (0..10)
|
let identifier: String = (0..10)
|
||||||
|
@ -66,6 +78,10 @@ pub fn insert(
|
||||||
delete_at,
|
delete_at,
|
||||||
language_id,
|
language_id,
|
||||||
paste,
|
paste,
|
||||||
|
stdin,
|
||||||
|
stdout,
|
||||||
|
stderr,
|
||||||
|
exit_code,
|
||||||
};
|
};
|
||||||
diesel::insert_into(pastes::table)
|
diesel::insert_into(pastes::table)
|
||||||
.values(&insert_paste)
|
.values(&insert_paste)
|
||||||
|
@ -79,6 +95,10 @@ pub struct ExternPaste {
|
||||||
pub language_id: i32,
|
pub language_id: i32,
|
||||||
pub delete_at: Option<DateTime<Utc>>,
|
pub delete_at: Option<DateTime<Utc>>,
|
||||||
pub markdown: String,
|
pub markdown: String,
|
||||||
|
pub stdin: String,
|
||||||
|
pub exit_code: Option<i32>,
|
||||||
|
pub stdout: Option<String>,
|
||||||
|
pub stderr: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ExternPaste {
|
impl ExternPaste {
|
||||||
|
@ -88,6 +108,10 @@ impl ExternPaste {
|
||||||
language_id,
|
language_id,
|
||||||
identifier,
|
identifier,
|
||||||
delete_at,
|
delete_at,
|
||||||
|
stdin,
|
||||||
|
exit_code,
|
||||||
|
stdout,
|
||||||
|
stderr,
|
||||||
} = paste;
|
} = paste;
|
||||||
let markdown = if identifier == "markdown" {
|
let markdown = if identifier == "markdown" {
|
||||||
render_markdown(&paste)
|
render_markdown(&paste)
|
||||||
|
@ -99,6 +123,10 @@ impl ExternPaste {
|
||||||
language_id,
|
language_id,
|
||||||
delete_at,
|
delete_at,
|
||||||
markdown,
|
markdown,
|
||||||
|
stdin,
|
||||||
|
exit_code,
|
||||||
|
stdout,
|
||||||
|
stderr,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -69,6 +69,10 @@ pub fn insert_paste(
|
||||||
expiration.map(|expiration| Utc::now() + expiration.0),
|
expiration.map(|expiration| Utc::now() + expiration.0),
|
||||||
&language,
|
&language,
|
||||||
code,
|
code,
|
||||||
|
"".into(),
|
||||||
|
None,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
.compat()
|
.compat()
|
||||||
|
|
|
@ -24,6 +24,10 @@ pub fn display_paste(
|
||||||
pastes::language_id,
|
pastes::language_id,
|
||||||
pastes::delete_at,
|
pastes::delete_at,
|
||||||
languages::identifier,
|
languages::identifier,
|
||||||
|
pastes::stdin,
|
||||||
|
pastes::exit_code,
|
||||||
|
pastes::stdout,
|
||||||
|
pastes::stderr,
|
||||||
))
|
))
|
||||||
.filter(pastes::identifier.eq(requested_identifier))
|
.filter(pastes::identifier.eq(requested_identifier))
|
||||||
.get_result(connection)
|
.get_result(connection)
|
||||||
|
|
|
@ -15,6 +15,11 @@ pub struct PasteForm {
|
||||||
language: String,
|
language: String,
|
||||||
code: String,
|
code: String,
|
||||||
autodelete: Option<IgnoredAny>,
|
autodelete: Option<IgnoredAny>,
|
||||||
|
#[serde(default)]
|
||||||
|
stdin: String,
|
||||||
|
stdout: Option<String>,
|
||||||
|
stderr: Option<String>,
|
||||||
|
status: Option<i32>,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn insert_paste(
|
pub fn insert_paste(
|
||||||
|
@ -22,12 +27,25 @@ pub fn insert_paste(
|
||||||
language,
|
language,
|
||||||
code,
|
code,
|
||||||
autodelete,
|
autodelete,
|
||||||
|
stdin,
|
||||||
|
stdout,
|
||||||
|
stderr,
|
||||||
|
status,
|
||||||
}: PasteForm,
|
}: PasteForm,
|
||||||
connection: Connection,
|
connection: Connection,
|
||||||
) -> impl Future<Item = impl Reply, Error = Rejection> {
|
) -> impl Future<Item = impl Reply, Error = Rejection> {
|
||||||
blocking::run(move || {
|
blocking::run(move || {
|
||||||
let delete_at = autodelete.map(|_| Utc::now() + Duration::hours(24));
|
let delete_at = autodelete.map(|_| Utc::now() + Duration::hours(24));
|
||||||
let identifier = paste::insert(&connection, delete_at, &language, code)?;
|
let identifier = paste::insert(
|
||||||
|
&connection,
|
||||||
|
delete_at,
|
||||||
|
&language,
|
||||||
|
code,
|
||||||
|
stdin,
|
||||||
|
stdout,
|
||||||
|
stderr,
|
||||||
|
status,
|
||||||
|
)?;
|
||||||
Ok(reply::with_header(
|
Ok(reply::with_header(
|
||||||
StatusCode::SEE_OTHER,
|
StatusCode::SEE_OTHER,
|
||||||
LOCATION,
|
LOCATION,
|
||||||
|
|
|
@ -37,6 +37,10 @@ table! {
|
||||||
created_at -> Timestamptz,
|
created_at -> Timestamptz,
|
||||||
language_id -> Int4,
|
language_id -> Int4,
|
||||||
paste -> Text,
|
paste -> Text,
|
||||||
|
stdin -> Text,
|
||||||
|
exit_code -> Nullable<Int4>,
|
||||||
|
stdout -> Nullable<Text>,
|
||||||
|
stderr -> Nullable<Text>,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -47,6 +47,9 @@ textarea {
|
||||||
height: 372px;
|
height: 372px;
|
||||||
resize: vertical;
|
resize: vertical;
|
||||||
}
|
}
|
||||||
|
[name=stdin] {
|
||||||
|
height: 124px;
|
||||||
|
}
|
||||||
#right-buttons {
|
#right-buttons {
|
||||||
float: right;
|
float: right;
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,4 +22,14 @@
|
||||||
<p><textarea id=code name=code>@('\n')@paste.paste</textarea></p>
|
<p><textarea id=code name=code>@('\n')@paste.paste</textarea></p>
|
||||||
@:buttons()
|
@:buttons()
|
||||||
</form>
|
</form>
|
||||||
|
<input type=hidden id=dbstdin value="@paste.stdin">
|
||||||
|
@if let Some(exit_code) = paste.exit_code {
|
||||||
|
<input type=hidden id=dbstatus value="@exit_code">
|
||||||
|
}
|
||||||
|
@if let Some(stdout) = paste.stdout {
|
||||||
|
<input type=hidden id=dbstdout value="@stdout">
|
||||||
|
}
|
||||||
|
@if let Some(stderr) = paste.stderr {
|
||||||
|
<input type=hidden id=dbstderr value="@stderr">
|
||||||
|
}
|
||||||
@:footer(session)
|
@:footer(session)
|
||||||
|
|
Loading…
Reference in New Issue
Block a user