Ticket #7786: trac_7786-template-jinja-idiomatic.10.patch
| File trac_7786-template-jinja-idiomatic.10.patch, 266.3 KB (added by mpatel, 3 years ago) |
|---|
-
deleted file sagenb/data/highlight/prettify.css
# HG changeset patch # User Mitesh Patel <qed777@gmail.com> # Date 1262826026 28800 # Node ID 52aad8c8742e464d4a7907226ea02d4df3487a5e # Parent cc5ea607663824397f62312a594b4029297ff43f [mq]: trac_7786-template-jinja-idiomatic.5.patch diff --git a/sagenb/data/highlight/prettify.css b/sagenb/data/highlight/prettify.css deleted file mode 100644
+ - 1 /* Pretty printing styles. Used with prettify.js. */2 3 .str { color: #080; }4 .kwd { color: #008; }5 .com { color: #800; }6 .typ { color: #606; }7 .lit { color: #066; }8 .pun { color: #660; }9 .pln { color: #000; }10 .tag { color: #008; }11 .atn { color: #606; }12 .atv { color: #080; }13 .dec { color: #606; }14 pre.prettyprint { padding: 2px; border: 1px solid #888; }15 16 @media print {17 .str { color: #060; }18 .kwd { color: #006; font-weight: bold; }19 .com { color: #600; font-style: italic; }20 .typ { color: #404; font-weight: bold; }21 .lit { color: #044; }22 .pun { color: #440; }23 .pln { color: #000; }24 .tag { color: #006; font-weight: bold; }25 .atn { color: #404; }26 .atv { color: #060; }27 } -
deleted file sagenb/data/sage/css/account_settings.css
diff --git a/sagenb/data/sage/css/account_settings.css b/sagenb/data/sage/css/account_settings.css deleted file mode 100644
+ - 1 html, body, div, span, applet, object, iframe, h1, h2, h3, h4, h5, h6, p, blockquote, pre, a, abbr, acronym, address, big, cite, code, del, dfn, em, font, img, ins, kbd, q, s, samp, small, strike, strong, sub, sup, tt, var, dl, dt, dd, ol, ul, li, fieldset, form, label, legend, table, caption, tbody, tfoot, thead, tr, th, td { margin: 0; padding: 0; border: 0; outline: 0; font-weight: inherit; font-style: inherit; font-size: 100%; font-family: inherit; vertical-align: baseline; }2 3 *:focus { outline: 0; }4 5 body { line-height: 1em; color: black; background: #fff; }6 7 ol, ul { list-style: none; }8 9 /* tables still need 'cellspacing="0"' in the markup */10 table { border-collapse: separate; border-spacing: 0; vertical-align: middle; }11 12 caption, th, td { text-align: left; font-weight: normal; vertical-align: middle; }13 14 q, blockquote { quotes: "" ""; }15 q:before, q:after, blockquote:before, blockquote:after { content: ""; }16 17 img a { border: none; }18 19 html { font-size: 100.1%; }20 21 body { font: 100%/1.4 Arial, Helvetica, sans-serif; }22 23 h1 { background: #DCDCDC; border-bottom: 1px solid #CCC; font-size: 2em; padding: 0 5px; }24 25 label { display: block; }26 27 #buttons { background: #DCDCDC; padding: 5px; }28 #buttons button { margin-right: 1em; }29 30 h2 { font-size: 1.5em; }31 32 .section { border-bottom: 1px solid #CCC; padding: 5px; }33 .section div { margin-bottom: 0.5em; }34 35 .error { color: red; }36 37 .updated { color: green; }38 39 input.c1 { width: 200px; } -
sagenb/data/sage/css/main.css
diff --git a/sagenb/data/sage/css/main.css b/sagenb/data/sage/css/main.css
a b 1 /* Warning: These .css files are automatically generated and will be overwritten */ 2 /* when they are next generated. Please edit the SASS source located at */ 3 /* <sagenb-spkg-root>/sass/src. Kindly refer to the readme for editing */ 4 /* instructions at <sagenb-spkg-root>/sass */ 1 5 thead { font-weight: bold; } 2 6 3 body { background-color: white; }7 body { background-color: white; font-family: "Gill Sans", "Gill Sans MT", "Myriad Pro", Myriad, "Liberation Sans", "Nimbus Sans L", Tahoma, Geneva, "Helvetica Neue", Helvetica, Arial, sans-serif; } 4 8 body.worksheet-online { margin-bottom: 80%; } 5 9 6 10 .hidden { display: none; } 7 11 8 12 div.fivepix { height: 5px; } 9 13 10 /* ****** Top Bar (Banner, controls, etc.) ******** */11 14 body div#banner { font-size: 1.2em; float: left; margin: 0; max-width: 35%; } 12 15 body div#banner a.banner { text-decoration: none; border: none; margin-top: 2px; float: left; position: relative; } 13 16 body div#banner a.banner:visited { color: #1950c8; } … … body div#banner a.banner span { margin-l 16 19 body div#banner #ping { float: left; } 17 20 body div#banner div.version { float: left; clear: left; font-size: xx-small; text-indent: 13px; color: black; } 18 21 19 #controls { float: right; width: 65%; } 20 #controls ul { list-style: none; margin: 0; padding: 0; text-align: right; } 21 #controls ul li { border-right: 1px solid #000; color: #112abb; display: inline; font-size: 14px; margin: 0; padding: 0 0.5em; } 22 #controls ul li:last-child { border-right: 0; } 23 #controls ul li.username { border: 0; color: #000; font-family: sans-serif; font-weight: bold; padding: 0; } 24 #controls ul a { text-decoration: underline; white-space: nowrap; } 25 #controls ul a:hover { cursor: pointer; } 22 #main-controls { float: right; width: 65%; } 23 #main-controls ul { list-style: none; margin: 0; padding: 0; text-align: right; } 24 #main-controls ul li { border-right: 1px solid #000; color: #112abb; display: inline; font-size: 14px; margin: 0; padding: 0 0.5em; } 25 #main-controls ul li:last-child { border-right: 0; } 26 #main-controls ul li.username { border: 0; color: #000; font-family: sans-serif; font-weight: bold; padding: 0; } 27 #main-controls ul a { text-decoration: underline; white-space: nowrap; } 28 #main-controls ul a:hover { cursor: pointer; } 29 #main-controls ul #toggle-link { display: none; } 30 31 .worksheet-online #main-controls ul #toggle-link { display: inline; } 26 32 27 33 #top-bar { position: relative; padding: 10px 5px; border-bottom: 1px solid #c9d7f1; min-height: 40px; margin-bottom: 0.5em; overflow: hidden; display: inline-block; } 28 34 #top-bar { display: block; } … … body div#banner div.version { float: lef 31 37 32 38 hr.usercontrol { clear: both; float: left; } 33 39 34 div#user controls { overflow: hidden; display: inline-block; clear: both; border-bottom: 1px solid #c9d7f1; padding: 10px; }35 div#user controls { display: block; }40 div#user-controls { overflow: hidden; display: inline-block; clear: both; border-bottom: 1px solid #c9d7f1; padding: 10px; } 41 div#user-controls { display: block; } 36 42 div#worksheet-list-controls { padding: 10px; clear: both; overflow: hidden; display: inline-block; } 37 43 div#worksheet-list-controls { display: block; } 38 44 div#worksheet-list-controls div.action-buttons { float: left; } … … span.pane div.worksheet_list { position: 172 178 a.new_worksheet { font-family: arial, monospace; font-size: 12pt; text-align: right; color: #0000aa; } 173 179 a.new_worksheet:hover { cursor: pointer; } 174 180 175 div.worksheet_bottom_padding { height: 50%; }176 div.worksheet_top_padding { height: 5%; }177 181 div.worksheet_menu { top: 50px; } 178 182 179 183 a.worksheet_title { text-decoration: none; font-size: 20px; font-family: arial; font-weight: bold; color: #000000; } … … span.control a.cs { color: #777777; text 212 216 span.control:hover a.cs, span.control a:hover.cs { color: black; border: 1px solid #333333; } 213 217 214 218 /* *********** WORKSHEET ************************* */ 215 div.worksheet { background-color: white; border: 1px solid #aaa; }219 div.worksheet { background-color: white; border: 1px solid #aaa; padding: .75em 0.2em; } 216 220 div.banner { background-color: white; font-family: sans-serif; font-size: 18px; text-decoration: none; color: #1950c8; } 217 221 div.banner a.banner { text-decoration: none; border: none; margin-top: 2px; } 218 222 … … pre.cell_input_hide:hover { cursor: text 248 252 textarea.cell_input_active { background-color: white; border: 2px solid #8888fe; font-family: monospace; font-size: 12pt; overflow: hidden; padding-bottom: 0px; padding-left: 5px; padding-right: 0px; padding-top: 3px; margin-top: 0px; margin-bottom: 0px; line-height: 1.2em; width: 97%; } 249 253 250 254 div.cell_input_active { background-color: white; border: 2px solid #8888fe; font-family: monospace; font-size: 12pt; padding-bottom: 0px; padding-left: 5px; padding-right: 0px; padding-top: 3px; margin-top: 0px; margin-bottom: 0px; line-height: 1.2em; width: 97%; z-index: -100; visibility: hidden; position: absolute; } 251 div.cell_input_print { background-color: white; border: 1px solid #a8a8a8; font-family: monospace; font-size: 12pt; padding-bottom: 1px; padding-left: 6px; padding-right: 1px; padding-top: 4px; margin-top: 0px; margin-bottom: 0px; line-height: 1.2em; width: 97%; }255 div.cell_input_print { background-color: white; border: 1px solid #a8a8a8; font-family: monospace; font-size: 12pt; padding-bottom: 1px; padding-left: 6px; padding-right: 1px; padding-top: 4px; margin-top: 0px; margin-bottom: 0px; line-height: 1.2em; width: 97%; white-space: pre-wrap; } 252 256 253 257 textarea.cell_input:hover { cursor: text; } 254 258 … … span.worksheet_buttons { position: relat 304 308 .thin-right { position: absolute; top: auto; right: 0; width: 70%; } 305 309 306 310 /* *********** User Home (Worksheet listing) ************************* */ 307 span.ratingmsg { color: #112abb; padding: 0.3em; font-size: 14px; } 308 span.pubmsg { font-family: sans-serif; color: #112abb; padding: 0.3em; font-size: 12px; } 311 .ratingmsg { color: #112abb; padding: 0.3em; font-size: 14px; } 312 313 .pubmsg { font-family: sans-serif; color: #112abb; padding: 0.3em; font-size: 12px; } 309 314 310 315 #worksheet-list { clear: both; width: 100%; } 311 316 #worksheet-list thead { background-color: #e8eef7; } 312 317 #worksheet-list td.checkbox { padding: 4px; } 313 318 314 a.usercontrol { color: #112abb; padding: 0.3em; font-size: 14px; text-decoration: underline; }315 a.usercontrol:hover { cursor: pointer; }319 .controls a, .usercontrol { color: #112abb; font-size: 14px; text-decoration: underline; } 320 .controls a:hover, .usercontrol:hover { cursor: pointer; } 316 321 317 span.usercontrol{ color: #112abb; padding: 0.3em; font-size: 14px; }322 .controls span { color: #112abb; padding: 0.3em; font-size: 14px; } 318 323 319 a.boldusercontrol { color: #112abb; padding: 0.5em; font-weight: bold; font-size: 14px; } 324 .user-controls a, .boldusercontrol { color: #112abb; font-weight: bold; font-size: 14px; } 325 326 .user-controls a, .controls a, .controls span { padding: 0.3em; } 327 320 328 a.control, a.control-select { background-color: #7799bb; font-family: sans-serif; color: #ffffff; padding-top: 0.25em; padding-bottom: 0.25em; padding-left: 0.5em; padding-right: 0.5em; font-size: 15px; font-weight: bold; text-decoration: none; } 321 329 a.control:hover { cursor: pointer; } 322 330 a.control-select { background-color: #4477aa; } 323 331 a.control-select:hover { cursor: pointer; } 324 332 325 span.sharebar { background-color: #4477aa; font-family: sans-serif; color: #ffffff; position: absolute; left: 0.5em; right: 0ex; padding-top: 0.5em; padding-bottom: 0.5em; padding-left: 2em; font-size: 18px; font-weight: bold; }333 .sharebar { background-color: #4477aa; font-family: sans-serif; color: #ffffff; padding-top: 0.5em; padding-bottom: 0.5em; padding-left: 2em; font-size: 1.25em; font-weight: bold; } 326 334 327 335 textarea.edit { font-family: courier, monospace; font-size: 10pt; border: 1px solid #8cacbb; color: black; background-color: white; padding: 3px; overflow: auto; margin-top: 0.5em; } 328 336 … … tr.thingreybox { background-color: #aaa; 347 355 348 356 div.ultrathinspace { border: 0; height: 0px; } 349 357 350 span.lastedit { font-family: sans-serif; font-size: 10px; color: #717171; } 351 span.revs { font-family: sans-serif; font-size: 12px; font-weight: bold; color: #333333; } 352 span.users { font-family: sans-serif; font-size: 13px; color: #222222; } 358 .lastedit { font-family: sans-serif; font-size: 10px; color: #717171; } 359 360 .revs { font-family: sans-serif; font-size: 12px; font-weight: bold; color: #333333; } 361 362 .users { font-family: sans-serif; font-size: 13px; color: #222222; } 353 363 354 364 a.share { font-family: sans-serif; font-size: 10px; color: #7777cc; } 355 365 … … pre.plaintext { overflow: auto; font-fam 368 378 div.docidx { text-align: center; font-family: sans-serif; font-size: 16px; color: #222; font-weight: bold; } 369 379 370 380 span.ping { display: none; } 371 span.pingdown { font-family: sans-serif; font-size: 15px; font-weight: bold; color: white; background-color: #990000; }381 span.pingdown { font-family: sans-serif; font-size: 15px; font-weight: bold; color: white; background-color: #990000; margin-left: 1em; } 372 382 373 /* These have been scraped directly from pygment. */ 383 #source-code-page .str { color: #080; } 384 #source-code-page .kwd { color: #008; } 385 #source-code-page .com { color: #800; } 386 #source-code-page .typ { color: #606; } 387 #source-code-page .lit { color: #066; } 388 #source-code-page .pun { color: #660; } 389 #source-code-page .pln { color: #000; } 390 #source-code-page .tag { color: #008; } 391 #source-code-page .atn { color: #606; } 392 #source-code-page .atv { color: #080; } 393 #source-code-page .dec { color: #606; } 394 395 #source-code-page h1, #source-code-page h2 { text-align: center; } 396 #source-code-page .filename { font-family: monospace; } 397 #source-code-page code { display: block; border-top: 1px solid #ccc; border-bottom: 1px solid #ccc; padding: 1em; } 398 399 #print-page h1 { text-align: center; } 400 401 #guest-worksheet-page h1, #guest-worksheet-page h2 { text-align: center; } 402 #guest-worksheet-page ul.controls { margin: 0; padding: 0; border: 0; outline: 0; overflow: hidden; display: inline-block; } 403 #guest-worksheet-page ul.controls { display: block; } 404 #guest-worksheet-page ul.controls li { list-style-type: none; margin-left: 0px; white-space: nowrap; display: inline; float: left; padding-left: 0.5em; padding-right: 0.5em; } 405 #guest-worksheet-page ul.controls li.first { padding-left: 0px; } 406 #guest-worksheet-page ul.controls li.last { padding-right: 0px; } 407 408 #before-publish-page form a { text-decoration: none; } 409 #before-publish-page form button { margin-left: 1em; margin-bottom: 0.5em; } 410 #before-publish-page form input { margin-left: 1em; } 411 412 #after-publish-page input { margin-top: 1em; } 413 414 #edit-page .sharebar span { margin-right: 2em; } 415 416 .settings-page { line-height: 1.4; } 417 .settings-page h1 { font-size: 2em; padding: 0 5px; } 418 .settings-page label { display: block; } 419 .settings-page #buttons { padding: 5px; } 420 .settings-page #buttons button { margin-right: 1em; } 421 .settings-page #buttons a { text-decoration: none; } 422 .settings-page h2 { font-size: 1.5em; margin: 0 0 0.75em; } 423 .settings-page .section { border-bottom: 1px solid #CCC; padding: 5px; margin: 0.5em 0; } 424 .settings-page .section div { margin-bottom: 0.5em; } 425 .settings-page .error, .settings-page .error_found { color: red; } 426 .settings-page .error_found { font-size: 1.2em; } 427 .settings-page .updated { color: green; } 428 .settings-page input.c1 { width: 200px; } 429 430 #settings-nav { margin: 0; padding: 0; border: 0; outline: 0; overflow: hidden; display: inline-block; } 431 #settings-nav { display: block; } 432 #settings-nav li { list-style-type: none; margin-left: 0px; white-space: nowrap; display: inline; float: left; padding-left: 0.5em; padding-right: 0.5em; } 433 #settings-nav li.first { padding-left: 0px; } 434 #settings-nav li.last { padding-right: 0px; } 435 #settings-nav li { border-right: 1px solid #ccc; } 436 #settings-nav li:last-child, #settings-nav li.last { border-right: none; } 437 438 #user-management-page table { border-collapse: collapse; } 439 #user-management-page th, #user-management-page td { border: 1px solid #696969; padding: 0.25em; } 440 #user-management-page th { background: #CCC; } 441 #user-management-page a:link, #user-management-page a:visited { color: #112abb; } 442 443 .accounts-page #wrapper { margin: 0 auto; max-width: 600px; } 444 .accounts-page h1, .accounts-page h2, .accounts-page h3, .accounts-page h4, .accounts-page h5 { font-weight: normal; } 445 .accounts-page h1 { border-bottom: 1px solid #696969; font-size: 2em; padding: 10px 0; } 446 .accounts-page h2 { font-weight: bold; } 447 .accounts-page h1, .accounts-page h2, .accounts-page p, .accounts-page li { margin-bottom: 10px; } 448 .accounts-page .entry { margin-bottom: 10px; border: 1px solid #999; padding: 3px; width: 200; } 449 .accounts-page li { border-bottom: 1px solid #CCC; } 450 .accounts-page .error { color: red; } 451 .accounts-page .error_found { color: red; font-size: 1.5em; } 452 .accounts-page button { margin-right: 1em; } 453 .accounts-page form label { display: block; } 454 .accounts-page form div { margin-bottom: 1em; } 455 .accounts-page form a { text-decoration: none; } 456 457 #login-page h2 { font-size: 1.5em; margin-bottom: 0.375em; } 458 #login-page h1, #login-page h2, #login-page h3, #login-page h4, #login-page h5, #login-page h6 { line-height: 1em; } 459 #login-page p { margin-bottom: 1em; } 460 #login-page strong { font-weight: bold; } 461 #login-page #desc { float: left; margin-right: 400px; } 462 #login-page div { padding: 0.5em 1em; } 463 #login-page #sign-in-box { background-color: #efefff; float: left; margin-left: -400px; width: 350px; } 464 #login-page #sign-in-box form label { display: block; } 465 #login-page #sign-in-box a { font-size: 0.875em; } 466 374 467 .hll { background-color: #ffffcc; } 375 468 376 469 .c { color: #408090; font-style: italic; } … … span.pingdown { font-family: sans-serif; 474 567 .vc, .vg, .vi { color: #bb60d5; } 475 568 476 569 .il { color: #208050; } 477 478 /* end stuff scraped from pygment */ -
deleted file sagenb/data/sage/css/master.css
diff --git a/sagenb/data/sage/css/master.css b/sagenb/data/sage/css/master.css deleted file mode 100644
+ - 1 html, body, div, span, applet, object, iframe, h1, h2, h3, h4, h5, h6, p, blockquote, pre, a, abbr, acronym, address, big, cite, code, del, dfn, em, font, img, ins, kbd, q, s, samp, small, strike, strong, sub, sup, tt, var, dl, dt, dd, ol, ul, li, fieldset, form, label, legend, table, caption, tbody, tfoot, thead, tr, th, td { margin: 0; padding: 0; border: 0; outline: 0; font-weight: inherit; font-style: inherit; font-size: 100%; font-family: inherit; vertical-align: baseline; }2 3 *:focus { outline: 0; }4 5 body { line-height: 1em; color: black; background: #fff; }6 7 ol, ul { list-style: none; }8 9 /* tables still need 'cellspacing="0"' in the markup */10 table { border-collapse: separate; border-spacing: 0; vertical-align: middle; }11 12 caption, th, td { text-align: left; font-weight: normal; vertical-align: middle; }13 14 q, blockquote { quotes: "" ""; }15 q:before, q:after, blockquote:before, blockquote:after { content: ""; }16 17 img a { border: none; }18 19 html { font-size: 100.1%; }20 21 body { font: .9em/1.2em Arial, Helvetica, sans-serif; }22 23 div { padding: 0.5em 1em; }24 25 #desc { float: left; margin-right: 400px; }26 27 #sign-in-box { float: left; margin-left: -400px; width: 350px; background-color: #efefff; }28 #sign-in-box form label { display: block; }29 30 p { margin-bottom: 1em; }31 32 h1, h2, h3, h4, h5, h6 { line-height: 1em; }33 34 h2 { font-size: 1.5em; margin-bottom: 0.375em; }35 36 #banner { font-size: 1.2em; float: left; clear: both; margin-bottom: 0.25em; }37 #banner a.banner { text-decoration: none; border: none; margin-top: 2px; float: left; }38 #banner a.banner:visited { color: #1950c8; }39 #banner #ping { display: none; }40 #banner div.version { float: left; clear: left; font-size: xx-small; text-indent: 13px; color: black; }41 42 .section { border-bottom: 1px solid #CCC; padding: 5px; }43 .section > div { max-width: 350px; text-align: right; }44 45 input.c1 { width: 200px; }46 47 strong { font-weight: bold; } -
deleted file sagenb/data/sage/css/registration.css
diff --git a/sagenb/data/sage/css/registration.css b/sagenb/data/sage/css/registration.css deleted file mode 100644
+ - 1 html, body, div, span, applet, object, iframe, h1, h2, h3, h4, h5, h6, p, blockquote, pre, a, abbr, acronym, address, big, cite, code, del, dfn, em, font, img, ins, kbd, q, s, samp, small, strike, strong, sub, sup, tt, var, dl, dt, dd, ol, ul, li, table, caption, tbody, tfoot, thead, tr, th, td { border: 0; font-family: inherit; font-size: 100%; font-style: inherit; font-weight: inherit; margin: 0; outline: 0; padding: 0; text-decoration: none; vertical-align: baseline; }2 3 html { font-size: 100.1%; }4 5 body { font: 0.88em/1.4 Arial, Helvetica, sans-serif; }6 7 #wrapper { margin: 0 auto; max-width: 600px; }8 9 h1, h2, h3, h4, h5 { font-wieght: normal; }10 11 h1 { border-bottom: 1px solid #696969; font-size: 2em; padding: 10px 0; }12 13 h2 { font-weight: bold; }14 15 h1, h2, p, li { margin-bottom: 10px; }16 17 .entry { margin-bottom: 10px; border: 1px solid #999; padding: 3px; width: 200; }18 19 li { border-bottom: 1px solid #CCC; }20 21 .error { color: red; }22 23 .error_found { color: red; font-size: 1.5em; }24 25 button { margin-right: 1em; }26 27 form label { display: block; }28 form div { margin-bottom: 1em; } -
sagenb/data/sage/css/test_report.css
diff --git a/sagenb/data/sage/css/test_report.css b/sagenb/data/sage/css/test_report.css
a b 1 /* Warning: These .css files are automatically generated and will be overwritten */ 2 /* when they are next generated. Please edit the SASS source located at */ 3 /* <sagenb-spkg-root>/sass/src. Kindly refer to the readme for editing */ 4 /* instructions at <sagenb-spkg-root>/sass */ 1 5 body, table { background-color: #fff; color: #111; font-family: sans-serif; -moz-border-radius: 0.25em; -webkit-border-radius: 0.25em; } 2 6 3 7 pre { margin: 0; padding: 0; padding-top: 0.25em; } -
deleted file sagenb/data/sage/css/user_management.css
diff --git a/sagenb/data/sage/css/user_management.css b/sagenb/data/sage/css/user_management.css deleted file mode 100644
+ - 1 html, body, div, span, applet, object, iframe, h1, h2, h3, h4, h5, h6, p, blockquote, pre, a, abbr, acronym, address, big, cite, code, del, dfn, em, font, img, ins, kbd, q, s, samp, small, strike, strong, sub, sup, tt, var, dl, dt, dd, ol, ul, li, fieldset, form, label, legend, table, caption, tbody, tfoot, thead, tr, th, td { margin: 0; padding: 0; border: 0; outline: 0; font-weight: inherit; font-style: inherit; font-size: 100%; font-family: inherit; vertical-align: baseline; }2 3 *:focus { outline: 0; }4 5 body { line-height: 1em; color: black; background: #fff; }6 7 ol, ul { list-style: none; }8 9 /* tables still need 'cellspacing="0"' in the markup */10 table { border-collapse: separate; border-spacing: 0; vertical-align: middle; }11 12 caption, th, td { text-align: left; font-weight: normal; vertical-align: middle; }13 14 q, blockquote { quotes: "" ""; }15 q:before, q:after, blockquote:before, blockquote:after { content: ""; }16 17 img a { border: none; }18 19 html { font-size: 100.1%; }20 21 body { font: .9em/1.2em Arial, Helvetica, sans-serif; }22 23 div { padding: 0.5em 1em; }24 25 #desc { float: left; margin-right: 400px; }26 27 #sign-in-box { float: left; margin-left: -400px; width: 350px; background-color: #efefff; }28 #sign-in-box form label { display: block; }29 30 p { margin-bottom: 1em; }31 32 h1, h2, h3, h4, h5, h6 { line-height: 1em; }33 34 h2 { font-size: 1.5em; margin-bottom: 0.375em; }35 36 #banner { font-size: 1.2em; float: left; clear: both; margin-bottom: 0.25em; }37 #banner a.banner { text-decoration: none; border: none; margin-top: 2px; float: left; }38 #banner a.banner:visited { color: #1950c8; }39 #banner #ping { display: none; }40 #banner div.version { float: left; clear: left; font-size: xx-small; text-indent: 13px; color: black; }41 42 .section { border-bottom: 1px solid #CCC; padding: 5px; }43 .section > div { max-width: 350px; text-align: right; }44 45 input.c1 { width: 200px; }46 47 strong { font-weight: bold; }48 49 body { margin: 10px; } -
deleted file sagenb/data/sage/html/account_recovery.html
diff --git a/sagenb/data/sage/html/account_recovery.html b/sagenb/data/sage/html/account_recovery.html deleted file mode 100644
+ - 1 {% extends "html/base.html" %}2 3 {% block title %}Account Recovery{% endblock %}4 {% block css %}registration{% endblock %}5 6 {% block body %}7 <div id="wrapper">8 <h1>Account Recovery</h1>9 <p>A new password will be emailed to the email address connected to your account. However if you didn't confirm your email address you will be unable to recover your account.</p>10 11 <form method="GET" action="/forgotpass">12 <div>13 <label for="username">Username</label>14 <input type="text" name="username" size="15" />15 </div>16 <div>17 <button type="submit">Submit</button> <a href="/"><button >Cancel</button></a>18 </div>19 </form>20 </div>21 22 23 {% endblock %} -
deleted file sagenb/data/sage/html/account_settings.html
diff --git a/sagenb/data/sage/html/account_settings.html b/sagenb/data/sage/html/account_settings.html deleted file mode 100644
+ - 1 {% extends "html/base.html" %}2 3 {% block title %}Account Settings{% endblock %}4 {% block css %}account_settings{% endblock %}5 {% block page_id %}account-settings-page{% endblock %}6 {% block body %}7 <h1>Account Settings</h1>8 <div class="section">{% if admin %}<a href="/users">Manage Users</a> | <a href="/notebooksettings">Notebook Settings</a> | {% endif %}<a href="/">My Worksheets</a> | <a href="/logout">Sign Out</a></div>9 10 <form method="post" action="/settings">11 12 <div class="section">13 <h2>Change Auto-Save Interval</h2>14 <div>15 Minutes:16 <select name="autosave">17 {% for i, selected in autosave_intervals %}18 <option{{ selected }}>{{ i }}</option>19 {% endfor %}20 </select>21 </div>22 </div>23 <div class="section">24 <h2>Change Password</h2>25 <div id="passwd">26 <div>27 <label for="old-pass">Old password</label>28 <input type="password" name="old-pass" />29 </div>30 <div>31 <label for="new-pass">New password</label>32 <input type="password" name="new-pass" />33 </div>34 <div>35 <label for="retype-pass">Retype new password</label>36 <input type="password" name="retype-pass" />37 </div>38 </div>39 </div>40 41 {% if true %}42 <div class="section">43 <h2>Change E-mail Address</h2>44 45 <div>46 <div>47 <label>Current e-mail</label>48 {{ email_address }} {{ email_confirmed }}49 </div>50 <div>51 <label for="new-email">New e-mail</label>52 <input type="text" name="new-email" class="c1" />53 </div>54 </div>55 </div>56 {% endif %}57 <div id="buttons">58 <button type="submit">Save</button>59 <a href="/"><button>Cancel</button></a>60 </div>61 </form>62 {% endblock %} -
new file sagenb/data/sage/html/accounts/account_recovery.html
diff --git a/sagenb/data/sage/html/accounts/account_recovery.html b/sagenb/data/sage/html/accounts/account_recovery.html new file mode 100644
- + 1 {% extends "html/accounts/base.html" %} 2 3 {% block title %}Account Recovery{% endblock %} 4 {% block page_id %}account-recovery-page{% endblock %} 5 6 {% block body %} 7 <div id="wrapper"> 8 <h1>Account Recovery</h1> 9 <p>A new password will be emailed to the email address connected to your account. However if you didn't confirm your email address you will be unable to recover your account.</p> 10 11 <form method="GET" action="/forgotpass"> 12 <div> 13 <label for="username">Username</label> 14 <input type="text" name="username" size="15" /> 15 </div> 16 <div> 17 <button type="submit">Submit</button> <a href="/"><button >Cancel</button></a> 18 </div> 19 </form> 20 </div> 21 {% endblock %} -
new file sagenb/data/sage/html/accounts/base.html
diff --git a/sagenb/data/sage/html/accounts/base.html b/sagenb/data/sage/html/accounts/base.html new file mode 100644
- + 1 {% extends "html/base.html" %} 2 {% block body_classes %}accounts-page{% endblock %} -
new file sagenb/data/sage/html/accounts/registration.html
diff --git a/sagenb/data/sage/html/accounts/registration.html b/sagenb/data/sage/html/accounts/registration.html new file mode 100644
- + 1 {% extends "html/accounts/base.html" %} 2 3 {% block title %}Sign up{% endblock %} 4 5 {% block page_id %}registration-page{% endblock %} 6 7 {% block body %} 8 <div id="wrapper"> 9 <h1>Sign up for a Sage Notebook account</h1> 10 {% if error %} 11 <h2 class="error_found">Error{{ error[1:] }}found</h2> 12 {% endif %} 13 <form method="POST" action="/register"> 14 <ol> 15 <li> 16 <h2>Create a username</h2> 17 <p>Your username must start with a letter and be between 3 and 64 18 characters long. You may only use letters, numbers, underscores, @, 19 and dots.</p> 20 <input type="text" name="username" value="{{ username }}" class="entry" tabindex="1" /> 21 {% if username_missing %} 22 <p><span class="error">Error:</span> No username given</p> 23 {% endif %} 24 {% if username_taken %} 25 <p><span class="error">Error:</span> Username already in use</p> 26 {% endif %} 27 {% if username_invalid %} 28 <p><span class="error">Error:</span> Bad username</p> 29 {% endif %} 30 </li> 31 <li> 32 <h2>Create a good password</h2> 33 <p> 34 Your password must be between 4 and 32 characters 35 long. Your password can not contain your username nor spaces. 36 </p> 37 <input type="password" name="password" class="entry" tabindex="2" /> 38 {% if password_missing %} 39 <p><span class="error">Error:</span> No password given</p> 40 {% endif %} 41 {% if password_invalid %} 42 <p><span class="error">Error:</span> Bad password</p> 43 {% endif %} 44 </li> 45 <li><h2>Re-type your password</h2> 46 <input type="password" name="retype_password" class="entry" tabindex="3" /> 47 {% if passwords_dont_match or retype_password_missing %} 48 <p><span class="error">Error:</span> Passwords didn't match</p> 49 {% endif %} 50 </li> 51 {% if email or email_missing or email_invaild %} 52 <li> 53 <h2>Enter your email address</h2> 54 <p> 55 Your email address is required for account 56 confirmation and recovery. You will be emailed a confirmation link 57 right after you successfully sign up. 58 </p> 59 <input type="text" name="email" value="{{ email_address }}" class="entry" tabindex="4" /> 60 {% if email_missing %} 61 <p><span class="error">Error:</span> No email address given</p> 62 {% endif %} 63 {% if email_invalid %} 64 <p><span class="error">Error:</span> Invalid email address</p> 65 {% endif %} 66 </li> 67 {% endif %} 68 {% if challenge %} 69 <li> 70 <h2>Answer a challenge</h2> 71 {{ challenge_html }} 72 {% if challenge_missing %} 73 <p><span class="error">Error:</span> No challenge response given</p> 74 {% endif %} 75 {% if challenge_invalid %} 76 <p><span class="error">Error:</span> Invalid challenge response</p> 77 {% endif %} 78 </li> 79 {% endif %} 80 </ol> 81 <button type="submit" tabindex="100" id="create-account-button">Create account</button> 82 <a href="/"><button tabindex="101">Cancel</button></a> 83 </form> 84 </div> 85 {% endblock %} 86 No newline at end of file -
deleted file sagenb/data/sage/html/admin_add_user.html
diff --git a/sagenb/data/sage/html/admin_add_user.html b/sagenb/data/sage/html/admin_add_user.html deleted file mode 100644
+ - 1 <html>2 <head>3 <title>Add New User | {{ sitename }}</title>4 <style>5 /***** Global Settings *****/6 7 html,body,div,span,applet,object,iframe,h1,h2,h3,h4,h5,h6,p,blockquote,pre,a,abbr,acronym,address,big,cite,code,del,dfn,em,font,img,ins,kbd,q,s,samp,small,strike,strong,sub,sup,tt,var,dl,dt,dd,ol,ul,li,table,caption,tbody,tfoot,thead,tr,th,td {8 border:0;9 font-family:inherit;10 font-size:100%;11 font-style:inherit;12 font-weight:inherit;13 margin:0;14 outline:0;15 padding:0;16 text-decoration:none;17 vertical-align:baseline18 }19 20 html {21 font-size:100.1%22 }23 24 body {25 font:0.88em/1.4 Arial, Helvetica, sans-serif;26 }27 28 #wrapper {29 margin:0 auto;30 max-width:600px31 }32 33 /***** Headings *****/34 35 h1,h2,h3,h4,h5 {36 font-wieght:normal37 }38 39 h1 {40 border-bottom:1px solid #696969;41 font-size:2em;42 padding:10px 043 }44 45 h2 {46 font-weight:bold47 }48 49 h1, h2, p, li, .entry {50 margin-bottom:10px51 }52 53 .entry {54 border:1px solid #999;55 padding:3px;56 width:20057 }58 59 li {60 border-bottom:1px solid #CCC61 }62 63 .error, .error_found {64 color:red65 }66 67 .error_found {68 font-size:1.5em69 }70 71 .button {72 font-size:1.2em73 }74 </style>75 </head>76 <body>77 <div id="wrapper">78 <h1>Add New User</h1>79 {% if error %}80 <h2 class="error_found">Username Error</h2>81 {% endif %}82 <form method="POST" action="/adduser">83 <ol>84 <li><h2>Pick a username</h2>85 <p>The username must start with a letter and be between 4 and 32 characters long. It can only consist of letters, numbers, underscores, and one dot (.).</p>86 <input type="text" name="username" value="{{ username }}" class="entry" />87 {% if username_error %}88 {% if username_error == 'invalid' %}89 <p><span class="error">Error:</span> Invalid username</p>90 {% else %}91 <p><span class="error">Error:</span> Username taken</p>92 {% endif %}93 {% endif %}94 </li>95 </ol>96 <input type="submit" value="Create account" class="button" />97 <input type="button" value="Cancel" style="margin-left:10px" onClick="parent.location='/users'" class="button" />98 </form>99 </div>100 </body>101 </html>102 No newline at end of file -
deleted file sagenb/data/sage/html/banner.html
diff --git a/sagenb/data/sage/html/banner.html b/sagenb/data/sage/html/banner.html deleted file mode 100644
+ - 1 <div id="banner">2 <a class="banner" href="http://nb.sagemath.org/">3 <img align="top" src="/images/sagenb.png" alt="Sage" /><span>The Sage Notebook</span>4 </a>5 <span class="ping" id="ping">Searching for Sage server...</span>6 <div class="version">7 Version {{ sage_version }}8 </div>9 </div> -
sagenb/data/sage/html/base.html
diff --git a/sagenb/data/sage/html/base.html b/sagenb/data/sage/html/base.html
a b 1 {%- macro render_title -%}{% block title %}{% endblock %}{%- endmacro -%} 1 2 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"> 2 3 <html lang="en"> 3 4 <head> 4 <title>{ % block title %}{% endblock %}</title>5 <title>{{ render_title() }} -- Sage</title> 5 6 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> 6 7 {% block pre_main_css %}{% endblock %} 7 <link type="text/css" rel="stylesheet" href="/css/{% block css %}ma ster{% endblock %}.css" media="screen" />8 <link type="text/css" rel="stylesheet" href="/css/{% block css %}main{% endblock %}.css" /> 8 9 {% block more_css %}{% endblock %} 9 <!-- jQuery - general-purpose functions --> 10 {# jQuery and other universally used libraries #} 10 11 <script type="text/javascript" src="/javascript/jquery/jquery-1.3.2.min.js"></script> 11 12 {% block javascript %} 12 <!-- Worksheet list functions --> 13 {# Page-specific libraries #} 13 14 <script type="text/javascript" src="/javascript/sage/ws_list.js"></script> 14 15 {% endblock %} 16 {# Behavior #} 17 <script type="text/javascript" src="/javascript/sage/master.js"></script> 15 18 </head> 16 <body {% block body_attrs %}{% endblock %} id="{% block page_id %}{% endblock %}"> 17 {% block body %}{% endblock %} 19 <body id="{% block page_id %}{% endblock %}" 20 class="{% block body_classes %}{% endblock %}"> 21 {% block body %} 22 <div id="header"> 23 {% block header %} 24 <div id="top-bar"> 25 <div id="banner"> 26 <a class="banner" href="http://nb.sagemath.org/"> 27 <img align="top" src="/images/sagenb.png" alt="Sage" /><span>The Sage Notebook</span> 28 </a> 29 <span class="ping" id="ping">Searching for Sage server...</span> 30 <div class="version"> 31 Version {{ sage_version }} 32 </div> 33 </div> 34 {% block controls %} 35 {% endblock %} 36 </div> 37 {% endblock %} 38 </div> 39 <div id="main"> 40 {% block main %} 41 42 {% endblock %} 43 </div> 44 {% endblock %} 18 45 </body> 19 </html> 46 </html> 47 No newline at end of file -
new file sagenb/data/sage/html/base_authenticated.html
diff --git a/sagenb/data/sage/html/base_authenticated.html b/sagenb/data/sage/html/base_authenticated.html new file mode 100644
- + 1 {% extends "html/base.html" %} 2 {% block controls %} 3 <div id="main-controls" class="controls"> 4 <ul> 5 <li class="username">{{ username }}</li> 6 {% if username == 'guest' %} 7 <li><a title="Please log in to the Sage notebook" href="/">Log in</a></li> 8 {% else %} 9 <li><a id="toggle-link" title="Toggle the top bar" onClick="$('#worksheet-bar').toggle()">Toggle</a></li> 10 <li><a title="Back to your personal worksheet list" href="/home/{{ username }}">Home</a></li> 11 {% if pub %} 12 <li><span>Published</span></li> 13 {% else %} 14 <li><a title="Browse the published worksheets" href="/pub">Published</a></li> 15 <li><a title="View a log of recent computations" href="#" onClick="history_window()">Log</a></li> 16 {% endif %} 17 <li><a title="Change account settings including password" href="/settings">Settings</a></li> 18 <li><a title="Documentation" href="#" onClick="help()">Help</a></li> 19 <li><a title="Report a problem or submit a bug to improve Sage" href="#" onClick="bugreport()">Report a Problem</a></li> 20 <li><a title="Log out of the Sage notebook" href="/logout">Sign out</a></li> 21 {% endif %} 22 </ul> 23 </div> 24 {% endblock %} -
deleted file sagenb/data/sage/html/command_history.html
diff --git a/sagenb/data/sage/html/command_history.html b/sagenb/data/sage/html/command_history.html deleted file mode 100644
+ - 1 2 {#3 INPUT:4 - history_text - a string containing the history text of the notebook5 #}6 <html>7 <head>8 <title>Command History</title>9 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />10 </head>11 <body>12 <pre>{{history_text}}</pre>13 <a name="bottom"></a>14 <script type="text/javascript"> window.location="#bottom"</script>15 </body>16 </html>17 No newline at end of file -
sagenb/data/sage/html/docs.html
diff --git a/sagenb/data/sage/html/docs.html b/sagenb/data/sage/html/docs.html
a b 1 {% extends "html/base .html" %}1 {% extends "html/base_authenticated.html" %} 2 2 3 3 {% block title %}Sage Documentation{% endblock %} 4 4 5 {% block css %}main{% endblock %}6 7 5 {% block javascript %} 8 6 <script type="text/javascript" src="/javascript/sage/ws_list.js"></script> 9 7 {% endblock%} 10 8 11 9 {% block page_id %}docs-main-page{% endblock %} 12 10 13 {% block body %} 14 15 {% include "html/top_bar.html" %} 11 {% block main %} 16 12 17 13 <div class="control-bar"> 18 14 <ul class="controls"> 19 15 <li><a title="To quickly try out Sage start here" href="/doc/live/tutorial/index.html">Tutorial</a></li> 20 <li><a title="View a 2000page reference manual about Sage" href="/doc/live/reference/index.html">Reference Manual</a></li>16 <li><a title="View a 4000+ page reference manual about Sage" href="/doc/live/reference/index.html">Reference Manual</a></li> 21 17 <li><a title="Learn to write Sage programs" href="/doc/live/developer/index.html">Developer Guide</a></li> 22 18 <li><a title="How do I construct ... in Sage?" href="/doc/live/constructions/index.html">Constructions</a></li> 23 19 </ul> -
sagenb/data/sage/html/error_message.html
diff --git a/sagenb/data/sage/html/error_message.html b/sagenb/data/sage/html/error_message.html
a b 1 {% extends "html/base .html" %}1 {% extends "html/base_authenticated.html" %} 2 2 3 3 {% block title %}Error{% endblock %} 4 4 5 {% block body %} 6 <br><a class="usercontrol" href="/">Home</a> 7 <hr class="usercontrol"> 8 <br/><br/> 9 {{ msg }} 10 <br/><br/> 5 {% block main %} 6 <div> 7 {{ msg }} 8 </div> 11 9 {% if cont %} 12 <center><a class="boldusercontrol" href="{{ cont }}"><font size=+1>Continue</font></a></center> 10 <div> 11 <a class="boldusercontrol" href="{{ cont }}">Continue</a> 12 </div> 13 13 {% endif %} 14 14 {% endblock %} -
sagenb/data/sage/html/history.html
diff --git a/sagenb/data/sage/html/history.html b/sagenb/data/sage/html/history.html
a b 2 2 3 3 {% block title %}Sage: History for {{username}} {% endblock %} 4 4 5 {% block css %}main{% endblock %}6 7 5 {% block javascript %} 8 6 <script type="text/javascript" src="/javascript/sage/ws_list.js"></script> 9 7 {% endblock %} … … 11 9 {% block page_id %}history-page{% endblock %} 12 10 13 11 {% block body %} 14 15 {% include "html/top_bar.html" %}16 17 12 <pre>{{ text | escape }}</pre> 18 13 <a title="Click here to turn the above into a Sage worksheet" href="/live_history">Create a new Sage worksheet version of the last 100 commands in the above log.</a> 19 14 <a name="bottom"></a> 20 <script type="text/javascript">$(document).load(function(){window.location="#bottom"});</script> 21 15 <script type="text/javascript"> 16 $(window).load(function () { 17 window.location = "#bottom"; 18 }); 19 </script> 22 20 {% endblock %} -
deleted file sagenb/data/sage/html/list_top.html
diff --git a/sagenb/data/sage/html/list_top.html b/sagenb/data/sage/html/list_top.html deleted file mode 100644
+ - 1 {% include "html/top_bar.html" %}2 3 <div id="usercontrols">4 {% if pub is not defined or not pub %}5 <a class="boldusercontrol" href="/new_worksheet" target="_blank">New Worksheet</a>6 <a class="boldusercontrol" href="/upload">Upload</a>7 {% if not accounts %}8 <a class="boldusercontrol" href="/download_worksheets.zip">Download All Active</a>9 {% endif %}10 {% endif %}11 12 <div id='search-area'>13 <form action="." method="GET">14 <input type="hidden" value="{{ typ if not pub else 'pub' }}" name="typ" />15 <input id="search-worksheets" size="20" value="{{ search if search else "" }}" name="search" />16 <button class="add_new_worksheet_menu" id="search-worksheets-button" type="submit">Search Worksheets</button>17 </form>18 </div>19 </div> -
sagenb/data/sage/html/login.html
diff --git a/sagenb/data/sage/html/login.html b/sagenb/data/sage/html/login.html
a b 2 2 3 3 {% block title %}Sign in{% endblock %} 4 4 5 {% block body %} 6 {% include "html/banner.html" %} 5 {% block page_id %}login-page{% endblock %} 7 6 7 {% block main %} 8 8 {% if welcome %} 9 9 <h2>Congratulations {{ welcome }}! You can now sign into the Sage Notebook.</h2> 10 10 {% endif %} … … 58 58 <label for="email">Username</label> 59 59 <input type="text" name="email" value="{{ default_user }}" size="15" /> 60 60 {% if username_error %} 61 <span style="color:red">Error: </span>Username is not in the system61 <span style="color:red">Error: </span>Username is not in the system 62 62 {% endif %} 63 63 </div> 64 64 <div> 65 65 <label for="password">Password</label> 66 66 <input type="password" name="password" size="15" /> 67 67 {% if password_error %} 68 <span style="color:red">Error: </span>Wrong password68 <span style="color:red">Error: </span>Wrong password 69 69 {% endif %} 70 70 </div> 71 71 <div> 72 <input type="checkbox" name="remember" /> Remember me72 <input type="checkbox" name="remember" /> Remember me 73 73 </div> 74 74 <div> 75 75 <button type="submit">Sign in</button> 76 76 </div> 77 77 </form> 78 {% if accounts %} 78 79 <div> 79 {% if accounts %}80 80 <a href="/register" id="register-link"><strong>Sign up for a new Sage Notebook account</strong></a> 81 {% endif %}82 81 </div> 82 {% endif %} 83 83 <div> 84 84 <a href="/pub"><strong>Browse published Sage worksheets<br>(no login required)</strong></a> 85 85 </div> 86 {% if recovery %} 86 87 <div> 87 {% if recovery %}88 88 <a href="/forgotpass"><strong>Forgot password</strong></a> 89 {% endif %}90 89 </div> 90 {% endif %} 91 91 </div> 92 92 {% endblock %} 93 93 -
sagenb/data/sage/html/notebook/afterpublish_window.html
diff --git a/sagenb/data/sage/html/notebook/afterpublish_window.html b/sagenb/data/sage/html/notebook/afterpublish_window.html
a b 1 {% extends "html/notebook/worksheet_page_template.html" %} 2 {# 3 INPUT: 4 - worksheet - an instance of Worksheet 5 - worksheet_filename - a string containing a worksheet's filename 6 - username - a string containing a username 7 - url - a string containing the url of the published page 8 - time - a string representing the time of publication 9 - JSMATH - a boolean stating whether to include jsMath 10 - JEDITABLE_TINYMCE - a boolean stating whether to include jEditable and TinyMCE 11 #} 1 {% extends "html/notebook/base_aux.html" %} 2 3 {% block page_id %}after-publish-page{% endblock %} 12 4 13 5 {% set checked = 'checked="true"' if worksheet.is_auto_publish() else '' %} 14 6 15 7 {% block sharebar_title %} 16 Worksheet is publicly viewable at <a href="{{ url }}" style="color:#FFF" target="_blank">{{ url }}</a> 17 <br /> 18 Published on {{ time }} 19 <br /> 20 <br /> 21 <input type="button" value="Re-publish worksheet" onClick="parent.location='?re'" /> 22 <input type="button" value="Stop publishing" style="margin-left:5px" onClick="parent.location='?stop'" /> 23 <br /><br /> 8 <p>Worksheet is publicly viewable at <a href="{{ url }}" style="color:#FFF" target="_blank">{{ url }}</a></p> 9 <p>Published on {{ time }}</p> 10 <div> 11 <a href=".?re"><button>Re-publish worksheet</button></a> 12 <a onClick="parent.location+='?stop'"><button>Stop publishing</button></p></a> 13 </div> 24 14 <input type="checkbox" name="auto" {{ checked }} onchange="parent.location='?auto'"/> <label for="auto">Automatically re-publish when changes are made</label> 25 15 {% endblock %} 26 16 {% set select = "publish" %} -
new file sagenb/data/sage/html/notebook/base.html
diff --git a/sagenb/data/sage/html/notebook/base.html b/sagenb/data/sage/html/notebook/base.html new file mode 100644
- + 1 {% extends "html/base_authenticated.html" %} 2 {# 3 INPUT: 4 - notebook - an instance of Notebook 5 - worksheet - an instance of Worksheet 6 - username - a string containing a username 7 - title - a string 8 - select - a string containing the control that is selected 9 - backwards - a boolean 10 #} 11 12 {% set system_names = worksheet.notebook().system_names() %} 13 {% block title %}{{ worksheet.name() }}{% endblock %} 14 15 16 {% block javascript %} 17 <!-- jQuery UI - interacts, widgets, drag-drop, etc. --> 18 <link rel="stylesheet" href="/javascript/jqueryui/css/sage/jquery-ui-1.7.2.custom.css" /> 19 <script type="text/javascript" src="/javascript/jqueryui/js/jquery-ui-1.7.2.custom.min.js"></script> 20 21 <!-- jQuery plugins - color pickers, shift-click, AJAX forms, IE fixes --> 22 <link rel="stylesheet" href="/javascript/jquery/plugins/farbtastic/farbtastic.css" type="text/css" /> 23 <script type="text/javascript" src="/javascript/jquery/plugins/farbtastic/farbtastic.min.js"></script> 24 <script type="text/javascript" src="/javascript/jquery/plugins/extendedclick/jquery.event.extendedclick.min.js"></script> 25 <script type="text/javascript" src="/javascript/jquery/plugins/form/jquery.form.min.js"></script> 26 <script type="text/javascript" src="/javascript/jquery/plugins/jquery.bgiframe.min.js"></script> 27 <link rel="stylesheet" href="/javascript/jquery/plugins/jpicker/css/jPicker-1.0.11.css" type="text/css" /> 28 <script type="text/javascript" src="/javascript/jquery/plugins/jpicker/jpicker-1.0.11.min.js"></script> 29 <link rel="stylesheet" media="screen" type="text/css" href="/javascript/jquery/plugins/colorpicker/css/colorpicker.css" /> 30 <script type="text/javascript" src="/javascript/jquery/plugins/colorpicker/js/colorpicker.min.js"></script> 31 32 <script type="text/javascript" src="/javascript/sage/main.js"></script> 33 34 {% if JSMATH %} 35 <!-- jsMath - typeset mathematics --> 36 <script type="text/javascript" src="/javascript/sage/jsmath.js"></script> 37 {% endif %} 38 39 <!-- Sage3d - accelerated 3D graphics --> 40 <script type="text/javascript" src="/javascript/sage3d/sage3d.js"></script> 41 42 <!-- Jmol - embedded 3D graphics --> 43 <script type="text/javascript" src="/java/jmol/appletweb/Jmol.js"></script> 44 <!-- This must stay in head --> 45 <script>jmolInitialize("/java/jmol");jmolSetCallback("menuFile","/java/jmol/appletweb/SageMenu.mnu");</script> 46 47 {% if JEDITABLE_TINYMCE and not worksheet.docbrowser() and not worksheet.is_published() %} 48 <!-- TinyMCE and jEditable - in-place editing of text cells --> 49 <script type="text/javascript" src="/javascript/tiny_mce/tiny_mce.js"></script> 50 <script type="text/javascript" src="/javascript/jquery/plugins/jeditable/jquery.jeditable.mini.js" charset="utf-8"></script> 51 <script type="text/javascript" src="/javascript/sage/tinymce.js"></script> 52 {% endif %} 53 54 <script type="text/javascript">user_name= "{{ username }}";</script> 55 {% if worksheet.filename() %} 56 <script type="text/javascript"> 57 worksheet_filename = "{{ worksheet.filename() }}"; 58 worksheet_name = "{{ worksheet.name() }}"; 59 server_ping_while_alive(); 60 </script> 61 {% endif %} 62 63 {% endblock %} 64 65 {% block main %} 66 <div id="worksheet-bar"> 67 <div class="worksheet_title"> 68 <a id="worksheet_title" class="worksheet_title" 69 onClick="rename_worksheet(); return false;" 70 title="Click to rename this worksheet"> 71 {{ worksheet.name() }} 72 </a> 73 <div><span class="lastedit">{{ worksheet.html_time_last_edited() }}</span></div> 74 {% if worksheet.warn_about_other_person_editing(username) and username != 'guest' and not worksheet.is_doc_worksheet() %} 75 <span class="pingdown">(Someone else is viewing this worksheet)</span> 76 {% endif %} 77 </div> 78 <div id="save-discard-buttons"> 79 {% if not worksheet.is_doc_worksheet() %} 80 <button name="button_save" title="Save changes" onClick="save_worksheet();">Save</button><button title="Save changes and close window" onClick="save_worksheet_and_close();" name="button_save">Save & quit</button><button title="Discard changes to this worksheet" onClick="worksheet_discard();">Discard & quit</button> 81 {% endif %} 82 </div> 83 84 <div id="worksheet-menu"> 85 <select class="worksheet" onchange="go_option(this);" id="file-menu"> 86 <option title="Select a file related function" value="" selected>File...</option> 87 <option title="Load a new worksheet stored in a file" value="upload_worksheet_button();">Load worksheet from a file...</option> 88 <option title="Create a new worksheet" value="new_worksheet();">New worksheet</option> 89 <option title="Save this worksheet to an sws file" value="download_worksheet();">Save worksheet to a file...</option> 90 <option title="Print this worksheet" value="print_worksheet();">Print</option> 91 <option title="Rename this worksheet" value="rename_worksheet();">Rename worksheet</option> 92 <option title="Copy this worksheet" value="copy_worksheet();">Copy worksheet</option> 93 <option title="Move this worksheet to the trash" value="delete_worksheet('{{ worksheet.filename() }}');">Delete worksheet</option> 94 </select> 95 96 <select class="worksheet" onchange="go_option(this);" id="action-menu"> 97 <option title="Select a worksheet function" value="" selected>Action...</option> 98 <option title="Interrupt currently running calculations, if possible" value="interrupt();">Interrupt</option> 99 <option title="Restart the worksheet process" value="restart_sage();">Restart worksheet</option> 100 <option title="Quit the worksheet process" value="save_worksheet_and_close();">Save and quit worksheet</option> 101 <option value="">---------------------------</option> 102 <option title="Evaluate all input cells in the worksheet" value="evaluate_all();">Evaluate All</option> 103 <option title="Hide all output" value="hide_all();">Hide All Output</option> 104 <option title="Show all output" value="show_all();">Show All Output</option> 105 <option title="Delete all output" value="delete_all_output();">Delete All Output</option> 106 <option value="">---------------------------</option> 107 <option title="Switch to single-cell mode" value="slide_mode();">One Cell Mode</option> 108 <option title="Switch to multi-cell mode" value="cell_mode();">Multi Cell Mode</option> 109 </select> 110 <select class="worksheet" onchange="handle_data_menu(this);" id="data-menu"> 111 <option title="Select an attached file" value="" selected>Data...</option> 112 <option title="Upload or create a data file in a wide range of formats" value="__upload_data_file__">Upload or create file...</option> 113 <option value="">--------------------</option> 114 {% for name in worksheet.attached_data_files()|sort %} 115 <option value="datafile?name={{ name }}">{{ name }}</option> 116 {% endfor %} 117 </select> 118 119 {% if not worksheet.is_doc_worksheet() %} 120 <select onchange="go_system_select(this, {{ worksheet.system_index() }});" class="worksheet" id="systems-menu"> 121 {% for system_name in worksheet.notebook().systems() %} 122 <option title="Evaluate all input cells using {{ system_names[loop.index0] }}" 123 {{ "selected" if worksheet.system_index() == loop.index0 else "" }} value="{{ system_names[loop.index0] }}"> 124 {{ system_name }} 125 </option> 126 {% endfor %} 127 </select> 128 <input type="checkbox" title="Enable/disable pretty_printing" 129 onchange="pretty_print_check(this.checked);" 130 class="worksheet" value="pretty_print" {{ "checked" if worksheet.pretty_print() else "" }} /> Typeset 131 {% endif %} 132 </div> 133 <div id="share-publish-buttons"> 134 {% if not worksheet.is_doc_worksheet() %} 135 {% macro cls(x) %} 136 {{ "control-select" if x == select else "control" }} 137 {% endmacro %} 138 {% macro backwards_text() %}{{ "../" if backwards else "" }}{% endmacro %} 139 <a title="Print this worksheet" class="print-link" onClick="print_worksheet()"><img border=0 src="/images/icon_print.gif" alt="Print">Print</a> 140 <a class="{{ cls('use') }}" title="Interactively use this worksheet" onClick="edit_worksheet();">Worksheet</a> 141 <a class="{{ cls('edit') }}" title="Edit text version of this worksheet" href="{{ backwards_text() }}edit">Edit</a> 142 <a class="{{ cls('text') }}" title="View plain text version of this worksheet" href="{{ backwards_text() }}text">Text</a> 143 <a class="{{ cls('undo') }}" title="View changes to this worksheet over time" href="{{ backwards_text() }}revisions">Undo</a> 144 <a class="{{ cls('share') }}" title="Let others edit this worksheet" href="{{ backwards_text() }}share">Share</a> 145 <a class="{{ cls('publish') }}" title="Make this worksheet publicly viewable" href="{{ backwards_text() }}publish">Publish</a> 146 {% endif %} 147 </div> 148 </div> 149 <div class="hidden" id="slide_controls"> 150 <div class="slideshow_control"> 151 <a class="slide_arrow" onClick="slide_next()">></a> 152 <a class="slide_arrow" onClick="slide_last()">>></a> <span class="vbar"></span> 153 <a class="cell_mode" onClick="cell_mode()">Exit</a> 154 </div> 155 <div class="slideshow_progress" id="slideshow_progress" onClick="slide_next()"> 156 <div class="slideshow_progress_bar" id="slideshow_progress_bar"> </div> 157 <div class="slideshow_progress_text" id="slideshow_progress_text"> </div> 158 </div> 159 <div class="slideshow_control"> 160 <a class="slide_arrow" onClick="slide_first()"><<</a> 161 <a class="slide_arrow" onClick="slide_prev()"><</a> 162 </div> 163 </div> 164 {% block worksheet_main %}{% endblock %} 165 {% endblock %} 166 -
new file sagenb/data/sage/html/notebook/base_aux.html
diff --git a/sagenb/data/sage/html/notebook/base_aux.html b/sagenb/data/sage/html/notebook/base_aux.html new file mode 100644
- + 1 {% extends "html/notebook/base.html" %} 2 {# Base template for auxilliary pages (Edit, Text, etc.) #} 3 4 {% block worksheet_main %} 5 {% block before_sharebar %}{% endblock %} 6 <div class="sharebar">{% block sharebar_title %}{% endblock %}</div> 7 {% block after_sharebar %}{% endblock %} 8 {% endblock %} -
sagenb/data/sage/html/notebook/beforepublish_window.html
diff --git a/sagenb/data/sage/html/notebook/beforepublish_window.html b/sagenb/data/sage/html/notebook/beforepublish_window.html
a b 1 {% extends "html/notebook/worksheet_page_template.html" %} 2 {# 3 INPUT: 4 - worksheet - an instance of Worksheet 5 - worksheet_filename - a string containing a worksheet's filename 6 - username - a string containing a username 7 - JSMATH - a boolean stating whether to include jsMath 8 - JEDITABLE_TINYMCE - a boolean stating whether to include jEditable and TinyMCE 9 #} 1 {% extends "html/notebook/base_aux.html" %} 10 2 3 {% block page_id %}before-publish-page{% endblock %} 11 4 {% block sharebar_title %} 12 5 <p>You can publish your worksheet to the Internet, where anyone will be able to access and view it online.</p> 13 6 … … INPUT: 17 10 18 11 <form method="get" action="."> 19 12 <input type="hidden" name="yes" value="" /> 20 <input type="submit" value="Yes" style="margin-left:10px" /> 21 <input type="button" value="No" style="margin-left:5px" onClick="parent.location='../'" /> 22 <br/> 23 <br/> 24 <input type="checkbox" name="auto" style="margin-left:13px" /> Automatically re-publish when changes are made 13 <div> 14 <button type="submit">Yes</button> 15 <a href="../"><button>No</button></a> 16 </div> 17 <div> 18 <input type="checkbox" name="auto" /> <label for="auto"> Automatically re-publish when changes are made</label> 19 </div> 25 20 </form> 26 21 {% endblock %} 27 22 {% set select = "publish" %} -
new file sagenb/data/sage/html/notebook/cell.html
diff --git a/sagenb/data/sage/html/notebook/cell.html b/sagenb/data/sage/html/notebook/cell.html new file mode 100644
- + 1 {# 2 INPUT: 3 4 - ``cell`` -- Cell instance 5 6 - ``wrap`` - an integer stating column position to wrap lines. Defaults to 7 configuration if not given. 8 9 - ``div_wrap`` - a boolean stating whether to wrap ``div``. 10 11 - ``do_print`` - a boolean stating whether the HTML is for 12 print or not. 13 #} 14 {% if do_print %} 15 {% set wrap = 68 %} 16 {% set div_wrap = true %} 17 {% endif %} 18 {% set cell_cls = "cell_evaluated" if cell.evaluated() or do_print else "cell_not_evaluated" %} 19 20 {% if div_wrap %} 21 <div id="cell_outer_{{ cell.id() }}" class="cell_visible"> 22 <div id="cell_{{ cell.id() }}" class="{{ cell_cls }}"> 23 {% endif %} 24 {% if 'hideall' not in cell.percent_directives() %} 25 {# input #} 26 {% if not do_print %} 27 <div class="insert_new_cell" id="insert_new_cell_before{{ cell.id() }}"> 28 </div> 29 <script type="text/javascript"> 30 $("#insert_new_cell_before{{ cell.id() }}").plainclick(function (e) { 31 insert_new_cell_before({{ cell.id() }}); 32 }); 33 {% if not cell.worksheet().docbrowser() %} 34 $("#insert_new_cell_before{{ cell.id() }}").shiftclick(function (e) { 35 insert_new_text_cell_before({{ cell.id() }}); 36 }); 37 {% endif %} 38 </script> 39 {% endif %} 40 {% if 'hide' in cell.percent_directives() %} 41 {% set input_cls = 'cell_input_hide' %} 42 {% else %} 43 {% set input_cls = 'cell_input' %} 44 {% endif %} 45 {% if do_print %} 46 <div class="cell_input_print">{{ cell.input_text().rstrip()|escape }} </div> 47 {% else %} 48 <textarea class="cell_input" rows="{{ (1, cell.input_text().strip()|number_of_rows(80))|max }}" 49 cols="80" 50 id="cell_input_{{ cell.id() }}" 51 {# TODO: Migrate these 'on' handlers to a .js file #} 52 onKeyPress="return input_keypress({{ cell.id() }}, event);" 53 onKeyDown="return input_keydown({{ cell.id() }},event);" 54 onKeyUp="return input_keyup({{ cell.id() }}, event);" 55 onBlur="cell_blur({{ cell.id() }}); return true;" 56 onFocus="cell_focused(this, {{ cell.id() }}); return true;">{{ cell.input_text().rstrip() }}</textarea> 57 <a href="javascript:evaluate_cell({{ cell.id() }},0)" 58 class="eval_button" 59 id="eval_button{{ cell.id() }}" 60 alt="Click here or press shift-return to evaluate"> 61 evaluate 62 </a> 63 {% endif %} 64 {# end input #} 65 66 <div id='introspect_div_{{ cell.id() }}' class='introspection'></div> 67 {% endif %} 68 69 {% if do_print and cell.cell_output_type() == 'hidden' %} 70 <pre> 71 </pre> 72 {% else %} 73 {% set output_cls = 'cell_div_output_running' if cell.computing() else 'cell_div_output_' + cell.cell_output_type() %} 74 <div class="cell_output_div"> 75 <table class="cell_output_box"> 76 <tr> 77 <td class="cell_number" id="cell_number_{{ cell.id() }}" 78 {{ '' if do_print else 'onClick="cycle_cell_output_type(%s);"'|format(cell.id()) }} > 79 {% for i in range(7) %} {% endfor %} 80 </td> 81 <td class="output_cell"> 82 <div class="{{ output_cls }}" id="cell_div_output_{{ cell.id() }}"> 83 <div class="cell_output_{{ "print_" if do_print else '' }}{{ cell.cell_output_type() }}" 84 id="cell_output_{{ cell.id() }}"> 85 {% if cell.introspect() %} 86 {{ cell.output_text(0, html=true) }} 87 {% else %} 88 {{ cell.output_text(wrap, html=true) }} 89 {% endif %} 90 </div> 91 {% if not do_print %} 92 <div class="cell_output_{{ 'print_' if do_print else '' }}nowrap_{{ cell.cell_output_type() }}" 93 id="cell_output_nowrap_{{ cell.id() }}"> 94 {{ cell.output_text(0, html=true) }} 95 </div> 96 {% endif %} 97 <div class="cell_output_html_{{ cell.cell_output_type() }}" 98 id="cell_output_html_{{ cell.id() }}"> 99 {{ cell.output_html() }} 100 </div> 101 </div> 102 </td> 103 </tr> 104 </table> 105 </div> 106 {% endif %} 107 108 {% if div_wrap %} 109 </div> 110 </div> 111 {% endif %} -
deleted file sagenb/data/sage/html/notebook/debug_window.html
diff --git a/sagenb/data/sage/html/notebook/debug_window.html b/sagenb/data/sage/html/notebook/debug_window.html deleted file mode 100644
+ - 1 2 <div class='debug_window'>3 <div class='debug_output'><pre id='debug_output'></pre></div>4 <textarea rows=5 id='debug_input' class='debug_input'5 onKeyPress='return debug_keypress(event);'6 onFocus='debug_focus();' onBlur='debug_blur();'></textarea>7 </div>8 No newline at end of file -
sagenb/data/sage/html/notebook/doc_page.html
diff --git a/sagenb/data/sage/html/notebook/doc_page.html b/sagenb/data/sage/html/notebook/doc_page.html
a b 1 {% extends "html/notebook/ index.html" %}1 {% extends "html/notebook/worksheet_page.html" %} 2 2 3 3 {% block pre_main_css %} 4 4 <link type="text/css" rel="stylesheet" href="_static/default.css" media="screen" /> -
sagenb/data/sage/html/notebook/download_or_delete_datafile.html
diff --git a/sagenb/data/sage/html/notebook/download_or_delete_datafile.html b/sagenb/data/sage/html/notebook/download_or_delete_datafile.html
a b 1 {% extends "html/notebook/ worksheet_page_template.html" %}1 {% extends "html/notebook/base_aux.html" %} 2 2 {# 3 3 INPUT: 4 4 - worksheet - an instance of Worksheet 5 - worksheet_filename - a string containing a worksheet's filename6 5 - username - a string containing a username 7 - active_worksheets - a list of the Worksheet instances that are active for username8 6 - filename_ - the name of the file 9 - path - the path to the file10 7 - file_is_image - a boolean stating whether the file is an image 11 8 - file_is_text - a boolean stating whether the file is a text file 12 9 - text_file_content - a string containing the content of a text file 13 - JSMATH - a boolean stating whether to include jsMath14 - JEDITABLE_TINYMCE - a boolean stating whether to include jEditable and TinyMCE15 10 #} 16 11 12 {% set path = "/home/%s/data/%s"|format(worksheet.filename(), filename_) %} 13 17 14 {% block sharebar_title %} 18 15 Data file: {{ filename_ }} 19 16 {% endblock %} … … Data file: {{ filename_ }} 21 18 {% block after_sharebar %} 22 19 <p>You may download <a href="{{ path }}">{{ filename_ }}</a> or create a linked copy to the worksheet <select onchange="go_option(this);" class="worksheet"> 23 20 <option selected>select worksheet</option> 24 {% for worksheet in active_worksheets%}21 {% for worksheet in notebook.active_worksheets_for(username) %} 25 22 <option value='link_datafile("{{ worksheet.filename() }}","{{ filename_ }}")'>{{ worksheet.name() }}</option> 26 23 {% endfor %} 27 24 </select> or <a href="/home/{{ worksheet.filename() }}/datafile?name={{ filename_ }}&action=delete">delete {{ filename_ }}.</a></p> … … Data file: {{ filename_ }} 35 32 {% elif file_is_text %} 36 33 <form method="post" action="savedatafile" enctype="multipart/form-data"> 37 34 <input type="submit" value="Save Changes" name="button_save" /> <input type="submit" value="Cancel" name="button_cancel" style="display:block" /> 38 <textarea class="edit" name="textfield" rows=17 cols=70 id="textfield">{{ text_file_content }}</textarea>35 <textarea class="edit" name="textfield" rows=17 cols=70 id="textfield">{{ text_file_content | escape }}</textarea> 39 36 <input type="hidden" name="filename" value="{{ filename_ }}" id="filename" /> 40 37 </form> 41 38 {% endif %} -
sagenb/data/sage/html/notebook/edit_window.html
diff --git a/sagenb/data/sage/html/notebook/edit_window.html b/sagenb/data/sage/html/notebook/edit_window.html
a b 1 {% extends "html/notebook/worksheet_page_template.html" %} 2 {# 3 INPUT: 4 - worksheet - an instance of Worksheet 5 - worksheet_filename - a string containing a worksheet's filename 6 - username - a string containing a username 7 - text - a string containing the text of the worksheet 8 - n_lines - number of lines of the text of the worksheet 9 - JSMATH - a boolean stating whether to include jsMath 10 - JEDITABLE_TINYMCE - a boolean stating whether to include jEditable and TinyMCE 11 #} 1 {% extends "html/notebook/base_aux.html" %} 12 2 13 {% block sharebar_title %} 14 Edit plain text <input type="submit" value="Save Changes" name="button_save" id="button_save"> <input type="submit" value="Cancel" name="button_cancel"> 15 {% endblock %} 16 {% set select = "edit" %} 3 {% block page_id %}edit-page{% endblock %} 17 4 18 5 {% block before_sharebar %} 19 6 <form method="post" action="save" enctype="multipart/form-data"> 20 7 {% endblock %} 8 9 {% block sharebar_title %} 10 <span>Edit plain text</span> 11 <button type="submit" name="button_save" id="button_save">Save Changes</button> 12 <button type="submit" name="button_cancel">Cancel</button> 13 {% endblock %} 14 {% set select = "edit" %} 15 21 16 {% block after_sharebar %} 22 17 <script type="text/javascript"> 23 18 function save_worksheet() { … … Edit plain text 25 20 function save_worksheet_and_close() { 26 21 } 27 22 </script> 28 <textarea class="plaintextedit" id="cell_intext" name="textfield" rows="{{ n_lines }}">{{ text}}</textarea>23 <textarea class="plaintextedit" id="cell_intext" name="textfield" rows="{{ worksheet.edit_text().count("\n")+1 }}">{{ worksheet.edit_text()|escape }}</textarea> 29 24 </form> 30 25 {% endblock %} -
deleted file sagenb/data/sage/html/notebook/guest_top_bar_and_worksheet.html
diff --git a/sagenb/data/sage/html/notebook/guest_top_bar_and_worksheet.html b/sagenb/data/sage/html/notebook/guest_top_bar_and_worksheet.html deleted file mode 100644
+ - 1 2 {#3 INPUT:4 - original_worksheet - an instance of Worksheet5 - worksheet - an instance of Worksheet6 - notebook - an instance of Notebook which contains worksheet7 - worksheet_html - a string containing the html for the worksheet8 - username - a string containing a username9 #}10 {% if original_worksheet.is_collaborator(username) or original_worksheet.is_owner(username) %}11 {% set edit_text = "Edit this." %}12 {% set url = "edit_published_page" %}13 {% elif notebook.user_is_guest(username) %}14 {% set edit_text = "Log in to edit a copy." %}15 {% set url = "/" %}16 {% else %}17 {% set edit_text = "Edit a copy." %}18 {% set url = "edit_published_page" %}19 {% endif %}20 21 {% set download_name = worksheet.download_name() %}22 23 <a class="usercontrol" href="{{ url }}">{{ edit_text }}</a>24 <a class="usercontrol" href="download/{{ download_name }}.sws">Download.</a>25 <span class="ratingmsg">26 {% if worksheet.rating() != -1 %}27 <a class="usercontrol" href="rating_info">28 This page is rated {{ "%.1f"|format(worksheet.rating()) }}.29 </a>30 {% endif %}31 {% if not notebook.user_is_guest(username)32 and not worksheet.is_publisher(username) %}33 34 <span class="usercontrol">35 {{ "Rerate" if worksheet.is_rater(username) else "Rate" }} it:36 </span>37 {% for i in range(5) %}38 <a class="usercontrol"39 onClick="rate_worksheet({{ i }})">40 {{ i }} 41 </a>42 {% endfor %}43 <input name="rating_comment" id="rating_comment"></input>44 {% endif %}45 </span>46 <span class="pubmsg">47 <a href="/pub/">Other published documents...</a>48 </span>49 <hr class="usercontrol" />50 <h1 align="center" class="title">{{ worksheet.name() }}</h1>51 <h2 align="center">{{ worksheet.html_time_since_last_edited() }}</h2>52 {{ worksheet_html }}53 <hr class="usercontrol" />54 {% for i in range(10) %}55 56 {% endfor %}57 58 59 -
new file sagenb/data/sage/html/notebook/guest_worksheet_page.html
diff --git a/sagenb/data/sage/html/notebook/guest_worksheet_page.html b/sagenb/data/sage/html/notebook/guest_worksheet_page.html new file mode 100644
- + 1 {% extends "html/notebook/base.html" %} 2 {# 3 INPUT: 4 - worksheet - an instance of Worksheet 5 - notebook - an instance of Notebook which contains worksheet 6 - username - a string containing a username 7 #} 8 9 {% block page_id %}guest-worksheet-page{% endblock %} 10 11 {% set original_worksheet = worksheet.worksheet_that_was_published() %} 12 {% if original_worksheet.is_collaborator(username) or original_worksheet.is_owner(username) %} 13 {% set edit_text = "Edit this." %} 14 {% set url = "edit_published_page" %} 15 {% elif notebook.user_is_guest(username) %} 16 {% set edit_text = "Log in to edit a copy." %} 17 {% set url = "/" %} 18 {% else %} 19 {% set edit_text = "Edit a copy." %} 20 {% set url = "edit_published_page" %} 21 {% endif %} 22 23 {% set download_name = worksheet.download_name() %} 24 25 {% block body %} 26 <ul class="controls"> 27 <li><a href="{{ url }}">{{ edit_text }}</a></li> 28 <li><a href="download/{{ download_name }}.sws">Download.</a></li> 29 {% if worksheet.rating() != -1 or 30 not (notebook.user_is_guest(username) or worksheet.is_publisher(username)) %} 31 <li> 32 {% if worksheet.rating() != -1 %} 33 <a class="usercontrol" href="rating_info"> 34 This page is rated {{ "%.1f"|format(worksheet.rating()) }}. 35 </a> 36 {% endif %} 37 {% if not (notebook.user_is_guest(username) or worksheet.is_publisher(username)) %} 38 <span> 39 {{ "Rerate" if worksheet.is_rater(username) else "Rate" }} it: 40 </span> 41 {% for i in range(5) %} 42 <a class="usercontrol" 43 onClick="rate_worksheet({{ i }})">{{ i }}</a> 44 {% endfor %} 45 <input name="rating_comment" id="rating_comment" /> 46 {% endif %} 47 </li> 48 {% endif %} 49 <li><a href="/pub/">Other published documents...</a></li> 50 </ul> 51 <hr class="usercontrol" /> 52 <h1 class="title">{{ worksheet.name() }}</h1> 53 <h2 class="lastedit">{{ worksheet.html_time_since_last_edited() }}</h2> 54 {{ worksheet.html(do_print=false, publish=true) }} 55 <hr class="usercontrol" /> 56 {% for i in range(10) %} 57 58 {% endfor %} 59 {% endblock %} 60 61 62 -
deleted file sagenb/data/sage/html/notebook/head.tmpl
diff --git a/sagenb/data/sage/html/notebook/head.tmpl b/sagenb/data/sage/html/notebook/head.tmpl deleted file mode 100644
+ - 1 {#2 INPUT:3 - worksheet - an instance of Worksheet4 - worksheet_filename - a string containing a worksheet's filename5 - username - a string containing a user's name6 - JSMATH - a boolean stating whether to include jsMath7 - JEDITABLE_TINYMCE - a boolean stating whether to include jEditable and TinyMCE8 #}9 {% macro common_title(worksheet_filename, worksheet) %}10 {% if worksheet_filename %}11 {{ worksheet.name() }} (Sage)12 {% else %}13 Sage Notebook | Welcome14 {% endif %}15 {% endmacro %}16 17 {% macro common_javascript(worksheet, worksheet_filename, username, JSMATH, JEDITABLE_TINYMCE) %}18 <!-- jQuery UI - interacts, widgets, drag-drop, etc. -->19 <link rel="stylesheet" href="/javascript/jqueryui/css/sage/jquery-ui-1.7.2.custom.css" />20 <script type="text/javascript" src="/javascript/jqueryui/js/jquery-ui-1.7.2.custom.min.js"></script>21 22 <!-- jQuery plugins - color pickers, shift-click, AJAX forms, IE fixes -->23 <link rel="stylesheet" href="/javascript/jquery/plugins/farbtastic/farbtastic.css" type="text/css" />24 <script type="text/javascript" src="/javascript/jquery/plugins/farbtastic/farbtastic.min.js"></script>25 <script type="text/javascript" src="/javascript/jquery/plugins/extendedclick/jquery.event.extendedclick.min.js"></script>26 <script type="text/javascript" src="/javascript/jquery/plugins/form/jquery.form.min.js"></script>27 <script type="text/javascript" src="/javascript/jquery/plugins/jquery.bgiframe.min.js"></script>28 <link rel="stylesheet" href="/javascript/jquery/plugins/jpicker/css/jPicker-1.0.11.css" type="text/css" />29 <script type="text/javascript" src="/javascript/jquery/plugins/jpicker/jpicker-1.0.11.min.js"></script>30 <link rel="stylesheet" media="screen" type="text/css" href="/javascript/jquery/plugins/colorpicker/css/colorpicker.css" />31 <script type="text/javascript" src="/javascript/jquery/plugins/colorpicker/js/colorpicker.min.js"></script>32 33 <script type="text/javascript" src="/javascript/sage/main.js"></script>34 35 {% if JSMATH %}36 <!-- jsMath - typeset mathematics -->37 <script type="text/javascript" src="/javascript/sage/jsmath.js"></script>38 {% endif %}39 40 <!-- Sage3d - accelerated 3D graphics -->41 <script type="text/javascript" src="/javascript/sage3d/sage3d.js"></script>42 43 <!-- Jmol - embedded 3D graphics -->44 <script type="text/javascript" src="/java/jmol/appletweb/Jmol.js"></script>45 <!-- This must stay in head -->46 <script>jmolInitialize("/java/jmol");jmolSetCallback("menuFile","/java/jmol/appletweb/SageMenu.mnu");</script>47 48 {% if JEDITABLE_TINYMCE and not worksheet.docbrowser() and not worksheet.is_published() %}49 <!-- TinyMCE and jEditable - in-place editing of text cells -->50 <script type="text/javascript" src="/javascript/tiny_mce/tiny_mce.js"></script>51 <script type="text/javascript" src="/javascript/jquery/plugins/jeditable/jquery.jeditable.mini.js" charset="utf-8"></script>52 <script type="text/javascript" src="/javascript/sage/tinymce.js"></script>53 {% endif %}54 55 <script type="text/javascript">user_name= "{{ username }}";</script>56 {% if worksheet_filename %}57 <script type="text/javascript">58 worksheet_filename="{{ worksheet_filename }}";59 worksheet_name="{{ worksheet.name() }}";60 server_ping_while_alive();61 </script>62 {% endif %}63 64 {% endmacro %} -
deleted file sagenb/data/sage/html/notebook/index.html
diff --git a/sagenb/data/sage/html/notebook/index.html b/sagenb/data/sage/html/notebook/index.html deleted file mode 100644
+ - 1 {% extends "html/base.html" %}2 {#3 INPUT:4 - worksheet - an instance of Worksheet5 - worksheet_filename - a string containing a worksheet's filename6 - notebook - an instance of Notebook which contains worksheet7 - username - a string containing a username8 - show_debug - a boolean stating whether to show debug information9 - JSMATH - a boolean stating whether to include jsMath10 - JSMATH_IMAGE_FONTS - a boolean stating whether to include jsMath iamage fonts11 - JEDITABLE_TINYMCE - a boolean stating whether to include jEditable and TinyMCE12 - sage_jsmath_macros - an array containing strings of Javascript of Sage macros for jsMath13 - do_print - a boolean stating whether the file is for print mode14 - worksheet_html - a string containing the html for a worksheet15 - select - a string containing the control that is selected16 - backwards - a boolean17 - warn - boolean stating whether to warn that another user is viewing18 the worksheet19 #}20 21 {% if not select %}22 {% set select = none %}23 {% endif %}24 25 {% if not backwards %}26 {% set backwards = false %}27 {% endif %}28 29 {% include "html/notebook/head.tmpl"%}30 31 {% block title %}32 {{ common_title(worksheet_filename, worksheet) }}33 {% endblock %}34 35 {% block css %}main{% endblock %}36 37 {% block javascript %}38 {{ common_javascript(worksheet, worksheet_filename, username, JSMATH, JEDITABLE_TINYMCE) }}39 {% endblock %}40 41 {# TODO: Hack until the template restructuring #}42 {% block body_attrs %}43 {% if worksheet.is_published() or notebook.user_is_guest(username) %}44 class="worksheet-online" onLoad="initialize_the_notebook();"45 {% else %}46 class="worksheet-online" onLoad="initialize_the_notebook();" id="user-worksheet-index"47 {% endif %}48 {% endblock %}49 50 51 {% block body %}52 {% if worksheet.is_published() or notebook.user_is_guest(username) %}53 {% set original_worksheet = worksheet.worksheet_that_was_published() %}54 {% include "html/notebook/guest_top_bar_and_worksheet.html" %}55 {% else %}56 {% include "html/notebook/top_bar_and_worksheet.html" %}57 {% endif %}58 {% if not worksheet %}59 </td></tr></table></span>60 {% endif %}61 {% if worksheet.is_only_viewer(username) %}62 <script type="text/javascript">worksheet_locked=true;</script>63 {% else %}64 <script type="text/javascript">worksheet_locked=false;</script>65 {% endif %}66 {% if worksheet.computing() %}67 <!-- Set the update checking back in motion. -->68 <script type="text/javascript">69 active_cell_list = {{ worksheet.queue_id_list() }};70 for(var i = 0; i < active_cell_list.length; i++) {71 cell_set_running(active_cell_list[i]);72 }73 start_update_check();74 </script>75 {% endif %}76 {% endblock %} -
sagenb/data/sage/html/notebook/plain_text_window.html
diff --git a/sagenb/data/sage/html/notebook/plain_text_window.html b/sagenb/data/sage/html/notebook/plain_text_window.html
a b 1 {% extends "html/notebook/worksheet_page_template.html" %} 2 {# 3 INPUT: 4 - worksheet - an instance of Worksheet 5 - worksheet_filename - a string containing a worksheet's filename 6 - username - a string containing a username 7 - plain_text - a string containing the plain text version 8 - JSMATH - a boolean stating whether to include jsMath 9 - JEDITABLE_TINYMCE - a boolean stating whether to include jEditable and TinyMCE 10 #} 1 {% extends "html/notebook/base_aux.html" %} 11 2 12 3 {% block sharebar_title %} 13 4 View plain text … … View plain text 16 7 {% set select = "text" %} 17 8 18 9 {% block after_sharebar %} 19 <pre class="plaintext" id="cell_intext" name="textfield">{{ plain_text}}</pre>10 <pre class="plaintext" id="cell_intext" name="textfield">{{ worksheet.plain_text(prompts=true, banner=false)|escape|trim }}</pre> 20 11 {% endblock %} -
deleted file sagenb/data/sage/html/notebook/plain_text_worksheet.html
diff --git a/sagenb/data/sage/html/notebook/plain_text_worksheet.html b/sagenb/data/sage/html/notebook/plain_text_worksheet.html deleted file mode 100644
+ - 1 2 {#3 INPUT:4 - worksheet_name - a string containing a worksheet's name5 - worksheet_plain_text - a string containing the plain text version of a worksheet6 #}7 <head>8 <title>Sage Worksheet: {{ worksheet_name }}</title>9 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />10 </head>11 <body>12 <h1><a href=".">Sage Worksheet: %s</a></h1>13 <pre>{{ worksheet_plain_text }}</pre>14 </body>15 No newline at end of file -
new file sagenb/data/sage/html/notebook/print_worksheet.html
diff --git a/sagenb/data/sage/html/notebook/print_worksheet.html b/sagenb/data/sage/html/notebook/print_worksheet.html new file mode 100644
- + 1 {% extends "html/notebook/base.html" %} 2 3 {% block page_id %}print-page{% endblock %} 4 5 {% block body %} 6 <h1>{{ worksheet.name() }}</h1> 7 {{ worksheet.html(do_print=true) }} 8 {% endblock %} 9 10 11 No newline at end of file -
deleted file sagenb/data/sage/html/notebook/slide_controls.html
diff --git a/sagenb/data/sage/html/notebook/slide_controls.html b/sagenb/data/sage/html/notebook/slide_controls.html deleted file mode 100644
+ - 1 2 <div class="hidden" id="slide_controls">3 <div class="slideshow_control">4 <a class="slide_arrow" onClick="slide_next()">></a>5 <a class="slide_arrow" onClick="slide_last()">>></a> <span class="vbar"></span>6 <a class="cell_mode" onClick="cell_mode()">Exit</a>7 </div>8 <div class="slideshow_progress" id="slideshow_progress" onClick="slide_next()">9 <div class="slideshow_progress_bar" id="slideshow_progress_bar"> </div>10 <div class="slideshow_progress_text" id="slideshow_progress_text"> </div>11 </div>12 <div class="slideshow_control">13 <a class="slide_arrow" onClick="slide_first()"><<</a>14 <a class="slide_arrow" onClick="slide_prev()"><</a>15 </div>16 </div>17 18 19 20 21 22 23 -
sagenb/data/sage/html/notebook/specific_revision.html
diff --git a/sagenb/data/sage/html/notebook/specific_revision.html b/sagenb/data/sage/html/notebook/specific_revision.html
a b 1 {% extends "html/notebook/worksheet_page_template.html" %} 2 {# 3 INPUT: 4 - worksheet - an instance of Worksheet 5 - worksheet_filename - a string containing a worksheet's filename 6 - username - a string containing a username 7 - rev - this revision's key 8 - prev_rev - the previous revision's key 9 - next_rev - the next revision's key 10 - time_ago - a string containing the time since revision 11 - body_worksheet_html - the body html of the worksheet 12 - JSMATH - a boolean stating whether to include jsMath 13 - JEDITABLE_TINYMCE - a boolean stating whether to include jEditable and TinyMCE 14 #} 1 {% extends "html/notebook/base_aux.html" %} 15 2 16 3 {% set select = "revisions" %} 17 4 {% block sharebar_title %} … … Revision from {{ time_ago }} ago &n 40 27 {% block after_sharebar %} 41 28 {{ actions() }} 42 29 <div id="revision-data"> 43 {{ body_worksheet_html}}30 {{ worksheet.html(do_print=true, publish=true) }} 44 31 </div> 45 32 {{ actions() }} 46 33 <script type="text/javascript"> -
new file sagenb/data/sage/html/notebook/text_cell.html
diff --git a/sagenb/data/sage/html/notebook/text_cell.html b/sagenb/data/sage/html/notebook/text_cell.html new file mode 100644
- + 1 {# 2 INPUT: 3 4 - cell -- Cell instance 5 6 - wrap -- number of columns to wrap 7 8 - do_print -- whether to display for printing 9 10 - do_math_parse -- whether to parse jsMath 11 12 - editing -- whether user is editing the cell 13 #} 14 <span id="cell_outer_{{ cell.id() }}"> 15 {% if not do_print and not cell.worksheet().docbrowser() %} 16 <div class="insert_new_cell" id="insert_new_cell_before{{ cell.id() }}"> 17 </div> 18 <script type="text/javascript"> 19 $("#insert_new_cell_before{{ cell.id() }}").plainclick(function (e) { 20 insert_new_cell_before({{ cell.id() }}); 21 }); 22 $("#insert_new_cell_before{{ cell.id() }}").shiftclick(function (e) { 23 insert_new_text_cell_before({{ cell.id() }}); 24 }); 25 </script> 26 {% endif %} 27 <div class="text_cell" id="cell_text_{{ cell.id() }}"> 28 {% if do_math_parse %} 29 {{ cell.plain_text()|math_parse }} 30 {% else %} 31 {{ cell.plain_text() }} 32 {% endif %} 33 </div> 34 {% if JEDITABLE_TINYMCE and not cell.worksheet().is_published() and not cell.worksheet().docbrowser() and not do_print %} 35 <script type="text/javascript"> 36 $("#cell_text_{{ cell.id() }}").unbind('dblclick').editable(function(value,settings) { 37 evaluate_text_cell_input({{ cell.id() }},value,settings); 38 return(value); 39 }, 40 { 41 tooltip : "", 42 placeholder : "", 43 // type : 'textarea', 44 type : 'mce', 45 onblur : 'ignore', 46 select : false, 47 submit : 'Save changes', 48 cancel : 'Cancel changes', 49 event : "dblclick", 50 style : "inherit", 51 }); 52 </script> 53 {% endif %} 54 55 {% if editing and not do_print %} 56 <script> 57 $("#cell_text_{{ cell.id() }}").trigger('dblclick'); 58 </script> 59 {% endif %} 60 </span> -
deleted file sagenb/data/sage/html/notebook/top_bar_and_worksheet.html
diff --git a/sagenb/data/sage/html/notebook/top_bar_and_worksheet.html b/sagenb/data/sage/html/notebook/top_bar_and_worksheet.html deleted file mode 100644
+ - 1 {#2 INPUT:3 - username - a string containing a username4 - worksheet_filename - a string containing a worksheet's filename5 - worksheet_html - a string containing the html for a worksheet6 - show_debug - a boolean stating whether to show debug information7 #}8 {% include "html/notebook/worksheet_topbar.tmpl" %}9 {% set toggle=true %}10 {% include "html/top_bar.html" %}11 {% if worksheet.filename() %}12 {{ worksheet_topbar(worksheet, "use", username) }}13 {% endif %}14 {% if show_debug %}15 {% include "html/notebook/debug_window.html" %}16 {% endif %}17 18 <div class="worksheet" id="worksheet">19 {{ worksheet_html }}20 </div>21 -
sagenb/data/sage/html/notebook/upload_data_window.html
diff --git a/sagenb/data/sage/html/notebook/upload_data_window.html b/sagenb/data/sage/html/notebook/upload_data_window.html
a b 1 {% extends "html/notebook/worksheet_page_template.html" %} 2 {# 3 INPUT: 4 - worksheet - an instance of Worksheet 5 - worksheet_filename - a string containing a worksheet's filename 6 - username - a string containing a username 7 - JSMATH - a boolean stating whether to include jsMath 8 - JEDITABLE_TINYMCE - a boolean stating whether to include jEditable and TinyMCE 9 #} 1 {% extends "html/notebook/base_aux.html" %} 2 10 3 11 4 {% block page_id %}upload-data-page{% endblock %} 12 5 … … Upload or Create Data File to attach to 20 13 name="upload" enctype="multipart/form-data"> 21 14 <div> 22 15 <label for="file">Browse your computer to select a worksheet file to upload:</label> 23 <input size="50" type="file" name="file" ></input>16 <input size="50" type="file" name="file" /> 24 17 </div> 25 18 <div> 26 19 <label for="url">Or enter the url of a worksheet file on the web:</label> 27 <input size="50" type="text" name="url" ></input>20 <input size="50" type="text" name="url" /> 28 21 </div> 29 22 <div> 30 23 <label for="new">Or enter the name of a new file, which will be created:</label> 31 <input size="50" type="text" name="new" ></input>24 <input size="50" type="text" name="new" /> 32 25 </div> 33 26 <div> 34 27 <label for="name">What do you want to call it? (if different than the original name)</label> 35 <input size="50" type="text" name="name" ></input>28 <input size="50" type="text" name="name" /> 36 29 </div> 37 30 <button type="submit">Upload or Create Data File</button> 38 31 </form> -
sagenb/data/sage/html/notebook/worksheet.html
diff --git a/sagenb/data/sage/html/notebook/worksheet.html b/sagenb/data/sage/html/notebook/worksheet.html
a b 1 1 {# 2 2 INPUT: 3 - worksheet_name - a string containing a worksheet's name4 - worksheet_html - a string containing the html for a worksheet5 - do_print - a boolean stating whether to render a print version of the6 worksheet7 #}8 {% extends "html/base.html" %}9 3 10 {% block title %}Sage Worksheet: {{ worksheet_name }}{% endblock %} 4 - worksheet -- Worksheet object 11 5 12 {% block css %}main{% endblock %} 6 - publish -- boolean whether this is for the published version 13 7 14 {% block javascript %} 15 <script type="text/javascript" src="/javascript/sage/main.js"></script> 16 {% if do_print %} 17 <script type="text/javascript" src="/javascript/sage/jsmath.js"></script> 18 {% endif %} 19 {% endblock %} 8 - do_print -- boolean whether this is for a print version 20 9 21 {% block body_attrs %} 22 {% if not do_print %} 23 class="worksheet-online" onLoad="initialize_the_notebook();" 10 #} 11 12 {% set wrap = conf['word_wrap_cols'] %} 13 {% if not publish %} 14 {% set publish = worksheet.is_published() %} 24 15 {% endif %} 25 {% endblock %}26 16 27 {% block body %} 28 {% if do_print%}29 <div class="worksheet_print_title"> {{ worksheet_name }}</div>17 <div class="cell_input_active" id="cell_resizer"></div> 18 {% if not publish %} 19 <div class="worksheet_cell_list" id="worksheet_cell_list"> 30 20 {% endif %} 31 {{ worksheet_html }} 32 {% if do_print %} 33 <script type="text/javascript">jsMath.Process();</script> 21 22 {% for cell in worksheet.cell_list() %} 23 {{ cell.html(wrap = wrap, div_wrap = true, do_print = do_print or publish) }} 24 {% endfor %} 25 26 {% if not do_print and not publish %} 27 </div> 28 <div class="insert_new_cell" id="insert_last_cell"></div> 29 <script type="text/javascript"> 30 $("#insert_last_cell").plainclick(function (e) { 31 insert_new_cell_after(cell_id_list[cell_id_list.length - 1]); 32 }); 33 {% if not worksheet.docbrowser() %} 34 $("#insert_last_cell").shiftclick(function (e) { 35 insert_new_text_cell_after(cell_id_list[cell_id_list.length - 1]); 36 }); 34 37 {% endif %} 35 {% endblock %} 38 </script> 39 {% endif %} -
new file sagenb/data/sage/html/notebook/worksheet_page.html
diff --git a/sagenb/data/sage/html/notebook/worksheet_page.html b/sagenb/data/sage/html/notebook/worksheet_page.html new file mode 100644
- + 1 {% extends "html/notebook/base.html" %} 2 {# 3 INPUT: 4 - worksheet - an instance of Worksheet 5 - notebook - an instance of Notebook which contains worksheet 6 - show_debug - a boolean stating whether to show debug information 7 - do_print - a boolean stating whether the file is for print mode 8 #} 9 10 {% block body_classes %}worksheet-online{% if not (worksheet.is_published() or notebook.user_is_guest(username) or worksheet.is_doc_worksheet()) %} active-worksheet-page{% endif %}{% endblock %} 11 {% block page_id %}user-worksheet-index{% endblock %} 12 13 {% block worksheet_main %} 14 {% set toggle=true %} 15 <div class="worksheet" id="worksheet"> 16 {{ worksheet.html() }} 17 {% if do_print %} 18 <script> 19 jsMath.ProcessBeforeShowing(); 20 </script> 21 {% else %} 22 <script type="text/javascript"> 23 cell_id_list = {{ worksheet.cell_id_list() }}; 24 state_number = {{ worksheet.state_number() }}; 25 {% if not published %} 26 $(document).ready(function () { 27 if (worksheet_name === "Untitled") { 28 rename_worksheet(); 29 } 30 }); 31 {% endif %} 32 </script> 33 {% endif %} 34 </div> 35 36 {% if show_debug %} 37 <div class='debug_window'> 38 <div class='debug_output'><pre id='debug_output'></pre></div> 39 <textarea rows=5 id='debug_input' class='debug_input' 40 onKeyPress='return debug_keypress(event);' 41 onFocus='debug_focus();' onBlur='debug_blur();'> 42 </textarea> 43 </div> 44 {% endif %} 45 46 <script type="text/javascript"> 47 {% if worksheet.is_only_viewer(username) %} 48 worksheet_locked = true; 49 {% else %} 50 worksheet_locked = false; 51 {% endif %} 52 </script> 53 54 {% if worksheet.computing() %} 55 <!-- Set the update checking back in motion. --> 56 <script type="text/javascript"> 57 active_cell_list = {{ worksheet.queue_id_list() }}; 58 for (var i = 0; i < active_cell_list.length; i += 1) { 59 cell_set_running(active_cell_list[i]); 60 } 61 start_update_check(); 62 </script> 63 {% endif %} 64 {% endblock %} -
deleted file sagenb/data/sage/html/notebook/worksheet_page_template.html
diff --git a/sagenb/data/sage/html/notebook/worksheet_page_template.html b/sagenb/data/sage/html/notebook/worksheet_page_template.html deleted file mode 100644
+ - 1 {% extends "html/base.html" %}2 {#3 INPUT:4 - worksheet - an instance of Worksheet5 - worksheet_filename - a string containing a worksheet's filename6 - username - a string containing a username7 - title - a string8 - select - a string containing the control that is selected9 - backwards - a boolean10 - JSMATH - a boolean stating whether to include jsMath11 - JEDITABLE_TINYMCE - a boolean stating whether to include jEditable and TinyMCE12 #}13 14 {% if not select %}15 {% set select = none %}16 {% endif %}17 18 {% if not backwards %}19 {% set backwards = false %}20 {% endif %}21 22 {% include "html/notebook/head.tmpl" %}23 {% include "html/notebook/worksheet_topbar.tmpl" %}24 25 {% block title %}26 {{ common_title(worksheet_filename, worksheet) }}27 {% endblock %}28 29 {% block css %}main{% endblock %}30 31 {% block javascript %}32 {{ common_javascript(worksheet, worksheet_filename, username, JSMATH, JEDITABLE_TINYMCE) }}33 {% endblock %}34 35 {% block body %}36 {% set toggle=true %}37 {% include "html/top_bar.html" %}38 {{ worksheet_topbar(worksheet, select, username, backwards) }}39 <hr class="usercontrol" />40 {% block before_sharebar %}{% endblock %}41 <span class="sharebar">{% block sharebar_title %}{% endblock %}</span>42 <br /><br /><br />43 {% block after_sharebar %}{% endblock %}44 {% endblock %}45 -
sagenb/data/sage/html/notebook/worksheet_revision_list.html
diff --git a/sagenb/data/sage/html/notebook/worksheet_revision_list.html b/sagenb/data/sage/html/notebook/worksheet_revision_list.html
a b 1 {% extends "html/notebook/worksheet_page_template.html" %} 2 {# 3 INPUT: 4 - data - a list of pairs of the form ('how long ago', key) 5 - worksheet - an instance of Worksheet 6 - worksheet_filename - a string containing a worksheet's filename 7 - username - a string containing a username 8 - JSMATH - a boolean stating whether to include jsMath 9 - JEDITABLE_TINYMCE - a boolean stating whether to include jEditable and TinyMCE 10 #} 1 {% extends "html/notebook/base_aux.html" %} 11 2 12 3 {% block page_id %}revision-list-page{% endblock %} 13 4 … … Revision History 26 17 </tr> 27 18 </thead> 28 19 <tbody> 29 {% for desc, key in data|reverse %}20 {% for desc, key in worksheet.snapshot_data()|reverse %} 30 21 <tr> 31 22 <td><a href="revisions?rev={{ key }}">Revision {{ loop.revindex0 }}</a></td> 32 23 <td><span class="revs">{{ desc }}</span></td> -
deleted file sagenb/data/sage/html/notebook/worksheet_settings.html
diff --git a/sagenb/data/sage/html/notebook/worksheet_settings.html b/sagenb/data/sage/html/notebook/worksheet_settings.html deleted file mode 100644
+ - 1 {% extends "html/notebook/worksheet_page_template.html" %}2 {#3 INPUT:4 - worksheet - an instance of Worksheet5 - worksheet_filename - a string containing a worksheet's filename6 - username - a string containing a username7 - JSMATH - a boolean stating whether to include jsMath8 - JEDITABLE_TINYMCE - a boolean stating whether to include jEditable and TinyMCE9 #}10 11 {% block sharebar_title %}12 Worksheet Settings <button name="button_save">Save Settings</button> <input type="submit" value="Cancel" name="button_cancel"/>13 {% endblock %}14 15 {% block before_sharebar %}16 <form width=70% method="post" action="input_settings" enctype="multipart/form-data">17 {% endblock %}18 {% block after_sharebar %}19 </form>20 {% endblock %}21 22 23 -
sagenb/data/sage/html/notebook/worksheet_share.html
diff --git a/sagenb/data/sage/html/notebook/worksheet_share.html b/sagenb/data/sage/html/notebook/worksheet_share.html
a b 1 {% extends "html/notebook/ worksheet_page_template.html" %}1 {% extends "html/notebook/base_aux.html" %} 2 2 {# 3 3 INPUT: 4 4 - worksheet - an instance of Worksheet 5 - worksheet_filename - a string containing a worksheet's filename6 5 - username - a string containing a username 7 6 - other_users - a list of strings containing other users names 8 - user_is_admin - a boolean stating whether the user is an admin9 - JSMATH - a boolean stating whether to include jsMath10 - JEDITABLE_TINYMCE - a boolean stating whether to include jEditable and TinyMCE11 7 #} 12 8 13 9 {% block sharebar_title %} … … Share this document 17 13 {% set select = "share" %} 18 14 19 15 {% block after_sharebar %} 20 {% if not ( user_is_adminor username == worksheet.owner()) %}16 {% if not (notebook.user_is_admin(username) or username == worksheet.owner()) %} 21 17 Only the owner of a worksheet is allowed to share it. You can do whatever you want if you <a href="copy">make your own copy</a>. 22 18 {% else %} 23 19 <p>This Sage Worksheet is currently shared with the people listed in the box below.</p> -
deleted file sagenb/data/sage/html/notebook/worksheet_topbar.tmpl
diff --git a/sagenb/data/sage/html/notebook/worksheet_topbar.tmpl b/sagenb/data/sage/html/notebook/worksheet_topbar.tmpl deleted file mode 100644
+ - 1 {#2 INPUT:3 - worksheet - an instance of Worksheet4 - select - a string containing the control that is selected5 - username - a string containing a username6 - backwards - a boolean7 #}8 {% macro worksheet_topbar(worksheet, select=None, username='guest',9 backwards=false, warn=false) %}10 <div id="worksheet-bar">11 <div class="worksheet_title">12 <a id="worksheet_title" class="worksheet_title"13 onClick="rename_worksheet(); return false;"14 title="Click to rename this worksheet">15 {{ worksheet.name() }}16 </a>17 <br> {{ worksheet.html_time_last_edited() }}18 {% if worksheet.warn_about_other_person_editing(username) and username != 'guest' and not worksheet.is_doc_worksheet() %}19 <span class="pingdown">(Someone else is viewing this worksheet)</span>20 {% endif %}21 </div>22 <div id="save-discard-buttons">23 {{ worksheet.html_save_discard_buttons() }}24 </div>25 26 <div id="worksheet-menu">27 {{ worksheet.html_menu() }}28 </div>29 <div id="share-publish-buttons">30 {{ worksheet.html_share_publish_buttons(select, backwards) }}31 </div>32 </div>33 <div class="hidden" id="slide_controls">34 <div class="slideshow_control">35 <a class="slide_arrow" onClick="slide_next()">></a>36 <a class="slide_arrow" onClick="slide_last()">>></a> <span class="vbar"></span>37 <a class="cell_mode" onClick="cell_mode()">Exit</a>38 </div>39 <div class="slideshow_progress" id="slideshow_progress" onClick="slide_next()">40 <div class="slideshow_progress_bar" id="slideshow_progress_bar"> </div>41 <div class="slideshow_progress_text" id="slideshow_progress_text"> </div>42 </div>43 <div class="slideshow_control">44 <a class="slide_arrow" onClick="slide_first()"><<</a>45 <a class="slide_arrow" onClick="slide_prev()"><</a>46 </div>47 </div>48 {% endmacro %} -
deleted file sagenb/data/sage/html/notebook_settings.html
diff --git a/sagenb/data/sage/html/notebook_settings.html b/sagenb/data/sage/html/notebook_settings.html deleted file mode 100644
+ - 1 {% extends "html/base.html" %}2 3 {% block title %}Notebook Settings{% endblock %}4 {% block css %}account_settings{% endblock %}5 {% block more_css %}6 <link rel="stylesheet" href="/javascript/jquery/plugins/farbtastic/farbtastic.css" type="text/css" />7 {% endblock %}8 9 {% block javascript %}10 <script type="text/javascript" src="/javascript/jquery/plugins/farbtastic/farbtastic.min.js"></script>11 {% endblock %}12 13 {% block body %}14 <h1>Notebook Settings</h1>15 <div class="section"><a href="/users">Manage Users</a> | <a href="/settings">My Settings</a> | <a href="/">My Worksheets</a> | <a href="/logout">Sign Out</a></div>16 17 <form method="get" action="/notebooksettings">18 <input type="hidden" name="form" value="on" />19 {%- if auto_table %}20 {{ auto_table }}21 {%- endif %}22 <div id="buttons">23 <input type="submit" value="Save">24 <input type="button" value="Cancel" style="margin-left:5px" onClick="parent.location='/'">25 </div>26 </form>27 {% endblock %} -
deleted file sagenb/data/sage/html/registration.html
diff --git a/sagenb/data/sage/html/registration.html b/sagenb/data/sage/html/registration.html deleted file mode 100644
+ - 1 {% extends "html/base.html" %}2 3 {% block title %}Sign up{% endblock %}4 5 {% block css %}registration{% endblock %}6 7 {% block body %}8 <div id="wrapper">9 <h1>Sign up for a Sage Notebook account</h1>10 {% if error %}11 <h2 class="error_found">Error{{ error[1:] }}found</h2>12 {% endif %}13 <form method="POST" action="/register">14 <ol>15 <li><h2>Create a username</h2>16 <p>Your username must start with a letter and be between 3 and 6417 characters long. You may only use letters, numbers, underscores, @,18 and dots.</p>19 <input type="text" name="username" value="{{ username }}" class="entry" tabindex="1" />20 {% if username_missing %}21 <p><span class="error">Error:</span> No username given</p>22 {% endif %}23 {% if username_taken %}24 <p><span class="error">Error:</span> Username already in use</p>25 {% endif %}26 {% if username_invalid %}27 <p><span class="error">Error:</span> Bad username</p>28 {% endif %}29 </li>30 <li><h2>Create a good password</h2>31 <p>Your password must be between 4 and 32 characters long. Your password can not contain your username nor spaces.</p>32 <input type="password" name="password" class="entry" tabindex="2" />33 {% if password_missing %}34 <p><span class="error">Error:</span> No password given</p>35 {% endif %}36 {% if password_invalid %}37 <p><span class="error">Error:</span> Bad password</p>38 {% endif %}39 </li>40 <li><h2>Re-type your password</h2>41 <input type="password" name="retype_password" class="entry" tabindex="3" />42 {% if passwords_dont_match or retype_password_missing %}43 <p><span class="error">Error:</span> Passwords didn't match</p>44 {% endif %}45 </li>46 {% if email or email_missing or email_invaild %}47 <li><h2>Enter your email address</h2>48 <p>Your email address is required for account confirmation and recovery. You will be emailed a confirmation link right after you successfully sign up.</p>49 <input type="text" name="email" value="{{ email_address }}" class="entry" tabindex="4" />50 {% if email_missing %}51 <p><span class="error">Error:</span> No email address given</p>52 {% endif %}53 {% if email_invalid %}54 <p><span class="error">Error:</span> Invalid email address</p>55 {% endif %}56 </li>57 {% endif %}58 {% if challenge %}59 <li><h2>Answer a challenge</h2>60 {{ challenge_html }}61 {% if challenge_missing %}62 <p><span class="error">Error:</span> No challenge response given</p>63 {% endif %}64 {% if challenge_invalid %}65 <p><span class="error">Error:</span> Invalid challenge response</p>66 {% endif %}67 </li>68 {% endif %}69 </ol>70 <button type="submit" tabindex="100" id="create-account-button">Create account</button>71 <a href="/"><button tabindex="101">Cancel</button></a>72 </form>73 </div>74 {% endblock %} -
new file sagenb/data/sage/html/settings/account_settings.html
diff --git a/sagenb/data/sage/html/settings/account_settings.html b/sagenb/data/sage/html/settings/account_settings.html new file mode 100644
- + 1 {% extends "html/settings/base.html" %} 2 3 {% block title %}Account Settings{% endblock %} 4 {% block page_id %}account-settings-page{% endblock %} 5 6 {% block settings_main %} 7 <form method="post" action="/settings"> 8 9 <div class="section"> 10 <h2>Change Auto-Save Interval</h2> 11 <div> 12 Minutes: 13 <select name="autosave"> 14 {% for i, selected in autosave_intervals %} 15 <option{{ selected }}>{{ i }}</option> 16 {% endfor %} 17 </select> 18 </div> 19 </div> 20 <div class="section"> 21 <h2>Change Password</h2> 22 <div id="passwd"> 23 <div> 24 <label for="old-pass">Old password</label> 25 <input type="password" name="old-pass" /> 26 </div> 27 <div> 28 <label for="new-pass">New password</label> 29 <input type="password" name="new-pass" /> 30 </div> 31 <div> 32 <label for="retype-pass">Retype new password</label> 33 <input type="password" name="retype-pass" /> 34 </div> 35 </div> 36 </div> 37 38 {% if true %} 39 <div class="section"> 40 <h2>Change E-mail Address</h2> 41 42 <div> 43 <div> 44 <label>Current e-mail</label> 45 {{ email_address }} {{ email_confirmed }} 46 </div> 47 <div> 48 <label for="new-email">New e-mail</label> 49 <input type="text" name="new-email" class="c1" /> 50 </div> 51 </div> 52 </div> 53 {% endif %} 54 <div id="buttons"> 55 <button type="submit">Save</button> 56 <a href="/"><button>Cancel</button></a> 57 </div> 58 </form> 59 {% endblock %} -
new file sagenb/data/sage/html/settings/admin_add_user.html
diff --git a/sagenb/data/sage/html/settings/admin_add_user.html b/sagenb/data/sage/html/settings/admin_add_user.html new file mode 100644
- + 1 {% extends "html/settings/base.html" %} 2 {% block title %}Add New User{% endblock %} 3 {% block page_id %}add-user-page{% endblock %} 4 5 {% block main %} 6 <h1>Add New User</h1> 7 {% if error %} 8 <h2 class="error_found">Username Error</h2> 9 {% endif %} 10 <form method="POST" action="/adduser"> 11 <ol> 12 <li><h2>Pick a username</h2> 13 <p>The username must start with a letter and be between 4 and 32 characters long. It can only consist of letters, numbers, underscores, and one dot (.).</p> 14 <input type="text" name="username" value="{{ username_input if username_input else '' }}" /> 15 {% if username_error %} 16 {% if username_error == 'invalid' %} 17 <p><span class="error">Error:</span> Invalid username</p> 18 {% else %} 19 <p><span class="error">Error:</span> Username taken</p> 20 {% endif %} 21 {% endif %} 22 </li> 23 </ol> 24 <div id="buttons"> 25 <button type="submit">Create Account</buttoN> 26 <a href="/users"><button>Cancel</button></a> 27 </div> 28 </form> 29 </div> 30 {% endblock %} 31 -
new file sagenb/data/sage/html/settings/base.html
diff --git a/sagenb/data/sage/html/settings/base.html b/sagenb/data/sage/html/settings/base.html new file mode 100644
- + 1 {% extends "html/base_authenticated.html" %} 2 3 {% block body_classes %}settings-page{% endblock %} 4 5 {% block main %} 6 <h1>{{ render_title() }}</h1> 7 {% block settings_nav %} 8 <ul id="settings-nav" class="user-controls"> 9 {% if admin %} 10 <li><a href="/users">Manage Users</a></li> 11 <li><a href="/notebooksettings">Notebook Settings</a></li> 12 {% endif %} 13 <li><a href="/settings">Account Settings</a></li> 14 </ul> 15 {% endblock %} 16 {% block settings_main %} 17 {% endblock %} 18 {% endblock %} -
new file sagenb/data/sage/html/settings/notebook_settings.html
diff --git a/sagenb/data/sage/html/settings/notebook_settings.html b/sagenb/data/sage/html/settings/notebook_settings.html new file mode 100644
- + 1 {% extends "html/settings/base.html" %} 2 {% block title %}Notebook Settings{% endblock %} 3 4 {% block more_css %} 5 <link rel="stylesheet" href="/javascript/jquery/plugins/farbtastic/farbtastic.css" type="text/css" /> 6 {% endblock %} 7 8 {% block javascript %} 9 <script type="text/javascript" src="/javascript/sage/ws_list.js"></script> 10 <script type="text/javascript" src="/javascript/jquery/plugins/farbtastic/farbtastic.min.js"></script> 11 {% endblock %} 12 13 {% block page_id %}notebook-settings-page{% endblock %} 14 15 {% block settings_main %} 16 <form method="get" action="/notebooksettings"> 17 <input type="hidden" name="form" value="on" /> 18 {%- if auto_table %} 19 {{ auto_table }} 20 {%- endif %} 21 <div id="buttons"> 22 <input type="submit" value="Save" /> 23 <input type="button" value="Cancel" style="margin-left:5px" onClick="parent.location='/'" /> 24 </div> 25 </form> 26 {% endblock %} -
new file sagenb/data/sage/html/settings/user_management.html
diff --git a/sagenb/data/sage/html/settings/user_management.html b/sagenb/data/sage/html/settings/user_management.html new file mode 100644
- + 1 {% extends "html/settings/base.html" %} 2 3 {% block title %}Users{% endblock %} 4 {% block page_id %}user-management-page{% endblock %} 5 6 {% block settings_main %} 7 <h1>User Management</h1> 8 <a href="/adduser" class="boldusercontrol">Add User</a> 9 {% if reset %} 10 <p>The password for the user {{ reset[0] }} has been reset to <strong>{{ reset[1] }}</strong></p> 11 {% endif %} 12 <table> 13 <tr><th>Users</th><th>Password</th><th>Suspension</th></tr> 14 {% for user in users %} 15 {% if user != 'admin' %} 16 <tr><td><a href="/home/{{ user }}/">{{ user }}</a></td><td><a href="/users/?reset={{ user }}">Reset</a></td><td><a href="/users/?suspension={{ user }}">{% if user.is_suspended() %}Unsuspend{% else %}Suspend{% endif %}</td></tr> 17 {% endif %} 18 {% endfor %} 19 </table> 20 {% endblock %} -
sagenb/data/sage/html/source_code.html
diff --git a/sagenb/data/sage/html/source_code.html b/sagenb/data/sage/html/source_code.html
a b 1 {% extends "html/base .html" %}1 {% extends "html/base_authenticated.html" %} 2 2 3 3 {% block title %}{{ src_filename }} - Source Code{% endblock %} 4 4 5 5 {% block css %}main{% endblock %} 6 6 7 {% block more_css %}<link type="text/css" ref="stylesheet" href="/javascript/highlight/prettify.css" />{% endblock %} 8 9 {% block page_id %}source-code-page{% endblock %} 10 7 11 {% block body %} 8 {% include "html/top_bar.html" %} 9 <h1 align=center>Sage Source Browser</h1> 10 <h2 align=center><tt>{{ src_filename }} <a href="..">(browse directory)</a></tt></h2> 11 <br><hr><br> 12 <font size=+1><pre id="code">{{ src }}</pre></font> 13 <br><hr><br> 12 <div> 13 <h1>Sage Source Browser</h1> 14 <h2 class="filename" >{{ src_filename }} <a href="..">(browse directory)</a></h2> 15 </div> 16 17 <code id="code">{{ src }}</code> 18 14 19 <script src="/javascript/highlight/prettify.js" type="text/javascript"></script> 15 20 <script type="text/javascript"> 16 function get_element(id) { 17 if(document.getElementById) 18 return document.getElementById(id); 19 if(document.all) 20 return document.all[id]; 21 if(document.layers) 22 return document.layers[id]; 23 } 24 25 var x = get_element("code"); 26 x.innerHTML = prettyPrintOne(x.innerHTML); 21 code = $('code'); 22 code.html(prettyPrintOne(code.html())) 27 23 </script> 28 24 {% endblock %} -
deleted file sagenb/data/sage/html/template_error.html
diff --git a/sagenb/data/sage/html/template_error.html b/sagenb/data/sage/html/template_error.html deleted file mode 100644
+ - 1 {% extends "html/base.html" %}2 3 {% block title %}Error{% endblock %}4 5 {% block body %}6 <span style="color:red;font-weight:bold;">Internal Server Error:</span> The template <em>{{ template }}</em> wasn't found.7 {% endblock %} -
sagenb/data/sage/html/test_report.html
diff --git a/sagenb/data/sage/html/test_report.html b/sagenb/data/sage/html/test_report.html
a b 86 86 <td class="value">{{ sage_version }}</td> 87 87 </tr> 88 88 {% endif %} 89 {%- if environment %} 90 <tr> 91 <td class="label">Environment</td> 92 <td class="value">{{ environment }}</td> 93 </tr> 94 {% endif %} 89 95 <tr> 90 96 <td class="label">Start</td> 91 97 <td class="value">{{ start_time }}</td> -
deleted file sagenb/data/sage/html/top_bar.html
diff --git a/sagenb/data/sage/html/top_bar.html b/sagenb/data/sage/html/top_bar.html deleted file mode 100644
+ - 1 <div id="top-bar">2 {% include "html/banner.html" %}3 <div id="controls">4 <ul>5 <li class="username">{{ username }}</li>6 {% if username == 'guest' %}7 <li><a title="Please log in to the Sage notebook" class="usercontrol" href="/">Log in</a></li>8 {% else %}9 {# TODO: Hack-ish. Remove on template cleanup. #}10 {% if toggle %}11 <li><a title="Toggle the top bar" class="usercontrol" onClick="$('#worksheet-bar').toggle()">Toggle</a></li>12 {% endif %}13 <li><a title="Back to your personal worksheet list" class="usercontrol" href="/home/{{ username }}">Home</a></li>14 {% if pub %}15 <li><span class="usercontrol">Published</span></li>16 {% else %}17 <li><a title="Browse the published worksheets" class="usercontrol" href="/pub">Published</a></li>18 <li><a title="View a log of recent computations" class="usercontrol" href="#" onClick="history_window()">Log</a></li>19 {% endif %}20 <li><a title="Change account settings including password" class="usercontrol" href="/settings">Settings</a></li>21 <li><a title="Documentation" class="usercontrol" href="#" onClick="help()">Help</a></li>22 <li><a title="Report a problem or submit a bug to improve Sage" class="usercontrol" href="#" onClick="bugreport()">Report a Problem</a></li>23 <li><a title="Log out of the Sage notebook" class="usercontrol" href="/logout">Sign out</a></li>24 {% endif %}25 </ul>26 </div>27 </div> -
sagenb/data/sage/html/upload.html
diff --git a/sagenb/data/sage/html/upload.html b/sagenb/data/sage/html/upload.html
a b 1 {% extends "html/base .html" %}1 {% extends "html/base_authenticated.html" %} 2 2 3 3 {% block title %}Upload File{% endblock %} 4 4 5 {% block css %}main{% endblock %}6 7 5 {% block page_id %}upload-worksheet-page{% endblock %} 8 6 9 {% block body%}7 {% block main %} 10 8 11 {% include "html/top_bar.html" %}12 9 <div> 13 10 <h2>Upload worksheet (an sws or txt file) to the Sage Notebook</h2> 14 11 <form method="POST" action="upload_worksheet" 15 12 name="upload" enctype="multipart/form-data"> 16 13 <div> 17 14 <label for="file">Browse your computer to select a worksheet file to upload:</label> 18 <input size="50" type="file" name="file" ></input>15 <input size="50" type="file" name="file" /> 19 16 </div> 20 17 <div> 21 18 <label for="url">Or enter the url of a worksheet file on the web:</label> 22 <input size="50" type="text" name="url" ></input>19 <input size="50" type="text" name="url" /> 23 20 </div> 24 21 <div> 25 22 <label for="name">What do you want to call it? (if different than the original name)</label> 26 <input size="50" type="text" name="name" ></input>23 <input size="50" type="text" name="name" /> 27 24 </div> 28 25 <button type="submit">Upload Worksheet</button> 29 26 </form> -
deleted file sagenb/data/sage/html/user_management.html
diff --git a/sagenb/data/sage/html/user_management.html b/sagenb/data/sage/html/user_management.html deleted file mode 100644
+ - 1 <html>2 <head>3 <title>Users | {{ sitename }}</title>4 <style>5 body {6 font:1em Arial, Sans-serif;7 }8 9 table {10 border-collapse:collapse11 }12 13 th, td {14 border:1px solid #696969;15 padding:5px16 }17 18 th {19 background:#CCC20 }21 22 a:link, a:visited {23 color:blue24 }25 </style>26 </head>27 <body>28 <h1>User Management</h1>29 <a href="/adduser">Add User</a> | <a href="/notebooksettings">Notebook Settings</a> | <a href="/settings">My Settings</a> | <a href="/">My Worksheets</a> | <a href="/logout">Sign Out</a> {% if number_of_users %} <br/><br/>{{ number_of_users }} users {% endif %}<br/><br/>30 {% if reset %}31 <p>The password for the user {{ reset[0] }} has been reset to <strong>{{ reset[1] }}</strong></p>32 {% endif %}33 <table>34 <tr><th>Users</th><th>Password</th><th>Suspension</th></tr>35 {% for user in users %}36 {% if user != 'admin' %}37 <tr><td><a href="/home/{{ user }}/">{{ user }}</a></td><td><a href="/users/?reset={{ user }}">Reset</a></td><td><a href="/users/?suspension={{ user }}">{% if user.is_suspended() %}Unsuspend{% else %}Suspend{% endif %}</td></tr>38 {% endif %}39 {% endfor %}40 </table>41 </body>42 </html> -
deleted file sagenb/data/sage/html/worksheet/menu.html
diff --git a/sagenb/data/sage/html/worksheet/menu.html b/sagenb/data/sage/html/worksheet/menu.html deleted file mode 100644
+ - 1 {#2 INPUT3 - name - string with worksheet name4 - filename_ - string with worksheet filename5 - data - list of data to put in the Data menu6 - systems_enumerated - enumerated list of systems7 - system_names - list of system names8 - current_system_index - the currently selected system_index9 - pretty_print - a boolean stating whether to typeset as default10 - doc_worksheet - a boolean stating whether the worksheet is the doc worksheet11 #}12 <select class="worksheet" onchange="go_option(this);" id="file-menu">13 <option title="Select a file related function" value="" selected>File...</option>14 <option title="Load a new worksheet stored in a file" value="upload_worksheet_button();">Load worksheet from a file...</option>15 <option title="Create a new worksheet" value="new_worksheet();">New worksheet</option>16 <option title="Save this worksheet to an sws file" value="download_worksheet();">Save worksheet to a file...</option>17 <option title="Print this worksheet" value="print_worksheet();">Print</option>18 <option title="Rename this worksheet" value="rename_worksheet();">Rename worksheet</option>19 <option title="Copy this worksheet" value="copy_worksheet();">Copy worksheet</option>20 <option title="Move this worksheet to the trash" value="delete_worksheet('{{ filename_ }}');">Delete worksheet</option>21 </select>22 23 <select class="worksheet" onchange="go_option(this);" id="action-menu">24 <option title="Select a worksheet function" value="" selected>Action...</option>25 <option title="Interrupt currently running calculations, if possible" value="interrupt();">Interrupt</option>26 <option title="Restart the worksheet process" value="restart_sage();">Restart worksheet</option>27 <option title="Quit the worksheet process" value="save_worksheet_and_close();">Save and quit worksheet</option>28 <option value="">---------------------------</option>29 <option title="Evaluate all input cells in the worksheet" value="evaluate_all();">Evaluate All</option>30 <option title="Hide all output" value="hide_all();">Hide All Output</option>31 <option title="Show all output" value="show_all();">Show All Output</option>32 <option title="Delete all output" value="delete_all_output();">Delete All Output</option>33 <option value="">---------------------------</option>34 <option title="Switch to single-cell mode" value="slide_mode();">One Cell Mode</option>35 <option title="Switch to multi-cell mode" value="cell_mode();">Multi Cell Mode</option>36 </select>37 <select class="worksheet" onchange="handle_data_menu(this);" id="data-menu">38 <option title="Select an attached file" value="" selected>Data...</option>39 <option title="Upload or create a data file in a wide range of formats" value="__upload_data_file__">Upload or create file...</option>40 <option value="">--------------------</option>41 {% for name in data %}42 <option value="datafile?name={{ name }}">{{ name }}</option>43 {% endfor %}44 </select>45 46 {% if not doc_worksheet %}47 <select onchange="go_system_select(this, {{ current_system_index }});" class="worksheet" id="systems-menu">48 {% for system_index, system_name in systems_enumerated %}49 <option title="Evaluate all input cells using {{ system_names[system_index] }}"50 {{ "selected" if current_system_index == system_index else "" }} value="{{ system_names[system_index] }}">51 {{ system_name }}52 </option>53 {% endfor %}54 </select>55 <input type="checkbox" title="Enable/disable pretty_printing"56 onchange="pretty_print_check(this.checked);"57 class="worksheet" value="pretty_print" {{ "checked" if pretty_print else "" }} /> Typeset58 {% endif %} -
deleted file sagenb/data/sage/html/worksheet/published_worksheet.html
diff --git a/sagenb/data/sage/html/worksheet/published_worksheet.html b/sagenb/data/sage/html/worksheet/published_worksheet.html deleted file mode 100644
+ - 1 {#2 INPUT:3 - cell_id_list - a list of cell id's4 - cells_html - string of cells HTML5 #}6 {% set published = true %}7 {% set do_print = true %}8 9 {% include "html/worksheet/worksheet_body.html" %}10 11 12 <script language=javascript>jsMath.ProcessBeforeShowing();</script> -
new file sagenb/data/sage/html/worksheet/ratings_info.html
diff --git a/sagenb/data/sage/html/worksheet/ratings_info.html b/sagenb/data/sage/html/worksheet/ratings_info.html new file mode 100644
- + 1 {% extends "html/base.html" %} 2 3 {% block title %}Ratings for {{ worksheet.name() }}{% endblock %} 4 5 {% block body %} 6 <h2 align=center>Ratings for {{ worksheet.name() }}</h2> 7 <h3 align=center><a href='/home/{{ worksheet.filename() }}'>Go to the worksheet.</a> 8 <table width=70%%align=center border=1 cellpadding=10 cellspacing=0> 9 <tr bgcolor="#7799bb"><td width=30em>User</td><td width=10em align=center>Rating</td><td width=10em align=center width=60em>Comment</td></tr> 10 {% for rating in worksheet.ratings()|sort %} 11 <tr> 12 <td>{{ rating[0] }}{# User #}</td> 13 <td>{{ rating[1] }}{# Rating #}</td> 14 <td>{{'' if rating|length < 3 else rating[2]}}{# Comment #}</td> 15 </tr> 16 {% endfor %} 17 </table> 18 {% endblock %} -
deleted file sagenb/data/sage/html/worksheet/save_discard_buttons.html
diff --git a/sagenb/data/sage/html/worksheet/save_discard_buttons.html b/sagenb/data/sage/html/worksheet/save_discard_buttons.html deleted file mode 100644
+ - 1 {#2 INPUT:3 doc_worksheet - boolean stating whether this worksheet is the doc worksheet4 #}5 {% if not doc_worksheet %}6 <button name="button_save" title="Save changes" onClick="save_worksheet();">Save</button><button title="Save changes and close window" onClick="save_worksheet_and_close();" name="button_save">Save & quit</button><button title="Discard changes to this worksheet" onClick="worksheet_discard();">Discard & quit</button>7 {% endif %} -
deleted file sagenb/data/sage/html/worksheet/share_publish_buttons.html
diff --git a/sagenb/data/sage/html/worksheet/share_publish_buttons.html b/sagenb/data/sage/html/worksheet/share_publish_buttons.html deleted file mode 100644
+ - 1 2 {#3 INPUT:4 - worksheet - Worksheet instance5 - select - a boolean6 - backwards - a boolean7 #}8 {% if not worksheet.is_doc_worksheet() %}9 {% macro cls(x) %}10 {{ "control-select" if x == select else "control" }}11 {% endmacro %}12 {% macro backwards_text() %}13 {{ "../" if backwards else "" }}14 {% endmacro %}15 <a title="Print this worksheet" class="print-link" onClick="print_worksheet()"><img border=0 src="/images/icon_print.gif" alt="Print">Print</a>16 <a class="{{ cls('use') }}" title="Interactively use this worksheet" onClick="edit_worksheet();">Worksheet</a>17 <a class="{{ cls('edit') }}" title="Edit text version of this worksheet" href="{{ backwards_text() }}edit">Edit</a>18 <a class="{{ cls('text') }}" title="View plain text version of this worksheet" href="{{ backwards_text() }}text">Text</a>19 <a class="{{ cls('undo') }}" title="View changes to this worksheet over time" href="{{ backwards_text() }}revisions">Undo</a>20 <a class="{{ cls('share') }}" title="Let others edit this worksheet" href="{{ backwards_text() }}share">Share</a>21 <a class="{{ cls('publish') }}" title="Make this worksheet publicly viewable" href="{{ backwards_text() }}publish">Publish</a>22 {% endif %} -
deleted file sagenb/data/sage/html/worksheet/title.html
diff --git a/sagenb/data/sage/html/worksheet/title.html b/sagenb/data/sage/html/worksheet/title.html deleted file mode 100644
+ - 1 {#2 MARKED FOR DELETION.3 - worksheet - Worksheet instance4 - name - escaped name of the worksheet5 - username - string of username6 #}7 <div class="worksheet_title">8 <a id="worksheet_title" class="worksheet_title" onClick="rename_worksheet(); return false;" title="Click to rename this worksheet">{{ name }}</a>9 <br> {{ worksheet.html_time_last_edited() }}10 {% if warn and username != 'guest' and not doc_worksheet%}11 <span class="pingdown">(Someone else is viewing this worksheet)</span>12 {% endif %}13 </div>14 No newline at end of file -
deleted file sagenb/data/sage/html/worksheet/worksheet.html
diff --git a/sagenb/data/sage/html/worksheet/worksheet.html b/sagenb/data/sage/html/worksheet/worksheet.html deleted file mode 100644
+ - 1 {#2 INPUT:3 - do_print - a boolean4 - cell_id_list - a list of cell id's5 - confirm_before_leave - a boolean stating whether to popup a js confirm6 dialog before leaving7 - cells_html - string of cells HTML8 - published - a boolean stating whether the worksheet is published9 - state_number - worksheet.state_number()10 #}11 {% include "html/worksheet/worksheet_body.html" %}12 13 {% if do_print %}14 <script language="javascript">jsMath.ProcessBeforeShowing();</script>15 {% else %}16 <script type="text/javascript">17 $(document).ready(function() {18 cell_id_list={{ cell_id_list }};19 state_number={{ state_number }};20 {% if not published %}if(worksheet_name == "Untitled") rename_worksheet();{% endif %}21 });22 </script>23 {% endif %}24 25 {% if not do_print and confirm_before_leave %}26 <script type="text/javascript">27 $(document).ready(function() {28 window.onbeforeunload = confirmBrowseAway;29 function confirmBrowseAway()30 {31 return "Unsubmitted cells will be lost.";32 }33 });34 </script>35 {% endif %}36 -
deleted file sagenb/data/sage/html/worksheet/worksheet_body.html
diff --git a/sagenb/data/sage/html/worksheet/worksheet_body.html b/sagenb/data/sage/html/worksheet/worksheet_body.html deleted file mode 100644
+ - 1 {#2 INPUT:3 - cells_html - string of cells HTML4 - published - a boolean stating whether the worksheet is published5 #}6 7 <div class="cell_input_active" id="cell_resizer"></div>8 {% if not published %}9 <div class="worksheet_cell_list" id="worksheet_cell_list">10 {% endif %}11 12 {{ cells_html }}13 14 {% if not do_print and not published %}15 </div>16 <div class="insert_new_cell" id="insert_last_cell"></div>17 <script type="text/javascript">18 $("#insert_last_cell").plainclick(function(e) {insert_new_cell_after(cell_id_list[cell_id_list.length-1]);});19 $("#insert_last_cell").shiftclick(function(e) {insert_new_text_cell_after(cell_id_list[cell_id_list.length-1]);});20 </script>21 <div class="worksheet_bottom_padding"></div>22 {% endif %}23 24 -
sagenb/data/sage/html/worksheet_listing.html
diff --git a/sagenb/data/sage/html/worksheet_listing.html b/sagenb/data/sage/html/worksheet_listing.html
a b 1 {% extends "html/base .html" %}1 {% extends "html/base_authenticated.html" %} 2 2 {# 3 3 INPUT: 4 - pub - a boolean stating whether to show in public mode. 5 - typ - a string stating what kind of worksheets this listing shows 4 - pub -- a boolean stating whether to show in public mode. 5 - typ -- a string stating what kind of worksheets this listing shows 6 - worksheets -- list of Worksheet objects 6 7 #} 7 8 {% if pub %} 8 9 {% set worksheet_heading='Published Worksheets' %} … … INPUT: 14 15 {% set worksheet_heading='Archived Worksheets' %} 15 16 {% endif %} 16 17 17 18 18 {% block title %} 19 19 {{ worksheet_heading }} 20 20 {% endblock %} 21 21 22 {% block css %}main{% endblock %}22 {% block page_id %}worksheet-listing-page{% endblock %} 23 23 24 24 {% block javascript %} 25 25 {% if not pub %} … … INPUT: 27 27 <script type="text/javascript" src="/javascript/jqueryui/js/jquery-ui-1.7.2.custom.min.js"></script> 28 28 <script type="text/javascript" src="/javascript/jquery/plugins/form/jquery.form.min.js"></script> 29 29 <script type="text/javascript" src="/javascript/jquery/plugins/jquery.bgiframe.min.js"></script> 30 {% endif %}31 {% if not pub %}32 30 <script type="text/javascript"> 33 var worksheet_filenames = {{ worksheet_filenames }};31 var worksheet_filenames = {{ worksheet_filenames }}; 34 32 </script> 35 33 <script type="text/javascript" src="/javascript/sage/main.js"></script> 36 34 <script type="text/javascript" src="/javascript/gears/gears_init.js"></script> … … INPUT: 40 38 {% endif %} 41 39 {% endblock %} 42 40 43 {% block onload %} onLoad="checkForGearsInstalled();"{% endblock %}44 41 45 {% block body %} 42 {% block main %} 43 <div id="user-main-controls" class="user-controls"> 44 {% if pub is not defined or not pub %} 45 <a href="/new_worksheet" target="_blank">New Worksheet</a> 46 <a href="/upload">Upload</a> 47 {% if not accounts %} 48 <a href="/download_worksheets.zip">Download All Active</a> 49 {% endif %} 50 {% endif %} 46 51 47 {% include "html/list_top.html" %} 48 49 <div id="worksheet-list-controls"> 52 <div id="search-area"> 53 <form action="." method="GET"> 54 <input type="hidden" value="{{ typ if not pub else 'pub' }}" name="typ" /> 55 <input id="search-worksheets" size="20" value="{{ search if search else "" }}" name="search" /> 56 <button class="add_new_worksheet_menu" id="search-worksheets-button" type="submit">Search Worksheets</button> 57 </form> 58 </div> 59 </div> 60 <div id="worksheet-list-controls" class="controls"> 50 61 {% if not pub %} 51 62 <div class="action-buttons"> 52 63 {% if typ == 'archive' %} … … INPUT: 81 92 82 93 <table cellspacing="0" cellpadding="0" id="worksheet-list"> 83 94 <thead> 84 <tr>85 {% if not pub %}86 <td class="checkbox">87 <input id="controlbox" onClick="set_worksheet_list_checks();" class="entry" type="checkbox" />88 </td>89 {% else %}90 <td><a class="listcontrol" href=".?sort=rating">Rating</a></td>91 {% endif %}95 <tr> 96 {% if not pub %} 97 <td class="checkbox"> 98 <input id="controlbox" onClick="set_worksheet_list_checks();" class="entry" type="checkbox" /> 99 </td> 100 {% else %} 101 <td><a class="listcontrol" href=".?sort=rating">Rating</a></td> 102 {% endif %} 92 103 93 <td>94 <a class="listcontrol" href=".?typ={{ typ }}&sort=name{{ '' if sort != 'name' or reverse else '&reverse=True' }}">95 {{ worksheet_heading }}96 </a>97 </td>98 99 <td>100 <a class="listcontrol" href=".?typ={{ typ }}&sort=owner{{ '' if sort != 'owner' or reverse else '&reverse=True' }}">101 Owner {{ '' if pub else ' / Collaborators' }}102 </a>103 </td>104 <td> 105 <a class="listcontrol" href=".?typ={{ typ }}&sort=name{{ '' if sort != 'name' or reverse else '&reverse=True' }}"> 106 {{ worksheet_heading }} 107 </a> 108 </td> 109 110 <td> 111 <a class="listcontrol" href=".?typ={{ typ }}&sort=owner{{ '' if sort != 'owner' or reverse else '&reverse=True' }}"> 112 Owner {{ '' if pub else ' / Collaborators' }} 113 </a> 114 </td> 104 115 105 <td>106 <a class="listcontrol" href=".?typ={{ typ }}&{{ '' if sort != 'last_edited' or reverse else 'reverse=True' }}">107 Last Edited108 </a>109 </td>110 </tr>116 <td> 117 <a class="listcontrol" href=".?typ={{ typ }}{{ '' if sort != 'last_edited' or reverse else 'reverse&=True' }}"> 118 Last Edited 119 </a> 120 </td> 121 </tr> 111 122 </thead> 112 123 <tbody> 113 124 {% if not worksheets %} 114 125 {% if pub %} 115 126 <tr> 116 <td colspan="5" style="padding:20px;text-align:center">127 <td colspan="5"> 117 128 There are no published worksheets. 118 129 </td> 119 130 </tr> 120 131 {% elif typ == 'active' %} 121 132 <tr> 122 <td colspan="5" style="padding:20px;text-align:center">133 <td colspan="5"> 123 134 Welcome to Sage! You can <a href="/new_worksheet">create a new worksheet</a>, 124 135 view <a href="/pub/">published worksheets</a>, or read the 125 136 <a href="/help" target="_new">documentation</a>. … … INPUT: 145 156 {% else %} 146 157 147 158 <input type="checkbox" unchecked id="{{ name|css_escape }}" /> 148 {# I'm removing this select since it is a massive performance killer and these149 serve no real purpose at all. Plus google docs got rid of the analogous menu.150 <select onchange="go_option(this);" class="worksheet_edit">151 <option value="" title="File options" selected>File</option>152 <option value="list_rename_worksheet('{{ name }}','{{ worksheet.name() }}');" title="Change the name of this worksheet.">153 Rename...154 </option>155 <option value="list_edit_worksheet('{{ name }}');" title="Open this worksheet and edit it">Edit</option>156 <option value="list_copy_worksheet('{{ name }}');" title="Copy this worksheet">Copy Worksheet</option>157 <option value="list_share_worksheet('{{ name }}');" title="Share this worksheet with others">Collaborate</option>158 <option value="list_publish_worksheet('{{ name }}');" title="Publish this worksheet on the internet">Publish</option>159 <option value="list_revisions_of_worksheet('{{ name }}');" title="See all revisions of this worksheet">Revisions</option>160 </select>161 #}162 {% endif %}163 </td>159 {# I'm removing this select since it is a massive performance killer and these 160 serve no real purpose at all. Plus google docs got rid of the analogous menu. 161 <select onchange="go_option(this);" class="worksheet_edit"> 162 <option value="" title="File options" selected>File</option> 163 <option value="list_rename_worksheet('{{ name }}','{{ worksheet.name() }}');" title="Change the name of this worksheet."> 164 Rename... 165 </option> 166 <option value="list_edit_worksheet('{{ name }}');" title="Open this worksheet and edit it">Edit</option> 167 <option value="list_copy_worksheet('{{ name }}');" title="Copy this worksheet">Copy Worksheet</option> 168 <option value="list_share_worksheet('{{ name }}');" title="Share this worksheet with others">Collaborate</option> 169 <option value="list_publish_worksheet('{{ name }}');" title="Publish this worksheet on the internet">Publish</option> 170 <option value="list_revisions_of_worksheet('{{ name }}');" title="See all revisions of this worksheet">Revisions</option> 171 </select> 172 #} 173 {% endif %} 174 </td> 164 175 165 <td class="worksheet_link">166 <a title="{{ worksheet.name() | escape }}" id="name-{{ name|css_escape }}" class="worksheetname" href="/home/{{ name }}">167 {% if worksheet.compute_process_has_been_started() %}(running) {% endif %}168 {{ worksheet.truncated_name(50) | escape}}169 </a>170 171 {% if not pub and worksheet.is_published() %}(Published){% endif %}172 </td>173 <td class="owner_collab">176 <td class="worksheet_link"> 177 <a title="{{ worksheet.name() | escape }}" id="name-{{ name|css_escape }}" class="worksheetname" href="/home/{{ name }}"> 178 {% if worksheet.compute_process_has_been_started() %}(running) {% endif %} 179 {{ worksheet.truncated_name(50) | escape}} 180 </a> 181 182 {% if not pub and worksheet.is_published() %}(Published){% endif %} 183 </td> 184 <td class="owner_collab"> 174 185 175 {% if not pub %}176 {{ worksheet.owner() }}177 {% else %}178 {{worksheet.worksheet_that_was_published().owner()}}179 {% endif %}180 181 {% if not pub and typ != 'trash' %}186 {% if not pub %} 187 {{ worksheet.owner() }} 188 {% else %} 189 {{worksheet.worksheet_that_was_published().owner()}} 190 {% endif %} 191 192 {% if not pub and typ != 'trash' %} 182 193 183 {% set shared = False %}194 {% set shared = False %} 184 195 185 {% if worksheet.collaborator_names() %}186 / {{ worksheet.collaborator_names(5) }}187 {% set shared = True %}188 {% endif %}196 {% if worksheet.collaborator_names() %} 197 / {{ worksheet.collaborator_names(5) }} 198 {% set shared = True %} 199 {% endif %} 189 200 190 {% if worksheet.viewer_names() %}191 / {{ worksheet.viewer_names(5) }}192 {% set shared = True %}193 {% endif %}201 {% if worksheet.viewer_names() %} 202 / {{ worksheet.viewer_names(5) }} 203 {% set shared = True %} 204 {% endif %} 194 205 195 {% if (worksheet.owner() != username) or username == 'admin' %}196 {% set shared = False %}197 {% endif %}198 199 {% if shared %}200 <a class="share" href="/home/{{ worksheet.filename() }}/share">Add or Delete</a>201 {% else %}202 <a class="share" href="/home/{{ worksheet.filename() }}/share">Share now</a>203 {% endif %}206 {% if (worksheet.owner() != username) or username == 'admin' %} 207 {% set shared = False %} 208 {% endif %} 209 210 {% if shared %} 211 <a class="share" href="/home/{{ worksheet.filename() }}/share">Add or Delete</a> 212 {% else %} 213 <a class="share" href="/home/{{ worksheet.filename() }}/share">Share now</a> 214 {% endif %} 204 215 205 {% if worksheet.has_published_version() %}206 <a href="/home/{{ worksheet.published_version().filename() }}">207 (published)208 </a>209 {% endif %}210 211 {% endif %}212 </td>213 <td>214 {{ worksheet.html_time_since_last_edited() }}215 </td>216 </tr>217 {% endfor %}218 {% endif %}219 </tbody>220 </table>221 {% endblock %}216 {% if worksheet.has_published_version() %} 217 <a href="/home/{{ worksheet.published_version().filename() }}"> 218 (published) 219 </a> 220 {% endif %} 221 222 {% endif %} 223 </td> 224 <td> 225 {{ worksheet.html_time_since_last_edited() }} 226 </td> 227 </tr> 228 {% endfor %} 229 {% endif %} 230 </tbody> 231 </table> 232 {% endblock %} -
sagenb/data/sage/html/yes_no.html
diff --git a/sagenb/data/sage/html/yes_no.html b/sagenb/data/sage/html/yes_no.html
a b 4 4 5 5 {% block body %} 6 6 <table align=center border=1 cellpadding=20 bgcolor="efefef"> 7 <tr><td>8 {{ message }}9 <br><br>10 <font size=+3><a href="yes">Yes</a> or <a href="no">No</a>?</font>11 </td></tr>7 <tr><td> 8 {{ message }} 9 <br><br> 10 <font size=+3><a href="yes">Yes</a> or <a href="no">No</a>?</font> 11 </td></tr> 12 12 </table> 13 13 {% endblock %} -
new file sagenb/data/sage/js/master.js
diff --git a/sagenb/data/sage/js/master.js b/sagenb/data/sage/js/master.js new file mode 100644
- + 1 $(window).load(function () { 2 body = $('body'), body_id = body.attr('id'); 3 if (body_id === 'worksheet-listing-page') { 4 checkForGearsInstalled(); 5 } 6 7 if (body.hasClass('worksheet-online')) { 8 initialize_the_notebook(); 9 } 10 }); -
sagenb/notebook/cell.py
diff --git a/sagenb/notebook/cell.py b/sagenb/notebook/cell.py
a b TRACEBACK = 'Traceback (most recent call 39 39 # we don't get several of these combined in one. 40 40 re_cell = re.compile('"cell://.*?"') 41 41 re_cell_2 = re.compile("'cell://.*?'") # same, but with single quotes 42 # Matches script blocks 43 re_script = re.compile(r'<script[^>]*?>.*?</script>', re.DOTALL | re.I) 42 44 43 45 JEDITABLE_TINYMCE = True 44 46 … … import errno, hashlib, time 48 50 from sphinx.application import Sphinx 49 51 _SAGE_INTROSPECT = None 50 52 53 51 54 class Cell_generic: 52 55 def is_interactive_cell(self): 53 56 """ … … class Cell_generic: 79 82 """ 80 83 raise NotImplementedError 81 84 82 def html_new_cell_before(self):83 """84 Returns the HTML code for inserting a new cell before self.85 86 EXAMPLES::87 88 sage: C = sagenb.notebook.cell.Cell(0, '2+3', '5', None)89 sage: print C.html_new_cell_before()90 <div class="insert_new_cell" id="insert_new_cell_before0">...91 """92 return """<div class="insert_new_cell" id="insert_new_cell_before%(id)s">93 </div>94 <script type="text/javascript">95 $("#insert_new_cell_before%(id)s").plainclick(function(e) {insert_new_cell_before(%(id)s);});96 $("#insert_new_cell_before%(id)s").shiftclick(function(e) {insert_new_text_cell_before(%(id)s);});97 </script>"""%{'id': self.id()}98 99 def html_new_cell_after(self):100 """101 Returns the HTML code for inserting a new cell after self.102 103 EXAMPLES::104 105 sage: C = sagenb.notebook.cell.Cell(0, '2+3', '5', None)106 sage: print C.html_new_cell_after()107 <div class="insert_new_cell" id="insert_new_cell_after0">...108 """109 return """<div class="insert_new_cell" id="insert_new_cell_after%(id)s">110 </div>111 <script type="text/javascript">112 $("#insert_new_cell_after%(id)s").plainclick(function(e) {insert_new_cell_after(%(id)s);});113 $("#insert_new_cell_after%(id)s").shiftclick(function(e) {insert_new_text_cell_after(%(id)s);});114 </script>"""%{'id': self.id()}115 116 117 85 class TextCell(Cell_generic): 118 86 def __init__(self, id, text, worksheet): 119 87 """ … … class TextCell(Cell_generic): 202 170 """ 203 171 return self.__worksheet 204 172 205 def html(self, ncols=0, do_print=False, do_math_parse=True, editing=False):173 def html(self, wrap=None, div_wrap=True, do_print=False, do_math_parse=True, editing=False): 206 174 """ 207 175 Returns an HTML version of self as a string. 208 176 209 177 INPUT: 210 178 179 - ``wrap`` -- number of columns to wrap at (not used) 180 181 - ``div_wrap`` -- whether to wrap in a div (not used) 182 211 183 - ``do_math_parse`` - bool (default: True) 212 184 If True, call math_parse (defined in cell.py) 213 185 on the html. 214 186 187 - ``do_print`` - bool (default: False) 188 If True, display for printing 189 190 - ``editing`` - bool (default: False) 191 If True, # TODO: figure out what this does 192 215 193 EXAMPLES:: 216 194 217 195 sage: C = sagenb.notebook.cell.TextCell(0, '2+3', None) 218 196 sage: C.html() 219 '...<div class="text_cell" id="cell_text_0">2+3...'197 u'...text_cell...2+3...' 220 198 sage: C.set_input_text("$2+3$") 221 199 sage: C.html(do_math_parse=True) 222 '...<div class="text_cell" id="cell_text_0"><span class="math">2+3</span>...'200 u'...text_cell...class="math"...2+3...' 223 201 """ 224 s = '<span id="cell_outer_%s">'%self.__id 225 226 if not do_print: 227 s += self.html_new_cell_before() 228 229 s += """<div class="text_cell" id="cell_text_%s">%s</div>"""%( 230 self.__id, 231 self.html_inner(ncols=ncols, do_print=do_print, do_math_parse=do_math_parse, editing=editing)) 232 233 if JEDITABLE_TINYMCE and hasattr(self.worksheet(),'is_published') and not self.worksheet().is_published() and not self.worksheet().docbrowser() and not do_print: 234 235 try: 236 z = ((self.__text).decode('utf-8')).encode('ascii', 'xmlcharrefreplace') 237 except Exception, msg: 238 print msg 239 # better to get the worksheet at all than to get a blank screen and nothing. 240 z = self.__text 241 242 s += """<script>$("#cell_text_%s").unbind('dblclick').editable(function(value,settings) { 243 evaluate_text_cell_input(%s,value,settings); 244 return(value); 245 }, { 246 tooltip : "", 247 placeholder : "", 248 // type : 'textarea', 249 type : 'mce', 250 onblur : 'ignore', 251 select : false, 252 submit : 'Save changes', 253 cancel : 'Cancel changes', 254 event : "dblclick", 255 style : "inherit", 256 data : %r 257 }); 258 </script>"""%(self.__id,self.__id, z) 259 260 261 if editing and not do_print: 262 s += """<script>$("#cell_text_%s").trigger('dblclick');</script>"""%self.__id 263 264 s += '</span>' 265 return s 266 267 def html_inner(self,ncols=0, do_print=False, do_math_parse=True, editing=False): 268 """ 269 Returns an HTML version of the content of self as a string. 270 271 INPUT: 272 273 - ``do_math_parse`` - bool (default: True) 274 If True, call math_parse (defined in cell.py) 275 on the html. 276 277 EXAMPLES:: 278 279 sage: C = sagenb.notebook.cell.TextCell(0, '2+3', None) 280 sage: C.html_inner() 281 '2+3...' 282 sage: C.set_input_text("$2+3$") 283 sage: C.html_inner(do_math_parse=True) 284 '<span class="math">2+3</span>...' 285 """ 286 t = self.__text 287 if do_math_parse: 288 # Do dollar sign math parsing 289 try: 290 t = math_parse(t) 291 except Exception, msg: 292 # Since there is no guarantee the user's input/output 293 # is in any way valid, and we don't want to stop the 294 # server process (which is doing this work). 295 pass 296 s = """%s"""%t 297 return s 202 from template import template 203 return template(os.path.join('html', 'notebook', 'text_cell.html'), 204 cell = self, wrap = wrap, do_print = do_print, 205 do_math_parse = do_math_parse, editing = editing, 206 div_wrap=div_wrap) 298 207 299 208 300 209 def plain_text(self, prompts=False): … … class Cell(Cell_generic): 1381 1290 sage: W = nb.create_new_worksheet('Test', 'sage') 1382 1291 sage: C = sagenb.notebook.cell.Cell(0, '2+3', '5', W) 1383 1292 sage: C.process_cell_urls('"cell://foobar"') 1384 '/home/sage/0/cells/0/foobar?0 "'1293 '/home/sage/0/cells/0/foobar?0' 1385 1294 """ 1386 end = '?%d "'%self.version()1295 end = '?%d' % self.version() 1387 1296 begin = self.url_to_self() 1388 1297 for s in re_cell.findall(urls) + re_cell_2.findall(urls): 1389 1298 urls = urls.replace(s,begin + s[7:-1] + end) … … class Cell(Cell_generic): 1493 1402 # Everything not wrapped in <html> ... </html> should be 1494 1403 # escaped and word wrapped. 1495 1404 t = '' 1405 1496 1406 while len(s) > 0: 1497 1407 i = s.find('<html>') 1498 1408 if i == -1: … … class Cell(Cell_generic): 1510 1420 # be evaluated twice. They are only evaluated in the wrapped 1511 1421 # version of the output. 1512 1422 if ncols == 0: 1513 while True: 1514 i = t.lower().find('<script>') 1515 if i == -1: break 1516 j = t[i:].lower().find('</script>') 1517 if j == -1: break 1518 t = t[:i] + t[i+j+len('</script>'):] 1519 1423 t = re_script.sub('', t) 1520 1424 return t 1521 1425 1522 1426 … … class Cell(Cell_generic): 1802 1706 TODO: Remove this hack (:meth:`doc_html`) 1803 1707 """ 1804 1708 self.evaluate() 1805 if wrap is None: 1806 wrap = self.notebook().conf()['word_wrap_cols'] 1807 evaluated = self.evaluated() 1808 if evaluated: 1809 cls = 'cell_evaluated' 1810 else: 1811 cls = 'cell_not_evaluated' 1812 1813 html_in = self.html_in(do_print=do_print) 1814 introspect = "<div id='introspect_div_%s' class='introspection'></div>"%self.id() 1815 #html_out = self.html_out(wrap, do_print=do_print) 1816 html_out = self.html() 1817 s = html_out 1818 if div_wrap: 1819 s = '\n\n<div id="cell_outer_%s" class="cell_visible"><div id="cell_%s" class="%s">'%(self.id(), self.id(), cls) + s + '</div></div>' 1820 return s 1709 return self.html(wrap, div_wrap, do_print) 1821 1710 1822 1711 def html(self, wrap=None, div_wrap=True, do_print=False): 1823 1712 r""" … … class Cell(Cell_generic): 1825 1714 1826 1715 INPUT: 1827 1716 1828 - ``wrap`` - None or an integer stating column position to wrap lines. Defaults to1829 configuration if not given.1717 - ``wrap`` - None or an integer stating column position to 1718 wrap lines. Defaults to configuration if not given. 1830 1719 1831 1720 - ``div_wrap`` - a boolean stating whether to wrap ``div``. 1832 1721 … … class Cell(Cell_generic): 1835 1724 1836 1725 EXAMPLES:: 1837 1726 1838 sage: nb = sagenb.notebook.notebook. Notebook(tmp_dir()+'.sagenb')1727 sage: nb = sagenb.notebook.notebook.load_notebook(tmp_dir()+'.sagenb') 1839 1728 sage: nb.add_user('sage','sage','sage@sagemath.org',force=True) 1840 1729 sage: W = nb.create_new_worksheet('Test', 'sage') 1841 1730 sage: C = sagenb.notebook.cell.Cell(0, '2+3', '5', W) 1842 1731 sage: C.html() 1843 '\n\n<div id="cell_outer_0" cl...</div>'1732 u'...cell_outer_0...2+3...5...' 1844 1733 """ 1845 if do_print: 1846 wrap = 68 1847 div_wrap = 68 1848 key = (wrap,div_wrap,do_print) 1734 from template import template 1849 1735 1850 1736 if wrap is None: 1851 1737 wrap = self.notebook().conf()['word_wrap_cols'] 1852 evaluated = self.evaluated() 1853 if evaluated or do_print: 1854 cls = 'cell_evaluated' 1855 else: 1856 cls = 'cell_not_evaluated' 1857 1858 html_in = self.html_in(do_print=do_print) 1859 introspect = "<div id='introspect_div_%s' class='introspection'></div>"%self.id() 1860 html_out = self.html_out(wrap, do_print=do_print) 1861 1862 if 'hideall' in self.percent_directives(): 1863 s = html_out 1864 else: 1865 s = html_in + introspect + html_out 1866 1867 if div_wrap: 1868 s = '\n\n<div id="cell_outer_%s" class="cell_visible"><div id="cell_%s" class="%s">'%(self.id(), self.id(), cls) + s + '</div></div>' 1869 1870 #self._html_cache[key] = s 1871 return s 1872 1873 def html_in(self, do_print=False, ncols=80): 1874 """ 1875 Returns the HTML code for the input of this cell. 1876 1877 EXAMPLES:: 1878 1879 sage: C = sagenb.notebook.cell.Cell(0, '2+3', '5', None) 1880 sage: print C.html_in() 1881 <div class="insert_new_cell" id="insert_new_cell_before0"...</a> 1882 """ 1883 s = '' 1884 id = self.__id 1885 t = self.__in.rstrip() 1886 1887 cls = "cell_input_hide" if 'hide' in self.percent_directives() else "cell_input" 1888 1889 if not do_print: 1890 s += self.html_new_cell_before() 1891 1892 r = max(1, number_of_rows(t.strip(), ncols)) 1893 1894 if do_print: 1895 if 'hide' in self.percent_directives(): 1896 return '' 1897 1898 tt = escape(t).replace('\n','<br>').replace(' ',' ') + ' ' 1899 s += '<div class="cell_input_print">%s</div>'%tt 1900 else: 1901 s += """ 1902 <textarea class="%s" rows=%s cols=%s 1903 id = 'cell_input_%s' 1904 onKeyPress = 'return input_keypress(%s,event);' 1905 onKeyDown = 'return input_keydown(%s,event);' 1906 onKeyUp = 'return input_keyup(%s, event);' 1907 onBlur = 'cell_blur(%s); return true;' 1908 onFocus = 'cell_focused(this,%s); return true;' 1909 >%s</textarea> 1910 """%(cls, r, ncols, id, id, id, id, id, id, t) 1911 1912 if not do_print: 1913 s+= '<a href="javascript:evaluate_cell(%s,0)" class="eval_button" id="eval_button%s" alt="Click here or press shift-return to evaluate">evaluate</a>'%(id,id) 1914 1915 t = escape(t)+" " 1916 1917 return s 1918 1738 1739 return template(os.path.join('html', 'notebook', 'cell.html'), 1740 cell=self, wrap=wrap, 1741 div_wrap=div_wrap, do_print=do_print) 1919 1742 1920 1743 def url_to_self(self): 1921 1744 """ … … class Cell(Cell_generic): 2087 1910 files = (' '*3).join(files) 2088 1911 return images + files 2089 1912 2090 def html_out(self, ncols=0, do_print=False):2091 r"""2092 Returns the HTML for self's output.2093 2094 INPUT:2095 2096 - ``do_print`` -- a boolean stating whether to output HTML2097 for print2098 2099 - ``ncols`` -- the number of columns2100 2101 EXAMPLES::2102 2103 sage: nb = sagenb.notebook.notebook.Notebook(tmp_dir()+'.sagenb')2104 sage: nb.add_user('sage','sage','sage@sagemath.org',force=True)2105 sage: W = nb.create_new_worksheet('Test', 'sage')2106 sage: C = sagenb.notebook.cell.Cell(0, '2+3', '5', W)2107 sage: C.html_out()2108 '\n...<div class="cell_output_div">\n...</div>'2109 """2110 if do_print and self.cell_output_type() == 'hidden':2111 return '<pre>\n</pre>'2112 2113 out_nowrap = self.output_text(0, html=True)2114 2115 out_html = self.output_html()2116 if self.introspect():2117 out_wrap = out_nowrap2118 else:2119 out_wrap = self.output_text(ncols, html=True)2120 2121 typ = self.cell_output_type()2122 2123 if self.computing():2124 cls = "cell_div_output_running"2125 else:2126 cls = 'cell_div_output_' + typ2127 2128 top = '<div class="%s" id="cell_div_output_%s">'%(2129 cls, self.__id)2130 2131 if do_print:2132 prnt = "print_"2133 else:2134 prnt = ""2135 2136 out_wrap = '<div class="cell_output_%s%s" id="cell_output_%s">%s</div>'%(2137 prnt, typ, self.__id, out_wrap)2138 if not do_print:2139 out_nowrap = '<div class="cell_output_%snowrap_%s" id="cell_output_nowrap_%s">%s</div>'%(2140 prnt, typ, self.__id, out_nowrap)2141 out_html = '<div class="cell_output_html_%s" id="cell_output_html_%s">%s </div>'%(2142 typ, self.__id, out_html)2143 2144 if do_print:2145 out = out_wrap + out_html2146 else:2147 out = out_wrap + out_nowrap + out_html2148 2149 s = top + out + '</div>'2150 2151 r = ''2152 r += ' '*(7-len(r))2153 tbl = """2154 <div class="cell_output_div">2155 <table class="cell_output_box"><tr>2156 <td class="cell_number" id="cell_number_%s" %s>2157 %s2158 </td>2159 <td class="output_cell">%s</td></tr></table></div>"""%(2160 self.__id,2161 '' if do_print else 'onClick="cycle_cell_output_type(%s);"'%self.__id,2162 r, s)2163 2164 return tbl2165 2166 2167 2168 1913 ######## 2169 1914 2170 1915 def format_exception(s0, ncols): -
sagenb/notebook/challenge.py
diff --git a/sagenb/notebook/challenge.py b/sagenb/notebook/challenge.py
a b class reCAPTCHAChallenge(AbstractChallen 443 443 sage: nb = n.Notebook(tmp) 444 444 sage: chal = reCAPTCHAChallenge(nb.conf(), remote_ip = 'localhost') 445 445 sage: chal.html() 446 '<script type="text/javascript">...</script>'446 u'...recaptcha...' 447 447 sage: chal.html('incorrect-captcha-sol') 448 '<script...incorrect-captcha-sol...</script>'448 u'...incorrect-captcha-sol...' 449 449 450 450 """ 451 451 error_param = '' -
sagenb/notebook/js.py
diff --git a/sagenb/notebook/js.py b/sagenb/notebook/js.py
a b which is inserted to the head of the not 14 14 interesting Javascript code is contained under 15 15 ``data/sage/js/notebook_lib.js``. 16 16 """ 17 18 import os19 from sagenb.misc.misc import SAGE_URL20 from compress.JavaScriptCompressor import JavaScriptCompressor21 import keyboards22 23 17 ########################################################################### 24 18 # Copyright (C) 2006 William Stein <wstein@gmail.com> 25 19 # 2006 Tom Boothby <boothby@u.washington.edu> 26 20 # 27 21 # Released under the *modified* BSD license. 28 # Tom wrote in email to me at wstein@gmail.com on March 2, 2008: "You have my permission 29 # to change the license on anything I've contributed to the notebook, to whatever suits you." 22 # Tom wrote in email to me at wstein@gmail.com on March 2, 2008: 23 # "You have my permission to change the license on anything I've 24 # contributed to the notebook, to whatever suits you." 30 25 # 31 26 ########################################################################### 32 27 28 import os 29 import keyboards 30 from template import template 31 from sagenb.misc.misc import SAGE_URL 32 from compress.JavaScriptCompressor import JavaScriptCompressor 33 34 # Debug mode? If sagenb lives under SAGE_ROOT/, we minify and cache 35 # the Notebook JS library. 36 try: 37 from sage.misc.misc import SAGE_ROOT 38 from pkg_resources import Requirement, working_set 39 sagenb_path = working_set.find(Requirement.parse('sagenb')).location 40 debug_mode = not SAGE_ROOT in os.path.realpath(sagenb_path) 41 except AttributeError, ImportError: 42 debug_mode = False 43 33 44 34 45 _cache_javascript = None 35 46 def javascript(): … … def javascript(): 60 71 if _cache_javascript is not None: 61 72 return _cache_javascript 62 73 63 from template import template64 74 s = template(os.path.join('js', 'notebook_lib.js'), 65 75 SAGE_URL=SAGE_URL, 66 76 KEY_CODES=keyhandler.all_tests()) … … def javascript(): 71 81 # Evil" clause in the license. Does that prevent us from 72 82 # distributing it (i.e., it adds an extra condition to the 73 83 # software)? See http://www.crockford.com/javascript/jsmin.py.txt 74 s = JavaScriptCompressor().getPacked(s) 84 global debug_mode 85 if debug_mode: 86 return s 87 88 s = JavaScriptCompressor().getPacked(s.encode('utf-8')) 75 89 _cache_javascript = s 90 76 91 return s 77 92 78 93 79 80 94 class JSKeyHandler: 81 95 """ 82 96 This class is used to make javascript functions to check -
sagenb/notebook/notebook.py
diff --git a/sagenb/notebook/notebook.py b/sagenb/notebook/notebook.py
a b import keyboards # keyboard layouts 43 43 import server_conf # server configuration 44 44 import user_conf # user configuration 45 45 import user # users 46 from template import template 46 from template import template, prettify_time_ago 47 47 48 48 49 49 try: … … class Notebook(object): 1178 1178 1179 1179 1180 1180 ########################################################## 1181 # Importing and exporting worksheets to a plain text format1182 ##########################################################1183 1184 def plain_text_worksheet_html(self, filename, prompts=True):1185 """1186 Return HTML containing the plain text version of a worksheet.1187 1188 INPUT:1189 1190 - ``filename`` - a string; filename of a worksheet1191 1192 - ``prompts`` - a bool (default: True); whether to format the1193 text for inclusion in docstrings1194 1195 OUTPUT:1196 1197 - a string - the worksheet's HTML representation1198 """1199 worksheet = self.get_worksheet_with_filename(filename)1200 text = escape(worksheet.plain_text(prompts = prompts))1201 return template(os.path.join("html", "notebook", "plain_text_worksheet.html"),1202 worksheet_name = worksheet.name(),1203 worksheet_plain_text = text)1204 1205 ##########################################################1206 1181 # Server configuration 1207 1182 ########################################################## 1208 1183 def conf(self): … … class Notebook(object): 1247 1222 ########################################################## 1248 1223 # Worksheet HTML generation 1249 1224 ########################################################## 1250 def worksheet_html(self, filename, do_print=False):1251 r"""1252 Return the HTML for a given worksheet.1253 1254 INPUT:1255 1256 - ``filename`` - a string; the worksheet's filename1257 1258 - ``do_print`` - a bool (default: False); whether this is a1259 printed worksheet1260 1261 OUTPUT:1262 1263 - a string - the worksheet rendered as HTML1264 1265 EXAMPLES::1266 1267 sage: nb = sagenb.notebook.notebook.load_notebook(tmp_dir()+'.sagenb')1268 sage: W = nb.create_new_worksheet('Test', 'admin')1269 sage: nb.worksheet_html(W.filename())1270 '...<!D...Test...cell_id_list=[1]...</body>...</html>'1271 """1272 worksheet = self.get_worksheet_with_filename(filename)1273 return template(os.path.join("html", "notebook", "worksheet.html"),1274 worksheet_name = worksheet.name(),1275 worksheet_html = worksheet.html(include_title=False, do_print=do_print),1276 do_print = do_print)1277 1278 1279 1280 1225 def worksheet_list_for_public(self, username, sort='last_edited', reverse=False, search=None): 1281 1226 W = [x for x in self.__worksheets.itervalues() if x.is_published() and not x.is_trashed(user)] 1282 1227 … … class Notebook(object): 1324 1269 '\n\n{{{id=1|\n\n///\n}}}' 1325 1270 sage: W.save_snapshot('admin') 1326 1271 sage: nb.html_worksheet_revision_list('admin', W) 1327 '...Revision...Last Edited...seconds...ago...'1272 u'...Revision...Last Edited...ago...' 1328 1273 """ 1329 1274 data = worksheet.snapshot_data() # pairs ('how long ago', key) 1330 1275 1331 1276 return template(os.path.join("html", "notebook", "worksheet_revision_list.html"), 1332 1277 data = data, worksheet = worksheet, 1333 1278 worksheet_filename = worksheet.filename(), 1334 username = username, JSMATH = JSMATH, 1335 JEDITABLE_TINYMCE = JEDITABLE_TINYMCE) 1279 username = username) 1336 1280 1337 1281 1338 1282 def html_specific_revision(self, username, ws, rev): … … class Notebook(object): 1352 1296 - a string - the revision rendered as HTML 1353 1297 """ 1354 1298 t = time.time() - float(rev[:-4]) 1355 time_ago = worksheet.convert_seconds_to_meaningful_time_span(t)1299 time_ago = prettify_time_ago(t) 1356 1300 1357 1301 filename = ws.get_snapshot_text_filename(rev) 1358 1302 txt = bz2.decompress(open(filename).read()) 1359 1303 W = self.scratch_worksheet() 1360 1304 W.delete_cells_directory() 1361 1305 W.edit_save(txt) 1362 body_worksheet_html = W.html_worksheet_body(do_print=True, publish=True)1363 1306 1364 1307 data = ws.snapshot_data() # pairs ('how long ago', key) 1365 1308 prev_rev = None … … class Notebook(object): 1373 1316 break 1374 1317 1375 1318 return template(os.path.join("html", "notebook", "specific_revision.html"), 1376 worksheet = ws, worksheet_filename = ws.filename(),1319 worksheet = ws, 1377 1320 username = username, rev = rev, prev_rev = prev_rev, 1378 next_rev = next_rev, time_ago = time_ago, 1379 body_worksheet_html = body_worksheet_html, 1380 JSMATH = JSMATH, JEDITABLE_TINYMCE = JEDITABLE_TINYMCE) 1321 next_rev = next_rev, time_ago = time_ago) 1381 1322 1382 1323 def html_share(self, worksheet, username): 1383 1324 r""" … … class Notebook(object): 1398 1339 sage: nb = sagenb.notebook.notebook.Notebook(tmp_dir()+'.sagenb') 1399 1340 sage: W = nb.create_new_worksheet('Test', 'admin') 1400 1341 sage: nb.html_share(W, 'admin') 1401 '...currently shared...add or remove collaborators...'1342 u'...currently shared...add or remove collaborators...' 1402 1343 """ 1403 1344 U = self.users() 1404 1345 other_users = [x for x, u in U.iteritems() if not u.is_guest() and not u.username() in [username, 'pub', '_sage_']] … … class Notebook(object): 1407 1348 return template(os.path.join("html", "notebook", "worksheet_share.html"), 1408 1349 worksheet = worksheet, 1409 1350 worksheet_filename = worksheet.filename(), 1410 username = username, other_users = other_users, 1411 user_is_admin = self.user(username).is_admin(), 1412 JSMATH = JSMATH, JEDITABLE_TINYMCE = JEDITABLE_TINYMCE) 1413 1351 username = username, other_users = other_users) 1352 1414 1353 def html_download_or_delete_datafile(self, ws, username, filename): 1415 1354 r""" 1416 1355 Return the HTML for the download or delete datafile page. … … class Notebook(object): 1432 1371 sage: nb = sagenb.notebook.notebook.Notebook(tmp_dir()+'.sagenb') 1433 1372 sage: W = nb.create_new_worksheet('Test', 'admin') 1434 1373 sage: nb.html_download_or_delete_datafile(W, 'admin', 'bar') 1435 '...Data file: bar...DATA is a special variable...uploaded...'1374 u'...Data file: bar...DATA is a special variable...uploaded...' 1436 1375 """ 1437 path = "/home/%s/data/%s"%(ws.filename(), filename)1438 1439 worksheets = self.get_worksheets_with_viewer(username)1440 active_worksheets = [worksheet for worksheet in worksheets if worksheet.is_active(username)]1441 sort_worksheet_list(active_worksheets, 'name', False)1442 1443 1376 ext = os.path.splitext(filename)[1].lower() 1444 1377 file_is_image, file_is_text = False, False 1445 1378 text_file_content = "" … … class Notebook(object): 1453 1386 return template(os.path.join("html", "notebook", "download_or_delete_datafile.html"), 1454 1387 worksheet = ws, worksheet_filename = ws.filename(), 1455 1388 username = username, 1456 active_worksheets = active_worksheets, 1457 filename_ = filename, path = path, 1389 filename_ = filename, 1458 1390 file_is_image = file_is_image, 1459 1391 file_is_text = file_is_text, 1460 text_file_content = text_file_content, 1461 JSMATH = JSMATH, JEDITABLE_TINYMCE = JEDITABLE_TINYMCE) 1392 text_file_content = text_file_content) 1462 1393 1463 1394 1464 1395 ########################################################## 1465 1396 # Accessing all worksheets with certain properties. 1466 1397 ########################################################## 1398 def active_worksheets_for(self, username): 1399 return [ws for ws in self.get_worksheets_with_viewer(username) if ws.is_active(username)] 1400 1467 1401 def get_all_worksheets(self): 1468 1402 return [x for x in self.__worksheets.itervalues() if not x.owner() in ['_sage_', 'pub']] 1469 1403 … … class Notebook(object): 1543 1477 ########################################################### 1544 1478 # HTML -- generate most html related to the whole notebook page 1545 1479 ########################################################### 1546 def html_debug_window(self):1547 r"""1548 Return the HTML for the debug window.1549 1550 OUTPUT:1551 1552 - a string - the debug window rendered as HTML1553 1554 EXAMPLES::1555 1556 sage: nb = sagenb.notebook.notebook.Notebook(tmp_dir()+'.sagenb')1557 sage: nb.html_debug_window()1558 "\n<div class='debug_window'>...</div>"1559 """1560 return template(os.path.join("html", "notebook", "debug_window.html"))1561 1562 1563 1480 def html_plain_text_window(self, worksheet, username): 1564 1481 r""" 1565 1482 Return HTML for the window that displays a plain text version … … class Notebook(object): 1580 1497 sage: nb = sagenb.notebook.notebook.Notebook(tmp_dir()+'.sagenb') 1581 1498 sage: W = nb.create_new_worksheet('Test', 'admin') 1582 1499 sage: nb.html_plain_text_window(W, 'admin') 1583 '...pre class="plaintext"...cell_intext...textfield...'1500 u'...pre class="plaintext"...cell_intext...textfield...' 1584 1501 """ 1585 1502 plain_text = worksheet.plain_text(prompts=True, banner=False) 1586 1503 plain_text = escape(plain_text).strip() … … class Notebook(object): 1610 1527 sage: nb = sagenb.notebook.notebook.Notebook(tmp_dir()+'.sagenb') 1611 1528 sage: W = nb.create_new_worksheet('Test', 'admin') 1612 1529 sage: nb.html_edit_window(W, 'admin') 1613 '...textarea class="plaintextedit"...{{{id=1|...//...}}}...'1530 u'...textarea class="plaintextedit"...{{{id=1|...//...}}}...' 1614 1531 """ 1615 text = worksheet.edit_text()1616 text = escape(text)1617 n_lines = text.count("\n")+11618 1532 1619 1533 return template(os.path.join("html", "notebook", "edit_window.html"), 1620 1534 worksheet = worksheet, 1621 1535 worksheet_filename = worksheet.filename(), 1622 username = username, text = text, n_lines = n_lines, 1623 JSMATH = JSMATH, JEDITABLE_TINYMCE = JEDITABLE_TINYMCE) 1536 username = username) 1624 1537 1625 1538 def html_beforepublish_window(self, worksheet, username): 1626 1539 r""" … … class Notebook(object): 1642 1555 sage: nb = sagenb.notebook.notebook.Notebook(tmp_dir()+'.sagenb') 1643 1556 sage: W = nb.create_new_worksheet('Test', 'admin') 1644 1557 sage: nb.html_beforepublish_window(W, 'admin') 1645 '...want to publish this worksheet?...re-publish when changes...'1558 u'...want to publish this worksheet?...re-publish when changes...' 1646 1559 """ 1647 1560 msg = """You can publish your worksheet to the Internet, where anyone will be able to access and view it online. 1648 1561 Your worksheet will be assigned a unique address (URL) that you can send to your friends and colleagues.<br/><br/> … … class Notebook(object): 1708 1621 sage: nb = sagenb.notebook.notebook.Notebook(tmp_dir()+'.sagenb') 1709 1622 sage: W = nb.create_new_worksheet('Test', 'admin') 1710 1623 sage: nb.html_upload_data_window(W, 'admin') 1711 '...Upload or Create Data File...Browse...url...name of a new...'1624 u'...Upload or Create Data File...Browse...url...name of a new...' 1712 1625 """ 1713 1626 return template(os.path.join("html", "notebook", "upload_data_window.html"), 1714 worksheet = ws, worksheet_filename = ws.filename(), 1715 username = username, 1716 JSMATH = JSMATH, JEDITABLE_TINYMCE = JEDITABLE_TINYMCE) 1627 worksheet = ws, username = username) 1717 1628 1718 def html(self, worksheet_filename=None, username='guest', show_debug=False, admin=False): 1629 def html(self, worksheet_filename=None, username='guest', show_debug=False, 1630 admin=False, do_print=False): 1719 1631 r""" 1720 1632 Return the HTML for a worksheet's index page. 1721 1633 … … class Notebook(object): 1738 1650 sage: nb = sagenb.notebook.notebook.Notebook(tmp_dir()+'.sagenb') 1739 1651 sage: W = nb.create_new_worksheet('Test', 'admin') 1740 1652 sage: nb.html(W.filename(), 'admin') 1741 '...Test...cell_input...plainclick...state_number...worksheet_locked=false...'1653 u'...Test...cell_input...plainclick...state_number...' 1742 1654 """ 1743 1655 if worksheet_filename is None or worksheet_filename == '': 1744 1656 worksheet_filename = None … … class Notebook(object): 1749 1661 except KeyError: 1750 1662 W = None 1751 1663 1752 template_page = os.path.join("html", "notebook", " index.html")1664 template_page = os.path.join("html", "notebook", "worksheet_page.html") 1753 1665 if W.docbrowser(): 1754 1666 template_page = os.path.join("html", "notebook", "doc_page.html") 1667 elif do_print: 1668 template_page = os.path.join('html', 'notebook', 'print_worksheet.html') 1669 elif W.is_published() or self.user_is_guest(username): 1670 template_page = os.path.join('html', 'notebook', 'guest_worksheet_page.html') 1755 1671 1756 1672 return template(template_page, worksheet = W, 1757 worksheet_filename = W.filename(), 1758 worksheet_html = W.html(), notebook = self, 1759 username = username, show_debug = show_debug, 1760 JSMATH = JSMATH, JEDITABLE_TINYMCE = JEDITABLE_TINYMCE) 1673 notebook = self, do_print=do_print, 1674 username = username, show_debug = show_debug) 1761 1675 1762 1676 #################################################################### 1763 1677 … … def make_path_relative(dir): 1994 1908 # Misc 1995 1909 ########################################################## 1996 1910 1997 def clean_name(name):1998 return ''.join([x if (x.isalnum() or x == '_') else '_' for x in name])1999 1911 2000 1912 def sort_worksheet_list(v, sort, reverse): 2001 1913 """ -
sagenb/notebook/template.py
diff --git a/sagenb/notebook/template.py b/sagenb/notebook/template.py
a b AUTHORS: 17 17 18 18 import jinja 19 19 20 from jinja.filters import stringfilter 20 from jinja.filters import stringfilter, simplefilter 21 21 22 22 import os, re, sys 23 23 24 24 from sagenb.misc.misc import SAGE_VERSION, DATA 25 from sagenb.notebook.cell import number_of_rows 26 from sagenb.notebook.jsmath import math_parse 25 27 26 28 27 29 TEMPLATE_PATH = os.path.join(DATA, 'sage') … … def css_escape(string): 41 43 42 44 EXAMPLES:: 43 45 44 sage: from sagenb.notebook.template import contained_in,env, css_escape46 sage: from sagenb.notebook.template import env, css_escape 45 47 sage: escaper = css_escape() 46 48 sage: print(escaper(env, {}, '12abcd')) 47 49 12abcd … … def css_escape(string): 71 73 """ 72 74 return css_illegal_re.sub('-', string) 73 75 74 def contained_in(container):76 def prettify_time_ago(t): 75 77 """ 76 Given a container, returns a function which takes an environment, 77 context, and value and returns True if that value is in the 78 container and False otherwise. This is registered and used as a 79 test in the templates. 78 Converts seconds to a meaningful string. 79 80 INPUT 81 82 - t -- time in seconds 83 84 """ 85 if t < 60: 86 s = int(t) 87 if s == 1: 88 return "1 second" 89 return "%d seconds"%s 90 if t < 3600: 91 m = int(t/60) 92 if m == 1: 93 return "1 minute" 94 return "%d minutes"%m 95 if t < 3600*24: 96 h = int(t/3600) 97 if h == 1: 98 return "1 hour" 99 return "%d hours"%h 100 d = int(t/(3600*24)) 101 if d == 1: 102 return "1 day" 103 return "%d days"%d 104 105 def clean_name(name): 106 """ 107 Converts a string to a safe/clean name by converting non-alphanumeric characters to underscores. 80 108 81 109 INPUT: 82 110 83 - ``container`` - a container, e.g., a list or dictionary111 - name -- a string 84 112 85 113 EXAMPLES:: 86 114 87 sage: from sagenb.notebook.template import contained_in 88 sage: f = contained_in([1,2,3]) 89 sage: f(None, None, 2) 90 True 91 sage: f(None, None, 4) 92 False 115 sage: from sagenb.notebook.template import clean_name 116 sage: print clean_name('this!is@bad+string') 117 this_is_bad_string 93 118 """ 94 def wrapped(env, context, value): 95 return value in container 96 return wrapped 97 119 return ''.join([x if x.isalnum() else '_' for x in name]) 98 120 99 121 env.filters['css_escape'] = css_escape 100 env.tests['contained_in'] = contained_in 101 102 #A dictionary containing the default context 103 #The values in this dictionary will be updated 104 #by the 105 default_context = {'sitename': 'Sage Notebook', 106 'sage_version': SAGE_VERSION} 122 env.filters['number_of_rows'] = simplefilter(number_of_rows) 123 env.filters['clean_name'] = stringfilter(clean_name) 124 env.filters['prettify_time_ago'] = simplefilter(prettify_time_ago) 125 env.filters['math_parse'] = stringfilter(math_parse) 126 env.filters['max'] = simplefilter(max) 107 127 108 128 def template(filename, **user_context): 109 129 """ … … def template(filename, **user_context): 126 146 127 147 sage: from sagenb.notebook.template import template 128 148 sage: s = template(os.path.join('html', 'yes_no.html')); type(s) 129 <type ' str'>149 <type 'unicode'> 130 150 sage: 'Yes' in s 131 151 True 132 133 sage: from sagenb.notebook.template import template134 152 sage: u = unicode('Are Gröbner bases awesome?','utf-8') 135 153 sage: s = template(os.path.join('html', 'yes_no.html'), message=u) 136 sage: 'Gr\xc3\xb6bner' in s154 sage: u'Gr\xf6bner' in s 137 155 True 138 156 """ 157 from sagenb.notebook.notebook import JSMATH, JEDITABLE_TINYMCE 158 from twist import notebook 159 #A dictionary containing the default context 160 default_context = {'sitename': 'Sage Notebook', 161 'sage_version': SAGE_VERSION, 162 'JSMATH': JSMATH, 163 'JEDITABLE_TINYMCE': JEDITABLE_TINYMCE, 164 'conf': notebook.conf() if notebook else None} 139 165 try: 140 166 tmpl = env.get_template(filename) 141 167 except jinja.exceptions.TemplateNotFound: … … def template(filename, **user_context): 143 169 context = dict(default_context) 144 170 context.update(user_context) 145 171 r = tmpl.render(**context) 146 return r .encode('utf-8')172 return r -
sagenb/notebook/twist.py
diff --git a/sagenb/notebook/twist.py b/sagenb/notebook/twist.py
a b def message(msg, cont='/'): 135 135 return template(os.path.join('html', 'error_message.html'), 136 136 **template_dict) 137 137 138 class Response(http.Response): 139 """ 140 An adapter for ``twisted.web2.http.Response`` that automatically 141 encodes its stream into UTF-8. 142 143 INPUT: 144 145 - code -- HTTP status code for the response 146 147 - headers -- headers to be sent 148 149 - stream -- content body to send 150 """ 151 def __init__(self, code=None, headers=None, stream=None): 152 if stream is not None: 153 if isinstance(stream, unicode): 154 stream = stream.encode('utf-8', 'ignore') 155 super(Response, self).__init__(code, headers, stream) 156 138 157 def HTMLResponse(*args, **kwds): 139 158 """ 140 159 Returns an HTMLResponse object whose 'Content-Type' header has been set … … def HTMLResponse(*args, **kwds): 148 167 <Headers: Raw: {'content-type': ['text/html; charset=utf-8']} Parsed: {'content-type': <RecalcNeeded>}> 149 168 150 169 """ 151 response = http.Response(*args, **kwds)170 response = Response(*args, **kwds) 152 171 response.headers.addRawHeader('Content-Type', 'text/html; charset=utf-8') 153 172 return response 154 173 … … class SettingsPage(resource.PostableReso 1008 1027 1009 1028 td['admin'] = nu.is_admin() 1010 1029 1011 s = template(os.path.join('html', ' account_settings.html'), **td)1030 s = template(os.path.join('html', 'settings', 'account_settings.html'), **td) 1012 1031 return HTMLResponse(stream = s) 1013 1032 1014 1033 … … class NotebookSettingsPage(resource.Post 1023 1042 1024 1043 template_dict = {} 1025 1044 template_dict['auto_table'] = notebook.conf().html_table(updated) 1026 s = template(os.path.join('html', 'notebook_settings.html'), 1045 template_dict['admin'] = notebook.user(self.username).is_admin() 1046 template_dict['username'] = self.username 1047 s = template(os.path.join('html', 'settings', 'notebook_settings.html'), 1027 1048 **template_dict) 1028 return http.Response(stream = s)1049 return HTMLResponse(stream = s) 1029 1050 1030 1051 1031 1052 ######################################################## … … class Worksheet_cell_list(WorksheetResou 1038 1059 """ 1039 1060 def render(self, ctx): 1040 1061 W = self.worksheet 1041 v = encode_list([W.state_number(), W.html_cell_list()]) 1062 # TODO: Send and actually use the body's HTML. 1063 v = encode_list([W.state_number(), '']) 1064 # v = encode_list([W.state_number(), W.html_cell_list()]) 1042 1065 return HTMLResponse(stream=v) 1043 1066 1044 1067 … … class Worksheet_publish(WorksheetResourc 1324 1347 class Worksheet_rating_info(WorksheetResource, resource.Resource): 1325 1348 def render(self, ctx): 1326 1349 s = self.worksheet.html_ratings_info() 1327 return HTMLResponse(stream=message(''' 1328 <h2 align=center>Ratings for %s</h2> 1329 <h3 align=center><a href='/home/%s'>Go to the worksheet.</a> 1330 <br><br> 1331 <table width=70%%align=center border=1 cellpadding=10 cellspacing=0> 1332 <tr bgcolor="#7799bb"><td width=30em>User</td><td width=10em align=center>Rating</td><td width=10em align=center width=60em>Comment</td></tr> 1333 %s 1334 </table> 1335 <br><br> 1336 '''%(self.worksheet.name(), self.worksheet.filename(), s))) 1337 1350 return HTMLResponse(stream=s) 1338 1351 1339 1352 class Worksheet_rate(WorksheetResource, resource.Resource): 1340 1353 def render(self, ctx): … … class Worksheet_interrupt(WorksheetResou 1439 1452 s = self.worksheet.interrupt() 1440 1453 return HTMLResponse(stream='ok' if s else 'failed') 1441 1454 1442 class Worksheet_plain(WorksheetResource, resource.Resource):1443 def render(self, ctx):1444 s = notebook.plain_text_worksheet_html(self.name)1445 return HTMLResponse(stream=s)1446 1447 1455 class Worksheet_hide_all(WorksheetResource, resource.Resource): 1448 1456 def render(self, ctx): 1449 1457 self.worksheet.hide_all() … … class Worksheet_delete_all_output(Worksh 1466 1474 1467 1475 class Worksheet_print(WorksheetResource, resource.Resource): 1468 1476 def render(self, ctx): 1469 s = notebook. worksheet_html(self.name, do_print=True)1477 s = notebook.html(self.name, do_print=True) 1470 1478 return HTMLResponse(stream=s) 1471 1479 1472 1480 … … class Main_css(resource.Resource): 1804 1812 def render(self, ctx): 1805 1813 s = css.css() 1806 1814 gzip_handler(ctx) 1807 response = http.Response(stream=s)1815 response = Response(stream=s) 1808 1816 response.headers.addRawHeader('Content-Type', 'text/css; charset=utf-8') 1809 1817 return response 1810 1818 1811 class Reset_css(resource.Resource):1812 def render(self, ctx):1813 s = template(os.path.join('css', 'reset.css'))1814 gzip_handler(ctx)1815 return http.Response(stream=s)1816 1817 1819 class CSS(resource.Resource): 1818 1820 addSlash = True 1819 1821 … … class CSS(resource.Resource): 1825 1827 return static.File(os.path.join(css_path, name)) 1826 1828 1827 1829 setattr(CSS, 'child_main.css', Main_css()) 1828 setattr(CSS, 'child_reset.css', Reset_css())1829 1830 1830 1831 ############################ 1831 1832 … … class JSMath_js(resource.Resource): 1842 1843 jsmath_macros = jsmath_macros, 1843 1844 jsmath_image_fonts = jsmath_image_fonts) 1844 1845 1845 return http.Response(stream=s)1846 return Response(stream=s) 1846 1847 1847 1848 class Main_js(resource.Resource): 1848 1849 def render(self, ctx): 1849 1850 gzip_handler(ctx) 1850 1851 s = js.javascript() 1851 return http.Response(stream=s)1852 return Response(stream=s) 1852 1853 1853 1854 class Keyboard_js_specific(resource.Resource): 1854 1855 def __init__(self, browser_os): … … class Keyboard_js_specific(resource.Reso 1856 1857 1857 1858 def render(self, ctx): 1858 1859 gzip_handler(ctx) 1859 return http.Response(stream = self.s)1860 return Response(stream = self.s) 1860 1861 1861 1862 class Keyboard_js(resource.Resource): 1862 1863 def childFactory(self, request, browser_os): … … class RegistrationPage(resource.Postable 2166 2167 # VALIDATE OVERALL. 2167 2168 if empty == required: 2168 2169 # All required fields are empty. Not really an error. 2169 form = template(os.path.join('html', ' registration.html'),2170 form = template(os.path.join('html', 'accounts', 'registration.html'), 2170 2171 **empty_form_dict) 2171 2172 return HTMLResponse(stream = form) 2172 2173 elif validated != required: … … class RegistrationPage(resource.Postable 2174 2175 errors = len(required) - len(validated) 2175 2176 template_dict['error'] = 'E ' if errors == 1 else 'Es ' 2176 2177 2177 form = template(os.path.join('html', ' registration.html'),2178 form = template(os.path.join('html', 'accounts', 'registration.html'), 2178 2179 **template_dict) 2179 2180 return HTMLResponse(stream = form) 2180 2181 … … class RegistrationPage(resource.Postable 2185 2186 template_dict['username_taken'] = True 2186 2187 template_dict['error'] = 'E ' 2187 2188 2188 form = template(os.path.join('html', ' registration.html'),2189 form = template(os.path.join('html', 'accounts', 'registration.html'), 2189 2190 **template_dict) 2190 2191 return HTMLResponse(stream = form) 2191 2192 … … class ForgotPassPage(resource.Resource): 2266 2267 2267 2268 return HTMLResponse(stream=message("A new password has been sent to your e-mail address.", '/')) 2268 2269 else: 2269 s = template(os.path.join('html', 'account _recovery.html'))2270 s = template(os.path.join('html', 'accounts', 'account_recovery.html')) 2270 2271 return HTMLResponse(stream=s) 2271 2272 2272 2273 class ListOfUsers(resource.Resource): … … class ListOfUsers(resource.Resource): 2303 2304 users = sorted(notebook.valid_login_names()) 2304 2305 del users[users.index('admin')] 2305 2306 template_dict['users'] = [notebook.user(i) for i in users] 2306 return HTMLResponse(stream = template(os.path.join('html', 'user_management.html'), **template_dict)) 2307 template_dict['admin'] = notebook.user(self.username).is_admin() 2308 template_dict['username'] = self.username 2309 return HTMLResponse(stream = template(os.path.join('html', 'settings', 'user_management.html'), **template_dict)) 2307 2310 2308 2311 class AdminAddUser(resource.PostableResource): 2309 def __init__(self, user db):2310 self.user db = userdb2312 def __init__(self, username): 2313 self.username = username 2311 2314 2312 2315 def render(self, request): 2313 2316 template_dict = {'admin': notebook.user(self.username).is_admin(), 2317 'username': self.username} 2314 2318 if 'username' in request.args: 2315 2319 username = request.args['username'][0] 2316 2320 if not is_valid_username(username): 2317 return HTMLResponse(stream=template(os.path.join('html', 'admin_add_user.html'), error='username_invalid', username=username)) 2321 return HTMLResponse(stream=template(os.path.join('html', 'settings', 'admin_add_user.html'), 2322 error='username_invalid', username=username, **template_dict)) 2318 2323 2319 2324 from random import choice 2320 2325 import string 2321 2326 chara = string.letters + string.digits 2322 2327 password = ''.join([choice(chara) for i in range(8)]) 2323 2328 if username in notebook.usernames(): 2324 return HTMLResponse(stream=template(os.path.join('html', 'admin_add_user.html'), error='username_taken', username=username)) 2329 return HTMLResponse(stream=template(os.path.join('html', 'settings', 'admin_add_user.html'), 2330 error='username_taken', username_input=username, **template_dict)) 2325 2331 notebook.add_user(username, password, '', force=True) 2326 return HTMLResponse(stream=message('The temporary password for the new user <em>%s</em> is <em>%s</em>' % (username, password), '/adduser')) 2332 return HTMLResponse(stream=message('The temporary password for the new user <em>%s</em> is <em>%s</em>' % 2333 (username, password), '/adduser')) 2327 2334 else: 2328 return HTMLResponse(stream=template(os.path.join('html', 'admin_add_user.html'))) 2335 2336 return HTMLResponse(stream=template(os.path.join('html', 'settings', 'admin_add_user.html'), **template_dict)) 2329 2337 2330 2338 class InvalidPage(resource.Resource): 2331 2339 addSlash = True … … class UserToplevel(Toplevel): 2481 2489 # better call userchildFactory it in the base class (Toplevel)! 2482 2490 def userchildFactory(self, request, name): 2483 2491 try: 2484 return UserToplevel.__dict__['userchild_%s'%name](username = self.username)2485 except KeyError:2492 return getattr(self.__class__, 'userchild_%s' % name )(username = self.username) 2493 except AttributeError: 2486 2494 pass 2487 2495 2488 2496 userchild_doc = Doc … … setattr(UserToplevel, 'userchild_downloa 2524 2532 2525 2533 class AdminToplevel(UserToplevel): 2526 2534 addSlash = True 2527 2535 2528 2536 userchild_home = WorksheetsAdmin 2529 child_users = ListOfUsers2530 child_adduser = AdminAddUser2531 child_notebooksettings = NotebookSettingsPage2537 userchild_users = ListOfUsers 2538 userchild_adduser = AdminAddUser 2539 userchild_notebooksettings = NotebookSettingsPage 2532 2540 2533 2541 def user_type(username): 2534 2542 # one of admin, guest, user -
sagenb/notebook/worksheet.py
diff --git a/sagenb/notebook/worksheet.py b/sagenb/notebook/worksheet.py
a b import sagenb.misc.support as support 44 44 45 45 # Imports specifically relevant to the sage notebook 46 46 from cell import Cell, TextCell 47 from template import template 47 from template import template, clean_name, prettify_time_ago 48 48 49 49 # Set some constants that will be used for regular expressions below. 50 50 whitespace = re.compile('\s') # Match any whitespace character … … def worksheet_filename(name, owner): 111 111 sage: sagenb.notebook.worksheet.worksheet_filename('Example#%&! work\\sheet 3', 'sage10') 112 112 'sage10/Example_____work_sheet_3' 113 113 """ 114 return os.path.join(owner, _notebook.clean_name(name))114 return os.path.join(owner, clean_name(name)) 115 115 116 116 def Worksheet_from_basic(obj, notebook_worksheet_directory): 117 117 """ … … class Worksheet(object): 1185 1185 del self.__published_version 1186 1186 raise ValueError 1187 1187 except AttributeError: 1188 raise ValueError , "no published version"1188 raise ValueError("no published version") 1189 1189 1190 1190 def set_worksheet_that_was_published(self, W): 1191 1191 """ … … class Worksheet(object): 1245 1245 [('hilbert', 3, 'this is great'), ('riemann', 0, 'this lacks content')] 1246 1246 """ 1247 1247 r = self.ratings() 1248 x = int(x) 1248 1249 for i in range(len(r)): 1249 1250 if r[i][0] == username: 1250 1251 r[i] = (username, x, comment) … … class Worksheet(object): 1320 1321 sage: W.rate(0, 'this lacks content', 'riemann') 1321 1322 sage: W.rate(3, 'this is great', 'hilbert') 1322 1323 sage: W.html_ratings_info() 1323 '<tr><td>hilbert</td><td align=center>3</td><td>this is great</td></tr>\n<tr><td>riemann</td><td align=center>0</td><td>this lacks content</td></tr>'1324 u'...hilbert...3...this is great...this lacks content...' 1324 1325 """ 1325 ratings = self.ratings() 1326 lines = [] 1327 for z in sorted(ratings): 1328 if len(z) == 2: 1329 person, rating = z 1330 comment = '' 1331 else: 1332 person, rating, comment = z 1333 lines.append('<tr><td>%s</td><td align=center>%s</td><td>%s</td></tr>'%( 1334 person, rating, ' ' if not comment else comment)) 1335 return '\n'.join(lines) 1326 return template(os.path.join('html', 'worksheet', 'ratings_info.html'), 1327 worksheet = self) 1336 1328 1337 1329 def rating(self): 1338 1330 """ … … class Worksheet(object): 1973 1965 filenames = os.listdir(self.snapshot_directory()) 1974 1966 filenames.sort() 1975 1967 t = time.time() 1976 v = [( convert_seconds_to_meaningful_time_span(t - float(os.path.splitext(x)[0]))+ self._saved_by_info(x), x) \1968 v = [(prettify_time_ago(t - float(os.path.splitext(x)[0]))+ self._saved_by_info(x), x) \ 1977 1969 for x in filenames] 1978 1970 self.__snapshot_data = v 1979 1971 return v … … class Worksheet(object): 2269 2261 print msg 2270 2262 return cells_html 2271 2263 2272 def html(self, include_title=True, do_print=False, 2273 confirm_before_leave=False, read_only=False): 2264 def html(self, do_print=False, publish=False): 2274 2265 r""" 2275 2266 INPUT: 2276 2267 … … class Worksheet(object): 2287 2278 sage: nb = sagenb.notebook.notebook.Notebook(tmp_dir()+'.sagenb') 2288 2279 sage: W = nb.create_new_worksheet('Test', 'admin') 2289 2280 sage: W.html() 2290 '\n\n\n<div class="cell_input_active" id="cell_resizer"></div>\n\n<div class="worksheet_cell_list" id...'2281 u'...cell_input_active...worksheet_cell_list...cell_1...cell_output_html_1...' 2291 2282 """ 2292 return template(os.path.join("html", "worksheet", "worksheet.html"), 2293 published = self.is_published(), 2294 do_print = do_print, confirm_before_leave = confirm_before_leave, 2295 cells_html = self.html_cell_list(do_print=do_print), 2296 cell_id_list = self.cell_id_list(), 2297 state_number = self.state_number()) 2283 return template(os.path.join("html", "notebook", "worksheet.html"), 2284 do_print=do_print, publish=publish, worksheet=self) 2298 2285 2299 2286 def truncated_name(self, max=30): 2300 2287 name = self.name() … … class Worksheet(object): 2311 2298 def set_is_doc_worksheet(self, value): 2312 2299 self.__is_doc_worksheet = value 2313 2300 2314 def html_save_discard_buttons(self):2315 r"""2316 OUTPUT:2317 2318 - string -- the HTML for the save, discard, etc. buttons2319 2320 EXAMPLES::2321 2322 sage: nb = sagenb.notebook.notebook.Notebook(tmp_dir()+'.sagenb')2323 sage: W = nb.create_new_worksheet('Test', 'admin')2324 sage: W.html_save_discard_buttons()2325 '\n\n<button name="button_save" title="Save changes" onClick="save_worksheet();">Save<...'2326 """2327 return template(os.path.join("html", "worksheet", "save_discard_buttons.html"),2328 doc_worksheet = self.is_doc_worksheet())2329 2330 def html_share_publish_buttons(self, select=None, backwards=False):2331 r"""2332 INPUT:2333 2334 - select - a boolean2335 2336 - backwards - a boolean2337 2338 OUTPUT:2339 2340 - string -- the HTML for the share, publish, etc. buttons2341 2342 EXAMPLES::2343 2344 sage: nb = sagenb.notebook.notebook.Notebook(tmp_dir()+'.sagenb')2345 sage: W = nb.create_new_worksheet('Test', 'admin')2346 sage: W.html_share_publish_buttons()2347 '...Print...Worksheet...Edit...Undo...Share...Publish...'2348 """2349 return template(os.path.join("html", "worksheet", "share_publish_buttons.html"),2350 worksheet = self, select = select, backwards = backwards)2351 2352 def html_menu(self):2353 r"""2354 OUTPUT:2355 2356 - string -- the HTML for the menus of the worksheet2357 2358 EXAMPLES::2359 2360 sage: nb = sagenb.notebook.notebook.Notebook(tmp_dir()+'.sagenb')2361 sage: W = nb.create_new_worksheet('Test', 'admin')2362 sage: W.html_menu()2363 '...File...Action...Data...pretty_print...'2364 """2365 return template(os.path.join("html", "worksheet", "menu.html"),2366 name = _notebook.clean_name(self.name()),2367 filename_ = self.filename(), data = sorted(self.attached_data_files()),2368 systems_enumerated = enumerate(self.notebook().systems()),2369 system_names = self.notebook().system_names(),2370 current_system_index = self.system_index(),2371 pretty_print = self.pretty_print(),2372 doc_worksheet = self.is_doc_worksheet())2373 2374 def html_worksheet_body(self, do_print, publish=False):2375 r"""2376 INPUT:2377 2378 - publish - a boolean stating whether the worksheet is published2379 2380 - do_print - a boolean2381 2382 OUTPUT:2383 2384 - string -- the HTML for the File menu of the worksheet2385 2386 EXAMPLES::2387 2388 sage: nb = sagenb.notebook.notebook.Notebook(tmp_dir()+'.sagenb')2389 sage: W = nb.create_new_worksheet('Test', 'admin')2390 sage: W.html_worksheet_body(false)2391 '\n\n<div class="cell_input_active" id="cell_resizer"></div>\n\n<div class="worksheet_cell_list" id...'2392 """2393 published = self.is_published() or publish2394 ncols = self.notebook().conf()['word_wrap_cols']2395 cells_html = ""2396 for cell in self.cell_list():2397 cells_html += cell.html(ncols, do_print=do_print) + '\n'2398 2399 return template(os.path.join("html", "worksheet", "worksheet_body.html"),2400 cells_html = cells_html,2401 published = published,2402 do_print = do_print)2403 2404 2301 2405 2302 ########################################################## 2406 2303 # Last edited … … class Worksheet(object): 2446 2343 sage: W.last_to_edit() 2447 2344 'john' 2448 2345 sage: W.date_edited() 2449 time.struct_time(tm_year=2009, tm_mon=10, tm_mday= 8, tm_hour=12, tm_min=23, tm_sec=20, tm_wday=3, tm_yday=281, tm_isdst=1)2346 time.struct_time(tm_year=2009, tm_mon=10, tm_mday=..., tm_hour=..., tm_min=23, tm_sec=20, tm_wday=..., tm_yday=..., tm_isdst=...) 2450 2347 sage: t = W.time_since_last_edited() # just test that call works 2451 2348 """ 2452 2349 username = str(username); tm = float(tm) … … class Worksheet(object): 2515 2412 2516 2413 def html_time_since_last_edited(self): 2517 2414 t = self.time_since_last_edited() 2518 tm = convert_seconds_to_meaningful_time_span(t)2415 tm = prettify_time_ago(t) 2519 2416 return template(os.path.join("html", "worksheet", "time_since_last_edited.html"), 2520 2417 last_editor = self.last_to_edit(), 2521 2418 time = tm) … … from sagenb.notebook.all import * 3746 3643 3747 3644 EXAMPLES: First, we set up a new notebook and worksheet.:: 3748 3645 3749 sage: nb = sagenb.notebook.notebook. Notebook(tmp_dir()+'.sagenb')3646 sage: nb = sagenb.notebook.notebook.load_notebook(tmp_dir()+'.sagenb') 3750 3647 sage: nb.add_user('sage','sage','sage@sagemath.org',force=True) 3751 3648 sage: W = nb.create_new_worksheet('Test', 'sage') 3752 3649 … … def next_available_id(v): 4119 4016 return i 4120 4017 4121 4018 4122 def convert_seconds_to_meaningful_time_span(t):4123 if t < 60:4124 s = int(t)4125 if s == 1:4126 return "1 second"4127 return "%d seconds"%s4128 if t < 3600:4129 m = int(t/60)4130 if m == 1:4131 return "1 minute"4132 return "%d minutes"%m4133 if t < 3600*24:4134 h = int(t/3600)4135 if h == 1:4136 return "1 hour"4137 return "%d hours"%h4138 d = int(t/(3600*24))4139 if d == 1:4140 return "1 day"4141 return "%d days"%d4142 4143 4144 4019 def convert_time_to_string(t): 4145 4020 return time.strftime('%B %d, %Y %I:%M %p', time.localtime(float(t))) 4146 4021 -
sagenb/testing/HTMLTestRunner.py
diff --git a/sagenb/testing/HTMLTestRunner.py b/sagenb/testing/HTMLTestRunner.py
a b class HTMLTestRunner(object): 347 347 results. 348 348 """ 349 349 def __init__(self, stream=sys.stdout, verbosity=1, title=None, 350 description=None ):350 description=None, **extra_args): 351 351 """ 352 352 Initialize variables. 353 353 """ … … class HTMLTestRunner(object): 355 355 self.verbosity = verbosity 356 356 self.title = title 357 357 self.description = description 358 self.extra_args = extra_args 358 359 359 360 # Set up Pygments syntax highlighting. 360 361 self.formatter = get_formatter_by_name('html', noclasses=True, … … class HTMLTestRunner(object): 407 408 template_dict['title'] = jinja2.escape(self.title) 408 409 template_dict['description'] = jinja2.escape(self.description) 409 410 template_dict['sagenb_version'] = SAGENB_VERSION 411 template_dict['environment'] = self.extra_args.get('environment') 410 412 template_dict['start_time'] = str(self.start_time)[:19] 411 413 template_dict['stop_time'] = str(self.stop_time)[:19] 412 414 template_dict['elapsed_time'] = self.elapsed_time -
sagenb/testing/notebook_test_case.py
diff --git a/sagenb/testing/notebook_test_case.py b/sagenb/testing/notebook_test_case.py
a b Notebook Test Case 5 5 This contains the base class for all SageNB test cases. 6 6 """ 7 7 8 from selenium.selenium import selenium 8 import copy 9 import os 10 import pexpect 11 import re 12 import shutil 13 import signal 14 import subprocess 15 import tempfile 16 import time 9 17 import unittest 10 18 11 import os, subprocess, pexpect, shutil, time, re, tempfile, signal 19 from selenium.selenium import selenium 20 21 # Default options. 22 NB_OPTIONS = { 23 'address': 'localhost', # Should *not* be left empty. 24 'directory': '', # Set automatically if empty. Must end 25 # in '.sagenb'. 26 'open_viewer': False, 27 'port': 8000, 28 'secure': False 29 } 30 SEL_OPTIONS = { 31 'server_host': 'localhost', 32 'server_port': 4444, 33 'environment': '*firefox3 /usr/bin/firefox', 34 'browser_url': '' # Set automatically if empty. 35 } 36 37 # This is for Google Chrome, which caches '/new_worksheet', for some 38 # reason. 39 CACHE_SKIP = 0 40 41 KEY_CODES = { 42 'tab': 9, 43 'enter': 10, 44 'shift': 16 45 } 46 12 47 13 48 class NotebookTestCase(unittest.TestCase): 14 49 """ 15 50 Base class for SageNB test cases. Contains multiple utility 16 51 functions, and sets up fixtures. 17 52 """ 18 tags = ('seleniumtest',) 53 tags = ('seleniumtest',) 54 55 def cleanup(self): 56 nb_dir = self.nb_options['directory'] 57 58 if os.path.exists(nb_dir): 59 twistd_pid_path = os.path.join(nb_dir, 'twistd.pid') 60 if os.path.exists(twistd_pid_path): 61 twistd_pid_fd = open(twistd_pid_path, 'r') 62 twistd_pid = int(twistd_pid_fd.read()) 63 try: 64 os.kill(twistd_pid, signal.SIGTERM) 65 os.kill(twistd_pid, signal.SIGKILL) 66 except OSError: 67 pass 68 twistd_pid_fd.close() 69 shutil.rmtree(nb_dir, ignore_errors=True) 70 19 71 def setUp(self): 20 72 """ 21 73 Makes sure that the tests start from a fresh slate, and starts 22 74 the server. 23 75 """ 24 self.temp_dir = os.path.join(tempfile.gettempdir(), 'sagenb_tests') 25 if os.path.exists(self.temp_dir + '.sagenb'): 26 twistd_pid_path = os.path.join(self.temp_dir + '.sagenb', 'twistd.pid') 27 if os.path.exists(twistd_pid_path): 28 twistd_pid = int(open(twistd_pid_path, 'r').read()) 29 try: 30 os.kill(twistd_pid, signal.SIGTERM) 31 os.kill(twistd_pid, signal.SIGKILL) 32 except OSError: 33 pass 34 shutil.rmtree(self.temp_dir + '.sagenb') 35 os.mkdir(self.temp_dir + '.sagenb') 36 self.verification_errors = [] 76 self.nb_options = copy.deepcopy(NB_OPTIONS) 77 self.nb_options['directory'] = (self.nb_options['directory'] or 78 os.path.join(tempfile.gettempdir(), 79 'sagenb_tests.sagenb')) 80 self.sel_options = copy.deepcopy(SEL_OPTIONS) 81 82 self.cleanup() 83 os.mkdir(self.nb_options['directory']) 37 84 self.start_notebook(initial=True) 38 self.selenium = selenium("localhost", 4444, "*firefox3 /usr/bin/firefox", "http://localhost:%d" % self.sagenb_port) 85 86 self.selenium = selenium(self.sel_options['server_host'], 87 self.sel_options['server_port'], 88 self.sel_options['environment'], 89 self.sel_options['browser_url']) 39 90 self.selenium.start() 40 91 self.selenium.open("/") 41 92 42 93 def start_notebook(self, initial=False): 43 94 """ 44 Starts the Sage notebook. If initial is True, then it expects to have to enter45 t he initial password twice.95 Starts the Sage notebook. If initial is True, then it expects 96 to have to enter the initial password twice. 46 97 """ 47 98 self._p = pexpect.spawn(self._sage_startup_command()) 48 99 if initial: 49 100 self._p.sendline("asdfasdf") 50 101 self._p.sendline("asdfasdf") 51 102 52 port_re = re.compile(r'http://localhost:(\d+)') 103 port_re = re.compile(r'http(?:s)?://' + self.nb_options['address'] + 104 r':(\d+)') 53 105 54 106 line = self._p.readline() 55 107 while not port_re.search(line): 56 108 line = self._p.readline() 57 58 self.sagenb_port = int(port_re.search(line).group(1)) 109 110 m = port_re.search(line) 111 self.sel_options['browser_url'] = (self.sel_options['browser_url'] or 112 m.group(0)) 113 self.sagenb_port = int(m.group(1)) 114 59 115 self._p.expect("Starting factory") 60 116 61 117 def _sage_startup_command(self): 62 118 """ 63 119 Command to send to pexpect to start the notebook. 64 120 """ 65 return 'sage -c "notebook(open_viewer=False, directory=\'%s\', port=8000)"'\ 66 % self.temp_dir 121 return 'sage -c "notebook(**%r)"' % self.nb_options 67 122 68 123 def focus_cell(self, id): 69 124 """ … … class NotebookTestCase(unittest.TestCase 71 126 """ 72 127 sel = self.selenium 73 128 sel.focus("cell_input_%s" % id) 74 129 75 130 def eval_cell(self, id, text, timeout=20000, output=True): 76 131 """ 77 132 Evaluates the cell id with input text text. … … class NotebookTestCase(unittest.TestCase 81 136 sel = self.selenium 82 137 id = str(id) 83 138 sel.type("cell_input_"+id, text) 84 self. shift_enter("cell_input_"+id)139 self.evaluate(id) 85 140 self.wait_for_no_active_cells() 86 141 if output: 87 142 return self.get_cell_output(id) 88 143 144 def evaluate(self, id): 145 """ 146 Triggers evaluation of a given cell. 147 """ 148 # self.shift_enter("cell_input_"+id) 149 self.selenium.get_eval('window.evaluate_cell(%s, 0);' % id) 150 89 151 def _get_cell_output_type(self, id, type='nowrap'): 90 152 out = '' 91 153 try: 92 out = self.selenium.get_eval("window.document.getElementById('cell_output_%s_%s').innerHTML" %(type, id)).strip()154 out = self.selenium.get_eval("window.document.getElementById('cell_output_%s_%s').innerHTML" % (type, id)).strip() 93 155 except: 94 156 pass 95 157 return out … … class NotebookTestCase(unittest.TestCase 102 164 out = self._get_cell_output_type(id, 'nowrap') 103 165 if out == '': 104 166 out = self._get_cell_output_type(id, 'html') 105 167 168 # Browser contortions. TODO: Simplify this with regular 169 # expressions. 106 170 preshrunk = '<pre class="shrunk">' 107 if out.startswith(preshrunk): 171 PREshrunk = '<PRE class="shrunk">' 172 PREshrunk2 = '<PRE class=shrunk>' 173 174 if out.startswith(preshrunk) or out.startswith(PREshrunk): 108 175 out = out[len(preshrunk):-6] 176 if out.startswith(PREshrunk2): 177 out = out[len(PREshrunk2):-6] 178 109 179 out = out.strip() 110 180 return out 111 181 112 182 def wait_for_no_active_cells(self, timeout=20000): 113 183 """ 114 Tells Selenium to wait until they're are no active cells on the worksheet. 184 Tells Selenium to wait until they're are no active cells on 185 the worksheet. 115 186 """ 116 187 self.selenium.wait_for_condition("selenium.browserbot.getCurrentWindow().active_cell_list.length == 0", "%s"%timeout) 117 188 … … class NotebookTestCase(unittest.TestCase 119 190 """ 120 191 Presses enter in the element ``locator``. 121 192 """ 193 # self.selenium.focus(locator) 122 194 self.selenium.key_press(locator, '13') 123 195 # self.selenium.key_press_native(KEY_CODES['enter']) 196 124 197 def shift_enter(self, locator): 125 198 """ 126 199 Presses shift-enter in the element ``locator``. For example, 127 200 self.shift_enter('cell_input_0') 128 201 """ 129 202 sel = self.selenium 203 # self.selenium.focus(locator) 130 204 sel.shift_key_down() 205 # sel.key_down_native(KEY_CODES['shift']) 131 206 self.enter(locator) 132 207 sel.shift_key_up() 208 # sel.key_up_native(KEY_CODES['shift']) 133 209 134 210 def tab(self, locator): 135 211 """ 136 212 Presses tab in the element ``locator``. 137 213 """ 138 214 self.selenium.focus(locator) 139 self.selenium.key_press_native(9) 140 215 self.selenium.key_press_native(KEY_CODES['tab']) 216 217 def introspect(self, id): 218 """ 219 Evaluates introspection in the given cell. 220 """ 221 # self.tab('cell_input_%s' % id) 222 self.selenium.get_eval('window.set_cursor_position(window.get_cell(%s), 100);' % id) 223 self.selenium.get_eval('window.evaluate_cell_introspection(%s, null, null);' % id) 224 141 225 def save_and_quit(self): 142 226 """ 143 227 Save and close the current worksheet and wait until we … … class NotebookTestCase(unittest.TestCase 145 229 """ 146 230 sel = self.selenium 147 231 sel.click("//button[@name='button_save' and @onclick='save_worksheet_and_close();']") 148 self.wait_for_title('Active Worksheets')149 232 sel.wait_for_page_to_load("30000") 233 self.wait_for_title('Active Worksheets -- Sage') 150 234 151 235 def wait_for_title(self, title): 152 236 """ 153 Tells Selenium to wait until the title of the page has changed to154 t itle since it doesn't recognize many of the page reloads in the Sage155 notebook.237 Tells Selenium to wait until the title of the page has changed 238 to title since it doesn't recognize many of the page reloads 239 in the Sage notebook. 156 240 """ 157 self.selenium.wait_for_condition('selenium.browserbot.getCurrentWindow().document.title == "%s"'%title, 30000)241 self.selenium.wait_for_condition('selenium.browserbot.getCurrentWindow().document.title.replace(/^\s+|\s+$/g, "") == "%s"'%title, 30000) 158 242 159 243 def rename_worksheet(self, new_title): 160 244 """ … … class NotebookTestCase(unittest.TestCase 162 246 """ 163 247 sel = self.selenium 164 248 sel.click("worksheet_title") 165 # Note: These locators also detect modal prompts that have been hidden, but not deleted. 249 # Note: These locators also detect modal prompts that have 250 # been hidden, but not deleted. 166 251 sel.type('//div[contains(@class,"modal-prompt")]//input[@type="text"]', new_title) 167 252 sel.click('//div[contains(@class, "modal-prompt")]/form/div[@class="button-div"]/button[@type="submit"]') 168 253 sel.wait_for_condition('selenium.browserbot.getCurrentWindow().$("#worksheet_title").text() == "%s"' % new_title, 5000) … … class NotebookTestCase(unittest.TestCase 170 255 def register_user(self, username, password='asdfasdf'): 171 256 """ 172 257 Registers a new user for the Sage notebook. 173 258 174 259 This assumes that you're at the login page. 175 260 """ 176 261 sel = self.selenium 177 262 sel.click("id=register-link") 178 263 sel.wait_for_page_to_load(30000) 179 self.wait_for_title("Sign up ")264 self.wait_for_title("Sign up -- Sage") 180 265 181 266 sel.type("username", username) 182 267 sel.type("password", password) 183 268 sel.type("retype_password", password) 184 269 sel.click("id=create-account-button") 185 270 sel.wait_for_page_to_load(30000) 186 self.wait_for_title('Sign in ')187 self.assertTrue(sel.is_text_present('regexp:Congratulations '))271 self.wait_for_title('Sign in -- Sage') 272 self.assertTrue(sel.is_text_present('regexp:Congratulations')) 188 273 189 274 def login_as(self, username, password='asdfasdf'): 190 275 """ … … class NotebookTestCase(unittest.TestCase 208 293 self.password = None 209 294 210 295 sel = self.selenium 211 sel.click(" //a[@href='/logout']")296 sel.click("link=Sign out") 212 297 sel.wait_for_page_to_load("30000") 213 298 214 299 def go_home(self): … … class NotebookTestCase(unittest.TestCase 222 307 223 308 def create_new_worksheet(self, title = "My New Worksheet"): 224 309 sel = self.selenium 225 sel.open('/new_worksheet') 310 self.go_home() 311 312 global CACHE_SKIP 313 CACHE_SKIP += 1 314 sel.open('/new_worksheet?%d' % CACHE_SKIP) 226 315 sel.wait_for_page_to_load("30000") 227 316 self.assert_(sel.is_element_present('//a[@id="worksheet_title" and contains(text(),"Untitled")]')) 228 317 sel.type('//div[contains(@class,"modal-prompt")]//input[@type="text"]', title) … … class NotebookTestCase(unittest.TestCase 231 320 232 321 def open_worksheet_with_title(self, title): 233 322 """ 234 Open the worksheet with the given title, starting at 323 Open the worksheet with the given title, starting at 235 324 worksheet list. This assumes the list contains the title. 236 325 """ 237 326 self.go_home() … … class NotebookTestCase(unittest.TestCase 248 337 sel = self.selenium 249 338 sel.click("link=Publish") 250 339 sel.wait_for_page_to_load("30000") 251 sel.click("// input[@value='Yes']")340 sel.click("//button[text()='Yes']") 252 341 sel.wait_for_page_to_load("30000") 253 342 sel.click("link=Worksheet") 254 343 sel.wait_for_page_to_load("30000") … … class NotebookTestCase(unittest.TestCase 261 350 sel = self.selenium 262 351 sel.click("link=Publish") 263 352 sel.wait_for_page_to_load("30000") 264 sel.click("// input[@value='Re-publish worksheet']")353 sel.click("//button[text()='Re-publish worksheet']") 265 354 sel.wait_for_page_to_load("30000") 266 355 sel.click("link=Worksheet") 267 356 sel.wait_for_page_to_load("30000") … … class NotebookTestCase(unittest.TestCase 272 361 """ 273 362 sel = self.selenium 274 363 sel.open('/pub') 275 sel.wait_for_page_to_load("30000") 364 sel.wait_for_page_to_load("30000") 276 365 277 366 def goto_published_worksheet(self, id): 278 367 """ … … class NotebookTestCase(unittest.TestCase 283 372 sel.click("link=Published") 284 373 sel.wait_for_page_to_load("30000") 285 374 sel.click("name-pub-"+id) 286 sel.wait_for_condition('selenium.browserbot.getCurrentWindow().worksheet_filename == "%s"'%('pub/'+id), 30000) 375 sel.wait_for_condition('selenium.browserbot.getCurrentWindow().worksheet_filename == "%s"'%('pub/'+id), 30000) 287 376 288 377 def open_worksheet_with_name(self, name): 289 378 """ 290 Opens the worksheet with the given name. Assumes that client is at list page. 379 Opens the worksheet with the given name. Assumes that client 380 is at list page. 291 381 """ 292 382 sel = self.selenium 293 383 self.wait_in_window('return this.$("a.worksheetname").attr("title").indexOf("{0}") != -1'.format(name), … … class NotebookTestCase(unittest.TestCase 313 403 browser window. Use ``this`` to access the browser window. 314 404 """ 315 405 self.selenium.wait_for_condition('(function(){ %s }).apply(selenium.browserbot.getCurrentWindow())' 316 % string, 317 timeout) 406 % string, timeout) 318 407 319 408 def stop_notebook(self): 320 409 """ … … class NotebookTestCase(unittest.TestCase 323 412 self._p.sendline(chr(3)+chr(3)) 324 413 self._p.kill(signal.SIGKILL) 325 414 self._p = None 326 415 327 416 def tearDown(self): 328 417 """ 329 418 Stops the notebook and cleans up. 330 419 """ 331 420 self.stop_notebook() 332 try: 333 shutil.rmtree(self.temp_dir + '.sagenb') 334 except OSError: 335 pass 421 self.cleanup() 336 422 self.selenium.stop() -
sagenb/testing/run_tests.py
diff --git a/sagenb/testing/run_tests.py b/sagenb/testing/run_tests.py
a b Functions for running SageNB tests. This 7 7 8 8 NOTE: 9 9 10 Selenium tests assume a Selenium server is running on port 4444. The 10 The SageNB tests tests assume a Selenium server or Grid hub is running 11 with the options given in :mod:`sagenb.testing.notebook_test_case` or 12 set by :func:`setup_tests`. 13 14 11 15 Selenium server can be downloaded from the Selenium `download page 12 16 <http://seleniumhq.org/download/>`_ as part of the Selenium RC package 13 and can be run with `java -jar selenium-server.jar`. 17 and can be run with `java -jar selenium-server.jar`. To set up 18 Selenium Grid, please visit its `home page 19 <http://selenium-grid.seleniumhq.org/>`_ for instructions. 14 20 15 21 TODO: 16 22 … … TODO: 23 29 # of the possibility of incompatible libraries and binaries with 24 30 # those of the user's browser (e.g., Python, etc.) 25 31 26 from subprocess import Popen 27 import unittest, os 32 import unittest 28 33 34 import notebook_test_case 29 35 from sagenb.misc.misc import browser 36 from tests import test_accounts, test_worksheet, test_worksheet_list 30 37 31 from tests import test_accounts, test_worksheet, test_worksheet_list 38 CASES = { 39 'TestAccounts': test_accounts, 40 'TestWorksheet': test_worksheet, 41 'TestWorksheetList': test_worksheet_list 42 } 32 43 33 44 all_tests = unittest.TestSuite((test_accounts.suite, 34 45 test_worksheet.suite, 35 46 test_worksheet_list.suite)) 36 47 37 def run_tests(): 48 49 def setup_tests(address='localhost', secure=False, 50 environment='*firefox3 /usr/bin/firefox'): 38 51 """ 39 Runs all SageNB tests. This assumes that a Selenium server is running on port 4444. 52 Sets selected options for SageNB Selenium tests. 53 54 INPUT: 55 56 - ``address`` - a string (default: 'localhost'); address of the 57 network interface at which the notebook server listens. Do not 58 leave this empty; see :mod:`sagenb.testing.notebook_test_case` 59 for details. 60 61 - ``secure`` - a boolean (default: False); whether to launch a 62 secure notebook server. Note: Browser security warnings will 63 yield failed tests. To work around these in Firefox, close all 64 windows, create a new profile (e.g., `firefox -P selenium`), 65 browse to a secure notebook server, accept the certificate, and 66 quit. Then launch the Selenium server with, e.g., 67 68 java -jar selenium-server -firefoxProfileTemplate $HOME/selenium/firefox 69 70 and run the tests. A minimal profile template directory can 71 contain just the files `cert8.db` and `cert_override.txt`. 72 73 - ``environment`` - a string (default: '*firefox3 74 /usr/bin/firefox'); the browser environment in which to run the 75 tests. The path is optional. However, for the Selenium server 76 to have complete control over the launched browser, it's best to 77 give the full path to the browser *executable* (i.e., not a 78 shell script). 79 80 Possible environments include '*chrome', '*firefox', 81 '*firefox3', '*googlechrome', '*iexplore', '*opera', '*safari'. 82 83 EXAMPLES:: 84 85 sage: import sagenb.testing.run_tests as rt # not tested 86 sage: env = '*firefox3 /usr/lib64/firefox-3.5.6/firefox' # not tested 87 sage: rt.setup_tests('localhost', True, env) # not tested 88 sage: rt.run_any() # not tested 89 sage: rt.setup_tests('localhost', True, '*opera') # not tested 90 sage: rt.run_and_report() # not tested 40 91 """ 41 unittest.TextTestRunner(verbosity=2).run(all_tests) 92 # TODO: Add a directory option for parallel testing. 93 notebook_test_case.NB_OPTIONS['address'] = address 94 notebook_test_case.NB_OPTIONS['secure'] = secure 95 notebook_test_case.SEL_OPTIONS['environment'] = environment 42 96 43 def run_test(suite): 97 98 def run_any(tests=all_tests, make_report=False, **kwargs): 44 99 """ 45 Runs a test suite. This assumes that a Selenium server is running on port 4444. 100 Creates and runs an ad hoc test suite from a test name, case, 101 suite, or a mixed list thereof. If no matching tests are found, 102 no tests are run. 103 104 INPUT: 105 106 - ``tests`` - a string, :class:`unittest.TestCase`, 107 :class:`unittest.TestSuite`, or a mixed list thereof. Strings 108 can be test names, with or without the prefix 'test_'. 109 110 - ``make_report`` - a boolean (default: False); whether to 111 generate a HTML report of the test results. 112 113 - ``kwargs`` - a dictionary; additional keyword options to pass to 114 :func:`run_suite` or :func:`run_and_report`. 115 116 EXAMPLES:: 117 118 sage: import sagenb.testing.run_tests as rt # not tested 119 sage: rt.run_any('simple_evaluation', make_report=True) # not tested 120 sage: rt.run_any(['4088', 'test_3711'], verbosity=1) # not tested 121 sage: rt.run_any('foo', False) # not tested 122 sage: rt.run_any(rt.test_accounts.TestAccounts) # not tested 123 sage: rt.run_any(make_report=True) # not tested 46 124 """ 47 unittest.TextTestRunner(verbosity=2).run(suite) 48 125 import inspect 126 from_name = unittest.TestLoader().loadTestsFromName 127 from_case = unittest.TestLoader().loadTestsFromTestCase 128 129 if not isinstance(tests, list): 130 tests = [tests] 131 132 alist = [] 133 for t in tests: 134 if isinstance(t, str): 135 if not t.startswith('test_'): 136 t = 'test_' + t 137 for c in CASES: 138 try: 139 alist.append(from_name(c + '.' + t, module = CASES[c])) 140 except AttributeError: 141 pass 142 elif inspect.isclass(t) and issubclass(t, unittest.TestCase): 143 alist.append(from_case(t)) 144 elif isinstance(t, unittest.TestSuite): 145 alist.append(t) 146 147 if alist: 148 suite = unittest.TestSuite(alist) 149 tot = suite.countTestCases() 150 151 environment = notebook_test_case.SEL_OPTIONS['environment'] 152 print 'Running %d test%s in environment %s...' % (tot, '' if tot == 1 else 's', environment) 153 154 if make_report: 155 run_and_report(suite, environment = environment, **kwargs) 156 else: 157 run_suite(suite, **kwargs) 158 159 160 def run_suite(suite=all_tests, verbosity=2): 161 """ 162 Runs a test suite. 163 164 For the SageNB test suite, this assumes a Selenium server or Grid 165 hub is running with the options given in 166 :mod:`sagenb.testing.notebook_test_case` or set by 167 :func:`setup_tests` 168 169 INPUT: 170 171 - ``suite`` - a TestSuite instance (default: all_tests); the test 172 suite to run 173 174 - ``verbosity`` - an integer (default: 2); how verbosely to report 175 instantaneous test results 176 177 EXAMPLES:: 178 179 sage: import sagenb.testing.run_tests as rt # not tested 180 sage: rt.run_suite() # not tested 181 sage: rt.run_suite(rt.test_worksheet.suite, verbosity=1) # not tested 182 """ 183 unittest.TextTestRunner(verbosity=verbosity).run(suite) 184 185 49 186 def run_and_report(suite=all_tests, verbosity=2, report_filename='report.html', 50 187 title='Sage Notebook Tests', 51 188 description='Selenium test results', 52 open_viewer=True ):189 open_viewer=True, **kwargs): 53 190 """ 54 191 Runs a test suite and generates a HTML report with the outcome 55 192 (pass, fail, or error) and output, including any tracebacks, for 56 each test, plus overall statistics. This assumes that a Selenium 57 server is running on port 4444. 193 each test, plus overall statistics. 194 195 For the SageNB test suite, this assumes a Selenium server or Grid 196 hub is running with the options given in 197 :mod:`sagenb.testing.notebook_test_case` or set by 198 :func:`setup_tests`. 58 199 59 200 INPUT: 60 201 … … def run_and_report(suite=all_tests, verb 75 216 76 217 - ``open_viewer`` - a boolean (default: True); whether to open 77 218 the report in a web browser 219 220 - ``kwargs`` - a dictionary; extra keyword arguments passed to the 221 test runner's constructor 222 223 EXAMPLES:: 224 225 sage: import sagenb.testing.run_tests as rt # not tested 226 sage: rt.run_and_report() # not tested 227 sage: rt.run_and_report(report_filename='test1.html') # not tested 228 sage: rt.run_and_report(rt.test_accounts.suite) # not tested 78 229 """ 79 230 from HTMLTestRunner import HTMLTestRunner 80 231 81 232 report_fd = open(report_filename, 'w') 82 233 runner = HTMLTestRunner(verbosity = verbosity, stream = report_fd, 83 title = title, description = description) 234 title = title, description = description, 235 **kwargs) 84 236 runner.run(suite) 85 237 86 238 if open_viewer: 87 Popen(browser() + ' ' + os.path.abspath(report_filename), shell=True) 239 import os, subprocess 240 subprocess.Popen(browser() + ' ' + os.path.abspath(report_filename), 241 shell=True) 88 242 89 243 90 244 if __name__ == '__main__': 91 run_tests() 92 93 94 95 96 97 245 run_suite() -
sagenb/testing/tests/test_accounts.py
diff --git a/sagenb/testing/tests/test_accounts.py b/sagenb/testing/tests/test_accounts.py
a b AUTHORS: 6 6 7 7 - Mike Hansen (?) -- initial revision 8 8 9 - Tim Dumol (Oct. 28, 2009) -- made the tests work again. Separated this out. 9 - Tim Dumol (Oct. 28, 2009) -- made the tests work again. Separated 10 this out. 10 11 """ 11 12 import unittest 12 13 … … from sagenb.testing.notebook_test_case i 14 15 15 16 class TestAccounts(NotebookTestCase): 16 17 def _sage_startup_command(self): 17 return 'sage -c "notebook(open_viewer=False, directory=\'%s\', accounts=True)"'\ 18 % self.temp_dir 18 self.nb_options['accounts'] = True 19 return super(TestAccounts, self)._sage_startup_command() 20 21 def setUp(self): 22 super(TestAccounts, self).setUp() 23 self.register_user('mike') 24 self.register_user('chris') 19 25 20 26 def test_3960(self): 21 27 """ 22 28 Tests to make sure that Trac ticket #3960 is actually fixed. 23 29 """ 24 30 sel = self.selenium 25 26 self.register_user('mike')27 self.register_user('chris')28 31 29 32 self.login_as('mike') 30 33 self.create_new_worksheet() … … class TestAccounts(NotebookTestCase): 34 37 35 38 self.login_as('chris') 36 39 self.goto_published_worksheet(0) 37 40 38 41 sel.click("link=Edit a copy.") 39 42 # Simply waiting for the page to load fails with slow computers. 40 self.wait_in_window('return this.location == "http://localhost:%d/home/chris/0/"' 41 % self.sagenb_port, 30000)43 # self.wait_in_window('return this.location == "%s/home/chris/0/"' % 44 # self.sel_options['browser_url'], 30000) 42 45 sel.wait_for_page_to_load(30000) 46 43 47 self.wait_in_window('return this.$.trim(this.$("#cell_output_nowrap_1").text()) == 4', 30000) 44 48 45 self.assertEqual(sel.get_location(), 'http://localhost:%d/home/chris/0/' % self.sagenb_port) 49 self.assertEqual(sel.get_location(), '%s/home/chris/0/' % 50 self.sel_options['browser_url']) 46 51 self.assertEqual(self.get_cell_output(1), '4') 47 self.assert_(sel.is_text_present('by chris'), 'chris does not own the worksheet') 52 self.assert_(sel.is_text_present('by chris'), 53 'chris does not own the worksheet') 48 54 49 55 def test_4088(self): 50 56 """ 51 Check to see that the 'Welcome to Sage!' message is not visible on the 52 published worksheets screen when there are no worksheets. 57 Check to see that the 'Welcome to Sage!' message is not 58 visible on the published worksheets screen when there are no 59 worksheets. 53 60 """ 54 61 sel = self.selenium 55 62 56 self.login_as(' admin')63 self.login_as('mike') 57 64 sel.click("link=Published") 58 65 sel.wait_for_page_to_load("30000") 59 66 60 self.assert_(not sel.is_text_present('Welcome to Sage!'), 'welcome message is still present')61 67 self.assert_(not sel.is_text_present('Welcome to Sage!'), 68 'welcome message is still present') 62 69 63 70 def test_4050(self): 64 71 """ 65 72 Tests to make sure that Trac ticket #4050 is actually fixed. 66 73 """ 67 74 sel = self.selenium 68 69 self.register_user('mike')70 self.register_user('chris')71 75 72 76 self.login_as('mike') 73 77 self.create_new_worksheet() … … class TestAccounts(NotebookTestCase): 80 84 self.login_as('chris') 81 85 sel.click("name-mike-0") 82 86 sel.wait_for_page_to_load("30000")
