Skip to content

Commit

Permalink
Merge remote-tracking branch 'upstream/master'
Browse files Browse the repository at this point in the history
* upstream/master:
  batch/apispec uses components.
  Dewarn
  Support foldup on a text input.
  Only show a comment as by the shepherd if they are currently the shepherd.
  Prefer 'collapsed' to 'folded' in review/comment JSON.
  Improve TokenInfo store API.
  Dewarn.
  Reset commentData.mentions to null when editing a comment to remove last @.
  Add hopefully-useful debugging about show:show.
  Correct crash in FormulaGraph.
  Make treatment of Job_Capability `argv` input consistent.
  Types
  Add Job_Capability::run_background.
  Add Capability.lookupKey.
  monitor_job: Look for `.is-job-progress`, rather than any <p>.
  Strip top-level parentheses from inferred legends.
  Author_PaperOption exports its max setting.
  • Loading branch information
xcompass committed Mar 27, 2024
2 parents 925321f + 8b30121 commit 7ea57f9
Show file tree
Hide file tree
Showing 35 changed files with 505 additions and 240 deletions.
61 changes: 53 additions & 8 deletions batch/apispec.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@ class APISpec_Batch {
public $user;
/** @var array<string,list<object>> */
public $api_map;
/** @var array<string,object> */
public $schemas = [];
/** @var array<string,object> */
public $parameters = [];

function __construct(Conf $conf, $arg) {
$this->conf = $conf;
Expand All @@ -37,13 +41,24 @@ function run() {
$paths[$path] = $this->expand($fn);
}
}
fwrite(STDOUT, json_encode([
$components = [];
if (!empty($this->schemas)) {
$components["schemas"] = $this->schemas;
}
if (!empty($this->parameters)) {
$components["parameters"] = $this->parameters;
}
$j = [
"openapi" => "3.0.0",
"info" => [
"title" => "HotCRP"
],
"paths" => $paths
], JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT) . "\n");
];
if (!empty($components)) {
$j["components"] = $components;
}
fwrite(STDOUT, json_encode($j, JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT) . "\n");
return 0;
}

Expand All @@ -58,22 +73,52 @@ private function expand($fn) {
return $x;
}

/** @param string $name
* @return array */
private function resolve_common_schema($name) {
if (!isset($this->schemas[$name])) {
if ($name === "pid") {
$this->schemas[$name] = [
"type" => "integer",
"minimum" => 1
];
} else {
assert(false);
}
}
return ["\$ref" => "#/components/schemas/{$name}"];
}

/** @param string $name
* @return array */
private function resolve_common_param($name) {
if (!isset($this->parameters[$name])) {
if ($name === "p") {
$this->parameters[$name] = [
"name" => "p",
"in" => "path",
"required" => true,
"schema" => $this->resolve_common_schema("pid")
];
} else {
assert(false);
}
}
return ["\$ref" => "#/components/parameters/{$name}"];
}

/** @return object */
private function expand1($fn, $method, $j) {
$x = (object) [];
$params = [];
if ($j->paper ?? false) {
$params["p"] = [
"name" => "p",
"in" => "path",
"required" => true
];
$params[] = $this->resolve_common_param("p");
}
$mparameters = strtolower($method) . "_parameters";
foreach ($j->$mparameters ?? $j->parameters ?? [] as $p) {
$optional = str_starts_with($p, "?");
$name = $optional ? substr($p, 1) : $p;
$params[$name] = [
$params[] = [
"name" => $name,
"in" => "query",
"required" => !$optional
Expand Down
10 changes: 8 additions & 2 deletions batch/autoassign.php
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<?php
<?php /*{hotcrp Autoassign_Batch}*/
// autoassign.php -- HotCRP autoassignment script
// Copyright (c) 2006-2024 Eddie Kohler; see LICENSE.

Expand Down Expand Up @@ -76,7 +76,7 @@ function __construct(Conf $conf, $arg, Getopt $getopt, $detacher = null) {
try {
$this->_jtok->update_use();
$this->parse_arg($arg);
$this->parse_arg($getopt->parse($this->_jtok->input("assign_argv") ?? []));
$this->parse_arg($getopt->parse($this->_jtok->input("assign_argv") ?? [], 0));
$this->complete_arg();
} catch (CommandLineException $ex) {
$this->report([MessageItem::error("<0>{$ex->getMessage()}")], $ex->exitStatus);
Expand Down Expand Up @@ -121,6 +121,12 @@ private function reportx($message_list, $exit_status = null) {
assert(false);
}

/** @param string $msg */
static private function my_error_log($msg) {
error_log($msg);
file_put_contents("/tmp/hotcrp.log", $msg, FILE_APPEND);
}

/** @param associative-array $arg */
private function parse_arg($arg) {
$this->quiet = $this->quiet || isset($arg["quiet"]);
Expand Down
5 changes: 3 additions & 2 deletions lib/getopt.php
Original file line number Diff line number Diff line change
Expand Up @@ -410,15 +410,16 @@ static function value_allowed($s) {
}

/** @param list<string> $argv
* @param ?int $first_arg
* @return array<string,string|int|float|list<string>> */
function parse($argv) {
function parse($argv, $first_arg = null) {
$res = [];
$rest = [];
$pot = 0;
$active_po = null;
$oname = $name = "";
$odone = false;
for ($i = 1; $i !== count($argv); ++$i) {
for ($i = $first_arg ?? 1; $i !== count($argv); ++$i) {
$arg = $argv[$i];
$po = null;
$wantpo = $value = false;
Expand Down
6 changes: 3 additions & 3 deletions lib/mailer.php
Original file line number Diff line number Diff line change
Expand Up @@ -286,9 +286,9 @@ function kw_passwordlink($args, $isbool, $uf) {
} else {
$capinfo->set_user($this->recipient)->set_token_pattern("hcpw0[20]");
}
$capinfo->set_expires_after(259200);
$token = $capinfo->create();
$this->preparation->reset_capability = $token;
$capinfo->set_expires_after(259200)->insert();
assert($capinfo->stored());
$this->preparation->reset_capability = $capinfo->salt;
}
$token = $this->censor ? "HIDDEN" : $this->preparation->reset_capability;
return $this->conf->hoturl_raw("resetpassword", null, Conf::HOTURL_ABSOLUTE | Conf::HOTURL_NO_DEFAULTS) . "/" . urlencode($token);
Expand Down
42 changes: 28 additions & 14 deletions lib/qrequest.php
Original file line number Diff line number Diff line change
Expand Up @@ -776,6 +776,34 @@ function maybe_post_value() {
return ".empty";
}
}


/** @return array<string,string|list> */
function debug_json() {
$a = [];
foreach ($this->_v as $k => $v) {
if ($v === "__array__" && ($av = $this->_a[$k] ?? null) !== null) {
if (count($av) > 20) {
$av = array_slice($av, 0, 20);
$av[] = "...";
}
$a[$k] = $av;
} else if ($v !== null) {
if (strlen($v) > 120) {
$v = substr($v, 0, 117) . "...";
}
$a[$k] = $v;
}
}
foreach ($this->_files as $k => $v) {
$fv = ["name" => $v->name, "type" => $v->type, "size" => $v->size];
if ($v->error) {
$fv["error"] = $v->error;
}
$a[$k] = $v;
}
return $a;
}
}

class QrequestFile {
Expand All @@ -801,18 +829,4 @@ function __construct($a) {
$this->content = $a["content"] ?? null;
$this->error = $a["error"] ?? 0;
}

/** @return array{name:string,type:string,size:int,tmp_name?:string,content?:string,error:int}
* @deprecated */
function as_array() {
$a = ["name" => $this->name, "type" => $this->type, "size" => $this->size];
if ($this->tmp_name !== null) {
$a["tmp_name"] = $this->tmp_name;
}
if ($this->content !== null) {
$a["content"] = $this->content;
}
$a["error"] = $this->error;
return $a;
}
}
57 changes: 33 additions & 24 deletions scripts/script.js
Original file line number Diff line number Diff line change
Expand Up @@ -4425,7 +4425,7 @@ function foldup(evt, opts) {
}
}
if (!("open" in opts)
&& (this.tagName === "INPUT" || this.tagName === "SELECT")) {
&& (this.tagName === "INPUT" || this.tagName === "SELECT" || this.tagName === "TEXTAREA")) {
var value = null;
if (this.type === "checkbox") {
opts.open = this.checked;
Expand All @@ -4435,9 +4435,12 @@ function foldup(evt, opts) {
value = this.value;
} else if (this.type === "select-one") {
value = this.selectedIndex < 0 ? "" : this.options[this.selectedIndex].value;
} else if (this.type === "text" || this.type === "textarea") {
opts.open = this.value !== "";
}
if (value !== null) {
var values = (e.getAttribute("data-" + foldname + "-values") || "").split(/\s+/);
var vstr = e.getAttribute("data-" + foldname + "-values") || "",
values = $.trim(vstr) === "" ? [] : vstr.split(/\s+/);
opts.open = values.indexOf(value) >= 0;
}
}
Expand Down Expand Up @@ -5266,7 +5269,7 @@ hotcrp.monitor_job = function (jobid, statuselt) {
}
if (data.progress != null || data.status === "done") {
let ex = statuselt.firstElementChild;
while (ex && ex.nodeName !== "P" && ex.nodeName !== "PROGRESS") {
while (ex && !hasClass(ex, "is-job-progress") && ex.nodeName !== "PROGRESS") {
ex = ex.nextElementSibling;
}
if (!ex || ex.nodeName !== "PROGRESS") {
Expand All @@ -5286,11 +5289,11 @@ hotcrp.monitor_job = function (jobid, statuselt) {
}
if (data.progress && data.progress !== true) {
let ex = statuselt.firstElementChild;
while (ex && ex.nodeName !== "P") {
while (ex && !hasClass(ex, "is-job-progress")) {
ex = ex.nextElementSibling;
}
if (!ex) {
ex = $e("p", "mb-0");
ex = $e("p", "mb-0 is-job-progress");
statuselt.appendChild(ex);
}
ex.replaceChildren($e("strong", null, "Status:"), " " + data.progress.replace(/\.*$/, "..."));
Expand Down Expand Up @@ -6284,7 +6287,7 @@ function revrating_key(evt) {

function make_review_h2(rrow, rlink, rdesc) {
let h2 = $e("h2"), ma, rd = $e("span");
if (rrow.folded) {
if (rrow.collapsed) {
ma = $e("button", {type: "button", "class": "qo ui js-foldup", "data-fold-target": 20}, make_expander_element(20));
} else {
ma = $e("a", {href: hoturl("review", rlink), "class": "qo"});
Expand All @@ -6294,7 +6297,7 @@ function make_review_h2(rrow, rlink, rdesc) {
ma.append(rd);
h2.append(ma);
if (rrow.editable) {
if (rrow.folded) {
if (rrow.collapsed) {
ma = $e("a", {href: hoturl("review", rlink), "class": "qo"});
h2.append(" ", ma);
} else {
Expand Down Expand Up @@ -6362,10 +6365,12 @@ hotcrp.add_review = function (rrow) {
rdesc = "Draft " + rdesc;
if (rrow.ordinal)
rdesc += " #" + rid;
if (rrow.folded && rrow.collapsed == null) /* XXX */
rrow.collapsed = rrow.folded;

earticle = document.createElement("article");
earticle.id = "r" + rid;
earticle.className = "pcard revcard need-anchor-unfold has-fold fold20" + (rrow.folded ? "c" : "o");
earticle.className = "pcard revcard need-anchor-unfold has-fold fold20" + (rrow.collapsed ? "c" : "o");
earticle.setAttribute("data-pid", rrow.pid);
earticle.setAttribute("data-rid", rrow.rid);
rrow.ordinal && earticle.setAttribute("data-review-ordinal", rrow.ordinal);
Expand Down Expand Up @@ -7238,6 +7243,8 @@ function cmt_save_callback(cj) {
if (!data.cmt && editing_response) {
data.cmt = {is_new: true, response: cj.response, editable: true};
}
if (data.cmt && data.cmt.folded && data.cmt.collapsed == null) /* XXX */
data.cmt.collapsed = data.cmt.folded;
var new_cid = data.cmt ? cj_cid(data.cmt) : null;
if (new_cid) {
cmts[new_cid] = data.cmt;
Expand Down Expand Up @@ -7329,7 +7336,7 @@ function cmt_button_click(evt) {
evt.preventDefault();
cmt_save(this, "submit");
} else if (this.name === "cancel") {
cj.folded && fold(this.closest(".cmtcard"), true, 20);
cj.collapsed && fold(this.closest(".cmtcard"), true, 20);
cmt_render(cj, false);
} else if (this.name === "delete") {
override_deadlines.call(this, function () {
Expand Down Expand Up @@ -7388,15 +7395,15 @@ function cmt_render(cj, editing) {
if (cj.response && cj.text !== false) {
const h2 = $e("h2");
let cnc = h2;
if (cj.folded && !editing) {
if (cj.collapsed && !editing) {
cnc = $e("button", {type: "button", "class": "qo ui js-foldup", "data-fold-target": 20}, make_expander_element(20));
} else if (cj.editable && !editing) {
cnc = $e("button", {type: "button", "class": "qo ui cmteditor"});
}
h2 === cnc || h2.append(cnc);
cnc.append($e("span", "cmtcard-header-name", cj_name(cj)));
if (cj.editable && !editing) {
if (cj.folded) {
if (cj.collapsed) {
cnc = $e("button", {type: "button", "class": "qo ui cmteditor"});
h2.append(" ", cnc);
}
Expand Down Expand Up @@ -7508,6 +7515,8 @@ function cmt_render_preview(evt, format, value, dest) {

function add_comment(cj, editing) {
var cid = cj_cid(cj), celt = $$(cid);
if (cj.folded && cj.collapsed == null) /* XXX */
cj.collapsed = cj.folded;
cmts[cid] = cj;
if (editing == null
&& cj.response
Expand All @@ -7517,9 +7526,9 @@ function add_comment(cj, editing) {
&& hotcrp.status.myperm.is_author) {
editing = 2;
}
if (cj.folded
if (cj.collapsed
&& cj.text === false) {
cj.folded = false;
cj.collapsed = false;
}
if (celt) {
cmt_render(cj, editing);
Expand Down Expand Up @@ -7557,7 +7566,7 @@ function add_new_comment_button(cj, cid) {

function add_new_comment(cj, cid) {
document.querySelector(".pcontainer").insertBefore($e("article", {
id: cid, "class": "pcard cmtcard cmtid comment need-anchor-unfold has-fold ".concat(cj.folded ? "fold20c" : "fold20o", cj.editable ? " editable" : "")
id: cid, "class": "pcard cmtcard cmtid comment need-anchor-unfold has-fold ".concat(cj.collapsed ? "fold20c" : "fold20o", cj.editable ? " editable" : "")
}), $$("k-comment-actions"));
}

Expand Down Expand Up @@ -12986,7 +12995,7 @@ handle_ui.on("js-edit-namedsearches", function () {
}, svge_use_licon("trash")));
qentry.append($e("textarea", {
id: "k-named_search/" + count + "/search",
"name": "named_search/" + count + "/search",
name: "named_search/" + count + "/search",
"class": "editsearches-query need-autogrow w-99",
rows: 1, cols: 64, placeholder: "(All)"
}, f.q))
Expand Down Expand Up @@ -13023,16 +13032,16 @@ handle_ui.on("js-edit-namedsearches", function () {
}
}
function ondelete() {
var $x = $(this).closest(".editsearches-search");
if ($x[0].hasAttribute("data-search-new"))
$x.addClass("hidden");
else {
$x.find(".editsearches-query").closest(".entryi").addClass("hidden");
$x.find(".editsearches-name").prop("disabled", true).css("text-decoration", "line-through");
$x.find(".delete-link").prop("disabled", true);
$x.append(render_feedback_list([{status: 1, message: "<0>This named search will be deleted."}]));
var fs = this.closest("fieldset");
if (fs.hasAttribute("data-search-new")) {
addClass(fs, "hidden");
} else {
$(fs).find(".editsearches-query").closest(".entryi").addClass("hidden");
$(fs).find(".editsearches-name").prop("disabled", true).css("text-decoration", "line-through");
$(fs).find(".delete-link").prop("disabled", true);
fs.append(render_feedback_list([{status: 1, message: "<0>This named search will be deleted."}]));
}
$x.append(hidden_input("named_search/" + $x.data("searchNumber") + "/delete", 1));
fs.append(hidden_input("named_search/" + fs.getAttribute("data-search-number") + "/delete", 1));
}
function submit(evt) {
evt.preventDefault();
Expand Down
Loading

0 comments on commit 7ea57f9

Please sign in to comment.