From e89f0b0e3a74195b3bce0f68c337ead9dc18a11e Mon Sep 17 00:00:00 2001 From: prathamesh Date: Fri, 11 Jul 2014 13:42:35 +0530 Subject: Exam app using django 1.6.5 Removed version specification to install latest version of django. Added settings.py to the exam app. Removed default from import statement in urls.py since it is deprecated. --- buildout.cfg | 6 ------ production.cfg | 6 ------ testapp/exam/settings.py | 20 ++++++++++++++++++++ testapp/exam/urls.py | 2 +- testapp/urls.py | 2 +- 5 files changed, 22 insertions(+), 14 deletions(-) create mode 100644 testapp/exam/settings.py diff --git a/buildout.cfg b/buildout.cfg index f0cb035..9ffc6d8 100644 --- a/buildout.cfg +++ b/buildout.cfg @@ -7,12 +7,6 @@ eggs = django-taggit-autocomplete-modified django-debug-toolbar -versions = versions -[versions] -django = 1.3 -django-taggit = 0.10a1 -django-debug-toolbar = 0.8.4 - [django] recipe = djangorecipe project = testapp diff --git a/production.cfg b/production.cfg index d623e80..c5ec49e 100644 --- a/production.cfg +++ b/production.cfg @@ -8,12 +8,6 @@ eggs = django-taggit-autocomplete-modified django-debug-toolbar -versions = versions -[versions] -django = 1.3 -django-taggit = 0.10a1 -django-debug-toolbar = 0.8.4 - [django] recipe = djangorecipe project = testapp diff --git a/testapp/exam/settings.py b/testapp/exam/settings.py new file mode 100644 index 0000000..682516f --- /dev/null +++ b/testapp/exam/settings.py @@ -0,0 +1,20 @@ +""" +settings for exam app. +""" +# The ports the code server should run on. This will run one separate +# server for each port listed in the following list. +SERVER_PORTS = [8001] # range(8001, 8026) + +# The server pool port. This is the server which returns available server +# ports so as to minimize load. This is some random number where no other +# service is running. It should be > 1024 and less < 65535 though. +SERVER_POOL_PORT = 53579 + +# Timeout for the code to run in seconds. This is an integer! +SERVER_TIMEOUT = 2 + +# The root of the URL, for example you might be in the situation where you +# are not hosted as host.org/exam/ but as host.org/foo/exam/ for whatever +# reason set this to the root you have to serve at. In the above example +# host.org/foo/exam set URL_ROOT='/foo' +URL_ROOT = '' diff --git a/testapp/exam/urls.py b/testapp/exam/urls.py index b659cf6..37a031d 100644 --- a/testapp/exam/urls.py +++ b/testapp/exam/urls.py @@ -1,4 +1,4 @@ -from django.conf.urls.defaults import patterns, include, url +from django.conf.urls import patterns, include, url urlpatterns = patterns('exam.views', url(r'^$', 'index'), diff --git a/testapp/urls.py b/testapp/urls.py index c82ecb6..0d126f4 100644 --- a/testapp/urls.py +++ b/testapp/urls.py @@ -1,4 +1,4 @@ -from django.conf.urls.defaults import patterns, include, url +from django.conf.urls import patterns, include, url # Uncomment the next two lines to enable the admin: from django.contrib import admin -- cgit From 0143710e78ae01bae78a3b760fc8410bc86a3b2b Mon Sep 17 00:00:00 2001 From: prathamesh Date: Fri, 11 Jul 2014 14:14:19 +0530 Subject: Moved templates and static inside the app. --- testapp/exam/static/exam/css/autotaggit.css | 48 + testapp/exam/static/exam/css/base.css | 2259 ++++++++++++++++++++ testapp/exam/static/exam/css/gradeuser.css | 52 + testapp/exam/static/exam/css/login.css | 10 + testapp/exam/static/exam/css/monitor.css | 11 + testapp/exam/static/exam/css/question.css | 42 + .../static/exam/css/question_paper_creation.css | 119 ++ testapp/exam/static/exam/css/question_quiz.css | 18 + testapp/exam/static/exam/css/showusers.css | 5 + testapp/exam/static/exam/js/add_question.js | 206 ++ testapp/exam/static/exam/js/add_questionpaper.js | 25 + testapp/exam/static/exam/js/add_quiz.js | 7 + testapp/exam/static/exam/js/bootstrap-modal.js | 260 +++ testapp/exam/static/exam/js/bootstrap-tabs.js | 80 + testapp/exam/static/exam/js/edit_question.js | 278 +++ testapp/exam/static/exam/js/edit_quiz.js | 21 + testapp/exam/static/exam/js/min.js | 19 + testapp/exam/static/exam/js/question.js | 152 ++ .../exam/static/exam/js/question_paper_creation.js | 237 ++ testapp/exam/static/exam/js/show_question.js | 39 + testapp/exam/static/exam/js/show_quiz.js | 41 + testapp/exam/templates/404.html | 5 + testapp/exam/templates/500.html | 7 + testapp/exam/templates/base.html | 46 + testapp/exam/templates/exam/add_question.html | 41 + testapp/exam/templates/exam/add_questionpaper.html | 28 + testapp/exam/templates/exam/add_quiz.html | 25 + testapp/exam/templates/exam/ajax_marks.html | 4 + testapp/exam/templates/exam/ajax_questions.html | 31 + .../templates/exam/automatic_questionpaper.html | 88 + testapp/exam/templates/exam/complete.html | 12 + .../exam/templates/exam/design_questionpaper.html | 184 ++ testapp/exam/templates/exam/edit_question.html | 54 + testapp/exam/templates/exam/edit_quiz.html | 39 + testapp/exam/templates/exam/editquestionpaper.html | 21 + testapp/exam/templates/exam/grade_user.html | 94 + testapp/exam/templates/exam/intro.html | 34 + testapp/exam/templates/exam/login.html | 22 + .../exam/templates/exam/manual_questionpaper.html | 81 + testapp/exam/templates/exam/monitor.html | 69 + testapp/exam/templates/exam/question.html | 138 ++ testapp/exam/templates/exam/quit.html | 14 + testapp/exam/templates/exam/quizlist.html | 24 + testapp/exam/templates/exam/quizzes_user.html | 81 + testapp/exam/templates/exam/register.html | 20 + testapp/exam/templates/exam/results_user.html | 28 + testapp/exam/templates/exam/show_quiz.html | 33 + .../exam/templates/exam/showquestionpapers.html | 23 + testapp/exam/templates/exam/showquestions.html | 21 + testapp/exam/templates/exam/showusers.html | 26 + testapp/exam/templates/exam/user_data.html | 80 + testapp/exam/templates/manage.html | 88 + testapp/exam/templates/user.html | 58 + testapp/settings.py | 14 - testapp/static/exam/css/autotaggit.css | 48 - testapp/static/exam/css/base.css | 2259 -------------------- testapp/static/exam/css/gradeuser.css | 52 - testapp/static/exam/css/login.css | 10 - testapp/static/exam/css/monitor.css | 11 - testapp/static/exam/css/question.css | 42 - .../static/exam/css/question_paper_creation.css | 119 -- testapp/static/exam/css/question_quiz.css | 18 - testapp/static/exam/css/showusers.css | 5 - testapp/static/exam/js/add_question.js | 206 -- testapp/static/exam/js/add_questionpaper.js | 25 - testapp/static/exam/js/add_quiz.js | 7 - testapp/static/exam/js/bootstrap-modal.js | 260 --- testapp/static/exam/js/bootstrap-tabs.js | 80 - testapp/static/exam/js/edit_question.js | 278 --- testapp/static/exam/js/edit_quiz.js | 21 - testapp/static/exam/js/min.js | 19 - testapp/static/exam/js/question.js | 152 -- testapp/static/exam/js/question_paper_creation.js | 237 -- testapp/static/exam/js/show_question.js | 39 - testapp/static/exam/js/show_quiz.js | 41 - testapp/templates/404.html | 5 - testapp/templates/500.html | 7 - testapp/templates/base.html | 46 - testapp/templates/exam/add_question.html | 41 - testapp/templates/exam/add_questionpaper.html | 28 - testapp/templates/exam/add_quiz.html | 25 - testapp/templates/exam/ajax_marks.html | 4 - testapp/templates/exam/ajax_questions.html | 31 - .../templates/exam/automatic_questionpaper.html | 88 - testapp/templates/exam/complete.html | 12 - testapp/templates/exam/design_questionpaper.html | 184 -- testapp/templates/exam/edit_question.html | 54 - testapp/templates/exam/edit_quiz.html | 39 - testapp/templates/exam/editquestionpaper.html | 21 - testapp/templates/exam/grade_user.html | 94 - testapp/templates/exam/intro.html | 34 - testapp/templates/exam/login.html | 22 - testapp/templates/exam/manual_questionpaper.html | 81 - testapp/templates/exam/monitor.html | 69 - testapp/templates/exam/question.html | 138 -- testapp/templates/exam/quit.html | 14 - testapp/templates/exam/quizlist.html | 24 - testapp/templates/exam/quizzes_user.html | 81 - testapp/templates/exam/register.html | 20 - testapp/templates/exam/results_user.html | 28 - testapp/templates/exam/show_quiz.html | 33 - testapp/templates/exam/showquestionpapers.html | 23 - testapp/templates/exam/showquestions.html | 21 - testapp/templates/exam/showusers.html | 26 - testapp/templates/exam/user_data.html | 80 - testapp/templates/manage.html | 88 - testapp/templates/user.html | 58 - 107 files changed, 5448 insertions(+), 5462 deletions(-) create mode 100644 testapp/exam/static/exam/css/autotaggit.css create mode 100644 testapp/exam/static/exam/css/base.css create mode 100644 testapp/exam/static/exam/css/gradeuser.css create mode 100644 testapp/exam/static/exam/css/login.css create mode 100644 testapp/exam/static/exam/css/monitor.css create mode 100644 testapp/exam/static/exam/css/question.css create mode 100644 testapp/exam/static/exam/css/question_paper_creation.css create mode 100644 testapp/exam/static/exam/css/question_quiz.css create mode 100644 testapp/exam/static/exam/css/showusers.css create mode 100644 testapp/exam/static/exam/js/add_question.js create mode 100644 testapp/exam/static/exam/js/add_questionpaper.js create mode 100644 testapp/exam/static/exam/js/add_quiz.js create mode 100644 testapp/exam/static/exam/js/bootstrap-modal.js create mode 100644 testapp/exam/static/exam/js/bootstrap-tabs.js create mode 100644 testapp/exam/static/exam/js/edit_question.js create mode 100644 testapp/exam/static/exam/js/edit_quiz.js create mode 100644 testapp/exam/static/exam/js/min.js create mode 100644 testapp/exam/static/exam/js/question.js create mode 100644 testapp/exam/static/exam/js/question_paper_creation.js create mode 100644 testapp/exam/static/exam/js/show_question.js create mode 100644 testapp/exam/static/exam/js/show_quiz.js create mode 100644 testapp/exam/templates/404.html create mode 100644 testapp/exam/templates/500.html create mode 100644 testapp/exam/templates/base.html create mode 100644 testapp/exam/templates/exam/add_question.html create mode 100644 testapp/exam/templates/exam/add_questionpaper.html create mode 100644 testapp/exam/templates/exam/add_quiz.html create mode 100644 testapp/exam/templates/exam/ajax_marks.html create mode 100644 testapp/exam/templates/exam/ajax_questions.html create mode 100644 testapp/exam/templates/exam/automatic_questionpaper.html create mode 100644 testapp/exam/templates/exam/complete.html create mode 100644 testapp/exam/templates/exam/design_questionpaper.html create mode 100644 testapp/exam/templates/exam/edit_question.html create mode 100644 testapp/exam/templates/exam/edit_quiz.html create mode 100644 testapp/exam/templates/exam/editquestionpaper.html create mode 100644 testapp/exam/templates/exam/grade_user.html create mode 100644 testapp/exam/templates/exam/intro.html create mode 100644 testapp/exam/templates/exam/login.html create mode 100644 testapp/exam/templates/exam/manual_questionpaper.html create mode 100644 testapp/exam/templates/exam/monitor.html create mode 100644 testapp/exam/templates/exam/question.html create mode 100644 testapp/exam/templates/exam/quit.html create mode 100644 testapp/exam/templates/exam/quizlist.html create mode 100644 testapp/exam/templates/exam/quizzes_user.html create mode 100644 testapp/exam/templates/exam/register.html create mode 100644 testapp/exam/templates/exam/results_user.html create mode 100644 testapp/exam/templates/exam/show_quiz.html create mode 100644 testapp/exam/templates/exam/showquestionpapers.html create mode 100644 testapp/exam/templates/exam/showquestions.html create mode 100644 testapp/exam/templates/exam/showusers.html create mode 100644 testapp/exam/templates/exam/user_data.html create mode 100644 testapp/exam/templates/manage.html create mode 100644 testapp/exam/templates/user.html delete mode 100644 testapp/static/exam/css/autotaggit.css delete mode 100644 testapp/static/exam/css/base.css delete mode 100644 testapp/static/exam/css/gradeuser.css delete mode 100644 testapp/static/exam/css/login.css delete mode 100644 testapp/static/exam/css/monitor.css delete mode 100644 testapp/static/exam/css/question.css delete mode 100644 testapp/static/exam/css/question_paper_creation.css delete mode 100644 testapp/static/exam/css/question_quiz.css delete mode 100644 testapp/static/exam/css/showusers.css delete mode 100644 testapp/static/exam/js/add_question.js delete mode 100644 testapp/static/exam/js/add_questionpaper.js delete mode 100644 testapp/static/exam/js/add_quiz.js delete mode 100644 testapp/static/exam/js/bootstrap-modal.js delete mode 100644 testapp/static/exam/js/bootstrap-tabs.js delete mode 100644 testapp/static/exam/js/edit_question.js delete mode 100644 testapp/static/exam/js/edit_quiz.js delete mode 100644 testapp/static/exam/js/min.js delete mode 100644 testapp/static/exam/js/question.js delete mode 100644 testapp/static/exam/js/question_paper_creation.js delete mode 100644 testapp/static/exam/js/show_question.js delete mode 100644 testapp/static/exam/js/show_quiz.js delete mode 100644 testapp/templates/404.html delete mode 100644 testapp/templates/500.html delete mode 100644 testapp/templates/base.html delete mode 100644 testapp/templates/exam/add_question.html delete mode 100644 testapp/templates/exam/add_questionpaper.html delete mode 100644 testapp/templates/exam/add_quiz.html delete mode 100644 testapp/templates/exam/ajax_marks.html delete mode 100644 testapp/templates/exam/ajax_questions.html delete mode 100644 testapp/templates/exam/automatic_questionpaper.html delete mode 100644 testapp/templates/exam/complete.html delete mode 100644 testapp/templates/exam/design_questionpaper.html delete mode 100644 testapp/templates/exam/edit_question.html delete mode 100644 testapp/templates/exam/edit_quiz.html delete mode 100644 testapp/templates/exam/editquestionpaper.html delete mode 100644 testapp/templates/exam/grade_user.html delete mode 100644 testapp/templates/exam/intro.html delete mode 100644 testapp/templates/exam/login.html delete mode 100644 testapp/templates/exam/manual_questionpaper.html delete mode 100644 testapp/templates/exam/monitor.html delete mode 100644 testapp/templates/exam/question.html delete mode 100644 testapp/templates/exam/quit.html delete mode 100644 testapp/templates/exam/quizlist.html delete mode 100644 testapp/templates/exam/quizzes_user.html delete mode 100644 testapp/templates/exam/register.html delete mode 100644 testapp/templates/exam/results_user.html delete mode 100644 testapp/templates/exam/show_quiz.html delete mode 100644 testapp/templates/exam/showquestionpapers.html delete mode 100644 testapp/templates/exam/showquestions.html delete mode 100644 testapp/templates/exam/showusers.html delete mode 100644 testapp/templates/exam/user_data.html delete mode 100644 testapp/templates/manage.html delete mode 100644 testapp/templates/user.html diff --git a/testapp/exam/static/exam/css/autotaggit.css b/testapp/exam/static/exam/css/autotaggit.css new file mode 100644 index 0000000..ed856ce --- /dev/null +++ b/testapp/exam/static/exam/css/autotaggit.css @@ -0,0 +1,48 @@ +.ac_results { + padding: 0px; + border: 1px solid #efefef; + background-color: white; + overflow: hidden; + z-index: 99999; +} + +.ac_results ul { + width: 100%; + list-style-position: outside; + list-style: none; + padding: 0; + margin: 0; +} + +.ac_results li { + margin: 0px; + padding: 2px 5px; + cursor: default; + display: block; + /* + if width will be 100% horizontal scrollbar will apear + when scroll mode will be used + */ + /*width: 100%;*/ + font: menu; + font-size: 12px; + /* + it is very important, if line-height not setted or setted + in relative units scroll will be broken in firefox + */ + line-height: 16px; + overflow: hidden; +} + +.ac_loading { + background: white url('indicator.gif') right center no-repeat; +} + +.ac_odd { + background-color: #CACACA; +} + +.ac_over { + background-color: #f5f5f5; + color: black; +} diff --git a/testapp/exam/static/exam/css/base.css b/testapp/exam/static/exam/css/base.css new file mode 100644 index 0000000..051ba22 --- /dev/null +++ b/testapp/exam/static/exam/css/base.css @@ -0,0 +1,2259 @@ +/*! +Copyright 2012 Twitter, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); you may not use this work except in compliance with the License. You may obtain a copy of the License in the LICENSE file, or at: + +Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. + + * Bootstrap v1.4.0 + * + * Copyright 2011 Twitter, Inc + * Licensed under the Apache License v2.0 + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Designed and built with all the love in the world @twitter by @mdo and @fat. + * Date: Sun Dec 25 20:18:31 PST 2011 + */ +/* Reset.less + * Props to Eric Meyer (meyerweb.com) for his CSS reset file. We're using an adapted version here that cuts out some of the reset HTML elements we will never need here (i.e., dfn, samp, etc). + * For Online Test Application, this CSS was changed as per the requirements wherever required. ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- */ + +html, body { + background-color: #eee; + margin: 0; + padding: 0; + +} +h1, +h2, +h3, +h4, +h5, +h6, +p, +blockquote, +pre, +a, +abbr, +acronym, +address, +cite, +code, +del, +dfn, +em, +img, +q, +s, +samp, +small, +strike, +strong, +sub, +sup, +tt, +var, +dd, +dl, +dt, +li, +ol, +ul, +fieldset, +form, +label, +legend, +button, +table, +caption, +tbody, +tfoot, +thead, +tr, +th, +td { + margin: 0; + padding: 0; + border: 0; + font-weight: normal; + font-style: normal; + font-size: 100%; + line-height: 1; + font-family: serif; +} +table { + border-collapse: collapse; + border-spacing: 0; +} +ol, ul { + list-style: none; +} +q:before, +q:after, +blockquote:before, +blockquote:after { + content: ""; +} +html { + overflow-y: scroll; + font-size: 100%; + -webkit-text-size-adjust: 100%; + -ms-text-size-adjust: 100%; +} +a:focus { + outline: thin dotted; +} +a:hover, a:active { + outline: 0; +} +article, +aside, +details, +figcaption, +figure, +footer, +header, +hgroup, +nav, +section { + display: block; +} +audio, canvas, video { + display: inline-block; + *display: inline; + *zoom: 1; +} +audio:not([controls]) { + display: none; +} +sub, sup { + font-size: 75%; + line-height: 0; + position: relative; + vertical-align: baseline; +} +sup { + top: -0.5em; +} +sub { + bottom: -0.25em; +} +img { + border: 0; + -ms-interpolation-mode: bicubic; +} +button, +input, +select, +textarea { + font-size: 100%; + margin: 0; + vertical-align: baseline; + *vertical-align: middle; +} +button, input { + line-height: normal; + *overflow: visible; +} +button::-moz-focus-inner, input::-moz-focus-inner { + border: 0; + padding: 0; +} +button, +input[type="button"], +input[type="reset"], +input[type="submit"] { + cursor: pointer; + -webkit-appearance: button; +} +input[type="search"] { + -webkit-appearance: textfield; + -webkit-box-sizing: content-box; + -moz-box-sizing: content-box; + box-sizing: content-box; +} +input[type="search"]::-webkit-search-decoration { + -webkit-appearance: none; +} +textarea { + overflow: visible; + vertical-align: top; +} +/* Variables.less +* Variables to customize the look and feel of Bootstrap +* ----------------------------------------------------- */ +/* Mixins.less +* Snippets of reusable CSS to develop faster and keep code readable +* ----------------------------------------------------------------- */ +/* +* Scaffolding +* Basic and global styles for generating a grid system, structural layout, and page templates +* ------------------------------------------------------------------------------------------- */ +body { + padding-top : 10px; + background-color: #eee; + margin: 0; + font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; + font-size: 13px; + font-weight: normal; + line-height: 18px; + color: #404040; + +} +.container { + width: 820px; + margin-left: auto; + margin-right: auto; + zoom: 1; +} +.container > footer p { + text-align: center; +} +.container > .content { + background-color: #fff; + padding: 20px; + margin: 0 -20px; + -webkit-border-radius: 0 0 6px 6px; + -moz-border-radius: 0 0 6px 6px; + border-radius: 0 0 6px 6px; + -webkit-box-shadow: 0 1px 2px rgba(0,0,0,.15); + -moz-box-shadow: 0 1px 2px rgba(0,0,0,.15); + box-shadow: 0 1px 2px rgba(0,0,0,.15); +} +.content .span10, +.content .span14 { + min-height: 475px; +} +.content .span4 { + margin-left: 0; + padding-left: 19px; + border-left: 1px solid #eee; +} +.topbar .btn { + border: 0; +} +.page-header { + background-color: #f5f5f5; + padding: 20px 20px 10px; + margin: -20px -20px 20px; +} +.container:before, .container:after { + display: table; + content: ""; + zoom: 1; +} +.container:after { + clear: both; +} + +a { + color: #0069d6; + text-decoration: none; + line-height: inherit; + font-weight: inherit; +} +a:hover { + color: #00438a; + text-decoration: underline; +} +.pull-right { + float: right; +} +.pull-left { + float: left; +} +.hide { + display: none; +} +.show { + display: block; +} +.row { + zoom: 1; + margin-left: -20px; +} +.row:before, .row:after { + display: table; + content: ""; + zoom: 1; +} +.row:after { + clear: both; +} +.row > [class*="span"] { + display: inline; + float: left; + margin-left: 20px; +} +.span1 { + width: 40px; +} +.span2 { + width: 100px; +} +.span3 { + width: 160px; +} +.span4 { + width: 220px; +} +.span5 { + width: 280px; +} +.span6 { + width: 340px; +} +.span7 { + width: 400px; +} +.span8 { + width: 460px; +} +.span9 { + width: 520px; +} +.span10 { + width: 560px; +} +.span11 { + width: 640px; +} +.span12 { + width: 700px; +} +.span13 { + width: 760px; +} +.span14 { + width: 820px; +} +.span15 { + width: 880px; +} +.span16 { + width: 940px; +} +.span17 { + width: 1000px; +} +.span18 { + width: 1060px; +} +.span19 { + width: 1120px; +} +.span20 { + width: 1180px; +} +.span21 { + width: 1240px; +} +.span22 { + width: 1300px; +} +.span23 { + width: 1360px; +} +.span24 { + width: 1420px; +} +.row > .offset1 { + margin-left: 80px; +} +.row > .offset2 { + margin-left: 140px; +} +.row > .offset3 { + margin-left: 200px; +} +.row > .offset4 { + margin-left: 260px; +} +.row > .offset5 { + margin-left: 320px; +} +.row > .offset6 { + margin-left: 380px; +} +.row > .offset7 { + margin-left: 440px; +} +.row > .offset8 { + margin-left: 500px; +} +.row > .offset9 { + margin-left: 560px; +} +.row > .offset10 { + margin-left: 620px; +} +.row > .offset11 { + margin-left: 680px; +} +.row > .offset12 { + margin-left: 740px; +} +.span-one-third { + width: 300px; +} +.span-two-thirds { + width: 620px; +} +.row > .offset-one-third { + margin-left: 340px; +} +.row > .offset-two-thirds { + margin-left: 660px; +} +/* Typography.less +* Headings, body text, lists, code, and more for a versatile and durable typography system +* ---------------------------------------------------------------------------------------- */ +p { + font-size: 13px; + font-weight: normal; + line-height: 18px; + margin-bottom: 9px; +} +p small { + font-size: 11px; + color: #bfbfbf; +} +h1, +h2, +h3, +h4, +h5, +h6 { + font-weight: bold; + color: #404040; +} +h1 small, +h2 small, +h3 small, +h4 small, +h5 small, +h6 small { + color: #bfbfbf; +} +h1 { + margin-bottom: 18px; + font-size: 30px; + line-height: 36px; +} +h1 small { + font-size: 18px; +} +h2 { + font-size: 24px; + line-height: 36px; +} +h2 small { + font-size: 14px; +} +h3, +h4, +h5, +h6 { + line-height: 36px; +} +h3 { + font-size: 18px; +} +h3 small { + font-size: 14px; +} +h4 { + font-size: 16px; +} +h4 small { + font-size: 12px; +} +h5 { + font-size: 14px; +} +h6 { + font-size: 13px; + color: #bfbfbf; + text-transform: uppercase; +} +ul, ol { + margin: 0 0 18px 25px; +} +ul ul, +ul ol, +ol ol, +ol ul { + margin-bottom: 0; +} +ul { + list-style: disc; +} +ol { + list-style: decimal; +} +li { + line-height: 18px; + color: #808080; +} +ul.unstyled { + list-style: none; + margin-left: 0; +} +dl { + margin-bottom: 18px; +} +dl dt, dl dd { + line-height: 18px; +} +dl dt { + font-weight: bold; +} +dl dd { + margin-left: 9px; +} +hr { + margin: 20px 0 19px; + border: 0; + border-bottom: 1px solid; +} +strong { + font-style: inherit; + font-weight: bold; +} +em { + font-style: italic; + font-weight: inherit; + line-height: inherit; +} +.muted { + color: #bfbfbf; +} +blockquote { + margin-bottom: 18px; + border-left: 5px solid #eee; + padding-left: 15px; +} +blockquote p { + font-size: 14px; + font-weight: 300; + line-height: 18px; + margin-bottom: 0; +} +blockquote small { + display: block; + font-size: 12px; + font-weight: 300; + line-height: 18px; + color: #bfbfbf; +} +blockquote small:before { + content: '\2014 \00A0'; +} +address { + display: block; + line-height: 18px; + margin-bottom: 18px; +} +code, pre { + padding: 0 3px 2px; + font-family: Monaco, Andale Mono, Courier New, monospace; + font-size: 12px; + -webkit-border-radius: 3px; + -moz-border-radius: 3px; + border-radius: 3px; +} +code { + background-color: #FDE8E8; + color: rgba(0, 0, 0, 0.75); + padding: 1px 3px; +} +pre { + background-color: #EAB9B9; + color:red; + display: block; + padding: 8.5px; + margin: 0 0 18px; + line-height: 18px; + font-size: 12px; + border: 1px solid #ccc; + border: 1px solid rgba(0, 0, 0, 0.15); + -webkit-border-radius: 3px; + -moz-border-radius: 3px; + border-radius: 3px; + white-space: pre; + white-space: pre-wrap; + word-wrap: break-word; +} +/* Forms.less +* Base styles for various input types, form layouts, and states +* ------------------------------------------------------------- */ +form { + margin-bottom: 18px; +} +fieldset { + margin-bottom: 18px; + padding-top: 18px; +} +fieldset legend { + display: block; + padding-left: 150px; + font-size: 19.5px; + line-height: 1; + color: #404040; + *padding: 0 0 5px 145px; + /* IE6-7 */ + + *line-height: 1.5; + /* IE6-7 */ + +} +form .clearfix { + margin-bottom: 18px; + zoom: 1; +} +form .clearfix:before, form .clearfix:after { + display: table; + content: ""; + zoom: 1; +} +form .clearfix:after { + clear: both; +} +label, +input, +select, +textarea { + font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; + font-size: 13px; + font-weight: normal; + line-height: normal; +} +select +{ + width : auto; +} +label { + padding-top: 6px; + font-size: 13px; + line-height: 18px; + float: left; + width: 130px; + text-align: left; + color: #404040; +} +form .input { + margin-left: 150px; +} +input[type=checkbox], input[type=radio] { + cursor: pointer; +} +input, +textarea, +select, +.uneditable-input { + display: inline-block; + width: 210px; + height: 18px; + padding: 4px; + font-size: 13px; + line-height: 18px; + color: #808080; + border: 1px solid #ccc; + -webkit-border-radius: 3px; + -moz-border-radius: 3px; + border-radius: 3px; +} +select { + padding: initial; +} +input[type=checkbox], input[type=radio] { + width: auto; + height: auto; + padding: 0; + margin: 3px 0; + *margin-top: 0; + /* IE6-7 */ + + line-height: normal; + border: none; +} +input[type=file] { + background-color: #ffffff; + padding: initial; + border: initial; + line-height: initial; + -webkit-box-shadow: none; + -moz-box-shadow: none; + box-shadow: none; +} +input[type=button], input[type=reset], input[type=submit] { + width: auto; + height: auto; +} +select, input[type=file] { + height: 27px; + *height: auto; + line-height: 27px; + *margin-top: 4px; + /* For IE7, add top margin to align select with labels */ + +} +select[multiple] { + height: inherit; + background-color: #ffffff; +} +textarea { + height: auto; +} +.uneditable-input { + background-color: #ffffff; + display: block; + border-color: #eee; + -webkit-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.025); + -moz-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.025); + box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.025); + cursor: not-allowed; +} +:-moz-placeholder { + color: #bfbfbf; +} +::-webkit-input-placeholder { + color: #bfbfbf; +} +input, textarea { + -webkit-transition: border linear 0.2s, box-shadow linear 0.2s; + -moz-transition: border linear 0.2s, box-shadow linear 0.2s; + -ms-transition: border linear 0.2s, box-shadow linear 0.2s; + -o-transition: border linear 0.2s, box-shadow linear 0.2s; + transition: border linear 0.2s, box-shadow linear 0.2s; + -webkit-box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.1); + -moz-box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.1); + box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.1); +} +input:focus, textarea:focus { + outline: 0; + border-color: rgba(82, 168, 236, 0.8); + -webkit-box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.1), 0 0 8px rgba(82, 168, 236, 0.6); + -moz-box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.1), 0 0 8px rgba(82, 168, 236, 0.6); + box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.1), 0 0 8px rgba(82, 168, 236, 0.6); +} +input[type=file]:focus, input[type=checkbox]:focus, select:focus { + -webkit-box-shadow: none; + -moz-box-shadow: none; + box-shadow: none; + outline: 1px dotted #666; +} +form .clearfix.error > label, form .clearfix.error .help-block, form .clearfix.error .help-inline { + color: #b94a48; +} +form .clearfix.error input, form .clearfix.error textarea { + color: #b94a48; + border-color: #ee5f5b; +} +form .clearfix.error input:focus, form .clearfix.error textarea:focus { + border-color: #e9322d; + -webkit-box-shadow: 0 0 6px #f8b9b7; + -moz-box-shadow: 0 0 6px #f8b9b7; + box-shadow: 0 0 6px #f8b9b7; +} +form .clearfix.error .input-prepend .add-on, form .clearfix.error .input-append .add-on { + color: #b94a48; + background-color: #fce6e6; + border-color: #b94a48; +} +form .clearfix.warning > label, form .clearfix.warning .help-block, form .clearfix.warning .help-inline { + color: #c09853; +} +form .clearfix.warning input, form .clearfix.warning textarea { + color: #c09853; + border-color: #ccae64; +} +form .clearfix.warning input:focus, form .clearfix.warning textarea:focus { + border-color: #be9a3f; + -webkit-box-shadow: 0 0 6px #e5d6b1; + -moz-box-shadow: 0 0 6px #e5d6b1; + box-shadow: 0 0 6px #e5d6b1; +} +form .clearfix.warning .input-prepend .add-on, form .clearfix.warning .input-append .add-on { + color: #c09853; + background-color: #d2b877; + border-color: #c09853; +} +form .clearfix.success > label, form .clearfix.success .help-block, form .clearfix.success .help-inline { + color: #468847; +} +form .clearfix.success input, form .clearfix.success textarea { + color: #468847; + border-color: #57a957; +} +form .clearfix.success input:focus, form .clearfix.success textarea:focus { + border-color: #458845; + -webkit-box-shadow: 0 0 6px #9acc9a; + -moz-box-shadow: 0 0 6px #9acc9a; + box-shadow: 0 0 6px #9acc9a; +} +form .clearfix.success .input-prepend .add-on, form .clearfix.success .input-append .add-on { + color: #468847; + background-color: #bcddbc; + border-color: #468847; +} +textarea +{ + width : 290px; +} +.input-mini, +input.mini, +textarea.mini, +select.mini { + width: 60px; +} +.input-small, +input.small, +textarea.small, +select.small { + width: 90px; +} +.input-medium, +input.medium, +textarea.medium, +select.medium { + width: 150px; +} +.input-large, +input.large, +textarea.large, +select.large { + width: 210px; +} +.input-xlarge, +input.xlarge, +textarea.xlarge, +select.xlarge { + width: 270px; +} +.input-xxlarge, +input.xxlarge, +textarea.xxlarge, +select.xxlarge { + width: 530px; +} +textarea.xxlarge { + overflow-y: auto; +} +input.span1, textarea.span1 { + display: inline-block; + float: none; + width: 30px; + margin-left: 0; +} +input.span2, textarea.span2 { + display: inline-block; + float: none; + width: 90px; + margin-left: 0; +} +input.span3, textarea.span3 { + display: inline-block; + float: none; + width: 150px; + margin-left: 0; +} +input.span4, textarea.span4 { + display: inline-block; + float: none; + width: 210px; + margin-left: 0; +} +input.span5, textarea.span5 { + display: inline-block; + float: none; + width: 270px; + margin-left: 0; +} +input.span6, textarea.span6 { + display: inline-block; + float: none; + width: 330px; + margin-left: 0; +} +input.span7, textarea.span7 { + display: inline-block; + float: none; + width: 390px; + margin-left: 0; +} +input.span8, textarea.span8 { + display: inline-block; + float: none; + width: 450px; + margin-left: 0; +} +input.span9, textarea.span9 { + display: inline-block; + float: none; + width: 510px; + margin-left: 0; +} +input.span10, textarea.span10 { + display: inline-block; + float: none; + width: 570px; + margin-left: 0; +} +input.span11, textarea.span11 { + display: inline-block; + float: none; + width: 630px; + margin-left: 0; +} +input.span12, textarea.span12 { + display: inline-block; + float: none; + width: 690px; + margin-left: 0; +} +input.span13, textarea.span13 { + display: inline-block; + float: none; + width: 750px; + margin-left: 0; +} +input.span14, textarea.span14 { + display: inline-block; + float: none; + width: 810px; + margin-left: 0; +} +input.span15, textarea.span15 { + display: inline-block; + float: none; + width: 870px; + margin-left: 0; +} +input.span16, textarea.span16 { + display: inline-block; + float: none; + width: 930px; + margin-left: 0; +} +input[disabled], +select[disabled], +textarea[disabled], +input[readonly], +select[readonly], +textarea[readonly] { + background-color: #f5f5f5; + border-color: #ddd; + cursor: not-allowed; +} +.actions { + background: #f5f5f5; + margin-top: 18px; + margin-bottom: 18px; + padding: 17px 20px 18px 150px; + border-top: 1px solid #ddd; + -webkit-border-radius: 0 0 3px 3px; + -moz-border-radius: 0 0 3px 3px; + border-radius: 0 0 3px 3px; +} +.actions .secondary-action { + float: right; +} +.actions .secondary-action a { + line-height: 30px; +} +.actions .secondary-action a:hover { + text-decoration: underline; +} +.help-inline, .help-block { + font-size: 13px; + line-height: 18px; + color: #bfbfbf; +} +.help-inline { + padding-left: 5px; + *position: relative; + /* IE6-7 */ + + *top: -5px; + /* IE6-7 */ + +} +.help-block { + display: block; + max-width: 600px; +} +.inline-inputs { + color: #808080; +} +.inline-inputs span { + padding: 0 2px 0 1px; +} +.input-prepend input, .input-append input { + -webkit-border-radius: 0 3px 3px 0; + -moz-border-radius: 0 3px 3px 0; + border-radius: 0 3px 3px 0; +} +.input-prepend .add-on, .input-append .add-on { + position: relative; + background: #f5f5f5; + border: 1px solid #ccc; + z-index: 2; + float: left; + display: block; + width: auto; + min-width: 16px; + height: 18px; + padding: 4px 4px 4px 5px; + margin-right: -1px; + font-weight: normal; + line-height: 18px; + color: #bfbfbf; + text-align: center; + text-shadow: 0 1px 0 #ffffff; + -webkit-border-radius: 3px 0 0 3px; + -moz-border-radius: 3px 0 0 3px; + border-radius: 3px 0 0 3px; +} +.input-prepend .active, .input-append .active { + background: #a9dba9; + border-color: #46a546; +} +.input-prepend .add-on { + *margin-top: 1px; + /* IE6-7 */ + +} +.input-append input { + float: left; + -webkit-border-radius: 3px 0 0 3px; + -moz-border-radius: 3px 0 0 3px; + border-radius: 3px 0 0 3px; +} +.input-append .add-on { + -webkit-border-radius: 0 3px 3px 0; + -moz-border-radius: 0 3px 3px 0; + border-radius: 0 3px 3px 0; + margin-right: 0; + margin-left: -1px; +} +.inputs-list { + margin: 0 0 5px; + width: 100%; +} +.inputs-list li { + display: block; + padding: 0; + width: 100%; +} +.inputs-list label { + display: block; + float: none; + width: auto; + padding: 0; + margin-left: 20px; + line-height: 18px; + text-align: left; + white-space: normal; +} +.inputs-list label strong { + color: #808080; +} +.inputs-list label small { + font-size: 11px; + font-weight: normal; +} +.inputs-list .inputs-list { + margin-left: 25px; + margin-bottom: 10px; + padding-top: 0; +} +.inputs-list:first-child { + padding-top: 6px; +} +.inputs-list li + li { + padding-top: 2px; +} +.inputs-list input[type=radio], .inputs-list input[type=checkbox] { + margin-bottom: 0; + margin-left: -20px; + float: left; +} +.form-stacked { + padding-left: 20px; +} +.form-stacked fieldset { + padding-top: 9px; +} +.form-stacked legend { + padding-left: 0; +} +.form-stacked label { + display: block; + float: none; + width: auto; + font-weight: bold; + text-align: left; + line-height: 20px; + padding-top: 0; +} +.form-stacked .clearfix { + margin-bottom: 9px; +} +.form-stacked .clearfix div.input { + margin-left: 0; +} +.form-stacked .inputs-list { + margin-bottom: 0; +} +.form-stacked .inputs-list li { + padding-top: 0; +} +.form-stacked .inputs-list li label { + font-weight: normal; + padding-top: 0; +} +.form-stacked div.clearfix.error { + padding-top: 10px; + padding-bottom: 10px; + padding-left: 10px; + margin-top: 0; + margin-left: -10px; +} +.form-stacked .actions { + margin-left: -20px; + padding-left: 20px; +} +/* +* Tables.less +* Tables for, you guessed it, tabular data +* ---------------------------------------- */ +table { + width: 100%; + margin-bottom: 18px; + padding: 0; + font-size: 13px; + border-collapse: collapse; +} +table th, table td { + padding: 10px 10px 9px; + line-height: 18px; + text-align: center; +} +table th { + padding-top: 9px; + font-weight: bold; + vertical-align: middle; +} +table td { + vertical-align: top; + /*border-top: 1px solid #ddd;*/ +} +table tbody th { +/* border-top: 1px solid #ddd;*/ + vertical-align: top; +} +.condensed-table th, .condensed-table td { + padding: 5px 5px 4px; +} +.bordered-table { + border: 1px solid #ddd; + border-collapse: separate; + *border-collapse: collapse; + /* IE7, collapse table to remove spacing */ + + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; +} +.bordered-table th + th, .bordered-table td + td, .bordered-table th + td { + border-left: 1px solid #ddd; +} +.bordered-table thead tr:first-child th:first-child, .bordered-table tbody tr:first-child td:first-child { + -webkit-border-radius: 4px 0 0 0; + -moz-border-radius: 4px 0 0 0; + border-radius: 4px 0 0 0; +} +.bordered-table thead tr:first-child th:last-child, .bordered-table tbody tr:first-child td:last-child { + -webkit-border-radius: 0 4px 0 0; + -moz-border-radius: 0 4px 0 0; + border-radius: 0 4px 0 0; +} +.bordered-table tbody tr:last-child td:first-child { + -webkit-border-radius: 0 0 0 4px; + -moz-border-radius: 0 0 0 4px; + border-radius: 0 0 0 4px; +} +.bordered-table tbody tr:last-child td:last-child { + -webkit-border-radius: 0 0 4px 0; + -moz-border-radius: 0 0 4px 0; + border-radius: 0 0 4px 0; +} +table .span1 { + width: 20px; +} +table .span2 { + width: 60px; +} +table .span3 { + width: 100px; +} +table .span4 { + width: 140px; +} +table .span5 { + width: 180px; +} +table .span6 { + width: 220px; +} +table .span7 { + width: 260px; +} +table .span8 { + width: 300px; +} +table .span9 { + width: 340px; +} +table .span10 { + width: 380px; +} +table .span11 { + width: 420px; +} +table .span12 { + width: 460px; +} +table .span13 { + width: 500px; +} +table .span14 { + width: 540px; +} +table .span15 { + width: 580px; +} +table .span16 { + width: 620px; +} +.zebra-striped tbody tr:nth-child(odd) td, .zebra-striped tbody tr:nth-child(odd) th { + background-color: #f9f9f9; +} +.zebra-striped tbody tr:hover td, .zebra-striped tbody tr:hover th { + background-color: #f5f5f5; +} +table .header { + cursor: pointer; +} +table .header:after { + content: ""; + float: right; + margin-top: 7px; + border-width: 0 4px 4px; + border-style: solid; + border-color: #000 transparent; + visibility: hidden; +} +table .headerSortUp, table .headerSortDown { + background-color: rgba(141, 192, 219, 0.25); + text-shadow: 0 1px 1px rgba(255, 255, 255, 0.75); +} +table .header:hover:after { + visibility: visible; +} +table .headerSortDown:after, table .headerSortDown:hover:after { + visibility: visible; + filter: alpha(opacity=60); + -khtml-opacity: 0.6; + -moz-opacity: 0.6; + opacity: 0.6; +} +table .headerSortUp:after { + border-bottom: none; + border-left: 4px solid transparent; + border-right: 4px solid transparent; + border-top: 4px solid #000; + visibility: visible; + -webkit-box-shadow: none; + -moz-box-shadow: none; + box-shadow: none; + filter: alpha(opacity=60); + -khtml-opacity: 0.6; + -moz-opacity: 0.6; + opacity: 0.6; +} +table .blue { + color: #049cdb; + border-bottom-color: #049cdb; +} +table .headerSortUp.blue, table .headerSortDown.blue { + background-color: #ade6fe; +} +table .green { + color: #46a546; + border-bottom-color: #46a546; +} +table .headerSortUp.green, table .headerSortDown.green { + background-color: #cdeacd; +} +table .red { + color: #9d261d; + border-bottom-color: #9d261d; +} +table .headerSortUp.red, table .headerSortDown.red { + background-color: #f4c8c5; +} +table .yellow { + color: #ffc40d; + border-bottom-color: #ffc40d; +} +table .headerSortUp.yellow, table .headerSortDown.yellow { + background-color: #fff6d9; +} +table .orange { + color: #f89406; + border-bottom-color: #f89406; +} +.center1 +{ +margin-left: auto; +margin-right: auto; +} +table .headerSortUp.orange, table .headerSortDown.orange { + background-color: #fee9cc; +} +table .purple { + color: #7a43b6; + border-bottom-color: #7a43b6; +} +table .headerSortUp.purple, table .headerSortDown.purple { + background-color: #e2d5f0; +} +/* Patterns.less +* Repeatable UI elements outside the base styles provided from the scaffolding +* ---------------------------------------------------------------------------- */ +.topbar { + height: 40px; + position: fixed; + top: 0; + left: 0; + right: 0; + z-index: 10000; + overflow: visible; +} +.topbar a { + color: #bfbfbf; + text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); +} +.topbar h3 a:hover, .topbar .brand:hover, .topbar ul .active > a { + background-color: #333; + background-color: rgba(255, 255, 255, 0.05); + color: #ffffff; + text-decoration: none; +} +.topbar h3 { + position: relative; +} +.topbar h3 a, .topbar .brand { + float: left; + display: block; + padding: 8px 20px 12px; + margin-left: -20px; + color: #ffffff; + font-size: 20px; + font-weight: 200; + line-height: 1; +} +.topbar p { + margin: 0; + line-height: 40px; +} +.topbar p a:hover { + background-color: transparent; + color: #ffffff; +} +.topbar form { + float: left; + margin: 5px 0 0 0; + position: relative; + filter: alpha(opacity=100); + -khtml-opacity: 1; + -moz-opacity: 1; + opacity: 1; +} +.topbar form.pull-right { + float: right; +} +.topbar input { + background-color: #444; + background-color: rgba(255, 255, 255, 0.3); + font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; + font-size: normal; + font-weight: 13px; + line-height: 1; + padding: 4px 9px; + color: #ffffff; + color: rgba(255, 255, 255, 0.75); + border: 1px solid #111; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; + -webkit-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1), 0 1px 0px rgba(255, 255, 255, 0.25); + -moz-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1), 0 1px 0px rgba(255, 255, 255, 0.25); + box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1), 0 1px 0px rgba(255, 255, 255, 0.25); + -webkit-transition: none; + -moz-transition: none; + -ms-transition: none; + -o-transition: none; + transition: none; +} +.topbar input:-moz-placeholder { + color: #e6e6e6; +} +.topbar input::-webkit-input-placeholder { + color: #e6e6e6; +} +.topbar input:hover { + background-color: #bfbfbf; + background-color: rgba(255, 255, 255, 0.5); + color: #ffffff; +} +.topbar input:focus, .topbar input.focused { + outline: 0; + background-color: #ffffff; + color: #404040; + text-shadow: 0 1px 0 #ffffff; + border: 0; + padding: 5px 10px; + -webkit-box-shadow: 0 0 3px rgba(0, 0, 0, 0.15); + -moz-box-shadow: 0 0 3px rgba(0, 0, 0, 0.15); + box-shadow: 0 0 3px rgba(0, 0, 0, 0.15); +} +.topbar-inner, .topbar .fill { + background-color: #222; + background-color: #222222; + background-repeat: repeat-x; + background-image: -khtml-gradient(linear, left top, left bottom, from(#333333), to(#222222)); + background-image: -moz-linear-gradient(top, #333333, #222222); + background-image: -ms-linear-gradient(top, #333333, #222222); + background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #333333), color-stop(100%, #222222)); + background-image: -webkit-linear-gradient(top, #333333, #222222); + background-image: -o-linear-gradient(top, #333333, #222222); + background-image: linear-gradient(top, #333333, #222222); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#333333', endColorstr='#222222', GradientType=0); + -webkit-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.25), inset 0 -1px 0 rgba(0, 0, 0, 0.1); + -moz-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.25), inset 0 -1px 0 rgba(0, 0, 0, 0.1); + box-shadow: 0 1px 3px rgba(0, 0, 0, 0.25), inset 0 -1px 0 rgba(0, 0, 0, 0.1); +} +.topbar div > ul, .nav { + display: block; + float: left; + margin: 0 10px 0 0; + position: relative; + left: 0; +} +.topbar div > ul > li, .nav > li { + display: block; + float: left; +} +.topbar div > ul a, .nav a { + display: block; + float: none; + padding: 10px 10px 11px; + line-height: 19px; + text-decoration: none; +} +.topbar div > ul a:hover, .nav a:hover { + color: #ffffff; + text-decoration: none; +} +.topbar div > ul .active > a, .nav .active > a { + background-color: #222; + background-color: rgba(0, 0, 0, 0.5); +} +.topbar div > ul.secondary-nav, .nav.secondary-nav { + float: right; + margin-left: 10px; + margin-right: 0; +} +.topbar div > ul.secondary-nav .menu-dropdown, +.nav.secondary-nav .menu-dropdown, +.topbar div > ul.secondary-nav .dropdown-menu, +.nav.secondary-nav .dropdown-menu { + right: 0; + border: 0; +} +.topbar div > ul a.menu:hover, +.nav a.menu:hover, +.topbar div > ul li.open .menu, +.nav li.open .menu, +.topbar div > ul .dropdown-toggle:hover, +.nav .dropdown-toggle:hover, +.topbar div > ul .dropdown.open .dropdown-toggle, +.nav .dropdown.open .dropdown-toggle { + background: #444; + background: rgba(255, 255, 255, 0.05); +} +.topbar div > ul .menu-dropdown, +.nav .menu-dropdown, +.topbar div > ul .dropdown-menu, +.nav .dropdown-menu { + background-color: #333; +} +.topbar div > ul .menu-dropdown a.menu, +.nav .menu-dropdown a.menu, +.topbar div > ul .dropdown-menu a.menu, +.nav .dropdown-menu a.menu, +.topbar div > ul .menu-dropdown .dropdown-toggle, +.nav .menu-dropdown .dropdown-toggle, +.topbar div > ul .dropdown-menu .dropdown-toggle, +.nav .dropdown-menu .dropdown-toggle { + color: #ffffff; +} +.topbar div > ul .menu-dropdown a.menu.open, +.nav .menu-dropdown a.menu.open, +.topbar div > ul .dropdown-menu a.menu.open, +.nav .dropdown-menu a.menu.open, +.topbar div > ul .menu-dropdown .dropdown-toggle.open, +.nav .menu-dropdown .dropdown-toggle.open, +.topbar div > ul .dropdown-menu .dropdown-toggle.open, +.nav .dropdown-menu .dropdown-toggle.open { + background: #444; + background: rgba(255, 255, 255, 0.05); +} +.topbar div > ul .menu-dropdown li a, +.nav .menu-dropdown li a, +.topbar div > ul .dropdown-menu li a, +.nav .dropdown-menu li a { + color: #999; + text-shadow: 0 1px 0 rgba(0, 0, 0, 0.5); +} +.topbar div > ul .menu-dropdown li a:hover, +.nav .menu-dropdown li a:hover, +.topbar div > ul .dropdown-menu li a:hover, +.nav .dropdown-menu li a:hover { + background-color: #191919; + background-repeat: repeat-x; + background-image: -khtml-gradient(linear, left top, left bottom, from(#292929), to(#191919)); + background-image: -moz-linear-gradient(top, #292929, #191919); + background-image: -ms-linear-gradient(top, #292929, #191919); + background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #292929), color-stop(100%, #191919)); + background-image: -webkit-linear-gradient(top, #292929, #191919); + background-image: -o-linear-gradient(top, #292929, #191919); + background-image: linear-gradient(top, #292929, #191919); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#292929', endColorstr='#191919', GradientType=0); + color: #ffffff; +} +.topbar div > ul .menu-dropdown .active a, +.nav .menu-dropdown .active a, +.topbar div > ul .dropdown-menu .active a, +.nav .dropdown-menu .active a { + color: #ffffff; +} +.topbar div > ul .menu-dropdown .divider, +.nav .menu-dropdown .divider, +.topbar div > ul .dropdown-menu .divider, +.nav .dropdown-menu .divider { + background-color: #222; + border-color: #444; +} +.topbar ul .menu-dropdown li a, .topbar ul .dropdown-menu li a { + padding: 4px 15px; +} +li.menu, .dropdown { + position: relative; +} +a.menu:after, .dropdown-toggle:after { + width: 0; + height: 0; + display: inline-block; + content: "↓"; + text-indent: -99999px; + vertical-align: top; + margin-top: 8px; + margin-left: 4px; + border-left: 4px solid transparent; + border-right: 4px solid transparent; + border-top: 4px solid #ffffff; + filter: alpha(opacity=50); + -khtml-opacity: 0.5; + -moz-opacity: 0.5; + opacity: 0.5; +} +.menu-dropdown, .dropdown-menu { + background-color: #ffffff; + float: left; + display: none; + position: absolute; + top: 40px; + z-index: 900; + min-width: 160px; + max-width: 220px; + _width: 160px; + margin-left: 0; + margin-right: 0; + padding: 6px 0; + zoom: 1; + border-color: #999; + border-color: rgba(0, 0, 0, 0.2); + border-style: solid; + border-width: 0 1px 1px; + -webkit-border-radius: 0 0 6px 6px; + -moz-border-radius: 0 0 6px 6px; + border-radius: 0 0 6px 6px; + -webkit-box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2); + -moz-box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2); + box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2); + -webkit-background-clip: padding-box; + -moz-background-clip: padding-box; + background-clip: padding-box; +} +.menu-dropdown li, .dropdown-menu li { + float: none; + display: block; + background-color: none; +} +.menu-dropdown .divider, .dropdown-menu .divider { + height: 1px; + margin: 5px 0; + overflow: hidden; + background-color: #eee; + border-bottom: 1px solid #ffffff; +} +.topbar .dropdown-menu a, .dropdown-menu a { + display: block; + padding: 4px 15px; + clear: both; + font-weight: normal; + line-height: 18px; + color: #808080; + text-shadow: 0 1px 0 #ffffff; +} +.topbar .dropdown-menu a:hover, +.dropdown-menu a:hover, +.topbar .dropdown-menu a.hover, +.dropdown-menu a.hover { + background-color: #dddddd; + background-repeat: repeat-x; + background-image: -khtml-gradient(linear, left top, left bottom, from(#eeeeee), to(#dddddd)); + background-image: -moz-linear-gradient(top, #eeeeee, #dddddd); + background-image: -ms-linear-gradient(top, #eeeeee, #dddddd); + background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #eeeeee), color-stop(100%, #dddddd)); + background-image: -webkit-linear-gradient(top, #eeeeee, #dddddd); + background-image: -o-linear-gradient(top, #eeeeee, #dddddd); + background-image: linear-gradient(top, #eeeeee, #dddddd); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#eeeeee', endColorstr='#dddddd', GradientType=0); + color: #404040; + text-decoration: none; + -webkit-box-shadow: inset 0 1px 0 rgba(0, 0, 0, 0.025), inset 0 -1px rgba(0, 0, 0, 0.025); + -moz-box-shadow: inset 0 1px 0 rgba(0, 0, 0, 0.025), inset 0 -1px rgba(0, 0, 0, 0.025); + box-shadow: inset 0 1px 0 rgba(0, 0, 0, 0.025), inset 0 -1px rgba(0, 0, 0, 0.025); +} +footer { + margin-top: 17px; + padding-top: 17px; +} +.page-header { + margin-bottom: 17px; + border-bottom: 1px solid #ddd; + -webkit-box-shadow: 0 1px 0 rgba(255, 255, 255, 0.5); + -moz-box-shadow: 0 1px 0 rgba(255, 255, 255, 0.5); + box-shadow: 0 1px 0 rgba(255, 255, 255, 0.5); +} +.page-header h3 { + margin-top: 20px; + margin-bottom : -17px; +} +.btn.danger, +.alert-message.danger, +.btn.danger:hover, +.alert-message.danger:hover, +.btn.error, +.alert-message.error, +.btn.error:hover, +.alert-message.error:hover, +.btn.success, +.alert-message.success, +.btn.success:hover, +.alert-message.success:hover, +.btn.info, +.alert-message.info, +.btn.info:hover, +.alert-message.info:hover { + color: #ffffff; +} +.btn .close, .alert-message .close { + font-family: Arial, sans-serif; + line-height: 18px; +} +.btn-mini { + padding: 2px 6px; + font-size: 15px; + line-height: 16px; +} +.btn.danger, +.alert-message.danger, +.btn.error, +.alert-message.error { + background-color: #c43c35; + background-repeat: repeat-x; + background-image: -khtml-gradient(linear, left top, left bottom, from(#ee5f5b), to(#c43c35)); + background-image: -moz-linear-gradient(top, #ee5f5b, #c43c35); + background-image: -ms-linear-gradient(top, #ee5f5b, #c43c35); + background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #ee5f5b), color-stop(100%, #c43c35)); + background-image: -webkit-linear-gradient(top, #ee5f5b, #c43c35); + background-image: -o-linear-gradient(top, #ee5f5b, #c43c35); + background-image: linear-gradient(top, #ee5f5b, #c43c35); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ee5f5b', endColorstr='#c43c35', GradientType=0); + text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); + border-color: #c43c35 #c43c35 #882a25; + border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); +} +.btn.success, .alert-message.success { + background-color: #57a957; + background-repeat: repeat-x; + background-image: -khtml-gradient(linear, left top, left bottom, from(#62c462), to(#57a957)); + background-image: -moz-linear-gradient(top, #62c462, #57a957); + background-image: -ms-linear-gradient(top, #62c462, #57a957); + background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #62c462), color-stop(100%, #57a957)); + background-image: -webkit-linear-gradient(top, #62c462, #57a957); + background-image: -o-linear-gradient(top, #62c462, #57a957); + background-image: linear-gradient(top, #62c462, #57a957); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#62c462', endColorstr='#57a957', GradientType=0); + text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); + border-color: #57a957 #57a957 #3d773d; + border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); +} +.btn.info, .alert-message.info { + background-color: #339bb9; + background-repeat: repeat-x; + background-image: -khtml-gradient(linear, left top, left bottom, from(#5bc0de), to(#339bb9)); + background-image: -moz-linear-gradient(top, #5bc0de, #339bb9); + background-image: -ms-linear-gradient(top, #5bc0de, #339bb9); + background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #5bc0de), color-stop(100%, #339bb9)); + background-image: -webkit-linear-gradient(top, #5bc0de, #339bb9); + background-image: -o-linear-gradient(top, #5bc0de, #339bb9); + background-image: linear-gradient(top, #5bc0de, #339bb9); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#5bc0de', endColorstr='#339bb9', GradientType=0); + text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); + border-color: #339bb9 #339bb9 #22697d; + border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); +} +.btn { + cursor: pointer; + display: inline-block; + background-color: #e6e6e6; + background-repeat: no-repeat; + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#ffffff), color-stop(25%, #ffffff), to(#e6e6e6)); + background-image: -webkit-linear-gradient(#ffffff, #ffffff 25%, #e6e6e6); + background-image: -moz-linear-gradient(top, #ffffff, #ffffff 25%, #e6e6e6); + background-image: -ms-linear-gradient(#ffffff, #ffffff 25%, #e6e6e6); + background-image: -o-linear-gradient(#ffffff, #ffffff 25%, #e6e6e6); + background-image: linear-gradient(#ffffff, #ffffff 25%, #e6e6e6); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffff', endColorstr='#e6e6e6', GradientType=0); + padding: 5px 14px 6px; + text-shadow: 0 1px 1px rgba(255, 255, 255, 0.75); + color: #333; + font-size: 13px; + line-height: normal; + border: 1px solid #ccc; + border-bottom-color: #bbb; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; + -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05); + -moz-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05); + box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05); + -webkit-transition: 0.1s linear all; + -moz-transition: 0.1s linear all; + -ms-transition: 0.1s linear all; + -o-transition: 0.1s linear all; + transition: 0.1s linear all; +} +.btn:hover { + background-position: 0 -15px; + color: #333; + text-decoration: none; +} +.btn:focus { + outline: 1px dotted #666; +} +.btn.primary { + color: #ffffff; + background-color: #0064cd; + background-repeat: repeat-x; + background-image: -khtml-gradient(linear, left top, left bottom, from(#049cdb), to(#0064cd)); + background-image: -moz-linear-gradient(top, #049cdb, #0064cd); + background-image: -ms-linear-gradient(top, #049cdb, #0064cd); + background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #049cdb), color-stop(100%, #0064cd)); + background-image: -webkit-linear-gradient(top, #049cdb, #0064cd); + background-image: -o-linear-gradient(top, #049cdb, #0064cd); + background-image: linear-gradient(top, #049cdb, #0064cd); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#049cdb', endColorstr='#0064cd', GradientType=0); + text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); + border-color: #0064cd #0064cd #003f81; + border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); +} +.btn.active, .btn:active { + -webkit-box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.25), 0 1px 2px rgba(0, 0, 0, 0.05); + -moz-box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.25), 0 1px 2px rgba(0, 0, 0, 0.05); + box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.25), 0 1px 2px rgba(0, 0, 0, 0.05); +} +.btn.disabled { + cursor: default; + background-image: none; + filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); + filter: alpha(opacity=65); + -khtml-opacity: 0.65; + -moz-opacity: 0.65; + opacity: 0.65; + -webkit-box-shadow: none; + -moz-box-shadow: none; + box-shadow: none; +} +.btn[disabled] { + cursor: default; + background-image: none; + filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); + filter: alpha(opacity=65); + -khtml-opacity: 0.65; + -moz-opacity: 0.65; + opacity: 0.65; + -webkit-box-shadow: none; + -moz-box-shadow: none; + box-shadow: none; +} +.btn.large { + font-size: 15px; + line-height: normal; + padding: 9px 14px 9px; + -webkit-border-radius: 6px; + -moz-border-radius: 6px; + border-radius: 6px; +} +.btn.small { + padding: 7px 9px 7px; + font-size: 11px; +} +:root .alert-message, :root .btn { + border-radius: 0 \0; +} +.alert { + padding: 8px 35px 8px 14px; + margin-bottom: 18px; + text-shadow: 0 1px 0 rgba(255, 255, 255, 0.5); + background-color: #fcf8e3; + border: 1px solid #fbeed5; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; +} +.alert, .alert-heading { + color: #c09853; +} +.alert .close { + position: relative; + top: -2px; + right: -21px; + line-height: 18px; +} +.alert-success { + background-color: #dff0d8; + border-color: #d6e9c6; +} +.alert-success, .alert-success .alert-heading { + color: #468847; +} +.alert-danger, .alert-error { + background-color: #f2dede; + border-color: #eed3d7; +} +.alert-danger, +.alert-error, +.alert-danger .alert-heading, +.alert-error .alert-heading { + color: #b94a48; +} +.alert-info { + background-color: #d9edf7; + border-color: #bce8f1; +} +.alert-info, .alert-info .alert-heading { + color: #3a87ad; +} +.alert-block { + padding-top: 14px; + padding-bottom: 14px; +} +.alert-block > p, .alert-block > ul { + margin-bottom: 0; +} +.alert-block p + p { + margin-top: 5px; +} + +button.btn::-moz-focus-inner, input[type=submit].btn::-moz-focus-inner { + padding: 0; + border: 0; +} +.alert-message { + position: relative; + padding: 7px 15px; + margin-bottom: 18px; + color: #404040; + background-color: #eedc94; + background-repeat: repeat-x; + background-image: -khtml-gradient(linear, left top, left bottom, from(#fceec1), to(#eedc94)); + background-image: -moz-linear-gradient(top, #fceec1, #eedc94); + background-image: -ms-linear-gradient(top, #fceec1, #eedc94); + background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #fceec1), color-stop(100%, #eedc94)); + background-image: -webkit-linear-gradient(top, #fceec1, #eedc94); + background-image: -o-linear-gradient(top, #fceec1, #eedc94); + background-image: linear-gradient(top, #fceec1, #eedc94); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fceec1', endColorstr='#eedc94', GradientType=0); + text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); + border-color: #eedc94 #eedc94 #e4c652; + border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); + text-shadow: 0 1px 0 rgba(255, 255, 255, 0.5); + border-width: 1px; + border-style: solid; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; + -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.25); + -moz-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.25); + box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.25); +} +.alert-message .close { + margin-top: 1px; + *margin-top: 0; +} +.alert-message a { + font-weight: bold; + color: #404040; +} +.alert-message.danger p a, +.alert-message.error p a, +.alert-message.success p a, +.alert-message.info p a { + color: #ffffff; +} +.alert-message h5 { + line-height: 18px; +} +.alert-message p { + margin-bottom: 0; +} +.alert-message div { + margin-top: 5px; + margin-bottom: 2px; + line-height: 28px; +} +.alert-message .btn { + -webkit-box-shadow: 0 1px 0 rgba(255, 255, 255, 0.25); + -moz-box-shadow: 0 1px 0 rgba(255, 255, 255, 0.25); + box-shadow: 0 1px 0 rgba(255, 255, 255, 0.25); +} +.alert-message.block-message { + background-image: none; + background-color: #fdf5d9; + filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); + padding: 14px; + border-color: #fceec1; + -webkit-box-shadow: none; + -moz-box-shadow: none; + box-shadow: none; +} +.alert-message.block-message ul, .alert-message.block-message p { + margin-right: 30px; +} +.alert-message.block-message ul { + margin-bottom: 0; +} +.alert-message.block-message li { + color: #404040; +} +.alert-message.block-message .alert-actions { + margin-top: 5px; +} +.alert-message.block-message.error, .alert-message.block-message.success, .alert-message.block-message.info { + color: #404040; + text-shadow: 0 1px 0 rgba(255, 255, 255, 0.5); +} +.alert-message.block-message.error { + background-color: #fddfde; + border-color: #fbc7c6; +} +.alert-message.block-message.success { + background-color: #d1eed1; + border-color: #bfe7bf; +} +.alert-message.block-message.info { + background-color: #ddf4fb; + border-color: #c6edf9; +} +.alert-message.block-message.danger p a, +.alert-message.block-message.error p a, +.alert-message.block-message.success p a, +.alert-message.block-message.info p a { + color: #404040; +} +.label { + padding: 1px 3px 2px; + font-size: 9.75px; + font-weight: bold; + color: #ffffff; + text-transform: uppercase; + white-space: nowrap; + background-color: #bfbfbf; + -webkit-border-radius: 3px; + -moz-border-radius: 3px; + border-radius: 3px; + text-shadow: none; +} +.label.important { + background-color: #c43c35; +} +.label.warning { + background-color: #f89406; +} +.label.success { + background-color: #46a546; +} +.label.notice { + background-color: #62cffc; +} +.well { + background-color: #f5f5f5; + margin-bottom: 20px; + padding: 19px; + min-height: 20px; + border: 1px solid #eee; + border: 1px solid rgba(0, 0, 0, 0.05); + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.05); + -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.05); + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.05); +} +.well blockquote { + border-color: #ddd; + border-color: rgba(0, 0, 0, 0.15); +} +.modal-backdrop { + background-color: #000000; + position: fixed; + top: 0; + left: 0; + right: 0; + bottom: 0; + z-index: 10000; +} +.modal-backdrop.fade { + opacity: 0; +} +.modal-backdrop, .modal-backdrop.fade.in { + filter: alpha(opacity=80); + -khtml-opacity: 0.8; + -moz-opacity: 0.8; + opacity: 0.8; +} +.modal { + position: fixed; + top: 10%; + left: 50%; + z-index: 1050; + width: 560px; + margin-left: -280px; + background-color: #ffffff; + border: 1px solid #999; + border: 1px solid rgba(0, 0, 0, 0.3); + *border: 1px solid #999; + -webkit-border-radius: 6px; + -moz-border-radius: 6px; + border-radius: 6px; + outline: none; + -webkit-box-shadow: 0 3px 7px rgba(0, 0, 0, 0.3); + -moz-box-shadow: 0 3px 7px rgba(0, 0, 0, 0.3); + box-shadow: 0 3px 7px rgba(0, 0, 0, 0.3); + -webkit-background-clip: padding-box; + -moz-background-clip: padding-box; + background-clip: padding-box; +} +.modal.fade { + top: -25%; + -webkit-transition: opacity 0.3s linear, top 0.3s ease-out; + -moz-transition: opacity 0.3s linear, top 0.3s ease-out; + -o-transition: opacity 0.3s linear, top 0.3s ease-out; + transition: opacity 0.3s linear, top 0.3s ease-out; +} + +.modal.fade.in { + top: 10%; +} + +.modal-header { + padding: 9px 15px; + border-bottom: 1px solid #eee; +} + +.modal-header .close { + margin-top: 2px; +} + +.modal-header h3 { + margin: 0; + line-height: 30px; +} + +.modal-body { + position: relative; + max-height: 400px; + padding: 15px; + overflow-y: auto; +} + +.modal-form { + margin-bottom: 0; +} + +.modal-footer { + padding: 14px 15px 15px; + margin-bottom: 0; + text-align: right; + background-color: #f5f5f5; + border-top: 1px solid #ddd; + -webkit-border-radius: 0 0 6px 6px; + -moz-border-radius: 0 0 6px 6px; + border-radius: 0 0 6px 6px; + *zoom: 1; + -webkit-box-shadow: inset 0 1px 0 #ffffff; + -moz-box-shadow: inset 0 1px 0 #ffffff; + box-shadow: inset 0 1px 0 #ffffff; +} + +.modal-footer:before, +.modal-footer:after { + display: table; + line-height: 0; + content: ""; +} + +.modal-footer:after { + clear: both; +} + +.modal-footer .btn + .btn { + margin-bottom: 0; + margin-left: 5px; +} + +.modal-footer .btn-group .btn + .btn { + margin-left: -1px; +} + +.modal-footer .btn-block + .btn-block { + margin-left: 0; +} +.tabs, .pills { + margin: 0 0 18px; + padding: 0; + list-style: none; + zoom: 1; +} +.tabs:before, +.pills:before, +.tabs:after, +.pills:after { + display: table; + content: ""; + zoom: 1; +} +.tabs:after, .pills:after { + clear: both; +} +.tabs > li, .pills > li { + float: left; +} +.tabs > li > a, .pills > li > a { + display: block; +} +.tabs { + border-color: #ddd; + border-style: solid; + border-width: 0 0 1px; +} +.tabs > li { + position: relative; + margin-bottom: -1px; +} +.tabs > li > a { + padding: 0 15px; + margin-right: 2px; + line-height: 23px; + border: 1px solid transparent; + -webkit-border-radius: 4px 4px 0 0; + -moz-border-radius: 4px 4px 0 0; + border-radius: 4px 4px 0 0; +} +.tabs > li > a:hover { + text-decoration: none; + background-color: #eee; + border-color: #eee #eee #ddd; +} +.tabs .active > a, .tabs .active > a:hover { + color: #808080; + background-color: #ffffff; + border: 1px solid #ddd; + border-bottom-color: transparent; + cursor: default; +} +.tabs .menu-dropdown, .tabs .dropdown-menu { + top: 35px; + border-width: 1px; + -webkit-border-radius: 0 6px 6px 6px; + -moz-border-radius: 0 6px 6px 6px; + border-radius: 0 6px 6px 6px; +} +.tabs a.menu:after, .tabs .dropdown-toggle:after { + border-top-color: #999; + margin-top: 15px; + margin-left: 5px; +} +.tabs li.open.menu .menu, .tabs .open.dropdown .dropdown-toggle { + border-color: #999; +} +.tabs li.open a.menu:after, .tabs .dropdown.open .dropdown-toggle:after { + border-top-color: #555; +} +.pills a { + margin: 5px 3px 5px 0; + padding: 0 15px; + line-height: 30px; + text-shadow: 0 1px 1px #ffffff; + -webkit-border-radius: 15px; + -moz-border-radius: 15px; + border-radius: 15px; +} +.pills a:hover { + color: #ffffff; + text-decoration: none; + text-shadow: 0 1px 1px rgba(0, 0, 0, 0.25); + background-color: #00438a; +} +.pills .active a { + color: #ffffff; + text-shadow: 0 1px 1px rgba(0, 0, 0, 0.25); + background-color: #0069d6; +} +.pills-vertical > li { + float: none; +} +.tab-content > .tab-pane, .pill-content > .pill-pane { + display: none; +} +.tab-content > .active, .pill-content > .active { + display: block; +} diff --git a/testapp/exam/static/exam/css/gradeuser.css b/testapp/exam/static/exam/css/gradeuser.css new file mode 100644 index 0000000..07b1079 --- /dev/null +++ b/testapp/exam/static/exam/css/gradeuser.css @@ -0,0 +1,52 @@ +textarea +{ +width : 550px; +height : 200px; + +} + +.for-question{ + background: none repeat scroll 0 0 #F1F1F1; + border-radius: 6px 6px 6px 6px; + margin-bottom: 10px; + padding: 5px; +} + +#headerDiv, #contentDiv { +float: left; +} +#titleText { +float: left; +font-size: 1.1em; +font-weight: bold; +margin: 5px; +} +#myHeader { +font-size: 1.1em; +font-weight: bold; +margin: 5px; +} +#headerDiv { +background-color: #0037DB; +color: #9EB6FF; +} + +#contentDiv { + background-color:#F0F8FF; + border: 1px solid #C9C9C9; + border-radius: 5px 5px 5px 5px; + margin-bottom: 10px; + min-width: 805px; + +} + +#myContent { +margin: 5px 10px; + +} +#headerDiv a { +float: right; +margin: 10px 10px 5px 5px; +} +#headerDiv a:hover { +color: #FFFFFF; diff --git a/testapp/exam/static/exam/css/login.css b/testapp/exam/static/exam/css/login.css new file mode 100644 index 0000000..a10cbaa --- /dev/null +++ b/testapp/exam/static/exam/css/login.css @@ -0,0 +1,10 @@ +label +{ + padding-top: 6px; + font-size: 15px; + line-height: 18px; + float: left; + width: 80px; + text-align: center; + color: #404040; + } diff --git a/testapp/exam/static/exam/css/monitor.css b/testapp/exam/static/exam/css/monitor.css new file mode 100644 index 0000000..b16c8b3 --- /dev/null +++ b/testapp/exam/static/exam/css/monitor.css @@ -0,0 +1,11 @@ + table td + { + vertical-align: top; + border-top: 1px solid #ddd; + } + table tbody th + { + border-top: 1px solid #ddd; + vertical-align: top; + } + diff --git a/testapp/exam/static/exam/css/question.css b/testapp/exam/static/exam/css/question.css new file mode 100644 index 0000000..4bf5913 --- /dev/null +++ b/testapp/exam/static/exam/css/question.css @@ -0,0 +1,42 @@ +.time-div +{ + background-color:black; + padding: 8px; + color: #5DFC0A; + vertical-align:middle; + width:150px; + float:right; + border-radius: 6px 6px 6px 6px; +} +.td1-class +{ + width:175px; +} +.td2-class +{ + width:50px; +} +.page-header { + height:50px; + text-align: center; + background-color: #f5f5f5; + padding: 35px 20px 10px; + margin: -20px -20px 20px; +} +#codeTextarea{ + + } + .textAreaWithLines{ + font-family:courier; + border:1px solid #eee; + + } + .textAreaWithLines textarea,.textAreaWithLines div{ + border:0px; + line-height:120%; + font-size:12px; + } + .lineObj{ + color: grey; + } + diff --git a/testapp/exam/static/exam/css/question_paper_creation.css b/testapp/exam/static/exam/css/question_paper_creation.css new file mode 100644 index 0000000..c915320 --- /dev/null +++ b/testapp/exam/static/exam/css/question_paper_creation.css @@ -0,0 +1,119 @@ +body { + font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; + font-size: 13px; + font-weight: normal; + line-height: 18px; + color: #404040; +} +.clearfix { + clear: both; +} +.tabs li { + text-align: center; + width: 33%; +} +.tabs li:last-child { + width: 34%; +} +.tabs > .active > a { + border: 0; + background: lightgreen; +} +.tabs > .active > a:hover { + border: 0; + background: green; + color: #ffffff; +} +.tabs li a { + border-radius: 0; + margin-right: 0; +} +.tabs { + border: 1px solid #ddd; +} +#progress { + background: red; +} +#content-left{ + text-align: center; + background: grey; +} +#content-right{ + text-align: center; + background: grey; +} +#selectors { + margin-left: 0; + background: #fafafa; + padding: 7px 0; + border: 2px solid #f5f5f5; +} +#selectors .span4 { + margin-left: 0; +} +#id_question_type { + width: 100%; +} +#id_marks { + width: 100%; +} +#fixed-questions .span7 > div, +#random-questions .span7 > div{ + background: #f5f5f5; + height: 200px; + border: 1px solid #333333; + padding: 5px; +} +#fixed-available, +#random-available { + height: 125px; + min-height: 125px; + overflow-y: scroll; + margin-bottom: 15px; +} +#fixed-added, +#random-added { + height: 160px; + overflow-y: scroll; +} +#fixed-added hr, +#random-added hr { + margin: 5px 0 4px; +} +.qcard { + position: relative; + background: #ffffff; + padding: 5px; + margin: 5px 5px; + box-shadow: 1px 1px 5px #cccccc; + -webkit-box-shadow: 1px 1px 5px #cccccc; + -moz-box-shadow: 1px 1px 5px #cccccc; + -o-box-shadow: 1px 1px 5px #cccccc; +} +.qcard ul { + margin-bottom: 5px; +} +.qcard .remove { + position: absolute; + + top: 3px; + right: 3px; + padding: 1px 3px; + text-decoration: none; + color: #ffffff; + background: #ff4136; + border-radius: 3px; + font-weight: bold; +} +.qcard .remove:hover { + background: #333333; +} +.red-alert { + border: 2px solid red; +} +#myModal .qcard .remove{ + display: none; +} +.well{ + padding: 5px; +} diff --git a/testapp/exam/static/exam/css/question_quiz.css b/testapp/exam/static/exam/css/question_quiz.css new file mode 100644 index 0000000..b702bd4 --- /dev/null +++ b/testapp/exam/static/exam/css/question_quiz.css @@ -0,0 +1,18 @@ +table th, table td + { + text-align: left; + } + +.mini-text +{ + height : 9px; + width : 30px; +} +.select-type +{ + width : 80px; +} +.tag-text +{ + width : 290px; +} diff --git a/testapp/exam/static/exam/css/showusers.css b/testapp/exam/static/exam/css/showusers.css new file mode 100644 index 0000000..66a3746 --- /dev/null +++ b/testapp/exam/static/exam/css/showusers.css @@ -0,0 +1,5 @@ +.table-class +{ + text-align:left; + width:60%; +} diff --git a/testapp/exam/static/exam/js/add_question.js b/testapp/exam/static/exam/js/add_question.js new file mode 100644 index 0000000..267cdb2 --- /dev/null +++ b/testapp/exam/static/exam/js/add_question.js @@ -0,0 +1,206 @@ +function increase(frm) +{ + if(frm.points.value == "") + { + frm.points.value = "0.5"; + return; + } + frm.points.value = parseFloat(frm.points.value) + 0.5; +} + +function decrease(frm) +{ + if(frm.points.value > 0) + { + frm.points.value = parseFloat(frm.points.value) - 0.5; + } + else + { + frm.points.value=0; + } + + +} + +function setSelectionRange(input, selectionStart, selectionEnd) +{ + if (input.setSelectionRange) + { + input.focus(); + input.setSelectionRange(selectionStart, selectionEnd); + } + else if (input.createTextRange) + { + var range = input.createTextRange(); + range.collapse(true); + range.moveEnd('character', selectionEnd); + range.moveStart('character', selectionStart); + range.select(); + } +} + +function replaceSelection (input, replaceString) +{ + if (input.setSelectionRange) + { + var selectionStart = input.selectionStart; + var selectionEnd = input.selectionEnd; + input.value = input.value.substring(0, selectionStart)+ replaceString + input.value.substring(selectionEnd); + if (selectionStart != selectionEnd) + { + setSelectionRange(input, selectionStart, selectionStart + replaceString.length); + } + else + { + setSelectionRange(input, selectionStart + replaceString.length, selectionStart + replaceString.length); + } + } + else if (document.selection) + { + var range = document.selection.createRange(); + if (range.parentElement() == input) + { + var isCollapsed = range.text == ''; + range.text = replaceString; + if (!isCollapsed) + { + range.moveStart('character', -replaceString.length); + range.select(); + } + } + } +} + +function textareaformat() +{ + document.getElementById('id_type').setAttribute('class','select-type'); + document.getElementById('id_points').setAttribute('class','mini-text'); + document.getElementById('id_tags').setAttribute('class','tag-text'); + + + $('#id_snippet').bind('keydown', function( event ){ + if(navigator.userAgent.match("Gecko")) + { + c=event.which; + } + else + { + c=event.keyCode; + } + if(c==9) + { + replaceSelection(document.getElementById('id_snippet'),String.fromCharCode(9)); + setTimeout(document.getElementById('id_snippet'),0); + return false; + } + }); + + $('#id_description').bind('focus', function( event ){ + document.getElementById("id_description").rows=5; + document.getElementById("id_description").cols=40; + }); + + $('#id_description').bind('blur', function( event ){ + document.getElementById("id_description").rows=1; + document.getElementById("id_description").cols=40; + }); + + $('#id_description').bind('keypress', function (event){ + document.getElementById('my').innerHTML = document.getElementById('id_description').value ; + }); + + $('#id_test').bind('focus', function( event ){ + document.getElementById("id_test").rows=5; + document.getElementById("id_test").cols=40; + }); + + $('#id_test').bind('blur', function( event ){ + document.getElementById("id_test").rows=1; + document.getElementById("id_test").cols=40; + }); + + $('#id_options').bind('focus', function( event ){ + document.getElementById("id_options").rows=5; + document.getElementById("id_options").cols=40; + }); + $('#id_options').bind('blur', function( event ){ + document.getElementById("id_options").rows=1; + document.getElementById("id_options").cols=40; + }); + + $('#id_snippet').bind('focus', function( event ){ + document.getElementById("id_snippet").rows=5; + document.getElementById("id_snippet").cols=40; + }); + $('#id_snippet').bind('blur', function( event ){ + document.getElementById("id_snippet").rows=1; + document.getElementById("id_snippet").cols=40; + }); + + + $('#id_type').bind('focus', function(event){ + var type = document.getElementById('id_type'); + type.style.border = '1px solid #ccc'; + }); + + $('#id_language').bind('focus', function(event){ + var language = document.getElementById('id_language'); + language.style.border = '1px solid #ccc'; + }); + + $('#id_type').bind('change',function(event){ + var value = document.getElementById('id_type').value; + if(value == 'mcq' || value == 'mcc') + { + document.getElementById('id_options').style.visibility='visible'; + document.getElementById('label_option').innerHTML="Options :" + + } + else + { + document.getElementById('id_options').style.visibility='hidden'; + document.getElementById('label_option').innerHTML = ""; + } + }); + document.getElementById('my').innerHTML = document.getElementById('id_description').value ; + var value = document.getElementById('id_type').value; + if(value == 'mcq' || value == 'mcc') + { + document.getElementById('id_options').style.visibility='visible'; + document.getElementById('label_option').innerHTML="Options :" + + } + else + { + document.getElementById('id_options').style.visibility='hidden'; + document.getElementById('label_option').innerHTML = ""; + } +} + +function autosubmit() +{ + var language = document.getElementById('id_language'); + if(language.value == 'select') + { + language.style.border="solid red"; + return false; + } + var type = document.getElementById('id_type'); + if(type.value == 'select') + { + type.style.border = 'solid red'; + return false; + } + + if (type.value == 'mcq' || type.value == 'mcc') + { + var value = document.getElementById('id_options').value; + if(value.split('\n').length < 4) + { + alert("Please Enter 4 options. One option per line."); + return false; + } + return true; + } + +} diff --git a/testapp/exam/static/exam/js/add_questionpaper.js b/testapp/exam/static/exam/js/add_questionpaper.js new file mode 100644 index 0000000..6185dd5 --- /dev/null +++ b/testapp/exam/static/exam/js/add_questionpaper.js @@ -0,0 +1,25 @@ +function load_data() +{ + var url_root = document.getElementById('url_root').value; + var value = document.getElementById('mode').value; + var pathArray = window.location.pathname.split( '/' ); + length = pathArray.length; + var digit = parseInt(pathArray[length-2]); + + if (! isNaN(digit) && value == 'Automatic') + { + window.location = url_root + "/exam/manage/designquestionpaper/automatic/" + digit; + } + else if(!isNaN(digit) && value == 'Manual') + { + window.location = url_root + "/exam/manage/designquestionpaper/manual/" + digit; + } + else if(value == 'Automatic') + { + window.location = window.location.pathname + "automatic"; + } + else if( value == 'Manual') + { + window.location = window.location.pathname + "manual"; + } +} diff --git a/testapp/exam/static/exam/js/add_quiz.js b/testapp/exam/static/exam/js/add_quiz.js new file mode 100644 index 0000000..d5688a8 --- /dev/null +++ b/testapp/exam/static/exam/js/add_quiz.js @@ -0,0 +1,7 @@ +function test() +{ + if (document.getElementById("id_description").value != "") + { + document.getElementById("submit").innerHTML = "Save"; + } +} diff --git a/testapp/exam/static/exam/js/bootstrap-modal.js b/testapp/exam/static/exam/js/bootstrap-modal.js new file mode 100644 index 0000000..b328217 --- /dev/null +++ b/testapp/exam/static/exam/js/bootstrap-modal.js @@ -0,0 +1,260 @@ +/* ========================================================= + * bootstrap-modal.js v1.4.0 + * http://twitter.github.com/bootstrap/javascript.html#modal + * ========================================================= + * Copyright 2011 Twitter, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ========================================================= */ + + +!function( $ ){ + + "use strict" + + /* CSS TRANSITION SUPPORT (https://gist.github.com/373874) + * ======================================================= */ + + var transitionEnd + + $(document).ready(function () { + + $.support.transition = (function () { + var thisBody = document.body || document.documentElement + , thisStyle = thisBody.style + , support = thisStyle.transition !== undefined || thisStyle.WebkitTransition !== undefined || thisStyle.MozTransition !== undefined || thisStyle.MsTransition !== undefined || thisStyle.OTransition !== undefined + return support + })() + + // set CSS transition event type + if ( $.support.transition ) { + transitionEnd = "TransitionEnd" + if ( $.browser.webkit ) { + transitionEnd = "webkitTransitionEnd" + } else if ( $.browser.mozilla ) { + transitionEnd = "transitionend" + } else if ( $.browser.opera ) { + transitionEnd = "oTransitionEnd" + } + } + + }) + + + /* MODAL PUBLIC CLASS DEFINITION + * ============================= */ + + var Modal = function ( content, options ) { + this.settings = $.extend({}, $.fn.modal.defaults, options) + this.$element = $(content) + .delegate('.close', 'click.modal', $.proxy(this.hide, this)) + + if ( this.settings.show ) { + this.show() + } + + return this + } + + Modal.prototype = { + + toggle: function () { + return this[!this.isShown ? 'show' : 'hide']() + } + + , show: function () { + var that = this + this.isShown = true + this.$element.trigger('show') + + escape.call(this) + backdrop.call(this, function () { + var transition = $.support.transition && that.$element.hasClass('fade') + + that.$element + .appendTo(document.body) + .show() + + if (transition) { + that.$element[0].offsetWidth // force reflow + } + + that.$element.addClass('in') + + transition ? + that.$element.one(transitionEnd, function () { that.$element.trigger('shown') }) : + that.$element.trigger('shown') + + }) + + return this + } + + , hide: function (e) { + e && e.preventDefault() + + if ( !this.isShown ) { + return this + } + + var that = this + this.isShown = false + + escape.call(this) + + this.$element + .trigger('hide') + .removeClass('in') + + $.support.transition && this.$element.hasClass('fade') ? + hideWithTransition.call(this) : + hideModal.call(this) + + return this + } + + } + + + /* MODAL PRIVATE METHODS + * ===================== */ + + function hideWithTransition() { + // firefox drops transitionEnd events :{o + var that = this + , timeout = setTimeout(function () { + that.$element.unbind(transitionEnd) + hideModal.call(that) + }, 500) + + this.$element.one(transitionEnd, function () { + clearTimeout(timeout) + hideModal.call(that) + }) + } + + function hideModal (that) { + this.$element + .hide() + .trigger('hidden') + + backdrop.call(this) + } + + function backdrop ( callback ) { + var that = this + , animate = this.$element.hasClass('fade') ? 'fade' : '' + if ( this.isShown && this.settings.backdrop ) { + var doAnimate = $.support.transition && animate + + this.$backdrop = $('"); + $element.html(random_number + " question(s) will be selected from " + count + " question(s)").append(html).append($input_random).append($input_number).append($remove); + $("#random-added").prepend($element); + total_marks = total_marks + random_number * marks_per; + $total_marks.text(total_marks) + } else { + $numbers.addClass("red-alert"); + } + e.preventDefault(); + }); + + /* removing added questions */ + $(".qcard .remove").live("click", function(e) { + var marks_per = $(this).attr('data-marks'); + var num_question = $(this).attr('data-num'); + var sub_marks = marks_per*num_question; + var total_marks = parseFloat($total_marks.text()); + total_marks = total_marks - sub_marks; + $total_marks.text(total_marks); + + $(this).parent().slideUp("normal", function(){ $(this).remove(); }); + e.preventDefault(); + }); + + /* showing/hiding selectors on tab click */ + $(".tabs li").click(function() { + if($(this).attr("id") == "finish-tab") { + $("#selectors").hide(); + } else { + $question_type.val('select'); + $marks.val('select') + $("#selectors").show(); + } + }); + /* check all questions on checked*/ + $("#checkall").live("click", function(){ + if($(this).attr("checked")) { + if($("#fixed-tab").hasClass("active")) { + $("#fixed-available input:checkbox").each(function(index, element) { + $(this).attr('checked','checked'); + }); + } + else { + $("#random-available input:checkbox").each(function(index, element) { + $(this).attr('checked','checked'); + }); + } + } + else { + if($("#fixed-tab").hasClass("active")) { + $("#fixed-available input:checkbox").each(function(index, element) { + $(this).removeAttr('checked'); + }); + } + else { + $("#random-available input:checkbox").each(function(index, element) { + $(this).removeAttr('checked'); + }); + } + } + }); + + /* show preview on preview click */ + $("#preview").click(function(){ + questions = getQuestions() + if(questions.trim() == ""){ + $('#modal_body').html("No questions selected"); + } + else { + $('#modal_body').html(questions); + } + $("#myModal").modal('show'); + }); + + /* tab change on next or previous button click */ + $("#fixed-next").click(function(){ + $("#random").click(); + }); + $("#random-next").click(function(){ + $("#finished").click(); + }); + + $("#random-prev").click(function(){ + $("#fixed").click(); + }); + + $("#finish-prev").click(function(){ + $("#random").click(); + }); + + /* Check at least one question is present before saving */ + $('#save').click(function(){ + questions = getQuestions(); + if(questions.trim() == ""){ + $("#modalSave").modal("show"); + } + else { + document.forms["frm"].submit(); + } + }); + + /* Fetch selected questions */ + function getQuestions(){ + var fixed_div = $("#fixed-added").html(); + var random_div = $("#random-added").html(); + return fixed_div+random_div; + } +}); //document diff --git a/testapp/exam/static/exam/js/show_question.js b/testapp/exam/static/exam/js/show_question.js new file mode 100644 index 0000000..e3ed1cc --- /dev/null +++ b/testapp/exam/static/exam/js/show_question.js @@ -0,0 +1,39 @@ +function confirm_delete(frm) +{ + var n=0; + for (var i =0;i +This event will be reported.
+Sorry for the inconvinience. +{% endblock %} diff --git a/testapp/exam/templates/base.html b/testapp/exam/templates/base.html new file mode 100644 index 0000000..3dfbe10 --- /dev/null +++ b/testapp/exam/templates/base.html @@ -0,0 +1,46 @@ + + + + + + {% block title %} + {% endblock %} + + + {% block meta %} + + + + {% endblock %} + + + {% block css %} + {% endblock %} + + {% block script %} + {% endblock %} + + + +
+
+ +
+
+

{% block formtitle %} {% endblock formtitle %}


+ {% block content %} + {% endblock %} +
+
+
+
+

© FOSSEE group, IIT Bombay

+
+
+ + + + diff --git a/testapp/exam/templates/exam/add_question.html b/testapp/exam/templates/exam/add_question.html new file mode 100644 index 0000000..b0b22b1 --- /dev/null +++ b/testapp/exam/templates/exam/add_question.html @@ -0,0 +1,41 @@ +{% extends "manage.html" %} + + +{% block subtitle %}Add Question{% endblock %} + +{% block css %} + + +{% endblock %} + +{% block script %} + + + + +{% endblock %} + +{% block onload %} onload='javascript:textareaformat();' {% endblock %} + +{% block manage %} +
+ {% csrf_token %} +
+ +
Summary: {{ form.summary }}{{ form.summary.errors }} +
Language: {{form.language}}{{form.language.errors}} +
Active: {{ form.active }}{{form.active.errors}}   Type:  {{ form.type }}{{form.type.errors}} +
Points:{{ form.points }}{{ form.points.errors }} +
Rendered:

+
Description: {{ form.description}} {{form.description.errors}} +
Test: {{ form.test }}{{form.test.errors}} +
Snippet: {{ form.snippet }}{{ form.snippet.errors }}
Tags: {{ form.tags }} +
Options: {{ form.options }} {{form.options.errors}} + + +
+
+
+
+{% endblock %} + diff --git a/testapp/exam/templates/exam/add_questionpaper.html b/testapp/exam/templates/exam/add_questionpaper.html new file mode 100644 index 0000000..4cce8a9 --- /dev/null +++ b/testapp/exam/templates/exam/add_questionpaper.html @@ -0,0 +1,28 @@ +{% extends "manage.html" %} + + +{% block subtitle %}Design Question Paper{% endblock %} + +{% block css %} + + +{% endblock %} +{% block script %} + + + +{% endblock %} + +{% block manage %} + +
+{% csrf_token %} +Select mode to design Question Paper: + +
+ +{% endblock %} diff --git a/testapp/exam/templates/exam/add_quiz.html b/testapp/exam/templates/exam/add_quiz.html new file mode 100644 index 0000000..c2533de --- /dev/null +++ b/testapp/exam/templates/exam/add_quiz.html @@ -0,0 +1,25 @@ +{% extends "manage.html" %} + + +{% block subtitle %}Add Quiz{% endblock %} + +{% block css %} + +{% endblock %} +{% block script %} + +{% endblock %} +{% block onload %} onload="javascript:test();" {% endblock %} +{% block manage %} +
+ {% csrf_token %} +
+ + {{ form.as_table }} +
+
+ +
+
+
+{% endblock %} diff --git a/testapp/exam/templates/exam/ajax_marks.html b/testapp/exam/templates/exam/ajax_marks.html new file mode 100644 index 0000000..716bb88 --- /dev/null +++ b/testapp/exam/templates/exam/ajax_marks.html @@ -0,0 +1,4 @@ + +{% for mark in marks %} + +{% endfor %} diff --git a/testapp/exam/templates/exam/ajax_questions.html b/testapp/exam/templates/exam/ajax_questions.html new file mode 100644 index 0000000..e343f9b --- /dev/null +++ b/testapp/exam/templates/exam/ajax_questions.html @@ -0,0 +1,31 @@ +
+ {% if questions %} + + Select All + {% endif %} +
    + + {% for question in questions %} +
  • + +
  • + {% endfor %} +
+
+ +
+ +
diff --git a/testapp/exam/templates/exam/automatic_questionpaper.html b/testapp/exam/templates/exam/automatic_questionpaper.html new file mode 100644 index 0000000..fcd3db5 --- /dev/null +++ b/testapp/exam/templates/exam/automatic_questionpaper.html @@ -0,0 +1,88 @@ +{% extends "manage.html" %} + + +{% block subtitle %}Design Question Paper{% endblock %} + +{% block css %} + + + +{% endblock %} +{% block script %} + + + +{% endblock %} + +{% block manage %} + +
Automatic mode to design the Question Paper

+
+ {% csrf_token %} +
+ Tag Conditions: + + + + + + + + + +
+ +
+ +
Number of question:  
+ +
+
+

Below is the list of Questions fetched according to the given tag conditions

+
+
+ +
+ {% endfor %} +
Summary + Type + Points + Tags + {% for question in data.questions %} + +
{{ question.summary }} {{ question.type }} {{ question.points }} + {% for tag in question.tags.all %} + {{ tag }} + {% endfor %} +
+ {% if data.msg %}
{{ data.msg }}
{% endif %} +
+ + +{% endblock %} diff --git a/testapp/exam/templates/exam/complete.html b/testapp/exam/templates/exam/complete.html new file mode 100644 index 0000000..1d5df3c --- /dev/null +++ b/testapp/exam/templates/exam/complete.html @@ -0,0 +1,12 @@ +{% extends "base.html" %} + +{% block title %}Good bye!{% endblock %} + +{% block pagetitle %}Online Test{% endblock %} +{% block content %} +{% csrf_token %} +

Good bye!

+

{{message}}

+

You may now close the browser.


+
Login Again
+{% endblock content %} diff --git a/testapp/exam/templates/exam/design_questionpaper.html b/testapp/exam/templates/exam/design_questionpaper.html new file mode 100644 index 0000000..8994148 --- /dev/null +++ b/testapp/exam/templates/exam/design_questionpaper.html @@ -0,0 +1,184 @@ +{% extends "manage.html" %} + +{% block subtitle %}Design Question Paper{% endblock %} + +{% block css %} + + + + + +{% endblock %} +{% block script %} + + + + + + + + +{% endblock %} + +{% block manage %} + +
Manual mode to design the {{lang}} Question Paper

+ + +
{% csrf_token %} +
+

Total Marks: 0

+
+
+ +
+
Please select Question type and Marks
+
+ {{ form.question_type }} +
+
+ {{ form.marks }} +
+
+
+
+
+

+ + +
+
+
+
+

Select questions to add:

+
+
+ Add to paper +
+
+
+
+

Fixed questions currently in paper:

+
+
+
+
+
+
+
+ Next > +
+ +
+ + +
+
+
+
+

Select questions to add to the pool:

+
+
+ Add to paper +
+
+
+
+

Pool of questions currently in paper:

+
+
+
+
+
+
+ +
+ Next > +
+
+ +
+
+
Almost finished creating your question paper
+

+ + +
+ +
+
+
+ +
+
+
+ + + + + + + + +{% endblock %} diff --git a/testapp/exam/templates/exam/edit_question.html b/testapp/exam/templates/exam/edit_question.html new file mode 100644 index 0000000..b28cc3e --- /dev/null +++ b/testapp/exam/templates/exam/edit_question.html @@ -0,0 +1,54 @@ +{% extends "manage.html" %} + +{% block subtitle %}Edit Question{% endblock %} + +{% block css %} + + +{% endblock %} +{% block script %} + + + +{% endblock %} + +{% block onload %} onload = 'javascript:textareaformat();' {% endblock %} + +{% block manage %} +
+ {% csrf_token %} +

Click on the Question links to edit the question.

+ + + + {% for form in forms %} + +
{{form.summary.value}} + + + {% endfor %} +
+{% for i in data %} + +{% endfor %} + +
+
+ +{% endblock %} diff --git a/testapp/exam/templates/exam/edit_quiz.html b/testapp/exam/templates/exam/edit_quiz.html new file mode 100644 index 0000000..6445907 --- /dev/null +++ b/testapp/exam/templates/exam/edit_quiz.html @@ -0,0 +1,39 @@ +{% extends "manage.html" %} + + +{% block subtitle %}Edit Quiz(zes){% endblock %} + +{% block css %} + +{% endblock %} + +{% block script %} + +{% endblock %} + +{% block onload %} onload = 'javascript:form_load();' {% endblock %} + +{% block manage %} +
+ {% csrf_token %} +
+ + {% for form in forms %} +
Start Date: {{ form.start_date}} +
Duration: {{ form.duration }}
{{form.duration.help_text}} +
Active: {{ form.active }} +
Description: {{ form.description }} +
Passing Criteria: {{ form.pass_criteria }}
{{form.pass_criteria.help_text}} +
Language: {{ form.language }} +
Prerequisite: {{ form.prerequisite }} +
+ {% endfor %} +
+
+{% for i in data %} + +{% endfor %} +
+
+
+{% endblock %} diff --git a/testapp/exam/templates/exam/editquestionpaper.html b/testapp/exam/templates/exam/editquestionpaper.html new file mode 100644 index 0000000..819ff06 --- /dev/null +++ b/testapp/exam/templates/exam/editquestionpaper.html @@ -0,0 +1,21 @@ +{% extends "manage.html" %} + + +{% block subtitle %}Questions in "{{ papers.quiz.description }}"{% endblock %} + +{% block script %} + +{% endblock %} + +{% block manage %} +
+{% csrf_token %} + +{% for i in papers.questions %} +  {{ i.summary}}
+{% endfor %} +
+   + +
+{% endblock %} diff --git a/testapp/exam/templates/exam/grade_user.html b/testapp/exam/templates/exam/grade_user.html new file mode 100644 index 0000000..ae9274e --- /dev/null +++ b/testapp/exam/templates/exam/grade_user.html @@ -0,0 +1,94 @@ +{% extends "manage.html" %} + +{% block title %} Grading papers for {{ data.user.get_full_name.title }} {% endblock title %} + +{% block subtitle %}Grading papers for {{ data.user.get_full_name.title }}{% endblock %} + +{% block css %} + +{% endblock %} + +{% block script %} + +{% endblock %} +{% block manage %} + +

+Name: {{ data.user.get_full_name.title }} +{% if data.profile %} +(roll number: {{ data.profile.roll_number }})
+{{ data.profile.position }}, +{{ data.profile.department }}, +{{ data.profile.institute }} +{% endif %} +

+ +{% if data.papers %} + +{% for paper in data.papers %} + +

Quiz: {{ paper.quiz.description }}

+ +

+Questions correctly answered: {{ paper.get_answered_str }}
+Total attempts at questions: {{ paper.answers.count }}
+Marks obtained: {{ paper.get_total_marks }}
+Start time: {{ paper.start_time }}
+

+ +{% if paper.answers.count %} +

Answers


+
+{% csrf_token %} +{% for question, answers in paper.get_question_answers.items %} +
+

+ Question: {{ question.id }}. {{ question.summary }} (Points: {{ question.points }}) + +Details

+
+ +
+
+ +{% if question.type == "mcq" %} +
+

Choices: +{% for option in question.options.strip.splitlines %} {{option}}, {% endfor %} +

+

Student answer: {{ answers.0 }}

+{% else %}{# non-mcq questions #} +
+{% for answer in answers %}################################################################################
+{{ answer.answer.strip }}
+# Autocheck: {{ answer.error }}
+{% endfor %}
+{% endif %} {# if question.type #} +{% with answers|last as answer %} +Marks:

+{% endwith %} +
+
+{% endfor %} {# for question, answers ... #} + + +

Teacher comments:

+ +
+
+ +
+{% endif %} {# if paper.answers.count #} + +{% endfor %} {# for paper in data.papers #} + +{% endif %} {# if data.papers #} + +{% endblock%} diff --git a/testapp/exam/templates/exam/intro.html b/testapp/exam/templates/exam/intro.html new file mode 100644 index 0000000..ec1888a --- /dev/null +++ b/testapp/exam/templates/exam/intro.html @@ -0,0 +1,34 @@ +{% extends "base.html" %} + +{% block title %}Instructions and Rules {% endblock %} +{% block pagetitle %}Online Test {% endblock %} +{% block formtitle %}Important instructions & rules {% endblock %} +{% block content %} + + + +

Welcome {{user.first_name.title}} {{user.last_name.title}}, to the programming quiz!

+

+ This examination system has been developed with the intention of making you + learn programming and be assessed in an interactive and fun manner. + You will be presented with a series of programming questions and problems that + you will answer online and get immediate feedback for. +

+

Here are some important instructions and rules that you should understand carefully.

+
    +
  • For any programming questions, you can submit solutions as many times as you want without a penalty. You may skip questions and solve them later. +
  • +
  • You may use your computer's Python/IPython shell or an editor to solve the problem and cut/paste the solution to the web interface. +
  • +
  • You are not allowed to use any internet resources, i.e. no google etc.
  • +
  • Do not copy or share the questions or answers with anyone until the exam is complete for everyone.
  • +
  • All your attempts at the questions are logged. Do not try to outsmart and break the testing system. If you do, we know who you are and we will expell you from the course. You have been warned. +
  • +
+

We hope you enjoy taking this exam !!!

+ +
+ {% csrf_token %} +
+
+{% endblock content %} diff --git a/testapp/exam/templates/exam/login.html b/testapp/exam/templates/exam/login.html new file mode 100644 index 0000000..078e7a7 --- /dev/null +++ b/testapp/exam/templates/exam/login.html @@ -0,0 +1,22 @@ +{% extends "base.html" %} + +{% block title %}Login{% endblock title %} +{% block pagetitle %} Online Test {% endblock %} +{% block formtitle %}Login{% endblock %} +{% block css %} + +{% endblock %} +{% block content %} + +
+ {% csrf_token %} + +
+ {{ form.as_table }} +
+
    
+
Forgot Password?

+
New User? Sign-Up
+
+ +{% endblock content %} diff --git a/testapp/exam/templates/exam/manual_questionpaper.html b/testapp/exam/templates/exam/manual_questionpaper.html new file mode 100644 index 0000000..1a1f95c --- /dev/null +++ b/testapp/exam/templates/exam/manual_questionpaper.html @@ -0,0 +1,81 @@ +{% extends "manage.html" %} + + +{% block subtitle %}Design Question Paper{% endblock %} + +{% block css %} + + + +{% endblock %} +{% block script %} + + + + +{% endblock %} + +{% block manage %} + +
Manual mode to design the Question Paper

+ +
+ {% csrf_token %} +
+ Tag Conditions: + + + + + +
+
+
+

Below is the list of Questions fetched according to the given tag conditions
+
+
+ +
+ {% endfor %} +
  + Summary + Type + Points + Tags + {% for question in data.questions %} +
{{ question.summary }} {{ question.type }} {{ question.points }} + {% for tag in question.tags.all %} + {{ tag }} + {% endfor %} +
+ {% if data.msg %}
{{ data.msg }}
{% endif %} +
+ + +{% endblock %} diff --git a/testapp/exam/templates/exam/monitor.html b/testapp/exam/templates/exam/monitor.html new file mode 100644 index 0000000..ecdb852 --- /dev/null +++ b/testapp/exam/templates/exam/monitor.html @@ -0,0 +1,69 @@ +{% extends "manage.html" %} + +{% block title %} Quiz results {% endblock title %} + +{% block meta %} {% endblock meta %} + +{% block css %} + +{% endblock %} +{% block subtitle %} + {% if not quizzes and not quiz %} + Quiz Results + {% endif %} + {% if quizzes %} + Available Quizzes + {% endif %} + {% if quiz %} + {{ quiz.description }} Results + {% endif %} +{% endblock %} +{% block manage %} + {% if not quizzes and not quiz %} +
No quizzes available.
+ {% endif %} + +{# ############################################################### #} +{# This is rendered when we are just viewing exam/monitor #} +{% if quizzes %} + +{% endif %} + +{# ############################################################### #} +{# This is rendered when we are just viewing exam/monitor/quiz_num #} +{% if quiz %} + +{% if papers %} +{#

Quiz: {{ quiz_name }}

#} +

Number of papers: {{ papers|length }}

+ + + + + + + + + + + {% for paper in papers %} + + + + + + + + + + {% endfor %} +
Name Username Roll number Institute Questions answered Marks obtained Attempts
{{ paper.user.get_full_name.title }} {{ paper.user.username }} {{ paper.profile.roll_number }} {{ paper.profile.institute }} {{ paper.get_answered_str }} {{ paper.marks_obtained }} {{ paper.answers.count }}
+{% else %} +

No answer papers so far.

+{% endif %} {# if papers #} +{% endif %} +{% endblock %} diff --git a/testapp/exam/templates/exam/question.html b/testapp/exam/templates/exam/question.html new file mode 100644 index 0000000..a3e8629 --- /dev/null +++ b/testapp/exam/templates/exam/question.html @@ -0,0 +1,138 @@ +{% extends "base.html" %} + + + +{% block title %} Answer question {% endblock %} + +{% block css %} + + +{% endblock %} + +{% block script %} + + + +{% endblock script %} + + + +{% block onload %} onload="update_time();setSnippetHeight()" {% endblock %} + +{% block pagetitle %} + +
+
You have {{ paper.questions_left }} question(s) left in {{ quiz_name }}
+
+
+
+ +{% endblock %} + +{% block content %} +
+
+
+

Online Test

+ +
+ {% csrf_token %} + + +
+
+
+
+ + +

{{ question.summary }} (Marks : {{ question.points }})


+ {{ question.description|safe }} + {% if error_message %} +
+ {% for e in error_message.splitlines %} + {{ e|join:"" }} +
+ {% endfor%} +
{% endif %} + + {% if success_msg %} + + {% endif %} +

+
+ {% csrf_token %} + {% if question.type == "mcq" %} + {% for option in question.options.strip.splitlines %} + {{option}}
+ {% endfor %} + {% endif %} + {% if question.type == "mcc" %} + {% for option in question.options.strip.splitlines %} + {{ option }} +
+ {% endfor %} + {% endif %} + {% if question.type == "code" %} + + + + +
+ + + + {% endif %} + + {% if question.type == "mcq" or question.type == "mcc "%} +
   + {% else %} +    + {% endif %} + +
+ + +{% endblock content %} diff --git a/testapp/exam/templates/exam/quit.html b/testapp/exam/templates/exam/quit.html new file mode 100644 index 0000000..fee11ed --- /dev/null +++ b/testapp/exam/templates/exam/quit.html @@ -0,0 +1,14 @@ +{% extends "base.html" %} + +{% block title %}Quit exam {% endblock %} +{% block pagetitle %}Online Test {% endblock %} +{% block content %} + +

Your current answers are saved.

+

Are you sure you wish to quit the exam?

+

Be sure, as you won't be able to restart this exam.

+
+ {% csrf_token %} +
 
+
+{% endblock content %} diff --git a/testapp/exam/templates/exam/quizlist.html b/testapp/exam/templates/exam/quizlist.html new file mode 100644 index 0000000..9b1fd73 --- /dev/null +++ b/testapp/exam/templates/exam/quizlist.html @@ -0,0 +1,24 @@ +{% extends "base.html" %} + +{% block title %} Quiz List {% endblock title %} + +{% block formtitle %} Quiz List {% endblock %} + +{% block pagetitle %} Online Test {% endblock %} + +{% block content %} +{% if not quizzes and not quiz %} +
No quizzes available.
+{% endif %} + +{% if quizzes %} +
+{% csrf_token %} + +{% for quiz in quizzes %} +{{ quiz.description }}
+{% endfor %} +
+{% endif %} + +{% endblock %} diff --git a/testapp/exam/templates/exam/quizzes_user.html b/testapp/exam/templates/exam/quizzes_user.html new file mode 100644 index 0000000..914b6b4 --- /dev/null +++ b/testapp/exam/templates/exam/quizzes_user.html @@ -0,0 +1,81 @@ +{% extends "user.html" %} + + +{% block subtitle %}Hello {{ user.first_name }}, welcome to your dashboard !{% endblock %} + +{% block css %} + +{% endblock %} + +{% block script %} + + +{% endblock %} + + +{% block manage %} + {% if cannot_attempt %} +

You have not passed the prerequisite & hence you cannot take the quiz.

+ {% endif %} +

List of quizzes availbale for you

+ {% if not quizzes %} +
No active quizzes for you
+ {% endif %} + + + + {% for paper in quizzes %} + + + + + {% endfor %} +
QuizPre requisite quiz
+ {{ paper.quiz.description }}
+
+ {% if paper.quiz.prerequisite %} + You have to pass {{ paper.quiz.prerequisite.description }} for taking {{ paper.quiz.description }} + {% else %} + No pre requisites for {{ paper.quiz.description }} + {% endif %} +
+
+

List of quizzes taken by you so far

+ {% if quizzes_taken %} + + + + + + + {% for paper in quizzes_taken %} + + + + + + + + {% endfor %} +
QuizResultMraks ObtainedTotal MarksPercentage
+ {{ paper.question_paper.quiz.description }} + + {% if paper.passed %} +

Pass

+ {% else %} +

Fail

+ {% endif %} +
+ {{ paper.marks_obtained }} + + {{ paper.question_paper.total_marks }} + + {{ paper.percent }} +
+ {% else %} +

You have not taken any quiz yet !!

+ {% endif %} + + +{% endblock %} + diff --git a/testapp/exam/templates/exam/register.html b/testapp/exam/templates/exam/register.html new file mode 100644 index 0000000..5ff79cc --- /dev/null +++ b/testapp/exam/templates/exam/register.html @@ -0,0 +1,20 @@ +{% extends "base.html" %} + +{% block title %}Registration form {% endblock %} + +{% block pagetitle %}Online Test {% endblock %} +{% block formtitle %}Please fill in the following details {% endblock %} + +{% block content %} + + + +
+ {% csrf_token %} +
+ {{ form.as_table }} +
+
  
+
+ +{% endblock content %} diff --git a/testapp/exam/templates/exam/results_user.html b/testapp/exam/templates/exam/results_user.html new file mode 100644 index 0000000..2a2a309 --- /dev/null +++ b/testapp/exam/templates/exam/results_user.html @@ -0,0 +1,28 @@ +{% extends "user.html" %} + + +{% block subtitle %}Results{% endblock %} + +{% block css %} + +{% endblock %} + +{% block manage %} +
+ {% csrf_token %} +
+ + {% for i in paper %} +
Quiz Description + Obtained Marks + Maximum Marks + Percentage + {% for paper in papers %} +
{{ i }} + {% endfor %} +
+ {% endfor %} +
+
+{% endblock %} + diff --git a/testapp/exam/templates/exam/show_quiz.html b/testapp/exam/templates/exam/show_quiz.html new file mode 100644 index 0000000..cf3f552 --- /dev/null +++ b/testapp/exam/templates/exam/show_quiz.html @@ -0,0 +1,33 @@ +{% extends "manage.html" %} + +{% block title %} Quiz List {% endblock title %} + +{% block script %} + +{% endblock %} + +{% block subtitle %} Quiz List {% endblock %} +{% block manage %} +{% if not quizzes and not quiz %} +
No quizzes available.
+   +{% endif %} + +{# ############################################################### #} +{# This is rendered when we are just viewing exam/monitor #} +{% if quizzes %} +
+{% csrf_token %} + +{% for quiz in quizzes %} +  {{ quiz.description }}
+{% endfor %} + +

+   +   + +
+{% endif %} + +{% endblock %} diff --git a/testapp/exam/templates/exam/showquestionpapers.html b/testapp/exam/templates/exam/showquestionpapers.html new file mode 100644 index 0000000..e511472 --- /dev/null +++ b/testapp/exam/templates/exam/showquestionpapers.html @@ -0,0 +1,23 @@ +{% extends "manage.html" %} + + +{% block subtitle %}List of Question Papers {% endblock %} + +{% block script %} + +{% endblock %} + +{% block manage %} +{% if papers %} +
+{% csrf_token %} +{% for i in papers %} +  {{ i.quiz.description }}
+{% endfor %} +
+ +
+{% else %} +

No Question Papers available

+{% endif %} +{% endblock %} diff --git a/testapp/exam/templates/exam/showquestions.html b/testapp/exam/templates/exam/showquestions.html new file mode 100644 index 0000000..62b40e4 --- /dev/null +++ b/testapp/exam/templates/exam/showquestions.html @@ -0,0 +1,21 @@ +{% extends "manage.html" %} + + +{% block subtitle %}List of Questions {% endblock %} + +{% block script %} + +{% endblock %} + +{% block manage %} +
+{% csrf_token %} +{% for i in questions %} +  {{ i }}
+{% endfor %} +
+   +   + +
+{% endblock %} diff --git a/testapp/exam/templates/exam/showusers.html b/testapp/exam/templates/exam/showusers.html new file mode 100644 index 0000000..01ecc37 --- /dev/null +++ b/testapp/exam/templates/exam/showusers.html @@ -0,0 +1,26 @@ +{% extends "manage.html" %} + + +{% block subtitle %} +List of Users +{% endblock %} + +{% block css %} + +{% endblock css %} + + +{% block manage %} +
+
Username +First Name +Last Name +Quiz Description +{% for papers in question %} +
{{ papers.user.username }}
+
{{ papers.user.first_name.title }} + {{ papers.user.last_name.title }} + {{ papers.question_paper.quiz.description }} +{% endfor %} +
+{% endblock %} diff --git a/testapp/exam/templates/exam/user_data.html b/testapp/exam/templates/exam/user_data.html new file mode 100644 index 0000000..61a3a97 --- /dev/null +++ b/testapp/exam/templates/exam/user_data.html @@ -0,0 +1,80 @@ +{% extends "manage.html" %} + +{% block title %} Data for user {{ data.user.get_full_name.title }} {% endblock title %} + +{% block manage %} + +{% block subtitle %}Data for user {{ data.user.get_full_name.title }}{% endblock %} +
+

+Name: {{ data.user.get_full_name.title }}
+Username: {{ data.user.username }}
+{% if data.profile %} +Roll number: {{ data.profile.roll_number }}
+Position: {{ data.profile.position }}
+Department: {{ data.profile.department }}
+Institute: {{ data.profile.institute }}
+{% endif %} +Email: {{ data.user.email }}
+Date joined: {{ data.user.date_joined }}
+Last login: {{ data.user.last_login }} +

+ +{% if data.papers %} +

+ Grade/correct paper +

+ +{% for paper in data.papers %} + +

Quiz: {{ paper.quiz.description }}

+ +

+Questions correctly answered: {{ paper.get_answered_str }}
+Total attempts at questions: {{ paper.answers.count }}
+Marks obtained: {{ paper.get_total_marks }}
+Start time: {{ paper.start_time }}
+User IP address: {{ paper.user_ip }} +

+ +{% if paper.answers.count %} +

Answers

+{% for question, answers in paper.get_question_answers.items %} +

Question: {{ question.id }}. {{ question.summary }} (Points: {{ question.points }})

+{% if question.type == "mcq" %} +

Choices: +{% for option in question.options.strip.splitlines %} {{option}}, {% endfor %} +

+

Student answer: {{ answers.0 }}

+{% else %}{# non-mcq questions #} +
 
+{% for answer in answers %}################################################################################
+{{ answer.answer.strip }}
+# Autocheck: {{ answer.error }}
+{% endfor %}
+{% endif %} +{% with answers|last as answer %} +

Marks: {{answer.marks}}

+{% endwith %} +{% endfor %} {# for question, answers ... #} +

Teacher comments:

+{{ paper.comments|default:"None" }} +{% endif %} {# if paper.answers.count #} + +{% endfor %} {# for paper in data.papers #} + +{% endif %} {# if data.papers #} +
+
+ + Grade/correct paper +
+{% if data.papers.count > 1 %} +Monitor quiz +{% else %} +{% with data.papers.0 as paper %} +Monitor quiz +{% endwith %} +{% endif %} + +{% endblock %} diff --git a/testapp/exam/templates/manage.html b/testapp/exam/templates/manage.html new file mode 100644 index 0000000..1db8a78 --- /dev/null +++ b/testapp/exam/templates/manage.html @@ -0,0 +1,88 @@ + + + + {% block title %} + {% endblock %} + + + {% block meta %} + + + + {% endblock %} + + + + {% block css %} + {% endblock %} + + {% block script %} + {% endblock %} + + + + +
+
+ +
+
+ {% block manage %} +

List of quizzes! Click on the given links to have a look at answer papers for a quiz.

+
+ + + + + + {% for paper, answer_papers, users_passed, users_failed in users_per_paper %} + + + + + + + {% endfor %} +
QuizTaken ByNo. of users PassedNo. of users Failed
+ {{ paper.quiz.description }} + + {{ answer_papers|length }} user(s) + + {{ users_passed }} + + {{ users_failed }} +
+
+
+

Moderator's Dashboard!

+
Click on the button given below to add a new quiz.
+ +
+{% endblock %} +
+
+
+
+

© FOSSEE group, IIT Bombay

+
+
+ + + diff --git a/testapp/exam/templates/user.html b/testapp/exam/templates/user.html new file mode 100644 index 0000000..22a9fac --- /dev/null +++ b/testapp/exam/templates/user.html @@ -0,0 +1,58 @@ + + + + + + {% block title %} + {% endblock %} + + + {% block meta %} + + + + {% endblock %} + + + {% block css %} + {% endblock %} + + {% block script %} + {% endblock %} + + + +
+
+
+

Online Test

+ + +
+
+
+
+
+ +
+
+ {% block manage %} + {% endblock %} +
+
+
+
+

© FOSSEE group, IIT Bombay

+
+
+ + + diff --git a/testapp/settings.py b/testapp/settings.py index 668eca0..88d4a5a 100644 --- a/testapp/settings.py +++ b/testapp/settings.py @@ -5,18 +5,6 @@ from os.path import dirname, join, basename, abspath DEBUG = True TEMPLATE_DEBUG = DEBUG -# The ports the code server should run on. This will run one separate -# server for each port listed in the following list. -SERVER_PORTS = [8001] # range(8001, 8026) - -# The server pool port. This is the server which returns available server -# ports so as to minimize load. This is some random number where no other -# service is running. It should be > 1024 and less < 65535 though. -SERVER_POOL_PORT = 53579 - -# Timeout for the code to run in seconds. This is an integer! -SERVER_TIMEOUT = 2 - # The root of the URL, for example you might be in the situation where you # are not hosted as host.org/exam/ but as host.org/foo/exam/ for whatever # reason set this to the root you have to serve at. In the above example @@ -111,7 +99,6 @@ STATICFILES_DIRS = ( # Put strings here, like "/home/html/static" or "C:/www/django/static". # Always use forward slashes, even on Windows. # Don't forget to use absolute paths, not relative paths. - join(CURDIR, 'static'), ) # List of finder classes that know how to find static files in @@ -148,7 +135,6 @@ TEMPLATE_DIRS = ( # Put strings here, like "/home/html/django_templates" or "C:/www/django/templates". # Always use forward slashes, even on Windows. # Don't forget to use absolute paths, not relative paths. - join(CURDIR, "templates"), ) INSTALLED_APPS = ( diff --git a/testapp/static/exam/css/autotaggit.css b/testapp/static/exam/css/autotaggit.css deleted file mode 100644 index ed856ce..0000000 --- a/testapp/static/exam/css/autotaggit.css +++ /dev/null @@ -1,48 +0,0 @@ -.ac_results { - padding: 0px; - border: 1px solid #efefef; - background-color: white; - overflow: hidden; - z-index: 99999; -} - -.ac_results ul { - width: 100%; - list-style-position: outside; - list-style: none; - padding: 0; - margin: 0; -} - -.ac_results li { - margin: 0px; - padding: 2px 5px; - cursor: default; - display: block; - /* - if width will be 100% horizontal scrollbar will apear - when scroll mode will be used - */ - /*width: 100%;*/ - font: menu; - font-size: 12px; - /* - it is very important, if line-height not setted or setted - in relative units scroll will be broken in firefox - */ - line-height: 16px; - overflow: hidden; -} - -.ac_loading { - background: white url('indicator.gif') right center no-repeat; -} - -.ac_odd { - background-color: #CACACA; -} - -.ac_over { - background-color: #f5f5f5; - color: black; -} diff --git a/testapp/static/exam/css/base.css b/testapp/static/exam/css/base.css deleted file mode 100644 index 051ba22..0000000 --- a/testapp/static/exam/css/base.css +++ /dev/null @@ -1,2259 +0,0 @@ -/*! -Copyright 2012 Twitter, Inc. - -Licensed under the Apache License, Version 2.0 (the "License"); you may not use this work except in compliance with the License. You may obtain a copy of the License in the LICENSE file, or at: - -Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. - - * Bootstrap v1.4.0 - * - * Copyright 2011 Twitter, Inc - * Licensed under the Apache License v2.0 - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Designed and built with all the love in the world @twitter by @mdo and @fat. - * Date: Sun Dec 25 20:18:31 PST 2011 - */ -/* Reset.less - * Props to Eric Meyer (meyerweb.com) for his CSS reset file. We're using an adapted version here that cuts out some of the reset HTML elements we will never need here (i.e., dfn, samp, etc). - * For Online Test Application, this CSS was changed as per the requirements wherever required. ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- */ - -html, body { - background-color: #eee; - margin: 0; - padding: 0; - -} -h1, -h2, -h3, -h4, -h5, -h6, -p, -blockquote, -pre, -a, -abbr, -acronym, -address, -cite, -code, -del, -dfn, -em, -img, -q, -s, -samp, -small, -strike, -strong, -sub, -sup, -tt, -var, -dd, -dl, -dt, -li, -ol, -ul, -fieldset, -form, -label, -legend, -button, -table, -caption, -tbody, -tfoot, -thead, -tr, -th, -td { - margin: 0; - padding: 0; - border: 0; - font-weight: normal; - font-style: normal; - font-size: 100%; - line-height: 1; - font-family: serif; -} -table { - border-collapse: collapse; - border-spacing: 0; -} -ol, ul { - list-style: none; -} -q:before, -q:after, -blockquote:before, -blockquote:after { - content: ""; -} -html { - overflow-y: scroll; - font-size: 100%; - -webkit-text-size-adjust: 100%; - -ms-text-size-adjust: 100%; -} -a:focus { - outline: thin dotted; -} -a:hover, a:active { - outline: 0; -} -article, -aside, -details, -figcaption, -figure, -footer, -header, -hgroup, -nav, -section { - display: block; -} -audio, canvas, video { - display: inline-block; - *display: inline; - *zoom: 1; -} -audio:not([controls]) { - display: none; -} -sub, sup { - font-size: 75%; - line-height: 0; - position: relative; - vertical-align: baseline; -} -sup { - top: -0.5em; -} -sub { - bottom: -0.25em; -} -img { - border: 0; - -ms-interpolation-mode: bicubic; -} -button, -input, -select, -textarea { - font-size: 100%; - margin: 0; - vertical-align: baseline; - *vertical-align: middle; -} -button, input { - line-height: normal; - *overflow: visible; -} -button::-moz-focus-inner, input::-moz-focus-inner { - border: 0; - padding: 0; -} -button, -input[type="button"], -input[type="reset"], -input[type="submit"] { - cursor: pointer; - -webkit-appearance: button; -} -input[type="search"] { - -webkit-appearance: textfield; - -webkit-box-sizing: content-box; - -moz-box-sizing: content-box; - box-sizing: content-box; -} -input[type="search"]::-webkit-search-decoration { - -webkit-appearance: none; -} -textarea { - overflow: visible; - vertical-align: top; -} -/* Variables.less -* Variables to customize the look and feel of Bootstrap -* ----------------------------------------------------- */ -/* Mixins.less -* Snippets of reusable CSS to develop faster and keep code readable -* ----------------------------------------------------------------- */ -/* -* Scaffolding -* Basic and global styles for generating a grid system, structural layout, and page templates -* ------------------------------------------------------------------------------------------- */ -body { - padding-top : 10px; - background-color: #eee; - margin: 0; - font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; - font-size: 13px; - font-weight: normal; - line-height: 18px; - color: #404040; - -} -.container { - width: 820px; - margin-left: auto; - margin-right: auto; - zoom: 1; -} -.container > footer p { - text-align: center; -} -.container > .content { - background-color: #fff; - padding: 20px; - margin: 0 -20px; - -webkit-border-radius: 0 0 6px 6px; - -moz-border-radius: 0 0 6px 6px; - border-radius: 0 0 6px 6px; - -webkit-box-shadow: 0 1px 2px rgba(0,0,0,.15); - -moz-box-shadow: 0 1px 2px rgba(0,0,0,.15); - box-shadow: 0 1px 2px rgba(0,0,0,.15); -} -.content .span10, -.content .span14 { - min-height: 475px; -} -.content .span4 { - margin-left: 0; - padding-left: 19px; - border-left: 1px solid #eee; -} -.topbar .btn { - border: 0; -} -.page-header { - background-color: #f5f5f5; - padding: 20px 20px 10px; - margin: -20px -20px 20px; -} -.container:before, .container:after { - display: table; - content: ""; - zoom: 1; -} -.container:after { - clear: both; -} - -a { - color: #0069d6; - text-decoration: none; - line-height: inherit; - font-weight: inherit; -} -a:hover { - color: #00438a; - text-decoration: underline; -} -.pull-right { - float: right; -} -.pull-left { - float: left; -} -.hide { - display: none; -} -.show { - display: block; -} -.row { - zoom: 1; - margin-left: -20px; -} -.row:before, .row:after { - display: table; - content: ""; - zoom: 1; -} -.row:after { - clear: both; -} -.row > [class*="span"] { - display: inline; - float: left; - margin-left: 20px; -} -.span1 { - width: 40px; -} -.span2 { - width: 100px; -} -.span3 { - width: 160px; -} -.span4 { - width: 220px; -} -.span5 { - width: 280px; -} -.span6 { - width: 340px; -} -.span7 { - width: 400px; -} -.span8 { - width: 460px; -} -.span9 { - width: 520px; -} -.span10 { - width: 560px; -} -.span11 { - width: 640px; -} -.span12 { - width: 700px; -} -.span13 { - width: 760px; -} -.span14 { - width: 820px; -} -.span15 { - width: 880px; -} -.span16 { - width: 940px; -} -.span17 { - width: 1000px; -} -.span18 { - width: 1060px; -} -.span19 { - width: 1120px; -} -.span20 { - width: 1180px; -} -.span21 { - width: 1240px; -} -.span22 { - width: 1300px; -} -.span23 { - width: 1360px; -} -.span24 { - width: 1420px; -} -.row > .offset1 { - margin-left: 80px; -} -.row > .offset2 { - margin-left: 140px; -} -.row > .offset3 { - margin-left: 200px; -} -.row > .offset4 { - margin-left: 260px; -} -.row > .offset5 { - margin-left: 320px; -} -.row > .offset6 { - margin-left: 380px; -} -.row > .offset7 { - margin-left: 440px; -} -.row > .offset8 { - margin-left: 500px; -} -.row > .offset9 { - margin-left: 560px; -} -.row > .offset10 { - margin-left: 620px; -} -.row > .offset11 { - margin-left: 680px; -} -.row > .offset12 { - margin-left: 740px; -} -.span-one-third { - width: 300px; -} -.span-two-thirds { - width: 620px; -} -.row > .offset-one-third { - margin-left: 340px; -} -.row > .offset-two-thirds { - margin-left: 660px; -} -/* Typography.less -* Headings, body text, lists, code, and more for a versatile and durable typography system -* ---------------------------------------------------------------------------------------- */ -p { - font-size: 13px; - font-weight: normal; - line-height: 18px; - margin-bottom: 9px; -} -p small { - font-size: 11px; - color: #bfbfbf; -} -h1, -h2, -h3, -h4, -h5, -h6 { - font-weight: bold; - color: #404040; -} -h1 small, -h2 small, -h3 small, -h4 small, -h5 small, -h6 small { - color: #bfbfbf; -} -h1 { - margin-bottom: 18px; - font-size: 30px; - line-height: 36px; -} -h1 small { - font-size: 18px; -} -h2 { - font-size: 24px; - line-height: 36px; -} -h2 small { - font-size: 14px; -} -h3, -h4, -h5, -h6 { - line-height: 36px; -} -h3 { - font-size: 18px; -} -h3 small { - font-size: 14px; -} -h4 { - font-size: 16px; -} -h4 small { - font-size: 12px; -} -h5 { - font-size: 14px; -} -h6 { - font-size: 13px; - color: #bfbfbf; - text-transform: uppercase; -} -ul, ol { - margin: 0 0 18px 25px; -} -ul ul, -ul ol, -ol ol, -ol ul { - margin-bottom: 0; -} -ul { - list-style: disc; -} -ol { - list-style: decimal; -} -li { - line-height: 18px; - color: #808080; -} -ul.unstyled { - list-style: none; - margin-left: 0; -} -dl { - margin-bottom: 18px; -} -dl dt, dl dd { - line-height: 18px; -} -dl dt { - font-weight: bold; -} -dl dd { - margin-left: 9px; -} -hr { - margin: 20px 0 19px; - border: 0; - border-bottom: 1px solid; -} -strong { - font-style: inherit; - font-weight: bold; -} -em { - font-style: italic; - font-weight: inherit; - line-height: inherit; -} -.muted { - color: #bfbfbf; -} -blockquote { - margin-bottom: 18px; - border-left: 5px solid #eee; - padding-left: 15px; -} -blockquote p { - font-size: 14px; - font-weight: 300; - line-height: 18px; - margin-bottom: 0; -} -blockquote small { - display: block; - font-size: 12px; - font-weight: 300; - line-height: 18px; - color: #bfbfbf; -} -blockquote small:before { - content: '\2014 \00A0'; -} -address { - display: block; - line-height: 18px; - margin-bottom: 18px; -} -code, pre { - padding: 0 3px 2px; - font-family: Monaco, Andale Mono, Courier New, monospace; - font-size: 12px; - -webkit-border-radius: 3px; - -moz-border-radius: 3px; - border-radius: 3px; -} -code { - background-color: #FDE8E8; - color: rgba(0, 0, 0, 0.75); - padding: 1px 3px; -} -pre { - background-color: #EAB9B9; - color:red; - display: block; - padding: 8.5px; - margin: 0 0 18px; - line-height: 18px; - font-size: 12px; - border: 1px solid #ccc; - border: 1px solid rgba(0, 0, 0, 0.15); - -webkit-border-radius: 3px; - -moz-border-radius: 3px; - border-radius: 3px; - white-space: pre; - white-space: pre-wrap; - word-wrap: break-word; -} -/* Forms.less -* Base styles for various input types, form layouts, and states -* ------------------------------------------------------------- */ -form { - margin-bottom: 18px; -} -fieldset { - margin-bottom: 18px; - padding-top: 18px; -} -fieldset legend { - display: block; - padding-left: 150px; - font-size: 19.5px; - line-height: 1; - color: #404040; - *padding: 0 0 5px 145px; - /* IE6-7 */ - - *line-height: 1.5; - /* IE6-7 */ - -} -form .clearfix { - margin-bottom: 18px; - zoom: 1; -} -form .clearfix:before, form .clearfix:after { - display: table; - content: ""; - zoom: 1; -} -form .clearfix:after { - clear: both; -} -label, -input, -select, -textarea { - font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; - font-size: 13px; - font-weight: normal; - line-height: normal; -} -select -{ - width : auto; -} -label { - padding-top: 6px; - font-size: 13px; - line-height: 18px; - float: left; - width: 130px; - text-align: left; - color: #404040; -} -form .input { - margin-left: 150px; -} -input[type=checkbox], input[type=radio] { - cursor: pointer; -} -input, -textarea, -select, -.uneditable-input { - display: inline-block; - width: 210px; - height: 18px; - padding: 4px; - font-size: 13px; - line-height: 18px; - color: #808080; - border: 1px solid #ccc; - -webkit-border-radius: 3px; - -moz-border-radius: 3px; - border-radius: 3px; -} -select { - padding: initial; -} -input[type=checkbox], input[type=radio] { - width: auto; - height: auto; - padding: 0; - margin: 3px 0; - *margin-top: 0; - /* IE6-7 */ - - line-height: normal; - border: none; -} -input[type=file] { - background-color: #ffffff; - padding: initial; - border: initial; - line-height: initial; - -webkit-box-shadow: none; - -moz-box-shadow: none; - box-shadow: none; -} -input[type=button], input[type=reset], input[type=submit] { - width: auto; - height: auto; -} -select, input[type=file] { - height: 27px; - *height: auto; - line-height: 27px; - *margin-top: 4px; - /* For IE7, add top margin to align select with labels */ - -} -select[multiple] { - height: inherit; - background-color: #ffffff; -} -textarea { - height: auto; -} -.uneditable-input { - background-color: #ffffff; - display: block; - border-color: #eee; - -webkit-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.025); - -moz-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.025); - box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.025); - cursor: not-allowed; -} -:-moz-placeholder { - color: #bfbfbf; -} -::-webkit-input-placeholder { - color: #bfbfbf; -} -input, textarea { - -webkit-transition: border linear 0.2s, box-shadow linear 0.2s; - -moz-transition: border linear 0.2s, box-shadow linear 0.2s; - -ms-transition: border linear 0.2s, box-shadow linear 0.2s; - -o-transition: border linear 0.2s, box-shadow linear 0.2s; - transition: border linear 0.2s, box-shadow linear 0.2s; - -webkit-box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.1); - -moz-box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.1); - box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.1); -} -input:focus, textarea:focus { - outline: 0; - border-color: rgba(82, 168, 236, 0.8); - -webkit-box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.1), 0 0 8px rgba(82, 168, 236, 0.6); - -moz-box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.1), 0 0 8px rgba(82, 168, 236, 0.6); - box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.1), 0 0 8px rgba(82, 168, 236, 0.6); -} -input[type=file]:focus, input[type=checkbox]:focus, select:focus { - -webkit-box-shadow: none; - -moz-box-shadow: none; - box-shadow: none; - outline: 1px dotted #666; -} -form .clearfix.error > label, form .clearfix.error .help-block, form .clearfix.error .help-inline { - color: #b94a48; -} -form .clearfix.error input, form .clearfix.error textarea { - color: #b94a48; - border-color: #ee5f5b; -} -form .clearfix.error input:focus, form .clearfix.error textarea:focus { - border-color: #e9322d; - -webkit-box-shadow: 0 0 6px #f8b9b7; - -moz-box-shadow: 0 0 6px #f8b9b7; - box-shadow: 0 0 6px #f8b9b7; -} -form .clearfix.error .input-prepend .add-on, form .clearfix.error .input-append .add-on { - color: #b94a48; - background-color: #fce6e6; - border-color: #b94a48; -} -form .clearfix.warning > label, form .clearfix.warning .help-block, form .clearfix.warning .help-inline { - color: #c09853; -} -form .clearfix.warning input, form .clearfix.warning textarea { - color: #c09853; - border-color: #ccae64; -} -form .clearfix.warning input:focus, form .clearfix.warning textarea:focus { - border-color: #be9a3f; - -webkit-box-shadow: 0 0 6px #e5d6b1; - -moz-box-shadow: 0 0 6px #e5d6b1; - box-shadow: 0 0 6px #e5d6b1; -} -form .clearfix.warning .input-prepend .add-on, form .clearfix.warning .input-append .add-on { - color: #c09853; - background-color: #d2b877; - border-color: #c09853; -} -form .clearfix.success > label, form .clearfix.success .help-block, form .clearfix.success .help-inline { - color: #468847; -} -form .clearfix.success input, form .clearfix.success textarea { - color: #468847; - border-color: #57a957; -} -form .clearfix.success input:focus, form .clearfix.success textarea:focus { - border-color: #458845; - -webkit-box-shadow: 0 0 6px #9acc9a; - -moz-box-shadow: 0 0 6px #9acc9a; - box-shadow: 0 0 6px #9acc9a; -} -form .clearfix.success .input-prepend .add-on, form .clearfix.success .input-append .add-on { - color: #468847; - background-color: #bcddbc; - border-color: #468847; -} -textarea -{ - width : 290px; -} -.input-mini, -input.mini, -textarea.mini, -select.mini { - width: 60px; -} -.input-small, -input.small, -textarea.small, -select.small { - width: 90px; -} -.input-medium, -input.medium, -textarea.medium, -select.medium { - width: 150px; -} -.input-large, -input.large, -textarea.large, -select.large { - width: 210px; -} -.input-xlarge, -input.xlarge, -textarea.xlarge, -select.xlarge { - width: 270px; -} -.input-xxlarge, -input.xxlarge, -textarea.xxlarge, -select.xxlarge { - width: 530px; -} -textarea.xxlarge { - overflow-y: auto; -} -input.span1, textarea.span1 { - display: inline-block; - float: none; - width: 30px; - margin-left: 0; -} -input.span2, textarea.span2 { - display: inline-block; - float: none; - width: 90px; - margin-left: 0; -} -input.span3, textarea.span3 { - display: inline-block; - float: none; - width: 150px; - margin-left: 0; -} -input.span4, textarea.span4 { - display: inline-block; - float: none; - width: 210px; - margin-left: 0; -} -input.span5, textarea.span5 { - display: inline-block; - float: none; - width: 270px; - margin-left: 0; -} -input.span6, textarea.span6 { - display: inline-block; - float: none; - width: 330px; - margin-left: 0; -} -input.span7, textarea.span7 { - display: inline-block; - float: none; - width: 390px; - margin-left: 0; -} -input.span8, textarea.span8 { - display: inline-block; - float: none; - width: 450px; - margin-left: 0; -} -input.span9, textarea.span9 { - display: inline-block; - float: none; - width: 510px; - margin-left: 0; -} -input.span10, textarea.span10 { - display: inline-block; - float: none; - width: 570px; - margin-left: 0; -} -input.span11, textarea.span11 { - display: inline-block; - float: none; - width: 630px; - margin-left: 0; -} -input.span12, textarea.span12 { - display: inline-block; - float: none; - width: 690px; - margin-left: 0; -} -input.span13, textarea.span13 { - display: inline-block; - float: none; - width: 750px; - margin-left: 0; -} -input.span14, textarea.span14 { - display: inline-block; - float: none; - width: 810px; - margin-left: 0; -} -input.span15, textarea.span15 { - display: inline-block; - float: none; - width: 870px; - margin-left: 0; -} -input.span16, textarea.span16 { - display: inline-block; - float: none; - width: 930px; - margin-left: 0; -} -input[disabled], -select[disabled], -textarea[disabled], -input[readonly], -select[readonly], -textarea[readonly] { - background-color: #f5f5f5; - border-color: #ddd; - cursor: not-allowed; -} -.actions { - background: #f5f5f5; - margin-top: 18px; - margin-bottom: 18px; - padding: 17px 20px 18px 150px; - border-top: 1px solid #ddd; - -webkit-border-radius: 0 0 3px 3px; - -moz-border-radius: 0 0 3px 3px; - border-radius: 0 0 3px 3px; -} -.actions .secondary-action { - float: right; -} -.actions .secondary-action a { - line-height: 30px; -} -.actions .secondary-action a:hover { - text-decoration: underline; -} -.help-inline, .help-block { - font-size: 13px; - line-height: 18px; - color: #bfbfbf; -} -.help-inline { - padding-left: 5px; - *position: relative; - /* IE6-7 */ - - *top: -5px; - /* IE6-7 */ - -} -.help-block { - display: block; - max-width: 600px; -} -.inline-inputs { - color: #808080; -} -.inline-inputs span { - padding: 0 2px 0 1px; -} -.input-prepend input, .input-append input { - -webkit-border-radius: 0 3px 3px 0; - -moz-border-radius: 0 3px 3px 0; - border-radius: 0 3px 3px 0; -} -.input-prepend .add-on, .input-append .add-on { - position: relative; - background: #f5f5f5; - border: 1px solid #ccc; - z-index: 2; - float: left; - display: block; - width: auto; - min-width: 16px; - height: 18px; - padding: 4px 4px 4px 5px; - margin-right: -1px; - font-weight: normal; - line-height: 18px; - color: #bfbfbf; - text-align: center; - text-shadow: 0 1px 0 #ffffff; - -webkit-border-radius: 3px 0 0 3px; - -moz-border-radius: 3px 0 0 3px; - border-radius: 3px 0 0 3px; -} -.input-prepend .active, .input-append .active { - background: #a9dba9; - border-color: #46a546; -} -.input-prepend .add-on { - *margin-top: 1px; - /* IE6-7 */ - -} -.input-append input { - float: left; - -webkit-border-radius: 3px 0 0 3px; - -moz-border-radius: 3px 0 0 3px; - border-radius: 3px 0 0 3px; -} -.input-append .add-on { - -webkit-border-radius: 0 3px 3px 0; - -moz-border-radius: 0 3px 3px 0; - border-radius: 0 3px 3px 0; - margin-right: 0; - margin-left: -1px; -} -.inputs-list { - margin: 0 0 5px; - width: 100%; -} -.inputs-list li { - display: block; - padding: 0; - width: 100%; -} -.inputs-list label { - display: block; - float: none; - width: auto; - padding: 0; - margin-left: 20px; - line-height: 18px; - text-align: left; - white-space: normal; -} -.inputs-list label strong { - color: #808080; -} -.inputs-list label small { - font-size: 11px; - font-weight: normal; -} -.inputs-list .inputs-list { - margin-left: 25px; - margin-bottom: 10px; - padding-top: 0; -} -.inputs-list:first-child { - padding-top: 6px; -} -.inputs-list li + li { - padding-top: 2px; -} -.inputs-list input[type=radio], .inputs-list input[type=checkbox] { - margin-bottom: 0; - margin-left: -20px; - float: left; -} -.form-stacked { - padding-left: 20px; -} -.form-stacked fieldset { - padding-top: 9px; -} -.form-stacked legend { - padding-left: 0; -} -.form-stacked label { - display: block; - float: none; - width: auto; - font-weight: bold; - text-align: left; - line-height: 20px; - padding-top: 0; -} -.form-stacked .clearfix { - margin-bottom: 9px; -} -.form-stacked .clearfix div.input { - margin-left: 0; -} -.form-stacked .inputs-list { - margin-bottom: 0; -} -.form-stacked .inputs-list li { - padding-top: 0; -} -.form-stacked .inputs-list li label { - font-weight: normal; - padding-top: 0; -} -.form-stacked div.clearfix.error { - padding-top: 10px; - padding-bottom: 10px; - padding-left: 10px; - margin-top: 0; - margin-left: -10px; -} -.form-stacked .actions { - margin-left: -20px; - padding-left: 20px; -} -/* -* Tables.less -* Tables for, you guessed it, tabular data -* ---------------------------------------- */ -table { - width: 100%; - margin-bottom: 18px; - padding: 0; - font-size: 13px; - border-collapse: collapse; -} -table th, table td { - padding: 10px 10px 9px; - line-height: 18px; - text-align: center; -} -table th { - padding-top: 9px; - font-weight: bold; - vertical-align: middle; -} -table td { - vertical-align: top; - /*border-top: 1px solid #ddd;*/ -} -table tbody th { -/* border-top: 1px solid #ddd;*/ - vertical-align: top; -} -.condensed-table th, .condensed-table td { - padding: 5px 5px 4px; -} -.bordered-table { - border: 1px solid #ddd; - border-collapse: separate; - *border-collapse: collapse; - /* IE7, collapse table to remove spacing */ - - -webkit-border-radius: 4px; - -moz-border-radius: 4px; - border-radius: 4px; -} -.bordered-table th + th, .bordered-table td + td, .bordered-table th + td { - border-left: 1px solid #ddd; -} -.bordered-table thead tr:first-child th:first-child, .bordered-table tbody tr:first-child td:first-child { - -webkit-border-radius: 4px 0 0 0; - -moz-border-radius: 4px 0 0 0; - border-radius: 4px 0 0 0; -} -.bordered-table thead tr:first-child th:last-child, .bordered-table tbody tr:first-child td:last-child { - -webkit-border-radius: 0 4px 0 0; - -moz-border-radius: 0 4px 0 0; - border-radius: 0 4px 0 0; -} -.bordered-table tbody tr:last-child td:first-child { - -webkit-border-radius: 0 0 0 4px; - -moz-border-radius: 0 0 0 4px; - border-radius: 0 0 0 4px; -} -.bordered-table tbody tr:last-child td:last-child { - -webkit-border-radius: 0 0 4px 0; - -moz-border-radius: 0 0 4px 0; - border-radius: 0 0 4px 0; -} -table .span1 { - width: 20px; -} -table .span2 { - width: 60px; -} -table .span3 { - width: 100px; -} -table .span4 { - width: 140px; -} -table .span5 { - width: 180px; -} -table .span6 { - width: 220px; -} -table .span7 { - width: 260px; -} -table .span8 { - width: 300px; -} -table .span9 { - width: 340px; -} -table .span10 { - width: 380px; -} -table .span11 { - width: 420px; -} -table .span12 { - width: 460px; -} -table .span13 { - width: 500px; -} -table .span14 { - width: 540px; -} -table .span15 { - width: 580px; -} -table .span16 { - width: 620px; -} -.zebra-striped tbody tr:nth-child(odd) td, .zebra-striped tbody tr:nth-child(odd) th { - background-color: #f9f9f9; -} -.zebra-striped tbody tr:hover td, .zebra-striped tbody tr:hover th { - background-color: #f5f5f5; -} -table .header { - cursor: pointer; -} -table .header:after { - content: ""; - float: right; - margin-top: 7px; - border-width: 0 4px 4px; - border-style: solid; - border-color: #000 transparent; - visibility: hidden; -} -table .headerSortUp, table .headerSortDown { - background-color: rgba(141, 192, 219, 0.25); - text-shadow: 0 1px 1px rgba(255, 255, 255, 0.75); -} -table .header:hover:after { - visibility: visible; -} -table .headerSortDown:after, table .headerSortDown:hover:after { - visibility: visible; - filter: alpha(opacity=60); - -khtml-opacity: 0.6; - -moz-opacity: 0.6; - opacity: 0.6; -} -table .headerSortUp:after { - border-bottom: none; - border-left: 4px solid transparent; - border-right: 4px solid transparent; - border-top: 4px solid #000; - visibility: visible; - -webkit-box-shadow: none; - -moz-box-shadow: none; - box-shadow: none; - filter: alpha(opacity=60); - -khtml-opacity: 0.6; - -moz-opacity: 0.6; - opacity: 0.6; -} -table .blue { - color: #049cdb; - border-bottom-color: #049cdb; -} -table .headerSortUp.blue, table .headerSortDown.blue { - background-color: #ade6fe; -} -table .green { - color: #46a546; - border-bottom-color: #46a546; -} -table .headerSortUp.green, table .headerSortDown.green { - background-color: #cdeacd; -} -table .red { - color: #9d261d; - border-bottom-color: #9d261d; -} -table .headerSortUp.red, table .headerSortDown.red { - background-color: #f4c8c5; -} -table .yellow { - color: #ffc40d; - border-bottom-color: #ffc40d; -} -table .headerSortUp.yellow, table .headerSortDown.yellow { - background-color: #fff6d9; -} -table .orange { - color: #f89406; - border-bottom-color: #f89406; -} -.center1 -{ -margin-left: auto; -margin-right: auto; -} -table .headerSortUp.orange, table .headerSortDown.orange { - background-color: #fee9cc; -} -table .purple { - color: #7a43b6; - border-bottom-color: #7a43b6; -} -table .headerSortUp.purple, table .headerSortDown.purple { - background-color: #e2d5f0; -} -/* Patterns.less -* Repeatable UI elements outside the base styles provided from the scaffolding -* ---------------------------------------------------------------------------- */ -.topbar { - height: 40px; - position: fixed; - top: 0; - left: 0; - right: 0; - z-index: 10000; - overflow: visible; -} -.topbar a { - color: #bfbfbf; - text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); -} -.topbar h3 a:hover, .topbar .brand:hover, .topbar ul .active > a { - background-color: #333; - background-color: rgba(255, 255, 255, 0.05); - color: #ffffff; - text-decoration: none; -} -.topbar h3 { - position: relative; -} -.topbar h3 a, .topbar .brand { - float: left; - display: block; - padding: 8px 20px 12px; - margin-left: -20px; - color: #ffffff; - font-size: 20px; - font-weight: 200; - line-height: 1; -} -.topbar p { - margin: 0; - line-height: 40px; -} -.topbar p a:hover { - background-color: transparent; - color: #ffffff; -} -.topbar form { - float: left; - margin: 5px 0 0 0; - position: relative; - filter: alpha(opacity=100); - -khtml-opacity: 1; - -moz-opacity: 1; - opacity: 1; -} -.topbar form.pull-right { - float: right; -} -.topbar input { - background-color: #444; - background-color: rgba(255, 255, 255, 0.3); - font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; - font-size: normal; - font-weight: 13px; - line-height: 1; - padding: 4px 9px; - color: #ffffff; - color: rgba(255, 255, 255, 0.75); - border: 1px solid #111; - -webkit-border-radius: 4px; - -moz-border-radius: 4px; - border-radius: 4px; - -webkit-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1), 0 1px 0px rgba(255, 255, 255, 0.25); - -moz-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1), 0 1px 0px rgba(255, 255, 255, 0.25); - box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1), 0 1px 0px rgba(255, 255, 255, 0.25); - -webkit-transition: none; - -moz-transition: none; - -ms-transition: none; - -o-transition: none; - transition: none; -} -.topbar input:-moz-placeholder { - color: #e6e6e6; -} -.topbar input::-webkit-input-placeholder { - color: #e6e6e6; -} -.topbar input:hover { - background-color: #bfbfbf; - background-color: rgba(255, 255, 255, 0.5); - color: #ffffff; -} -.topbar input:focus, .topbar input.focused { - outline: 0; - background-color: #ffffff; - color: #404040; - text-shadow: 0 1px 0 #ffffff; - border: 0; - padding: 5px 10px; - -webkit-box-shadow: 0 0 3px rgba(0, 0, 0, 0.15); - -moz-box-shadow: 0 0 3px rgba(0, 0, 0, 0.15); - box-shadow: 0 0 3px rgba(0, 0, 0, 0.15); -} -.topbar-inner, .topbar .fill { - background-color: #222; - background-color: #222222; - background-repeat: repeat-x; - background-image: -khtml-gradient(linear, left top, left bottom, from(#333333), to(#222222)); - background-image: -moz-linear-gradient(top, #333333, #222222); - background-image: -ms-linear-gradient(top, #333333, #222222); - background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #333333), color-stop(100%, #222222)); - background-image: -webkit-linear-gradient(top, #333333, #222222); - background-image: -o-linear-gradient(top, #333333, #222222); - background-image: linear-gradient(top, #333333, #222222); - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#333333', endColorstr='#222222', GradientType=0); - -webkit-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.25), inset 0 -1px 0 rgba(0, 0, 0, 0.1); - -moz-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.25), inset 0 -1px 0 rgba(0, 0, 0, 0.1); - box-shadow: 0 1px 3px rgba(0, 0, 0, 0.25), inset 0 -1px 0 rgba(0, 0, 0, 0.1); -} -.topbar div > ul, .nav { - display: block; - float: left; - margin: 0 10px 0 0; - position: relative; - left: 0; -} -.topbar div > ul > li, .nav > li { - display: block; - float: left; -} -.topbar div > ul a, .nav a { - display: block; - float: none; - padding: 10px 10px 11px; - line-height: 19px; - text-decoration: none; -} -.topbar div > ul a:hover, .nav a:hover { - color: #ffffff; - text-decoration: none; -} -.topbar div > ul .active > a, .nav .active > a { - background-color: #222; - background-color: rgba(0, 0, 0, 0.5); -} -.topbar div > ul.secondary-nav, .nav.secondary-nav { - float: right; - margin-left: 10px; - margin-right: 0; -} -.topbar div > ul.secondary-nav .menu-dropdown, -.nav.secondary-nav .menu-dropdown, -.topbar div > ul.secondary-nav .dropdown-menu, -.nav.secondary-nav .dropdown-menu { - right: 0; - border: 0; -} -.topbar div > ul a.menu:hover, -.nav a.menu:hover, -.topbar div > ul li.open .menu, -.nav li.open .menu, -.topbar div > ul .dropdown-toggle:hover, -.nav .dropdown-toggle:hover, -.topbar div > ul .dropdown.open .dropdown-toggle, -.nav .dropdown.open .dropdown-toggle { - background: #444; - background: rgba(255, 255, 255, 0.05); -} -.topbar div > ul .menu-dropdown, -.nav .menu-dropdown, -.topbar div > ul .dropdown-menu, -.nav .dropdown-menu { - background-color: #333; -} -.topbar div > ul .menu-dropdown a.menu, -.nav .menu-dropdown a.menu, -.topbar div > ul .dropdown-menu a.menu, -.nav .dropdown-menu a.menu, -.topbar div > ul .menu-dropdown .dropdown-toggle, -.nav .menu-dropdown .dropdown-toggle, -.topbar div > ul .dropdown-menu .dropdown-toggle, -.nav .dropdown-menu .dropdown-toggle { - color: #ffffff; -} -.topbar div > ul .menu-dropdown a.menu.open, -.nav .menu-dropdown a.menu.open, -.topbar div > ul .dropdown-menu a.menu.open, -.nav .dropdown-menu a.menu.open, -.topbar div > ul .menu-dropdown .dropdown-toggle.open, -.nav .menu-dropdown .dropdown-toggle.open, -.topbar div > ul .dropdown-menu .dropdown-toggle.open, -.nav .dropdown-menu .dropdown-toggle.open { - background: #444; - background: rgba(255, 255, 255, 0.05); -} -.topbar div > ul .menu-dropdown li a, -.nav .menu-dropdown li a, -.topbar div > ul .dropdown-menu li a, -.nav .dropdown-menu li a { - color: #999; - text-shadow: 0 1px 0 rgba(0, 0, 0, 0.5); -} -.topbar div > ul .menu-dropdown li a:hover, -.nav .menu-dropdown li a:hover, -.topbar div > ul .dropdown-menu li a:hover, -.nav .dropdown-menu li a:hover { - background-color: #191919; - background-repeat: repeat-x; - background-image: -khtml-gradient(linear, left top, left bottom, from(#292929), to(#191919)); - background-image: -moz-linear-gradient(top, #292929, #191919); - background-image: -ms-linear-gradient(top, #292929, #191919); - background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #292929), color-stop(100%, #191919)); - background-image: -webkit-linear-gradient(top, #292929, #191919); - background-image: -o-linear-gradient(top, #292929, #191919); - background-image: linear-gradient(top, #292929, #191919); - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#292929', endColorstr='#191919', GradientType=0); - color: #ffffff; -} -.topbar div > ul .menu-dropdown .active a, -.nav .menu-dropdown .active a, -.topbar div > ul .dropdown-menu .active a, -.nav .dropdown-menu .active a { - color: #ffffff; -} -.topbar div > ul .menu-dropdown .divider, -.nav .menu-dropdown .divider, -.topbar div > ul .dropdown-menu .divider, -.nav .dropdown-menu .divider { - background-color: #222; - border-color: #444; -} -.topbar ul .menu-dropdown li a, .topbar ul .dropdown-menu li a { - padding: 4px 15px; -} -li.menu, .dropdown { - position: relative; -} -a.menu:after, .dropdown-toggle:after { - width: 0; - height: 0; - display: inline-block; - content: "↓"; - text-indent: -99999px; - vertical-align: top; - margin-top: 8px; - margin-left: 4px; - border-left: 4px solid transparent; - border-right: 4px solid transparent; - border-top: 4px solid #ffffff; - filter: alpha(opacity=50); - -khtml-opacity: 0.5; - -moz-opacity: 0.5; - opacity: 0.5; -} -.menu-dropdown, .dropdown-menu { - background-color: #ffffff; - float: left; - display: none; - position: absolute; - top: 40px; - z-index: 900; - min-width: 160px; - max-width: 220px; - _width: 160px; - margin-left: 0; - margin-right: 0; - padding: 6px 0; - zoom: 1; - border-color: #999; - border-color: rgba(0, 0, 0, 0.2); - border-style: solid; - border-width: 0 1px 1px; - -webkit-border-radius: 0 0 6px 6px; - -moz-border-radius: 0 0 6px 6px; - border-radius: 0 0 6px 6px; - -webkit-box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2); - -moz-box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2); - box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2); - -webkit-background-clip: padding-box; - -moz-background-clip: padding-box; - background-clip: padding-box; -} -.menu-dropdown li, .dropdown-menu li { - float: none; - display: block; - background-color: none; -} -.menu-dropdown .divider, .dropdown-menu .divider { - height: 1px; - margin: 5px 0; - overflow: hidden; - background-color: #eee; - border-bottom: 1px solid #ffffff; -} -.topbar .dropdown-menu a, .dropdown-menu a { - display: block; - padding: 4px 15px; - clear: both; - font-weight: normal; - line-height: 18px; - color: #808080; - text-shadow: 0 1px 0 #ffffff; -} -.topbar .dropdown-menu a:hover, -.dropdown-menu a:hover, -.topbar .dropdown-menu a.hover, -.dropdown-menu a.hover { - background-color: #dddddd; - background-repeat: repeat-x; - background-image: -khtml-gradient(linear, left top, left bottom, from(#eeeeee), to(#dddddd)); - background-image: -moz-linear-gradient(top, #eeeeee, #dddddd); - background-image: -ms-linear-gradient(top, #eeeeee, #dddddd); - background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #eeeeee), color-stop(100%, #dddddd)); - background-image: -webkit-linear-gradient(top, #eeeeee, #dddddd); - background-image: -o-linear-gradient(top, #eeeeee, #dddddd); - background-image: linear-gradient(top, #eeeeee, #dddddd); - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#eeeeee', endColorstr='#dddddd', GradientType=0); - color: #404040; - text-decoration: none; - -webkit-box-shadow: inset 0 1px 0 rgba(0, 0, 0, 0.025), inset 0 -1px rgba(0, 0, 0, 0.025); - -moz-box-shadow: inset 0 1px 0 rgba(0, 0, 0, 0.025), inset 0 -1px rgba(0, 0, 0, 0.025); - box-shadow: inset 0 1px 0 rgba(0, 0, 0, 0.025), inset 0 -1px rgba(0, 0, 0, 0.025); -} -footer { - margin-top: 17px; - padding-top: 17px; -} -.page-header { - margin-bottom: 17px; - border-bottom: 1px solid #ddd; - -webkit-box-shadow: 0 1px 0 rgba(255, 255, 255, 0.5); - -moz-box-shadow: 0 1px 0 rgba(255, 255, 255, 0.5); - box-shadow: 0 1px 0 rgba(255, 255, 255, 0.5); -} -.page-header h3 { - margin-top: 20px; - margin-bottom : -17px; -} -.btn.danger, -.alert-message.danger, -.btn.danger:hover, -.alert-message.danger:hover, -.btn.error, -.alert-message.error, -.btn.error:hover, -.alert-message.error:hover, -.btn.success, -.alert-message.success, -.btn.success:hover, -.alert-message.success:hover, -.btn.info, -.alert-message.info, -.btn.info:hover, -.alert-message.info:hover { - color: #ffffff; -} -.btn .close, .alert-message .close { - font-family: Arial, sans-serif; - line-height: 18px; -} -.btn-mini { - padding: 2px 6px; - font-size: 15px; - line-height: 16px; -} -.btn.danger, -.alert-message.danger, -.btn.error, -.alert-message.error { - background-color: #c43c35; - background-repeat: repeat-x; - background-image: -khtml-gradient(linear, left top, left bottom, from(#ee5f5b), to(#c43c35)); - background-image: -moz-linear-gradient(top, #ee5f5b, #c43c35); - background-image: -ms-linear-gradient(top, #ee5f5b, #c43c35); - background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #ee5f5b), color-stop(100%, #c43c35)); - background-image: -webkit-linear-gradient(top, #ee5f5b, #c43c35); - background-image: -o-linear-gradient(top, #ee5f5b, #c43c35); - background-image: linear-gradient(top, #ee5f5b, #c43c35); - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ee5f5b', endColorstr='#c43c35', GradientType=0); - text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); - border-color: #c43c35 #c43c35 #882a25; - border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); -} -.btn.success, .alert-message.success { - background-color: #57a957; - background-repeat: repeat-x; - background-image: -khtml-gradient(linear, left top, left bottom, from(#62c462), to(#57a957)); - background-image: -moz-linear-gradient(top, #62c462, #57a957); - background-image: -ms-linear-gradient(top, #62c462, #57a957); - background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #62c462), color-stop(100%, #57a957)); - background-image: -webkit-linear-gradient(top, #62c462, #57a957); - background-image: -o-linear-gradient(top, #62c462, #57a957); - background-image: linear-gradient(top, #62c462, #57a957); - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#62c462', endColorstr='#57a957', GradientType=0); - text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); - border-color: #57a957 #57a957 #3d773d; - border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); -} -.btn.info, .alert-message.info { - background-color: #339bb9; - background-repeat: repeat-x; - background-image: -khtml-gradient(linear, left top, left bottom, from(#5bc0de), to(#339bb9)); - background-image: -moz-linear-gradient(top, #5bc0de, #339bb9); - background-image: -ms-linear-gradient(top, #5bc0de, #339bb9); - background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #5bc0de), color-stop(100%, #339bb9)); - background-image: -webkit-linear-gradient(top, #5bc0de, #339bb9); - background-image: -o-linear-gradient(top, #5bc0de, #339bb9); - background-image: linear-gradient(top, #5bc0de, #339bb9); - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#5bc0de', endColorstr='#339bb9', GradientType=0); - text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); - border-color: #339bb9 #339bb9 #22697d; - border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); -} -.btn { - cursor: pointer; - display: inline-block; - background-color: #e6e6e6; - background-repeat: no-repeat; - background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#ffffff), color-stop(25%, #ffffff), to(#e6e6e6)); - background-image: -webkit-linear-gradient(#ffffff, #ffffff 25%, #e6e6e6); - background-image: -moz-linear-gradient(top, #ffffff, #ffffff 25%, #e6e6e6); - background-image: -ms-linear-gradient(#ffffff, #ffffff 25%, #e6e6e6); - background-image: -o-linear-gradient(#ffffff, #ffffff 25%, #e6e6e6); - background-image: linear-gradient(#ffffff, #ffffff 25%, #e6e6e6); - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffff', endColorstr='#e6e6e6', GradientType=0); - padding: 5px 14px 6px; - text-shadow: 0 1px 1px rgba(255, 255, 255, 0.75); - color: #333; - font-size: 13px; - line-height: normal; - border: 1px solid #ccc; - border-bottom-color: #bbb; - -webkit-border-radius: 4px; - -moz-border-radius: 4px; - border-radius: 4px; - -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05); - -moz-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05); - box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05); - -webkit-transition: 0.1s linear all; - -moz-transition: 0.1s linear all; - -ms-transition: 0.1s linear all; - -o-transition: 0.1s linear all; - transition: 0.1s linear all; -} -.btn:hover { - background-position: 0 -15px; - color: #333; - text-decoration: none; -} -.btn:focus { - outline: 1px dotted #666; -} -.btn.primary { - color: #ffffff; - background-color: #0064cd; - background-repeat: repeat-x; - background-image: -khtml-gradient(linear, left top, left bottom, from(#049cdb), to(#0064cd)); - background-image: -moz-linear-gradient(top, #049cdb, #0064cd); - background-image: -ms-linear-gradient(top, #049cdb, #0064cd); - background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #049cdb), color-stop(100%, #0064cd)); - background-image: -webkit-linear-gradient(top, #049cdb, #0064cd); - background-image: -o-linear-gradient(top, #049cdb, #0064cd); - background-image: linear-gradient(top, #049cdb, #0064cd); - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#049cdb', endColorstr='#0064cd', GradientType=0); - text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); - border-color: #0064cd #0064cd #003f81; - border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); -} -.btn.active, .btn:active { - -webkit-box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.25), 0 1px 2px rgba(0, 0, 0, 0.05); - -moz-box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.25), 0 1px 2px rgba(0, 0, 0, 0.05); - box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.25), 0 1px 2px rgba(0, 0, 0, 0.05); -} -.btn.disabled { - cursor: default; - background-image: none; - filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); - filter: alpha(opacity=65); - -khtml-opacity: 0.65; - -moz-opacity: 0.65; - opacity: 0.65; - -webkit-box-shadow: none; - -moz-box-shadow: none; - box-shadow: none; -} -.btn[disabled] { - cursor: default; - background-image: none; - filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); - filter: alpha(opacity=65); - -khtml-opacity: 0.65; - -moz-opacity: 0.65; - opacity: 0.65; - -webkit-box-shadow: none; - -moz-box-shadow: none; - box-shadow: none; -} -.btn.large { - font-size: 15px; - line-height: normal; - padding: 9px 14px 9px; - -webkit-border-radius: 6px; - -moz-border-radius: 6px; - border-radius: 6px; -} -.btn.small { - padding: 7px 9px 7px; - font-size: 11px; -} -:root .alert-message, :root .btn { - border-radius: 0 \0; -} -.alert { - padding: 8px 35px 8px 14px; - margin-bottom: 18px; - text-shadow: 0 1px 0 rgba(255, 255, 255, 0.5); - background-color: #fcf8e3; - border: 1px solid #fbeed5; - -webkit-border-radius: 4px; - -moz-border-radius: 4px; - border-radius: 4px; -} -.alert, .alert-heading { - color: #c09853; -} -.alert .close { - position: relative; - top: -2px; - right: -21px; - line-height: 18px; -} -.alert-success { - background-color: #dff0d8; - border-color: #d6e9c6; -} -.alert-success, .alert-success .alert-heading { - color: #468847; -} -.alert-danger, .alert-error { - background-color: #f2dede; - border-color: #eed3d7; -} -.alert-danger, -.alert-error, -.alert-danger .alert-heading, -.alert-error .alert-heading { - color: #b94a48; -} -.alert-info { - background-color: #d9edf7; - border-color: #bce8f1; -} -.alert-info, .alert-info .alert-heading { - color: #3a87ad; -} -.alert-block { - padding-top: 14px; - padding-bottom: 14px; -} -.alert-block > p, .alert-block > ul { - margin-bottom: 0; -} -.alert-block p + p { - margin-top: 5px; -} - -button.btn::-moz-focus-inner, input[type=submit].btn::-moz-focus-inner { - padding: 0; - border: 0; -} -.alert-message { - position: relative; - padding: 7px 15px; - margin-bottom: 18px; - color: #404040; - background-color: #eedc94; - background-repeat: repeat-x; - background-image: -khtml-gradient(linear, left top, left bottom, from(#fceec1), to(#eedc94)); - background-image: -moz-linear-gradient(top, #fceec1, #eedc94); - background-image: -ms-linear-gradient(top, #fceec1, #eedc94); - background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #fceec1), color-stop(100%, #eedc94)); - background-image: -webkit-linear-gradient(top, #fceec1, #eedc94); - background-image: -o-linear-gradient(top, #fceec1, #eedc94); - background-image: linear-gradient(top, #fceec1, #eedc94); - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fceec1', endColorstr='#eedc94', GradientType=0); - text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); - border-color: #eedc94 #eedc94 #e4c652; - border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); - text-shadow: 0 1px 0 rgba(255, 255, 255, 0.5); - border-width: 1px; - border-style: solid; - -webkit-border-radius: 4px; - -moz-border-radius: 4px; - border-radius: 4px; - -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.25); - -moz-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.25); - box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.25); -} -.alert-message .close { - margin-top: 1px; - *margin-top: 0; -} -.alert-message a { - font-weight: bold; - color: #404040; -} -.alert-message.danger p a, -.alert-message.error p a, -.alert-message.success p a, -.alert-message.info p a { - color: #ffffff; -} -.alert-message h5 { - line-height: 18px; -} -.alert-message p { - margin-bottom: 0; -} -.alert-message div { - margin-top: 5px; - margin-bottom: 2px; - line-height: 28px; -} -.alert-message .btn { - -webkit-box-shadow: 0 1px 0 rgba(255, 255, 255, 0.25); - -moz-box-shadow: 0 1px 0 rgba(255, 255, 255, 0.25); - box-shadow: 0 1px 0 rgba(255, 255, 255, 0.25); -} -.alert-message.block-message { - background-image: none; - background-color: #fdf5d9; - filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); - padding: 14px; - border-color: #fceec1; - -webkit-box-shadow: none; - -moz-box-shadow: none; - box-shadow: none; -} -.alert-message.block-message ul, .alert-message.block-message p { - margin-right: 30px; -} -.alert-message.block-message ul { - margin-bottom: 0; -} -.alert-message.block-message li { - color: #404040; -} -.alert-message.block-message .alert-actions { - margin-top: 5px; -} -.alert-message.block-message.error, .alert-message.block-message.success, .alert-message.block-message.info { - color: #404040; - text-shadow: 0 1px 0 rgba(255, 255, 255, 0.5); -} -.alert-message.block-message.error { - background-color: #fddfde; - border-color: #fbc7c6; -} -.alert-message.block-message.success { - background-color: #d1eed1; - border-color: #bfe7bf; -} -.alert-message.block-message.info { - background-color: #ddf4fb; - border-color: #c6edf9; -} -.alert-message.block-message.danger p a, -.alert-message.block-message.error p a, -.alert-message.block-message.success p a, -.alert-message.block-message.info p a { - color: #404040; -} -.label { - padding: 1px 3px 2px; - font-size: 9.75px; - font-weight: bold; - color: #ffffff; - text-transform: uppercase; - white-space: nowrap; - background-color: #bfbfbf; - -webkit-border-radius: 3px; - -moz-border-radius: 3px; - border-radius: 3px; - text-shadow: none; -} -.label.important { - background-color: #c43c35; -} -.label.warning { - background-color: #f89406; -} -.label.success { - background-color: #46a546; -} -.label.notice { - background-color: #62cffc; -} -.well { - background-color: #f5f5f5; - margin-bottom: 20px; - padding: 19px; - min-height: 20px; - border: 1px solid #eee; - border: 1px solid rgba(0, 0, 0, 0.05); - -webkit-border-radius: 4px; - -moz-border-radius: 4px; - border-radius: 4px; - -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.05); - -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.05); - box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.05); -} -.well blockquote { - border-color: #ddd; - border-color: rgba(0, 0, 0, 0.15); -} -.modal-backdrop { - background-color: #000000; - position: fixed; - top: 0; - left: 0; - right: 0; - bottom: 0; - z-index: 10000; -} -.modal-backdrop.fade { - opacity: 0; -} -.modal-backdrop, .modal-backdrop.fade.in { - filter: alpha(opacity=80); - -khtml-opacity: 0.8; - -moz-opacity: 0.8; - opacity: 0.8; -} -.modal { - position: fixed; - top: 10%; - left: 50%; - z-index: 1050; - width: 560px; - margin-left: -280px; - background-color: #ffffff; - border: 1px solid #999; - border: 1px solid rgba(0, 0, 0, 0.3); - *border: 1px solid #999; - -webkit-border-radius: 6px; - -moz-border-radius: 6px; - border-radius: 6px; - outline: none; - -webkit-box-shadow: 0 3px 7px rgba(0, 0, 0, 0.3); - -moz-box-shadow: 0 3px 7px rgba(0, 0, 0, 0.3); - box-shadow: 0 3px 7px rgba(0, 0, 0, 0.3); - -webkit-background-clip: padding-box; - -moz-background-clip: padding-box; - background-clip: padding-box; -} -.modal.fade { - top: -25%; - -webkit-transition: opacity 0.3s linear, top 0.3s ease-out; - -moz-transition: opacity 0.3s linear, top 0.3s ease-out; - -o-transition: opacity 0.3s linear, top 0.3s ease-out; - transition: opacity 0.3s linear, top 0.3s ease-out; -} - -.modal.fade.in { - top: 10%; -} - -.modal-header { - padding: 9px 15px; - border-bottom: 1px solid #eee; -} - -.modal-header .close { - margin-top: 2px; -} - -.modal-header h3 { - margin: 0; - line-height: 30px; -} - -.modal-body { - position: relative; - max-height: 400px; - padding: 15px; - overflow-y: auto; -} - -.modal-form { - margin-bottom: 0; -} - -.modal-footer { - padding: 14px 15px 15px; - margin-bottom: 0; - text-align: right; - background-color: #f5f5f5; - border-top: 1px solid #ddd; - -webkit-border-radius: 0 0 6px 6px; - -moz-border-radius: 0 0 6px 6px; - border-radius: 0 0 6px 6px; - *zoom: 1; - -webkit-box-shadow: inset 0 1px 0 #ffffff; - -moz-box-shadow: inset 0 1px 0 #ffffff; - box-shadow: inset 0 1px 0 #ffffff; -} - -.modal-footer:before, -.modal-footer:after { - display: table; - line-height: 0; - content: ""; -} - -.modal-footer:after { - clear: both; -} - -.modal-footer .btn + .btn { - margin-bottom: 0; - margin-left: 5px; -} - -.modal-footer .btn-group .btn + .btn { - margin-left: -1px; -} - -.modal-footer .btn-block + .btn-block { - margin-left: 0; -} -.tabs, .pills { - margin: 0 0 18px; - padding: 0; - list-style: none; - zoom: 1; -} -.tabs:before, -.pills:before, -.tabs:after, -.pills:after { - display: table; - content: ""; - zoom: 1; -} -.tabs:after, .pills:after { - clear: both; -} -.tabs > li, .pills > li { - float: left; -} -.tabs > li > a, .pills > li > a { - display: block; -} -.tabs { - border-color: #ddd; - border-style: solid; - border-width: 0 0 1px; -} -.tabs > li { - position: relative; - margin-bottom: -1px; -} -.tabs > li > a { - padding: 0 15px; - margin-right: 2px; - line-height: 23px; - border: 1px solid transparent; - -webkit-border-radius: 4px 4px 0 0; - -moz-border-radius: 4px 4px 0 0; - border-radius: 4px 4px 0 0; -} -.tabs > li > a:hover { - text-decoration: none; - background-color: #eee; - border-color: #eee #eee #ddd; -} -.tabs .active > a, .tabs .active > a:hover { - color: #808080; - background-color: #ffffff; - border: 1px solid #ddd; - border-bottom-color: transparent; - cursor: default; -} -.tabs .menu-dropdown, .tabs .dropdown-menu { - top: 35px; - border-width: 1px; - -webkit-border-radius: 0 6px 6px 6px; - -moz-border-radius: 0 6px 6px 6px; - border-radius: 0 6px 6px 6px; -} -.tabs a.menu:after, .tabs .dropdown-toggle:after { - border-top-color: #999; - margin-top: 15px; - margin-left: 5px; -} -.tabs li.open.menu .menu, .tabs .open.dropdown .dropdown-toggle { - border-color: #999; -} -.tabs li.open a.menu:after, .tabs .dropdown.open .dropdown-toggle:after { - border-top-color: #555; -} -.pills a { - margin: 5px 3px 5px 0; - padding: 0 15px; - line-height: 30px; - text-shadow: 0 1px 1px #ffffff; - -webkit-border-radius: 15px; - -moz-border-radius: 15px; - border-radius: 15px; -} -.pills a:hover { - color: #ffffff; - text-decoration: none; - text-shadow: 0 1px 1px rgba(0, 0, 0, 0.25); - background-color: #00438a; -} -.pills .active a { - color: #ffffff; - text-shadow: 0 1px 1px rgba(0, 0, 0, 0.25); - background-color: #0069d6; -} -.pills-vertical > li { - float: none; -} -.tab-content > .tab-pane, .pill-content > .pill-pane { - display: none; -} -.tab-content > .active, .pill-content > .active { - display: block; -} diff --git a/testapp/static/exam/css/gradeuser.css b/testapp/static/exam/css/gradeuser.css deleted file mode 100644 index 07b1079..0000000 --- a/testapp/static/exam/css/gradeuser.css +++ /dev/null @@ -1,52 +0,0 @@ -textarea -{ -width : 550px; -height : 200px; - -} - -.for-question{ - background: none repeat scroll 0 0 #F1F1F1; - border-radius: 6px 6px 6px 6px; - margin-bottom: 10px; - padding: 5px; -} - -#headerDiv, #contentDiv { -float: left; -} -#titleText { -float: left; -font-size: 1.1em; -font-weight: bold; -margin: 5px; -} -#myHeader { -font-size: 1.1em; -font-weight: bold; -margin: 5px; -} -#headerDiv { -background-color: #0037DB; -color: #9EB6FF; -} - -#contentDiv { - background-color:#F0F8FF; - border: 1px solid #C9C9C9; - border-radius: 5px 5px 5px 5px; - margin-bottom: 10px; - min-width: 805px; - -} - -#myContent { -margin: 5px 10px; - -} -#headerDiv a { -float: right; -margin: 10px 10px 5px 5px; -} -#headerDiv a:hover { -color: #FFFFFF; diff --git a/testapp/static/exam/css/login.css b/testapp/static/exam/css/login.css deleted file mode 100644 index a10cbaa..0000000 --- a/testapp/static/exam/css/login.css +++ /dev/null @@ -1,10 +0,0 @@ -label -{ - padding-top: 6px; - font-size: 15px; - line-height: 18px; - float: left; - width: 80px; - text-align: center; - color: #404040; - } diff --git a/testapp/static/exam/css/monitor.css b/testapp/static/exam/css/monitor.css deleted file mode 100644 index b16c8b3..0000000 --- a/testapp/static/exam/css/monitor.css +++ /dev/null @@ -1,11 +0,0 @@ - table td - { - vertical-align: top; - border-top: 1px solid #ddd; - } - table tbody th - { - border-top: 1px solid #ddd; - vertical-align: top; - } - diff --git a/testapp/static/exam/css/question.css b/testapp/static/exam/css/question.css deleted file mode 100644 index 4bf5913..0000000 --- a/testapp/static/exam/css/question.css +++ /dev/null @@ -1,42 +0,0 @@ -.time-div -{ - background-color:black; - padding: 8px; - color: #5DFC0A; - vertical-align:middle; - width:150px; - float:right; - border-radius: 6px 6px 6px 6px; -} -.td1-class -{ - width:175px; -} -.td2-class -{ - width:50px; -} -.page-header { - height:50px; - text-align: center; - background-color: #f5f5f5; - padding: 35px 20px 10px; - margin: -20px -20px 20px; -} -#codeTextarea{ - - } - .textAreaWithLines{ - font-family:courier; - border:1px solid #eee; - - } - .textAreaWithLines textarea,.textAreaWithLines div{ - border:0px; - line-height:120%; - font-size:12px; - } - .lineObj{ - color: grey; - } - diff --git a/testapp/static/exam/css/question_paper_creation.css b/testapp/static/exam/css/question_paper_creation.css deleted file mode 100644 index c915320..0000000 --- a/testapp/static/exam/css/question_paper_creation.css +++ /dev/null @@ -1,119 +0,0 @@ -body { - font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; - font-size: 13px; - font-weight: normal; - line-height: 18px; - color: #404040; -} -.clearfix { - clear: both; -} -.tabs li { - text-align: center; - width: 33%; -} -.tabs li:last-child { - width: 34%; -} -.tabs > .active > a { - border: 0; - background: lightgreen; -} -.tabs > .active > a:hover { - border: 0; - background: green; - color: #ffffff; -} -.tabs li a { - border-radius: 0; - margin-right: 0; -} -.tabs { - border: 1px solid #ddd; -} -#progress { - background: red; -} -#content-left{ - text-align: center; - background: grey; -} -#content-right{ - text-align: center; - background: grey; -} -#selectors { - margin-left: 0; - background: #fafafa; - padding: 7px 0; - border: 2px solid #f5f5f5; -} -#selectors .span4 { - margin-left: 0; -} -#id_question_type { - width: 100%; -} -#id_marks { - width: 100%; -} -#fixed-questions .span7 > div, -#random-questions .span7 > div{ - background: #f5f5f5; - height: 200px; - border: 1px solid #333333; - padding: 5px; -} -#fixed-available, -#random-available { - height: 125px; - min-height: 125px; - overflow-y: scroll; - margin-bottom: 15px; -} -#fixed-added, -#random-added { - height: 160px; - overflow-y: scroll; -} -#fixed-added hr, -#random-added hr { - margin: 5px 0 4px; -} -.qcard { - position: relative; - background: #ffffff; - padding: 5px; - margin: 5px 5px; - box-shadow: 1px 1px 5px #cccccc; - -webkit-box-shadow: 1px 1px 5px #cccccc; - -moz-box-shadow: 1px 1px 5px #cccccc; - -o-box-shadow: 1px 1px 5px #cccccc; -} -.qcard ul { - margin-bottom: 5px; -} -.qcard .remove { - position: absolute; - - top: 3px; - right: 3px; - padding: 1px 3px; - text-decoration: none; - color: #ffffff; - background: #ff4136; - border-radius: 3px; - font-weight: bold; -} -.qcard .remove:hover { - background: #333333; -} -.red-alert { - border: 2px solid red; -} -#myModal .qcard .remove{ - display: none; -} -.well{ - padding: 5px; -} diff --git a/testapp/static/exam/css/question_quiz.css b/testapp/static/exam/css/question_quiz.css deleted file mode 100644 index b702bd4..0000000 --- a/testapp/static/exam/css/question_quiz.css +++ /dev/null @@ -1,18 +0,0 @@ -table th, table td - { - text-align: left; - } - -.mini-text -{ - height : 9px; - width : 30px; -} -.select-type -{ - width : 80px; -} -.tag-text -{ - width : 290px; -} diff --git a/testapp/static/exam/css/showusers.css b/testapp/static/exam/css/showusers.css deleted file mode 100644 index 66a3746..0000000 --- a/testapp/static/exam/css/showusers.css +++ /dev/null @@ -1,5 +0,0 @@ -.table-class -{ - text-align:left; - width:60%; -} diff --git a/testapp/static/exam/js/add_question.js b/testapp/static/exam/js/add_question.js deleted file mode 100644 index 267cdb2..0000000 --- a/testapp/static/exam/js/add_question.js +++ /dev/null @@ -1,206 +0,0 @@ -function increase(frm) -{ - if(frm.points.value == "") - { - frm.points.value = "0.5"; - return; - } - frm.points.value = parseFloat(frm.points.value) + 0.5; -} - -function decrease(frm) -{ - if(frm.points.value > 0) - { - frm.points.value = parseFloat(frm.points.value) - 0.5; - } - else - { - frm.points.value=0; - } - - -} - -function setSelectionRange(input, selectionStart, selectionEnd) -{ - if (input.setSelectionRange) - { - input.focus(); - input.setSelectionRange(selectionStart, selectionEnd); - } - else if (input.createTextRange) - { - var range = input.createTextRange(); - range.collapse(true); - range.moveEnd('character', selectionEnd); - range.moveStart('character', selectionStart); - range.select(); - } -} - -function replaceSelection (input, replaceString) -{ - if (input.setSelectionRange) - { - var selectionStart = input.selectionStart; - var selectionEnd = input.selectionEnd; - input.value = input.value.substring(0, selectionStart)+ replaceString + input.value.substring(selectionEnd); - if (selectionStart != selectionEnd) - { - setSelectionRange(input, selectionStart, selectionStart + replaceString.length); - } - else - { - setSelectionRange(input, selectionStart + replaceString.length, selectionStart + replaceString.length); - } - } - else if (document.selection) - { - var range = document.selection.createRange(); - if (range.parentElement() == input) - { - var isCollapsed = range.text == ''; - range.text = replaceString; - if (!isCollapsed) - { - range.moveStart('character', -replaceString.length); - range.select(); - } - } - } -} - -function textareaformat() -{ - document.getElementById('id_type').setAttribute('class','select-type'); - document.getElementById('id_points').setAttribute('class','mini-text'); - document.getElementById('id_tags').setAttribute('class','tag-text'); - - - $('#id_snippet').bind('keydown', function( event ){ - if(navigator.userAgent.match("Gecko")) - { - c=event.which; - } - else - { - c=event.keyCode; - } - if(c==9) - { - replaceSelection(document.getElementById('id_snippet'),String.fromCharCode(9)); - setTimeout(document.getElementById('id_snippet'),0); - return false; - } - }); - - $('#id_description').bind('focus', function( event ){ - document.getElementById("id_description").rows=5; - document.getElementById("id_description").cols=40; - }); - - $('#id_description').bind('blur', function( event ){ - document.getElementById("id_description").rows=1; - document.getElementById("id_description").cols=40; - }); - - $('#id_description').bind('keypress', function (event){ - document.getElementById('my').innerHTML = document.getElementById('id_description').value ; - }); - - $('#id_test').bind('focus', function( event ){ - document.getElementById("id_test").rows=5; - document.getElementById("id_test").cols=40; - }); - - $('#id_test').bind('blur', function( event ){ - document.getElementById("id_test").rows=1; - document.getElementById("id_test").cols=40; - }); - - $('#id_options').bind('focus', function( event ){ - document.getElementById("id_options").rows=5; - document.getElementById("id_options").cols=40; - }); - $('#id_options').bind('blur', function( event ){ - document.getElementById("id_options").rows=1; - document.getElementById("id_options").cols=40; - }); - - $('#id_snippet').bind('focus', function( event ){ - document.getElementById("id_snippet").rows=5; - document.getElementById("id_snippet").cols=40; - }); - $('#id_snippet').bind('blur', function( event ){ - document.getElementById("id_snippet").rows=1; - document.getElementById("id_snippet").cols=40; - }); - - - $('#id_type').bind('focus', function(event){ - var type = document.getElementById('id_type'); - type.style.border = '1px solid #ccc'; - }); - - $('#id_language').bind('focus', function(event){ - var language = document.getElementById('id_language'); - language.style.border = '1px solid #ccc'; - }); - - $('#id_type').bind('change',function(event){ - var value = document.getElementById('id_type').value; - if(value == 'mcq' || value == 'mcc') - { - document.getElementById('id_options').style.visibility='visible'; - document.getElementById('label_option').innerHTML="Options :" - - } - else - { - document.getElementById('id_options').style.visibility='hidden'; - document.getElementById('label_option').innerHTML = ""; - } - }); - document.getElementById('my').innerHTML = document.getElementById('id_description').value ; - var value = document.getElementById('id_type').value; - if(value == 'mcq' || value == 'mcc') - { - document.getElementById('id_options').style.visibility='visible'; - document.getElementById('label_option').innerHTML="Options :" - - } - else - { - document.getElementById('id_options').style.visibility='hidden'; - document.getElementById('label_option').innerHTML = ""; - } -} - -function autosubmit() -{ - var language = document.getElementById('id_language'); - if(language.value == 'select') - { - language.style.border="solid red"; - return false; - } - var type = document.getElementById('id_type'); - if(type.value == 'select') - { - type.style.border = 'solid red'; - return false; - } - - if (type.value == 'mcq' || type.value == 'mcc') - { - var value = document.getElementById('id_options').value; - if(value.split('\n').length < 4) - { - alert("Please Enter 4 options. One option per line."); - return false; - } - return true; - } - -} diff --git a/testapp/static/exam/js/add_questionpaper.js b/testapp/static/exam/js/add_questionpaper.js deleted file mode 100644 index 6185dd5..0000000 --- a/testapp/static/exam/js/add_questionpaper.js +++ /dev/null @@ -1,25 +0,0 @@ -function load_data() -{ - var url_root = document.getElementById('url_root').value; - var value = document.getElementById('mode').value; - var pathArray = window.location.pathname.split( '/' ); - length = pathArray.length; - var digit = parseInt(pathArray[length-2]); - - if (! isNaN(digit) && value == 'Automatic') - { - window.location = url_root + "/exam/manage/designquestionpaper/automatic/" + digit; - } - else if(!isNaN(digit) && value == 'Manual') - { - window.location = url_root + "/exam/manage/designquestionpaper/manual/" + digit; - } - else if(value == 'Automatic') - { - window.location = window.location.pathname + "automatic"; - } - else if( value == 'Manual') - { - window.location = window.location.pathname + "manual"; - } -} diff --git a/testapp/static/exam/js/add_quiz.js b/testapp/static/exam/js/add_quiz.js deleted file mode 100644 index d5688a8..0000000 --- a/testapp/static/exam/js/add_quiz.js +++ /dev/null @@ -1,7 +0,0 @@ -function test() -{ - if (document.getElementById("id_description").value != "") - { - document.getElementById("submit").innerHTML = "Save"; - } -} diff --git a/testapp/static/exam/js/bootstrap-modal.js b/testapp/static/exam/js/bootstrap-modal.js deleted file mode 100644 index b328217..0000000 --- a/testapp/static/exam/js/bootstrap-modal.js +++ /dev/null @@ -1,260 +0,0 @@ -/* ========================================================= - * bootstrap-modal.js v1.4.0 - * http://twitter.github.com/bootstrap/javascript.html#modal - * ========================================================= - * Copyright 2011 Twitter, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ========================================================= */ - - -!function( $ ){ - - "use strict" - - /* CSS TRANSITION SUPPORT (https://gist.github.com/373874) - * ======================================================= */ - - var transitionEnd - - $(document).ready(function () { - - $.support.transition = (function () { - var thisBody = document.body || document.documentElement - , thisStyle = thisBody.style - , support = thisStyle.transition !== undefined || thisStyle.WebkitTransition !== undefined || thisStyle.MozTransition !== undefined || thisStyle.MsTransition !== undefined || thisStyle.OTransition !== undefined - return support - })() - - // set CSS transition event type - if ( $.support.transition ) { - transitionEnd = "TransitionEnd" - if ( $.browser.webkit ) { - transitionEnd = "webkitTransitionEnd" - } else if ( $.browser.mozilla ) { - transitionEnd = "transitionend" - } else if ( $.browser.opera ) { - transitionEnd = "oTransitionEnd" - } - } - - }) - - - /* MODAL PUBLIC CLASS DEFINITION - * ============================= */ - - var Modal = function ( content, options ) { - this.settings = $.extend({}, $.fn.modal.defaults, options) - this.$element = $(content) - .delegate('.close', 'click.modal', $.proxy(this.hide, this)) - - if ( this.settings.show ) { - this.show() - } - - return this - } - - Modal.prototype = { - - toggle: function () { - return this[!this.isShown ? 'show' : 'hide']() - } - - , show: function () { - var that = this - this.isShown = true - this.$element.trigger('show') - - escape.call(this) - backdrop.call(this, function () { - var transition = $.support.transition && that.$element.hasClass('fade') - - that.$element - .appendTo(document.body) - .show() - - if (transition) { - that.$element[0].offsetWidth // force reflow - } - - that.$element.addClass('in') - - transition ? - that.$element.one(transitionEnd, function () { that.$element.trigger('shown') }) : - that.$element.trigger('shown') - - }) - - return this - } - - , hide: function (e) { - e && e.preventDefault() - - if ( !this.isShown ) { - return this - } - - var that = this - this.isShown = false - - escape.call(this) - - this.$element - .trigger('hide') - .removeClass('in') - - $.support.transition && this.$element.hasClass('fade') ? - hideWithTransition.call(this) : - hideModal.call(this) - - return this - } - - } - - - /* MODAL PRIVATE METHODS - * ===================== */ - - function hideWithTransition() { - // firefox drops transitionEnd events :{o - var that = this - , timeout = setTimeout(function () { - that.$element.unbind(transitionEnd) - hideModal.call(that) - }, 500) - - this.$element.one(transitionEnd, function () { - clearTimeout(timeout) - hideModal.call(that) - }) - } - - function hideModal (that) { - this.$element - .hide() - .trigger('hidden') - - backdrop.call(this) - } - - function backdrop ( callback ) { - var that = this - , animate = this.$element.hasClass('fade') ? 'fade' : '' - if ( this.isShown && this.settings.backdrop ) { - var doAnimate = $.support.transition && animate - - this.$backdrop = $('"); - $element.html(random_number + " question(s) will be selected from " + count + " question(s)").append(html).append($input_random).append($input_number).append($remove); - $("#random-added").prepend($element); - total_marks = total_marks + random_number * marks_per; - $total_marks.text(total_marks) - } else { - $numbers.addClass("red-alert"); - } - e.preventDefault(); - }); - - /* removing added questions */ - $(".qcard .remove").live("click", function(e) { - var marks_per = $(this).attr('data-marks'); - var num_question = $(this).attr('data-num'); - var sub_marks = marks_per*num_question; - var total_marks = parseFloat($total_marks.text()); - total_marks = total_marks - sub_marks; - $total_marks.text(total_marks); - - $(this).parent().slideUp("normal", function(){ $(this).remove(); }); - e.preventDefault(); - }); - - /* showing/hiding selectors on tab click */ - $(".tabs li").click(function() { - if($(this).attr("id") == "finish-tab") { - $("#selectors").hide(); - } else { - $question_type.val('select'); - $marks.val('select') - $("#selectors").show(); - } - }); - /* check all questions on checked*/ - $("#checkall").live("click", function(){ - if($(this).attr("checked")) { - if($("#fixed-tab").hasClass("active")) { - $("#fixed-available input:checkbox").each(function(index, element) { - $(this).attr('checked','checked'); - }); - } - else { - $("#random-available input:checkbox").each(function(index, element) { - $(this).attr('checked','checked'); - }); - } - } - else { - if($("#fixed-tab").hasClass("active")) { - $("#fixed-available input:checkbox").each(function(index, element) { - $(this).removeAttr('checked'); - }); - } - else { - $("#random-available input:checkbox").each(function(index, element) { - $(this).removeAttr('checked'); - }); - } - } - }); - - /* show preview on preview click */ - $("#preview").click(function(){ - questions = getQuestions() - if(questions.trim() == ""){ - $('#modal_body').html("No questions selected"); - } - else { - $('#modal_body').html(questions); - } - $("#myModal").modal('show'); - }); - - /* tab change on next or previous button click */ - $("#fixed-next").click(function(){ - $("#random").click(); - }); - $("#random-next").click(function(){ - $("#finished").click(); - }); - - $("#random-prev").click(function(){ - $("#fixed").click(); - }); - - $("#finish-prev").click(function(){ - $("#random").click(); - }); - - /* Check at least one question is present before saving */ - $('#save').click(function(){ - questions = getQuestions(); - if(questions.trim() == ""){ - $("#modalSave").modal("show"); - } - else { - document.forms["frm"].submit(); - } - }); - - /* Fetch selected questions */ - function getQuestions(){ - var fixed_div = $("#fixed-added").html(); - var random_div = $("#random-added").html(); - return fixed_div+random_div; - } -}); //document diff --git a/testapp/static/exam/js/show_question.js b/testapp/static/exam/js/show_question.js deleted file mode 100644 index e3ed1cc..0000000 --- a/testapp/static/exam/js/show_question.js +++ /dev/null @@ -1,39 +0,0 @@ -function confirm_delete(frm) -{ - var n=0; - for (var i =0;i -This event will be reported.
-Sorry for the inconvinience. -{% endblock %} diff --git a/testapp/templates/base.html b/testapp/templates/base.html deleted file mode 100644 index 3dfbe10..0000000 --- a/testapp/templates/base.html +++ /dev/null @@ -1,46 +0,0 @@ - - - - - - {% block title %} - {% endblock %} - - - {% block meta %} - - - - {% endblock %} - - - {% block css %} - {% endblock %} - - {% block script %} - {% endblock %} - - - -
-
- -
-
-

{% block formtitle %} {% endblock formtitle %}


- {% block content %} - {% endblock %} -
-
-
-
-

© FOSSEE group, IIT Bombay

-
-
- - - - diff --git a/testapp/templates/exam/add_question.html b/testapp/templates/exam/add_question.html deleted file mode 100644 index b0b22b1..0000000 --- a/testapp/templates/exam/add_question.html +++ /dev/null @@ -1,41 +0,0 @@ -{% extends "manage.html" %} - - -{% block subtitle %}Add Question{% endblock %} - -{% block css %} - - -{% endblock %} - -{% block script %} - - - - -{% endblock %} - -{% block onload %} onload='javascript:textareaformat();' {% endblock %} - -{% block manage %} - - {% csrf_token %} -
- -
Summary: {{ form.summary }}{{ form.summary.errors }} -
Language: {{form.language}}{{form.language.errors}} -
Active: {{ form.active }}{{form.active.errors}}   Type:  {{ form.type }}{{form.type.errors}} -
Points:{{ form.points }}{{ form.points.errors }} -
Rendered:

-
Description: {{ form.description}} {{form.description.errors}} -
Test: {{ form.test }}{{form.test.errors}} -
Snippet: {{ form.snippet }}{{ form.snippet.errors }}
Tags: {{ form.tags }} -
Options: {{ form.options }} {{form.options.errors}} - - -
-
-
- -{% endblock %} - diff --git a/testapp/templates/exam/add_questionpaper.html b/testapp/templates/exam/add_questionpaper.html deleted file mode 100644 index 4cce8a9..0000000 --- a/testapp/templates/exam/add_questionpaper.html +++ /dev/null @@ -1,28 +0,0 @@ -{% extends "manage.html" %} - - -{% block subtitle %}Design Question Paper{% endblock %} - -{% block css %} - - -{% endblock %} -{% block script %} - - - -{% endblock %} - -{% block manage %} - -
-{% csrf_token %} -Select mode to design Question Paper: - -
- -{% endblock %} diff --git a/testapp/templates/exam/add_quiz.html b/testapp/templates/exam/add_quiz.html deleted file mode 100644 index c2533de..0000000 --- a/testapp/templates/exam/add_quiz.html +++ /dev/null @@ -1,25 +0,0 @@ -{% extends "manage.html" %} - - -{% block subtitle %}Add Quiz{% endblock %} - -{% block css %} - -{% endblock %} -{% block script %} - -{% endblock %} -{% block onload %} onload="javascript:test();" {% endblock %} -{% block manage %} -
- {% csrf_token %} -
- - {{ form.as_table }} -
-
- -
-
-
-{% endblock %} diff --git a/testapp/templates/exam/ajax_marks.html b/testapp/templates/exam/ajax_marks.html deleted file mode 100644 index 716bb88..0000000 --- a/testapp/templates/exam/ajax_marks.html +++ /dev/null @@ -1,4 +0,0 @@ - -{% for mark in marks %} - -{% endfor %} diff --git a/testapp/templates/exam/ajax_questions.html b/testapp/templates/exam/ajax_questions.html deleted file mode 100644 index e343f9b..0000000 --- a/testapp/templates/exam/ajax_questions.html +++ /dev/null @@ -1,31 +0,0 @@ -
- {% if questions %} - - Select All - {% endif %} -
    - - {% for question in questions %} -
  • - -
  • - {% endfor %} -
-
- -
- -
diff --git a/testapp/templates/exam/automatic_questionpaper.html b/testapp/templates/exam/automatic_questionpaper.html deleted file mode 100644 index fcd3db5..0000000 --- a/testapp/templates/exam/automatic_questionpaper.html +++ /dev/null @@ -1,88 +0,0 @@ -{% extends "manage.html" %} - - -{% block subtitle %}Design Question Paper{% endblock %} - -{% block css %} - - - -{% endblock %} -{% block script %} - - - -{% endblock %} - -{% block manage %} - -
Automatic mode to design the Question Paper

-
- {% csrf_token %} -
- Tag Conditions: - - - - - - - - - -
- -
- -
Number of question:  
- -
-
-

Below is the list of Questions fetched according to the given tag conditions

-
-
- -
- {% endfor %} -
Summary - Type - Points - Tags - {% for question in data.questions %} - -
{{ question.summary }} {{ question.type }} {{ question.points }} - {% for tag in question.tags.all %} - {{ tag }} - {% endfor %} -
- {% if data.msg %}
{{ data.msg }}
{% endif %} -
- - -{% endblock %} diff --git a/testapp/templates/exam/complete.html b/testapp/templates/exam/complete.html deleted file mode 100644 index 1d5df3c..0000000 --- a/testapp/templates/exam/complete.html +++ /dev/null @@ -1,12 +0,0 @@ -{% extends "base.html" %} - -{% block title %}Good bye!{% endblock %} - -{% block pagetitle %}Online Test{% endblock %} -{% block content %} -{% csrf_token %} -

Good bye!

-

{{message}}

-

You may now close the browser.


-
Login Again
-{% endblock content %} diff --git a/testapp/templates/exam/design_questionpaper.html b/testapp/templates/exam/design_questionpaper.html deleted file mode 100644 index 8994148..0000000 --- a/testapp/templates/exam/design_questionpaper.html +++ /dev/null @@ -1,184 +0,0 @@ -{% extends "manage.html" %} - -{% block subtitle %}Design Question Paper{% endblock %} - -{% block css %} - - - - - -{% endblock %} -{% block script %} - - - - - - - - -{% endblock %} - -{% block manage %} - -
Manual mode to design the {{lang}} Question Paper

- - -
{% csrf_token %} -
-

Total Marks: 0

-
-
- -
-
Please select Question type and Marks
-
- {{ form.question_type }} -
-
- {{ form.marks }} -
-
-
-
-
-

- - -
-
-
-
-

Select questions to add:

-
-
- Add to paper -
-
-
-
-

Fixed questions currently in paper:

-
-
-
-
-
-
-
- Next > -
- -
- - -
-
-
-
-

Select questions to add to the pool:

-
-
- Add to paper -
-
-
-
-

Pool of questions currently in paper:

-
-
-
-
-
-
- -
- Next > -
-
- -
-
-
Almost finished creating your question paper
-

- - -
- -
-
-
- -
-
-
- - - - - - - - -{% endblock %} diff --git a/testapp/templates/exam/edit_question.html b/testapp/templates/exam/edit_question.html deleted file mode 100644 index b28cc3e..0000000 --- a/testapp/templates/exam/edit_question.html +++ /dev/null @@ -1,54 +0,0 @@ -{% extends "manage.html" %} - -{% block subtitle %}Edit Question{% endblock %} - -{% block css %} - - -{% endblock %} -{% block script %} - - - -{% endblock %} - -{% block onload %} onload = 'javascript:textareaformat();' {% endblock %} - -{% block manage %} -
- {% csrf_token %} -

Click on the Question links to edit the question.

- - - - {% for form in forms %} - -
{{form.summary.value}} - - - {% endfor %} -
-{% for i in data %} - -{% endfor %} - -
-
- -{% endblock %} diff --git a/testapp/templates/exam/edit_quiz.html b/testapp/templates/exam/edit_quiz.html deleted file mode 100644 index 6445907..0000000 --- a/testapp/templates/exam/edit_quiz.html +++ /dev/null @@ -1,39 +0,0 @@ -{% extends "manage.html" %} - - -{% block subtitle %}Edit Quiz(zes){% endblock %} - -{% block css %} - -{% endblock %} - -{% block script %} - -{% endblock %} - -{% block onload %} onload = 'javascript:form_load();' {% endblock %} - -{% block manage %} -
- {% csrf_token %} -
- - {% for form in forms %} -
Start Date: {{ form.start_date}} -
Duration: {{ form.duration }}
{{form.duration.help_text}} -
Active: {{ form.active }} -
Description: {{ form.description }} -
Passing Criteria: {{ form.pass_criteria }}
{{form.pass_criteria.help_text}} -
Language: {{ form.language }} -
Prerequisite: {{ form.prerequisite }} -
- {% endfor %} -
-
-{% for i in data %} - -{% endfor %} -
-
-
-{% endblock %} diff --git a/testapp/templates/exam/editquestionpaper.html b/testapp/templates/exam/editquestionpaper.html deleted file mode 100644 index 819ff06..0000000 --- a/testapp/templates/exam/editquestionpaper.html +++ /dev/null @@ -1,21 +0,0 @@ -{% extends "manage.html" %} - - -{% block subtitle %}Questions in "{{ papers.quiz.description }}"{% endblock %} - -{% block script %} - -{% endblock %} - -{% block manage %} -
-{% csrf_token %} - -{% for i in papers.questions %} -  {{ i.summary}}
-{% endfor %} -
-   - -
-{% endblock %} diff --git a/testapp/templates/exam/grade_user.html b/testapp/templates/exam/grade_user.html deleted file mode 100644 index ae9274e..0000000 --- a/testapp/templates/exam/grade_user.html +++ /dev/null @@ -1,94 +0,0 @@ -{% extends "manage.html" %} - -{% block title %} Grading papers for {{ data.user.get_full_name.title }} {% endblock title %} - -{% block subtitle %}Grading papers for {{ data.user.get_full_name.title }}{% endblock %} - -{% block css %} - -{% endblock %} - -{% block script %} - -{% endblock %} -{% block manage %} - -

-Name: {{ data.user.get_full_name.title }} -{% if data.profile %} -(roll number: {{ data.profile.roll_number }})
-{{ data.profile.position }}, -{{ data.profile.department }}, -{{ data.profile.institute }} -{% endif %} -

- -{% if data.papers %} - -{% for paper in data.papers %} - -

Quiz: {{ paper.quiz.description }}

- -

-Questions correctly answered: {{ paper.get_answered_str }}
-Total attempts at questions: {{ paper.answers.count }}
-Marks obtained: {{ paper.get_total_marks }}
-Start time: {{ paper.start_time }}
-

- -{% if paper.answers.count %} -

Answers


-
-{% csrf_token %} -{% for question, answers in paper.get_question_answers.items %} -
-

- Question: {{ question.id }}. {{ question.summary }} (Points: {{ question.points }}) - -Details

-
- -
-
- -{% if question.type == "mcq" %} -
-

Choices: -{% for option in question.options.strip.splitlines %} {{option}}, {% endfor %} -

-

Student answer: {{ answers.0 }}

-{% else %}{# non-mcq questions #} -
-{% for answer in answers %}################################################################################
-{{ answer.answer.strip }}
-# Autocheck: {{ answer.error }}
-{% endfor %}
-{% endif %} {# if question.type #} -{% with answers|last as answer %} -Marks:

-{% endwith %} -
-
-{% endfor %} {# for question, answers ... #} - - -

Teacher comments:

- -
-
- -
-{% endif %} {# if paper.answers.count #} - -{% endfor %} {# for paper in data.papers #} - -{% endif %} {# if data.papers #} - -{% endblock%} diff --git a/testapp/templates/exam/intro.html b/testapp/templates/exam/intro.html deleted file mode 100644 index ec1888a..0000000 --- a/testapp/templates/exam/intro.html +++ /dev/null @@ -1,34 +0,0 @@ -{% extends "base.html" %} - -{% block title %}Instructions and Rules {% endblock %} -{% block pagetitle %}Online Test {% endblock %} -{% block formtitle %}Important instructions & rules {% endblock %} -{% block content %} - - - -

Welcome {{user.first_name.title}} {{user.last_name.title}}, to the programming quiz!

-

- This examination system has been developed with the intention of making you - learn programming and be assessed in an interactive and fun manner. - You will be presented with a series of programming questions and problems that - you will answer online and get immediate feedback for. -

-

Here are some important instructions and rules that you should understand carefully.

-
    -
  • For any programming questions, you can submit solutions as many times as you want without a penalty. You may skip questions and solve them later. -
  • -
  • You may use your computer's Python/IPython shell or an editor to solve the problem and cut/paste the solution to the web interface. -
  • -
  • You are not allowed to use any internet resources, i.e. no google etc.
  • -
  • Do not copy or share the questions or answers with anyone until the exam is complete for everyone.
  • -
  • All your attempts at the questions are logged. Do not try to outsmart and break the testing system. If you do, we know who you are and we will expell you from the course. You have been warned. -
  • -
-

We hope you enjoy taking this exam !!!

- -
- {% csrf_token %} -
-
-{% endblock content %} diff --git a/testapp/templates/exam/login.html b/testapp/templates/exam/login.html deleted file mode 100644 index 078e7a7..0000000 --- a/testapp/templates/exam/login.html +++ /dev/null @@ -1,22 +0,0 @@ -{% extends "base.html" %} - -{% block title %}Login{% endblock title %} -{% block pagetitle %} Online Test {% endblock %} -{% block formtitle %}Login{% endblock %} -{% block css %} - -{% endblock %} -{% block content %} - -
- {% csrf_token %} - -
- {{ form.as_table }} -
-
    
-
Forgot Password?

-
New User? Sign-Up
-
- -{% endblock content %} diff --git a/testapp/templates/exam/manual_questionpaper.html b/testapp/templates/exam/manual_questionpaper.html deleted file mode 100644 index 1a1f95c..0000000 --- a/testapp/templates/exam/manual_questionpaper.html +++ /dev/null @@ -1,81 +0,0 @@ -{% extends "manage.html" %} - - -{% block subtitle %}Design Question Paper{% endblock %} - -{% block css %} - - - -{% endblock %} -{% block script %} - - - - -{% endblock %} - -{% block manage %} - -
Manual mode to design the Question Paper

- -
- {% csrf_token %} -
- Tag Conditions: - - - - - -
-
-
-

Below is the list of Questions fetched according to the given tag conditions
-
-
- -
- {% endfor %} -
  - Summary - Type - Points - Tags - {% for question in data.questions %} -
{{ question.summary }} {{ question.type }} {{ question.points }} - {% for tag in question.tags.all %} - {{ tag }} - {% endfor %} -
- {% if data.msg %}
{{ data.msg }}
{% endif %} -
- - -{% endblock %} diff --git a/testapp/templates/exam/monitor.html b/testapp/templates/exam/monitor.html deleted file mode 100644 index ecdb852..0000000 --- a/testapp/templates/exam/monitor.html +++ /dev/null @@ -1,69 +0,0 @@ -{% extends "manage.html" %} - -{% block title %} Quiz results {% endblock title %} - -{% block meta %} {% endblock meta %} - -{% block css %} - -{% endblock %} -{% block subtitle %} - {% if not quizzes and not quiz %} - Quiz Results - {% endif %} - {% if quizzes %} - Available Quizzes - {% endif %} - {% if quiz %} - {{ quiz.description }} Results - {% endif %} -{% endblock %} -{% block manage %} - {% if not quizzes and not quiz %} -
No quizzes available.
- {% endif %} - -{# ############################################################### #} -{# This is rendered when we are just viewing exam/monitor #} -{% if quizzes %} - -{% endif %} - -{# ############################################################### #} -{# This is rendered when we are just viewing exam/monitor/quiz_num #} -{% if quiz %} - -{% if papers %} -{#

Quiz: {{ quiz_name }}

#} -

Number of papers: {{ papers|length }}

- - - - - - - - - - - {% for paper in papers %} - - - - - - - - - - {% endfor %} -
Name Username Roll number Institute Questions answered Marks obtained Attempts
{{ paper.user.get_full_name.title }} {{ paper.user.username }} {{ paper.profile.roll_number }} {{ paper.profile.institute }} {{ paper.get_answered_str }} {{ paper.marks_obtained }} {{ paper.answers.count }}
-{% else %} -

No answer papers so far.

-{% endif %} {# if papers #} -{% endif %} -{% endblock %} diff --git a/testapp/templates/exam/question.html b/testapp/templates/exam/question.html deleted file mode 100644 index a3e8629..0000000 --- a/testapp/templates/exam/question.html +++ /dev/null @@ -1,138 +0,0 @@ -{% extends "base.html" %} - - - -{% block title %} Answer question {% endblock %} - -{% block css %} - - -{% endblock %} - -{% block script %} - - - -{% endblock script %} - - - -{% block onload %} onload="update_time();setSnippetHeight()" {% endblock %} - -{% block pagetitle %} - -
-
You have {{ paper.questions_left }} question(s) left in {{ quiz_name }}
-
-
-
- -{% endblock %} - -{% block content %} -
-
-
-

Online Test

- -
- {% csrf_token %} - - -
-
-
-
- - -

{{ question.summary }} (Marks : {{ question.points }})


- {{ question.description|safe }} - {% if error_message %} -
- {% for e in error_message.splitlines %} - {{ e|join:"" }} -
- {% endfor%} -
{% endif %} - - {% if success_msg %} - - {% endif %} -

-
- {% csrf_token %} - {% if question.type == "mcq" %} - {% for option in question.options.strip.splitlines %} - {{option}}
- {% endfor %} - {% endif %} - {% if question.type == "mcc" %} - {% for option in question.options.strip.splitlines %} - {{ option }} -
- {% endfor %} - {% endif %} - {% if question.type == "code" %} - - - - -
- - - - {% endif %} - - {% if question.type == "mcq" or question.type == "mcc "%} -
   - {% else %} -    - {% endif %} - -
- - -{% endblock content %} diff --git a/testapp/templates/exam/quit.html b/testapp/templates/exam/quit.html deleted file mode 100644 index fee11ed..0000000 --- a/testapp/templates/exam/quit.html +++ /dev/null @@ -1,14 +0,0 @@ -{% extends "base.html" %} - -{% block title %}Quit exam {% endblock %} -{% block pagetitle %}Online Test {% endblock %} -{% block content %} - -

Your current answers are saved.

-

Are you sure you wish to quit the exam?

-

Be sure, as you won't be able to restart this exam.

-
- {% csrf_token %} -
 
-
-{% endblock content %} diff --git a/testapp/templates/exam/quizlist.html b/testapp/templates/exam/quizlist.html deleted file mode 100644 index 9b1fd73..0000000 --- a/testapp/templates/exam/quizlist.html +++ /dev/null @@ -1,24 +0,0 @@ -{% extends "base.html" %} - -{% block title %} Quiz List {% endblock title %} - -{% block formtitle %} Quiz List {% endblock %} - -{% block pagetitle %} Online Test {% endblock %} - -{% block content %} -{% if not quizzes and not quiz %} -
No quizzes available.
-{% endif %} - -{% if quizzes %} -
-{% csrf_token %} - -{% for quiz in quizzes %} -{{ quiz.description }}
-{% endfor %} -
-{% endif %} - -{% endblock %} diff --git a/testapp/templates/exam/quizzes_user.html b/testapp/templates/exam/quizzes_user.html deleted file mode 100644 index 914b6b4..0000000 --- a/testapp/templates/exam/quizzes_user.html +++ /dev/null @@ -1,81 +0,0 @@ -{% extends "user.html" %} - - -{% block subtitle %}Hello {{ user.first_name }}, welcome to your dashboard !{% endblock %} - -{% block css %} - -{% endblock %} - -{% block script %} - - -{% endblock %} - - -{% block manage %} - {% if cannot_attempt %} -

You have not passed the prerequisite & hence you cannot take the quiz.

- {% endif %} -

List of quizzes availbale for you

- {% if not quizzes %} -
No active quizzes for you
- {% endif %} - - - - {% for paper in quizzes %} - - - - - {% endfor %} -
QuizPre requisite quiz
- {{ paper.quiz.description }}
-
- {% if paper.quiz.prerequisite %} - You have to pass {{ paper.quiz.prerequisite.description }} for taking {{ paper.quiz.description }} - {% else %} - No pre requisites for {{ paper.quiz.description }} - {% endif %} -
-
-

List of quizzes taken by you so far

- {% if quizzes_taken %} - - - - - - - {% for paper in quizzes_taken %} - - - - - - - - {% endfor %} -
QuizResultMraks ObtainedTotal MarksPercentage
- {{ paper.question_paper.quiz.description }} - - {% if paper.passed %} -

Pass

- {% else %} -

Fail

- {% endif %} -
- {{ paper.marks_obtained }} - - {{ paper.question_paper.total_marks }} - - {{ paper.percent }} -
- {% else %} -

You have not taken any quiz yet !!

- {% endif %} - - -{% endblock %} - diff --git a/testapp/templates/exam/register.html b/testapp/templates/exam/register.html deleted file mode 100644 index 5ff79cc..0000000 --- a/testapp/templates/exam/register.html +++ /dev/null @@ -1,20 +0,0 @@ -{% extends "base.html" %} - -{% block title %}Registration form {% endblock %} - -{% block pagetitle %}Online Test {% endblock %} -{% block formtitle %}Please fill in the following details {% endblock %} - -{% block content %} - - - -
- {% csrf_token %} -
- {{ form.as_table }} -
-
  
-
- -{% endblock content %} diff --git a/testapp/templates/exam/results_user.html b/testapp/templates/exam/results_user.html deleted file mode 100644 index 2a2a309..0000000 --- a/testapp/templates/exam/results_user.html +++ /dev/null @@ -1,28 +0,0 @@ -{% extends "user.html" %} - - -{% block subtitle %}Results{% endblock %} - -{% block css %} - -{% endblock %} - -{% block manage %} -
- {% csrf_token %} -
- - {% for i in paper %} -
Quiz Description - Obtained Marks - Maximum Marks - Percentage - {% for paper in papers %} -
{{ i }} - {% endfor %} -
- {% endfor %} -
-
-{% endblock %} - diff --git a/testapp/templates/exam/show_quiz.html b/testapp/templates/exam/show_quiz.html deleted file mode 100644 index cf3f552..0000000 --- a/testapp/templates/exam/show_quiz.html +++ /dev/null @@ -1,33 +0,0 @@ -{% extends "manage.html" %} - -{% block title %} Quiz List {% endblock title %} - -{% block script %} - -{% endblock %} - -{% block subtitle %} Quiz List {% endblock %} -{% block manage %} -{% if not quizzes and not quiz %} -
No quizzes available.
-   -{% endif %} - -{# ############################################################### #} -{# This is rendered when we are just viewing exam/monitor #} -{% if quizzes %} -
-{% csrf_token %} - -{% for quiz in quizzes %} -  {{ quiz.description }}
-{% endfor %} - -

-   -   - -
-{% endif %} - -{% endblock %} diff --git a/testapp/templates/exam/showquestionpapers.html b/testapp/templates/exam/showquestionpapers.html deleted file mode 100644 index e511472..0000000 --- a/testapp/templates/exam/showquestionpapers.html +++ /dev/null @@ -1,23 +0,0 @@ -{% extends "manage.html" %} - - -{% block subtitle %}List of Question Papers {% endblock %} - -{% block script %} - -{% endblock %} - -{% block manage %} -{% if papers %} -
-{% csrf_token %} -{% for i in papers %} -  {{ i.quiz.description }}
-{% endfor %} -
- -
-{% else %} -

No Question Papers available

-{% endif %} -{% endblock %} diff --git a/testapp/templates/exam/showquestions.html b/testapp/templates/exam/showquestions.html deleted file mode 100644 index 62b40e4..0000000 --- a/testapp/templates/exam/showquestions.html +++ /dev/null @@ -1,21 +0,0 @@ -{% extends "manage.html" %} - - -{% block subtitle %}List of Questions {% endblock %} - -{% block script %} - -{% endblock %} - -{% block manage %} -
-{% csrf_token %} -{% for i in questions %} -  {{ i }}
-{% endfor %} -
-   -   - -
-{% endblock %} diff --git a/testapp/templates/exam/showusers.html b/testapp/templates/exam/showusers.html deleted file mode 100644 index 01ecc37..0000000 --- a/testapp/templates/exam/showusers.html +++ /dev/null @@ -1,26 +0,0 @@ -{% extends "manage.html" %} - - -{% block subtitle %} -List of Users -{% endblock %} - -{% block css %} - -{% endblock css %} - - -{% block manage %} -
-
Username -First Name -Last Name -Quiz Description -{% for papers in question %} -
{{ papers.user.username }}
-
{{ papers.user.first_name.title }} - {{ papers.user.last_name.title }} - {{ papers.question_paper.quiz.description }} -{% endfor %} -
-{% endblock %} diff --git a/testapp/templates/exam/user_data.html b/testapp/templates/exam/user_data.html deleted file mode 100644 index 61a3a97..0000000 --- a/testapp/templates/exam/user_data.html +++ /dev/null @@ -1,80 +0,0 @@ -{% extends "manage.html" %} - -{% block title %} Data for user {{ data.user.get_full_name.title }} {% endblock title %} - -{% block manage %} - -{% block subtitle %}Data for user {{ data.user.get_full_name.title }}{% endblock %} -
-

-Name: {{ data.user.get_full_name.title }}
-Username: {{ data.user.username }}
-{% if data.profile %} -Roll number: {{ data.profile.roll_number }}
-Position: {{ data.profile.position }}
-Department: {{ data.profile.department }}
-Institute: {{ data.profile.institute }}
-{% endif %} -Email: {{ data.user.email }}
-Date joined: {{ data.user.date_joined }}
-Last login: {{ data.user.last_login }} -

- -{% if data.papers %} -

- Grade/correct paper -

- -{% for paper in data.papers %} - -

Quiz: {{ paper.quiz.description }}

- -

-Questions correctly answered: {{ paper.get_answered_str }}
-Total attempts at questions: {{ paper.answers.count }}
-Marks obtained: {{ paper.get_total_marks }}
-Start time: {{ paper.start_time }}
-User IP address: {{ paper.user_ip }} -

- -{% if paper.answers.count %} -

Answers

-{% for question, answers in paper.get_question_answers.items %} -

Question: {{ question.id }}. {{ question.summary }} (Points: {{ question.points }})

-{% if question.type == "mcq" %} -

Choices: -{% for option in question.options.strip.splitlines %} {{option}}, {% endfor %} -

-

Student answer: {{ answers.0 }}

-{% else %}{# non-mcq questions #} -
 
-{% for answer in answers %}################################################################################
-{{ answer.answer.strip }}
-# Autocheck: {{ answer.error }}
-{% endfor %}
-{% endif %} -{% with answers|last as answer %} -

Marks: {{answer.marks}}

-{% endwith %} -{% endfor %} {# for question, answers ... #} -

Teacher comments:

-{{ paper.comments|default:"None" }} -{% endif %} {# if paper.answers.count #} - -{% endfor %} {# for paper in data.papers #} - -{% endif %} {# if data.papers #} -
-
- - Grade/correct paper -
-{% if data.papers.count > 1 %} -Monitor quiz -{% else %} -{% with data.papers.0 as paper %} -Monitor quiz -{% endwith %} -{% endif %} - -{% endblock %} diff --git a/testapp/templates/manage.html b/testapp/templates/manage.html deleted file mode 100644 index 1db8a78..0000000 --- a/testapp/templates/manage.html +++ /dev/null @@ -1,88 +0,0 @@ - - - - {% block title %} - {% endblock %} - - - {% block meta %} - - - - {% endblock %} - - - - {% block css %} - {% endblock %} - - {% block script %} - {% endblock %} - - - - -
-
- -
-
- {% block manage %} -

List of quizzes! Click on the given links to have a look at answer papers for a quiz.

-
- - - - - - {% for paper, answer_papers, users_passed, users_failed in users_per_paper %} - - - - - - - {% endfor %} -
QuizTaken ByNo. of users PassedNo. of users Failed
- {{ paper.quiz.description }} - - {{ answer_papers|length }} user(s) - - {{ users_passed }} - - {{ users_failed }} -
-
-
-

Moderator's Dashboard!

-
Click on the button given below to add a new quiz.
- -
-{% endblock %} -
-
-
-
-

© FOSSEE group, IIT Bombay

-
-
- - - diff --git a/testapp/templates/user.html b/testapp/templates/user.html deleted file mode 100644 index 22a9fac..0000000 --- a/testapp/templates/user.html +++ /dev/null @@ -1,58 +0,0 @@ - - - - - - {% block title %} - {% endblock %} - - - {% block meta %} - - - - {% endblock %} - - - {% block css %} - {% endblock %} - - {% block script %} - {% endblock %} - - - -
-
-
-

Online Test

- - -
-
-
-
-
- -
-
- {% block manage %} - {% endblock %} -
-
-
-
-

© FOSSEE group, IIT Bombay

-
-
- - - -- cgit From ff2d8ef28e2c49be940fd87b8364162efc0c4351 Mon Sep 17 00:00:00 2001 From: prathamesh Date: Fri, 11 Jul 2014 15:37:26 +0530 Subject: Moved code server in the app folder. moved output folder in the app. --- testapp/code_server.py | 865 ----------------------------------------- testapp/exam/code_server.py | 865 +++++++++++++++++++++++++++++++++++++++++ testapp/exam/output/README.txt | 4 + testapp/exam/views.py | 2 +- testapp/output/README.txt | 4 - 5 files changed, 870 insertions(+), 870 deletions(-) delete mode 100755 testapp/code_server.py create mode 100755 testapp/exam/code_server.py create mode 100644 testapp/exam/output/README.txt delete mode 100644 testapp/output/README.txt diff --git a/testapp/code_server.py b/testapp/code_server.py deleted file mode 100755 index 792197d..0000000 --- a/testapp/code_server.py +++ /dev/null @@ -1,865 +0,0 @@ -#!/usr/bin/env python -"""This server runs an XMLRPC server that can be submitted code and tests -and returns the output. It *should* be run as root and will run as the user -'nobody' so as to minimize any damange by errant code. This can be configured -by editing settings.py to run as many servers as desired. One can also -specify the ports on the command line. Here are examples:: - - $ sudo ./code_server.py - # Runs servers based on settings.py:SERVER_PORTS one server per port given. - -or:: - - $ sudo ./code_server.py 8001 8002 8003 8004 8005 - # Runs 5 servers on ports specified. - -All these servers should be running as nobody. This will also start a server -pool that defaults to port 50000 and is configurable in -settings.py:SERVER_POOL_PORT. This port exposes a `get_server_port` function -that returns an available server. -""" -import sys -import traceback -from SimpleXMLRPCServer import SimpleXMLRPCServer -import pwd -import os -import stat -from os.path import isdir, dirname, abspath, join, isfile -import signal -from multiprocessing import Process, Queue -import subprocess -import re -# Local imports. -from settings import SERVER_PORTS, SERVER_TIMEOUT, SERVER_POOL_PORT - -MY_DIR = abspath(dirname(__file__)) - - -def run_as_nobody(): - """Runs the current process as nobody.""" - # Set the effective uid and to that of nobody. - nobody = pwd.getpwnam('nobody') - os.setegid(nobody.pw_gid) - os.seteuid(nobody.pw_uid) - - -# Raised when the code times-out. -# c.f. http://pguides.net/python/timeout-a-function -class TimeoutException(Exception): - pass - - -def timeout_handler(signum, frame): - """A handler for the ALARM signal.""" - raise TimeoutException('Code took too long to run.') - - -############################################################################### -# `CodeServer` class. -############################################################################### -class CodeServer(object): - """A code server that executes user submitted test code, tests it and - reports if the code was correct or not. - """ - def __init__(self, port, queue): - self.port = port - self.queue = queue - msg = 'Code took more than %s seconds to run. You probably '\ - 'have an infinite loop in your code.' % SERVER_TIMEOUT - self.timeout_msg = msg - - def run_python_code(self, answer, test_code, in_dir=None): - """Tests given Python function (`answer`) with the `test_code` - supplied. If the optional `in_dir` keyword argument is supplied - it changes the directory to that directory (it does not change - it back to the original when done). This function also timesout - when the function takes more than SERVER_TIMEOUT seconds to run - to prevent runaway code. - Returns - ------- - - A tuple: (success, error message). - - """ - if in_dir is not None and isdir(in_dir): - os.chdir(in_dir) - - # Add a new signal handler for the execution of this code. - old_handler = signal.signal(signal.SIGALRM, timeout_handler) - signal.alarm(SERVER_TIMEOUT) - - success = False - tb = None - try: - submitted = compile(answer, '', mode='exec') - g = {} - exec submitted in g - _tests = compile(test_code, '', mode='exec') - exec _tests in g - except TimeoutException: - err = self.timeout_msg - except AssertionError: - type, value, tb = sys.exc_info() - info = traceback.extract_tb(tb) - fname, lineno, func, text = info[-1] - text = str(test_code).splitlines()[lineno-1] - err = "{0} {1} in: {2}".format(type.__name__, str(value), text) - except: - type, value = sys.exc_info()[:2] - err = "Error: {0}".format(repr(value)) - else: - success = True - err = 'Correct answer' - finally: - del tb - # Set back any original signal handler. - signal.signal(signal.SIGALRM, old_handler) - - # Cancel the signal if any, see signal.alarm documentation. - signal.alarm(0) - - # Put us back into the server pool queue since we are free now. - self.queue.put(self.port) - - return success, err - - def run_bash_code(self, answer, test_code, in_dir=None): - """Tests given Bash code (`answer`) with the `test_code` supplied. - - The testcode should typically contain two lines, the first is a path to - the reference script we are to compare against. The second is a path - to the arguments to be supplied to the reference and submitted script. - The output of these will be compared for correctness. - - If the path's start with a "/" then we assume they are absolute paths. - If not, we assume they are relative paths w.r.t. the location of this - code_server script. - - If the optional `in_dir` keyword argument is supplied it changes the - directory to that directory (it does not change it back to the original - when done). - - Returns - ------- - - A tuple: (success, error message). - - """ - if in_dir is not None and isdir(in_dir): - os.chdir(in_dir) - - def _set_exec(fname): - os.chmod(fname, stat.S_IRUSR | stat.S_IWUSR | stat.S_IXUSR - | stat.S_IRGRP | stat.S_IWGRP | stat.S_IXGRP - | stat.S_IROTH | stat.S_IWOTH | stat.S_IXOTH) - submit_f = open('submit.sh', 'w') - submit_f.write(answer.lstrip()) - submit_f.close() - submit_path = abspath(submit_f.name) - _set_exec(submit_path) - - ref_path, test_case_path = test_code.strip().splitlines() - if not ref_path.startswith('/'): - ref_path = join(MY_DIR, ref_path) - if not test_case_path.startswith('/'): - test_case_path = join(MY_DIR, test_case_path) - - # Add a new signal handler for the execution of this code. - old_handler = signal.signal(signal.SIGALRM, timeout_handler) - signal.alarm(SERVER_TIMEOUT) - - # Do whatever testing needed. - success = False - try: - success, err = self.check_bash_script(ref_path, submit_path, - test_case_path) - except TimeoutException: - err = self.timeout_msg - except: - type, value = sys.exc_info()[:2] - err = "Error: {0}".format(repr(value)) - finally: - # Set back any original signal handler. - signal.signal(signal.SIGALRM, old_handler) - - # Delete the created file. - os.remove(submit_path) - - # Cancel the signal if any, see signal.alarm documentation. - signal.alarm(0) - - # Put us back into the server pool queue since we are free now. - self.queue.put(self.port) - - return success, err - - def _run_command(self, cmd_args, *args, **kw): - """Run a command in a subprocess while blocking, the process is killed - if it takes more than 2 seconds to run. Return the Popen object, the - stdout and stderr. - """ - try: - proc = subprocess.Popen(cmd_args, *args, **kw) - stdout, stderr = proc.communicate() - except TimeoutException: - # Runaway code, so kill it. - proc.kill() - # Re-raise exception. - raise - return proc, stdout, stderr - - def check_bash_script(self, ref_script_path, submit_script_path, - test_case_path=None): - """ Function validates student script using instructor script as - reference. Test cases can optionally be provided. The first argument - ref_script_path, is the path to instructor script, it is assumed to - have executable permission. The second argument submit_script_path, is - the path to the student script, it is assumed to have executable - permission. The Third optional argument is the path to test the - scripts. Each line in this file is a test case and each test case is - passed to the script as standard arguments. - - Returns - -------- - - returns (True, "Correct answer") : If the student script passes all - test cases/have same output, when compared to the instructor script - - returns (False, error_msg): If the student script fails a single - test/have dissimilar output, when compared to the instructor script. - - Returns (False, error_msg): If mandatory arguments are not files or if - the required permissions are not given to the file(s). - - """ - if not isfile(ref_script_path): - return False, "No file at %s" % ref_script_path - if not isfile(submit_script_path): - return False, 'No file at %s' % submit_script_path - if not os.access(ref_script_path, os.X_OK): - return False, 'Script %s is not executable' % ref_script_path - if not os.access(submit_script_path, os.X_OK): - return False, 'Script %s is not executable' % submit_script_path - - if test_case_path is None: - ret = self._run_command(ref_script_path, stdin=None, - stdout=subprocess.PIPE, - stderr=subprocess.PIPE) - proc, inst_stdout, inst_stderr = ret - ret = self._run_command(submit_script_path, stdin=None, - stdout=subprocess.PIPE, - stderr=subprocess.PIPE) - proc, stdnt_stdout, stdnt_stderr = ret - if inst_stdout == stdnt_stdout: - return True, 'Correct answer' - else: - err = "Error: expected %s, got %s" % (inst_stderr, - stdnt_stderr) - return False, err - else: - if not isfile(test_case_path): - return False, "No test case at %s" % test_case_path - if not os.access(ref_script_path, os.R_OK): - return False, "Test script %s, not readable" % test_case_path - valid_answer = True # We initially make it one, so that we can - # stop once a test case fails - loop_count = 0 # Loop count has to be greater than or - # equal to one. - # Useful for caching things like empty - # test files,etc. - test_cases = open(test_case_path).readlines() - num_lines = len(test_cases) - for test_case in test_cases: - loop_count += 1 - if valid_answer: - args = [ref_script_path] + [x for x in test_case.split()] - ret = self._run_command(args, stdin=None, - stdout=subprocess.PIPE, - stderr=subprocess.PIPE) - proc, inst_stdout, inst_stderr = ret - args = [submit_script_path]+[x for x in test_case.split()] - ret = self._run_command(args, stdin=None, - stdout=subprocess.PIPE, - stderr=subprocess.PIPE) - proc, stdnt_stdout, stdnt_stderr = ret - valid_answer = inst_stdout == stdnt_stdout - if valid_answer and (num_lines == loop_count): - return True, "Correct answer" - else: - err = "Error:expected %s, got %s" % (inst_stdout+inst_stderr, - stdnt_stdout+stdnt_stderr) - return False, err - - def run_c_code(self, answer, test_code, in_dir=None): - """Tests given C code (`answer`) with the `test_code` supplied. - - The testcode is a path to the reference code. - The reference code will call the function submitted by the student. - The reference code will check for the expected output. - - If the path's start with a "/" then we assume they are absolute paths. - If not, we assume they are relative paths w.r.t. the location of this - code_server script. - - If the optional `in_dir` keyword argument is supplied it changes the - directory to that directory (it does not change it back to the original - when done). - - Returns - ------- - - A tuple: (success, error message). - - """ - if in_dir is not None and isdir(in_dir): - os.chdir(in_dir) - - # File extension must be .c - submit_f = open('submit.c', 'w') - submit_f.write(answer.lstrip()) - submit_f.close() - submit_path = abspath(submit_f.name) - - ref_path = test_code.strip() - if not ref_path.startswith('/'): - ref_path = join(MY_DIR, ref_path) - - # Add a new signal handler for the execution of this code. - old_handler = signal.signal(signal.SIGALRM, timeout_handler) - signal.alarm(SERVER_TIMEOUT) - - # Do whatever testing needed. - success = False - try: - success, err = self._check_c_cpp_code(ref_path, submit_path) - except TimeoutException: - err = self.timeout_msg - except: - type, value = sys.exc_info()[:2] - err = "Error: {0}".format(repr(value)) - finally: - # Set back any original signal handler. - signal.signal(signal.SIGALRM, old_handler) - - # Delete the created file. - os.remove(submit_path) - - # Cancel the signal if any, see signal.alarm documentation. - signal.alarm(0) - - # Put us back into the server pool queue since we are free now. - self.queue.put(self.port) - - return success, err - - def _compile_command(self, cmd, *args, **kw): - """Compiles C/C++/java code and returns errors if any. - Run a command in a subprocess while blocking, the process is killed - if it takes more than 2 seconds to run. Return the Popen object, the - stderr. - """ - try: - proc_compile = subprocess.Popen(cmd, shell=True, stdin=None, - stdout=subprocess.PIPE, - stderr=subprocess.PIPE) - out, err = proc_compile.communicate() - except TimeoutException: - # Runaway code, so kill it. - proc_compile.kill() - # Re-raise exception. - raise - return proc_compile, err - - def _check_c_cpp_code(self, ref_code_path, submit_code_path): - """ Function validates student code using instructor code as - reference.The first argument ref_code_path, is the path to - instructor code, it is assumed to have executable permission. - The second argument submit_code_path, is the path to the student - code, it is assumed to have executable permission. - - Returns - -------- - - returns (True, "Correct answer") : If the student function returns - expected output when called by reference code. - - returns (False, error_msg): If the student function fails to return - expected output when called by reference code. - - Returns (False, error_msg): If mandatory arguments are not files or - if the required permissions are not given to the file(s). - - """ - if not isfile(ref_code_path): - return False, "No file at %s" % ref_code_path - if not isfile(submit_code_path): - return False, 'No file at %s' % submit_code_path - - success = False - output_path = os.getcwd() + '/output' - compile_command = "g++ %s -c -o %s" % (submit_code_path, output_path) - ret = self._compile_command(compile_command) - proc, stdnt_stderr = ret - - # Only if compilation is successful, the program is executed - # And tested with testcases - if stdnt_stderr == '': - executable = os.getcwd() + '/executable' - compile_main = "g++ %s %s -o %s" % (ref_code_path, output_path, - executable) - ret = self._compile_command(compile_main) - proc, main_err = ret - if main_err == '': - args = [executable] - ret = self._run_command(args, stdin=None, - stdout=subprocess.PIPE, - stderr=subprocess.PIPE) - proc, stdout, stderr = ret - if proc.returncode == 0: - success, err = True, "Correct answer" - else: - err = stdout + "\n" + stderr - os.remove(executable) - else: - err = "Error:" - try: - error_lines = main_err.splitlines() - for e in error_lines: - err = err + "\n" + e.split(":", 1)[1] - except: - err = err + "\n" + main_err - os.remove(output_path) - else: - err = "Compilation Error:" - try: - error_lines = stdnt_stderr.splitlines() - for e in error_lines: - if ':' in e: - err = err + "\n" + e.split(":", 1)[1] - else: - err = err + "\n" + e - except: - err = err + "\n" + stdnt_stderr - return success, err - - def run_cplus_code(self, answer, test_code, in_dir=None): - """Tests given C++ code (`answer`) with the `test_code` supplied. - - The testcode is a path to the reference code. - The reference code will call the function submitted by the student. - The reference code will check for the expected output. - - If the path's start with a "/" then we assume they are absolute paths. - If not, we assume they are relative paths w.r.t. the location of this - code_server script. - - If the optional `in_dir` keyword argument is supplied it changes the - directory to that directory (it does not change it back to the original - when done). - - Returns - ------- - - A tuple: (success, error message). - - """ - if in_dir is not None and isdir(in_dir): - os.chdir(in_dir) - - # The file extension must be .cpp - submit_f = open('submitstd.cpp', 'w') - submit_f.write(answer.lstrip()) - submit_f.close() - submit_path = abspath(submit_f.name) - - ref_path = test_code.strip() - if not ref_path.startswith('/'): - ref_path = join(MY_DIR, ref_path) - - # Add a new signal handler for the execution of this code. - old_handler = signal.signal(signal.SIGALRM, timeout_handler) - signal.alarm(SERVER_TIMEOUT) - - # Do whatever testing needed. - success = False - try: - success, err = self._check_c_cpp_code(ref_path, submit_path) - except TimeoutException: - err = self.timeout_msg - except: - type, value = sys.exc_info()[:2] - err = "Error: {0}".format(repr(value)) - finally: - # Set back any original signal handler. - signal.signal(signal.SIGALRM, old_handler) - - # Delete the created file. - os.remove(submit_path) - - # Cancel the signal if any, see signal.alarm documentation. - signal.alarm(0) - - # Put us back into the server pool queue since we are free now. - self.queue.put(self.port) - - return success, err - - def run_java_code(self, answer, test_code, in_dir=None): - """Tests given java code (`answer`) with the `test_code` supplied. - - The testcode is a path to the reference code. - The reference code will call the function submitted by the student. - The reference code will check for the expected output. - - If the path's start with a "/" then we assume they are absolute paths. - If not, we assume they are relative paths w.r.t. the location of this - code_server script. - - If the optional `in_dir` keyword argument is supplied it changes the - directory to that directory (it does not change it back to the original - when done). - - Returns - ------- - - A tuple: (success, error message). - - """ - if in_dir is not None and isdir(in_dir): - os.chdir(in_dir) - - # The file extension must be .java - # The class name and file name must be same in java - submit_f = open('Test.java', 'w') - submit_f.write(answer.lstrip()) - submit_f.close() - submit_path = abspath(submit_f.name) - - ref_path = test_code.strip() - if not ref_path.startswith('/'): - ref_path = join(MY_DIR, ref_path) - - # Add a new signal handler for the execution of this code. - old_handler = signal.signal(signal.SIGALRM, timeout_handler) - signal.alarm(SERVER_TIMEOUT) - - # Do whatever testing needed. - success = False - try: - success, err = self._check_java_code(ref_path, submit_path) - except TimeoutException: - err = self.timeout_msg - except: - type, value = sys.exc_info()[:2] - err = "Error: {0}".format(repr(value)) - finally: - # Set back any original signal handler. - signal.signal(signal.SIGALRM, old_handler) - - # Delete the created file. - os.remove(submit_path) - - # Cancel the signal if any, see signal.alarm documentation. - signal.alarm(0) - - # Put us back into the server pool queue since we are free now. - self.queue.put(self.port) - - return success, err - - def _check_java_code(self, ref_code_path, submit_code_path): - """ Function validates student code using instructor code as - reference.The first argument ref_code_path, is the path to - instructor code, it is assumed to have executable permission. - The second argument submit_code_path, is the path to the student - code, it is assumed to have executable permission. - - Returns - -------- - - returns (True, "Correct answer") : If the student function returns - expected output when called by reference code. - - returns (False, error_msg): If the student function fails to return - expected output when called by reference code. - - Returns (False, error_msg): If mandatory arguments are not files or - if the required permissions are not given to the file(s). - - """ - if not isfile(ref_code_path): - return False, "No file at %s" % ref_code_path - if not isfile(submit_code_path): - return False, 'No file at %s' % submit_code_path - - success = False - compile_command = "javac %s" % (submit_code_path) - ret = self._compile_command(compile_command) - proc, stdnt_stderr = ret - stdnt_stderr = self._remove_null_substitute_char(stdnt_stderr) - - # Only if compilation is successful, the program is executed - # And tested with testcases - if stdnt_stderr == '': - student_directory = os.getcwd() + '/' - student_file_name = "Test" - compile_main = "javac %s -classpath %s -d %s" % (ref_code_path, - student_directory, - student_directory) - ret = self._compile_command(compile_main) - proc, main_err = ret - main_err = self._remove_null_substitute_char(main_err) - - if main_err == '': - main_file_name = (ref_code_path.split('/')[-1]).split('.')[0] - run_command = "java -cp %s %s" % (student_directory, - main_file_name) - ret = self._run_command(run_command, - stdin=None, - shell=True, - stdout=subprocess.PIPE, - stderr=subprocess.PIPE) - proc, stdout, stderr = ret - if proc.returncode == 0: - success, err = True, "Correct answer" - else: - err = stdout + "\n" + stderr - success = False - os.remove("%s%s.class" % (student_directory, main_file_name)) - else: - err = "Error:\n" - try: - error_lines = main_err.splitlines() - for e in error_lines: - if ':' in e: - err = err + "\n" + e.split(":", 1)[1] - else: - err = err + "\n" + e - except: - err = err + "\n" + main_err - os.remove("%s%s.class" % (student_directory, student_file_name)) - else: - err = "Compilation Error:\n" - try: - error_lines = stdnt_stderr.splitlines() - for e in error_lines: - if ':' in e: - err = err + "\n" + e.split(":", 1)[1] - else: - err = err + "\n" + e - except: - err = err + "\n" + stdnt_stderr - return success, err - - def _remove_null_substitute_char(self, string): - """Returns a string without any null and substitute characters""" - stripped = "" - for c in string: - if ord(c) is not 26 and ord(c) is not 0: - stripped = stripped + c - return ''.join(stripped) - - def run_scilab_code(self, answer, test_code, in_dir=None): - """Tests given Scilab function (`answer`) with the `test_code` - supplied. If the optional `in_dir` keyword argument is supplied - it changes the directory to that directory (it does not change - it back to the original when done). This function also timesout - when the function takes more than SERVER_TIMEOUT seconds to run - to prevent runaway code. - - The testcode is a path to the reference code. - The reference code will call the function submitted by the student. - The reference code will check for the expected output. - - If the path's start with a "/" then we assume they are absolute paths. - If not, we assume they are relative paths w.r.t. the location of this - code_server script. - - Returns - ------- - - A tuple: (success, error message). - - """ - if in_dir is not None and isdir(in_dir): - os.chdir(in_dir) - - # Removes all the commands that terminates scilab - answer,i = self._remove_scilab_exit(answer.lstrip()) - - # Throw message if there are commmands that terminates scilab - add_err="" - if i > 0: - add_err = "Please do not use exit, quit and abort commands in your\ - code.\n Otherwise your code will not be evaluated\ - correctly.\n" - - # The file extension should be .sci - submit_f = open('function.sci','w') - submit_f.write(answer) - submit_f.close() - submit_path = abspath(submit_f.name) - - ref_path = test_code.strip() - if not ref_path.startswith('/'): - ref_path = join(MY_DIR, ref_path) - - # Add a new signal handler for the execution of this code. - old_handler = signal.signal(signal.SIGALRM, timeout_handler) - signal.alarm(SERVER_TIMEOUT) - - # Do whatever testing needed. - success = False - try: - cmd = 'printf "lines(0)\nexec(\'{0}\',2);\nquit();"'.format(ref_path) - cmd += ' | timeout 8 scilab-cli -nb' - ret = self._run_command(cmd, - shell=True, - stdout=subprocess.PIPE, - stderr=subprocess.PIPE) - proc, stdout, stderr = ret - - # Get only the error. - stderr = self._get_error(stdout) - if stderr is None: - # Clean output - stdout = self._strip_output(stdout) - if proc.returncode == 5: - success, err = True, "Correct answer" - else: - err = add_err + stdout - else: - err = add_err + stderr - except TimeoutException: - err = self.timeout_msg - except: - type, value = sys.exc_info()[:2] - err = "Error: {0}".format(repr(value)) - finally: - # Set back any original signal handler. - signal.signal(signal.SIGALRM, old_handler) - - # Delete the created file. - os.remove(submit_path) - - # Cancel the signal if any, see signal.alarm documentation. - signal.alarm(0) - - # Put us back into the server pool queue since we are free now. - self.queue.put(self.port) - - return success, err - - def _remove_scilab_exit(self, string): - """ - Removes exit, quit and abort from the scilab code - """ - new_string = "" - i=0 - for line in string.splitlines(): - new_line = re.sub(r"exit.*$","",line) - new_line = re.sub(r"quit.*$","",new_line) - new_line = re.sub(r"abort.*$","",new_line) - if line != new_line: - i=i+1 - new_string = new_string +'\n'+ new_line - return new_string, i - - def _get_error(self, string): - """ - Fetches only the error from the string. - Returns None if no error. - """ - obj = re.search("!.+\n.+",string); - if obj: - return obj.group() - return None - - def _strip_output(self, out): - """ - Cleans whitespace from the output - """ - strip_out = "Message" - for l in out.split('\n'): - if l.strip(): - strip_out = strip_out+"\n"+l.strip() - return strip_out - - def run(self): - """Run XMLRPC server, serving our methods. - """ - server = SimpleXMLRPCServer(("localhost", self.port)) - self.server = server - server.register_instance(self) - self.queue.put(self.port) - server.serve_forever() - - -############################################################################### -# `ServerPool` class. -############################################################################### -class ServerPool(object): - """Manages a pool of CodeServer objects.""" - def __init__(self, ports, pool_port=50000): - """Create a pool of servers. Uses a shared Queue to get available - servers. - - Parameters - ---------- - - ports : list(int) - List of ports at which the CodeServer's should run. - - pool_port : int - Port at which the server pool should serve. - """ - self.my_port = pool_port - self.ports = ports - queue = Queue(maxsize=len(ports)) - self.queue = queue - servers = [] - for port in ports: - server = CodeServer(port, queue) - servers.append(server) - p = Process(target=server.run) - p.start() - self.servers = servers - - def get_server_port(self): - """Get available server port from ones in the pool. This will block - till it gets an available server. - """ - q = self.queue - was_waiting = True if q.empty() else False - port = q.get() - if was_waiting: - print '*'*80 - print "No available servers, was waiting but got server \ - later at %d." % port - print '*'*80 - sys.stdout.flush() - return port - - def run(self): - """Run server which returns an available server port where code - can be executed. - """ - server = SimpleXMLRPCServer(("localhost", self.my_port)) - self.server = server - server.register_instance(self) - server.serve_forever() - - -############################################################################### -def main(): - run_as_nobody() - if len(sys.argv) == 1: - ports = SERVER_PORTS - else: - ports = [int(x) for x in sys.argv[1:]] - - server_pool = ServerPool(ports=ports, pool_port=SERVER_POOL_PORT) - server_pool.run() - -if __name__ == '__main__': - main() diff --git a/testapp/exam/code_server.py b/testapp/exam/code_server.py new file mode 100755 index 0000000..792197d --- /dev/null +++ b/testapp/exam/code_server.py @@ -0,0 +1,865 @@ +#!/usr/bin/env python +"""This server runs an XMLRPC server that can be submitted code and tests +and returns the output. It *should* be run as root and will run as the user +'nobody' so as to minimize any damange by errant code. This can be configured +by editing settings.py to run as many servers as desired. One can also +specify the ports on the command line. Here are examples:: + + $ sudo ./code_server.py + # Runs servers based on settings.py:SERVER_PORTS one server per port given. + +or:: + + $ sudo ./code_server.py 8001 8002 8003 8004 8005 + # Runs 5 servers on ports specified. + +All these servers should be running as nobody. This will also start a server +pool that defaults to port 50000 and is configurable in +settings.py:SERVER_POOL_PORT. This port exposes a `get_server_port` function +that returns an available server. +""" +import sys +import traceback +from SimpleXMLRPCServer import SimpleXMLRPCServer +import pwd +import os +import stat +from os.path import isdir, dirname, abspath, join, isfile +import signal +from multiprocessing import Process, Queue +import subprocess +import re +# Local imports. +from settings import SERVER_PORTS, SERVER_TIMEOUT, SERVER_POOL_PORT + +MY_DIR = abspath(dirname(__file__)) + + +def run_as_nobody(): + """Runs the current process as nobody.""" + # Set the effective uid and to that of nobody. + nobody = pwd.getpwnam('nobody') + os.setegid(nobody.pw_gid) + os.seteuid(nobody.pw_uid) + + +# Raised when the code times-out. +# c.f. http://pguides.net/python/timeout-a-function +class TimeoutException(Exception): + pass + + +def timeout_handler(signum, frame): + """A handler for the ALARM signal.""" + raise TimeoutException('Code took too long to run.') + + +############################################################################### +# `CodeServer` class. +############################################################################### +class CodeServer(object): + """A code server that executes user submitted test code, tests it and + reports if the code was correct or not. + """ + def __init__(self, port, queue): + self.port = port + self.queue = queue + msg = 'Code took more than %s seconds to run. You probably '\ + 'have an infinite loop in your code.' % SERVER_TIMEOUT + self.timeout_msg = msg + + def run_python_code(self, answer, test_code, in_dir=None): + """Tests given Python function (`answer`) with the `test_code` + supplied. If the optional `in_dir` keyword argument is supplied + it changes the directory to that directory (it does not change + it back to the original when done). This function also timesout + when the function takes more than SERVER_TIMEOUT seconds to run + to prevent runaway code. + Returns + ------- + + A tuple: (success, error message). + + """ + if in_dir is not None and isdir(in_dir): + os.chdir(in_dir) + + # Add a new signal handler for the execution of this code. + old_handler = signal.signal(signal.SIGALRM, timeout_handler) + signal.alarm(SERVER_TIMEOUT) + + success = False + tb = None + try: + submitted = compile(answer, '', mode='exec') + g = {} + exec submitted in g + _tests = compile(test_code, '', mode='exec') + exec _tests in g + except TimeoutException: + err = self.timeout_msg + except AssertionError: + type, value, tb = sys.exc_info() + info = traceback.extract_tb(tb) + fname, lineno, func, text = info[-1] + text = str(test_code).splitlines()[lineno-1] + err = "{0} {1} in: {2}".format(type.__name__, str(value), text) + except: + type, value = sys.exc_info()[:2] + err = "Error: {0}".format(repr(value)) + else: + success = True + err = 'Correct answer' + finally: + del tb + # Set back any original signal handler. + signal.signal(signal.SIGALRM, old_handler) + + # Cancel the signal if any, see signal.alarm documentation. + signal.alarm(0) + + # Put us back into the server pool queue since we are free now. + self.queue.put(self.port) + + return success, err + + def run_bash_code(self, answer, test_code, in_dir=None): + """Tests given Bash code (`answer`) with the `test_code` supplied. + + The testcode should typically contain two lines, the first is a path to + the reference script we are to compare against. The second is a path + to the arguments to be supplied to the reference and submitted script. + The output of these will be compared for correctness. + + If the path's start with a "/" then we assume they are absolute paths. + If not, we assume they are relative paths w.r.t. the location of this + code_server script. + + If the optional `in_dir` keyword argument is supplied it changes the + directory to that directory (it does not change it back to the original + when done). + + Returns + ------- + + A tuple: (success, error message). + + """ + if in_dir is not None and isdir(in_dir): + os.chdir(in_dir) + + def _set_exec(fname): + os.chmod(fname, stat.S_IRUSR | stat.S_IWUSR | stat.S_IXUSR + | stat.S_IRGRP | stat.S_IWGRP | stat.S_IXGRP + | stat.S_IROTH | stat.S_IWOTH | stat.S_IXOTH) + submit_f = open('submit.sh', 'w') + submit_f.write(answer.lstrip()) + submit_f.close() + submit_path = abspath(submit_f.name) + _set_exec(submit_path) + + ref_path, test_case_path = test_code.strip().splitlines() + if not ref_path.startswith('/'): + ref_path = join(MY_DIR, ref_path) + if not test_case_path.startswith('/'): + test_case_path = join(MY_DIR, test_case_path) + + # Add a new signal handler for the execution of this code. + old_handler = signal.signal(signal.SIGALRM, timeout_handler) + signal.alarm(SERVER_TIMEOUT) + + # Do whatever testing needed. + success = False + try: + success, err = self.check_bash_script(ref_path, submit_path, + test_case_path) + except TimeoutException: + err = self.timeout_msg + except: + type, value = sys.exc_info()[:2] + err = "Error: {0}".format(repr(value)) + finally: + # Set back any original signal handler. + signal.signal(signal.SIGALRM, old_handler) + + # Delete the created file. + os.remove(submit_path) + + # Cancel the signal if any, see signal.alarm documentation. + signal.alarm(0) + + # Put us back into the server pool queue since we are free now. + self.queue.put(self.port) + + return success, err + + def _run_command(self, cmd_args, *args, **kw): + """Run a command in a subprocess while blocking, the process is killed + if it takes more than 2 seconds to run. Return the Popen object, the + stdout and stderr. + """ + try: + proc = subprocess.Popen(cmd_args, *args, **kw) + stdout, stderr = proc.communicate() + except TimeoutException: + # Runaway code, so kill it. + proc.kill() + # Re-raise exception. + raise + return proc, stdout, stderr + + def check_bash_script(self, ref_script_path, submit_script_path, + test_case_path=None): + """ Function validates student script using instructor script as + reference. Test cases can optionally be provided. The first argument + ref_script_path, is the path to instructor script, it is assumed to + have executable permission. The second argument submit_script_path, is + the path to the student script, it is assumed to have executable + permission. The Third optional argument is the path to test the + scripts. Each line in this file is a test case and each test case is + passed to the script as standard arguments. + + Returns + -------- + + returns (True, "Correct answer") : If the student script passes all + test cases/have same output, when compared to the instructor script + + returns (False, error_msg): If the student script fails a single + test/have dissimilar output, when compared to the instructor script. + + Returns (False, error_msg): If mandatory arguments are not files or if + the required permissions are not given to the file(s). + + """ + if not isfile(ref_script_path): + return False, "No file at %s" % ref_script_path + if not isfile(submit_script_path): + return False, 'No file at %s' % submit_script_path + if not os.access(ref_script_path, os.X_OK): + return False, 'Script %s is not executable' % ref_script_path + if not os.access(submit_script_path, os.X_OK): + return False, 'Script %s is not executable' % submit_script_path + + if test_case_path is None: + ret = self._run_command(ref_script_path, stdin=None, + stdout=subprocess.PIPE, + stderr=subprocess.PIPE) + proc, inst_stdout, inst_stderr = ret + ret = self._run_command(submit_script_path, stdin=None, + stdout=subprocess.PIPE, + stderr=subprocess.PIPE) + proc, stdnt_stdout, stdnt_stderr = ret + if inst_stdout == stdnt_stdout: + return True, 'Correct answer' + else: + err = "Error: expected %s, got %s" % (inst_stderr, + stdnt_stderr) + return False, err + else: + if not isfile(test_case_path): + return False, "No test case at %s" % test_case_path + if not os.access(ref_script_path, os.R_OK): + return False, "Test script %s, not readable" % test_case_path + valid_answer = True # We initially make it one, so that we can + # stop once a test case fails + loop_count = 0 # Loop count has to be greater than or + # equal to one. + # Useful for caching things like empty + # test files,etc. + test_cases = open(test_case_path).readlines() + num_lines = len(test_cases) + for test_case in test_cases: + loop_count += 1 + if valid_answer: + args = [ref_script_path] + [x for x in test_case.split()] + ret = self._run_command(args, stdin=None, + stdout=subprocess.PIPE, + stderr=subprocess.PIPE) + proc, inst_stdout, inst_stderr = ret + args = [submit_script_path]+[x for x in test_case.split()] + ret = self._run_command(args, stdin=None, + stdout=subprocess.PIPE, + stderr=subprocess.PIPE) + proc, stdnt_stdout, stdnt_stderr = ret + valid_answer = inst_stdout == stdnt_stdout + if valid_answer and (num_lines == loop_count): + return True, "Correct answer" + else: + err = "Error:expected %s, got %s" % (inst_stdout+inst_stderr, + stdnt_stdout+stdnt_stderr) + return False, err + + def run_c_code(self, answer, test_code, in_dir=None): + """Tests given C code (`answer`) with the `test_code` supplied. + + The testcode is a path to the reference code. + The reference code will call the function submitted by the student. + The reference code will check for the expected output. + + If the path's start with a "/" then we assume they are absolute paths. + If not, we assume they are relative paths w.r.t. the location of this + code_server script. + + If the optional `in_dir` keyword argument is supplied it changes the + directory to that directory (it does not change it back to the original + when done). + + Returns + ------- + + A tuple: (success, error message). + + """ + if in_dir is not None and isdir(in_dir): + os.chdir(in_dir) + + # File extension must be .c + submit_f = open('submit.c', 'w') + submit_f.write(answer.lstrip()) + submit_f.close() + submit_path = abspath(submit_f.name) + + ref_path = test_code.strip() + if not ref_path.startswith('/'): + ref_path = join(MY_DIR, ref_path) + + # Add a new signal handler for the execution of this code. + old_handler = signal.signal(signal.SIGALRM, timeout_handler) + signal.alarm(SERVER_TIMEOUT) + + # Do whatever testing needed. + success = False + try: + success, err = self._check_c_cpp_code(ref_path, submit_path) + except TimeoutException: + err = self.timeout_msg + except: + type, value = sys.exc_info()[:2] + err = "Error: {0}".format(repr(value)) + finally: + # Set back any original signal handler. + signal.signal(signal.SIGALRM, old_handler) + + # Delete the created file. + os.remove(submit_path) + + # Cancel the signal if any, see signal.alarm documentation. + signal.alarm(0) + + # Put us back into the server pool queue since we are free now. + self.queue.put(self.port) + + return success, err + + def _compile_command(self, cmd, *args, **kw): + """Compiles C/C++/java code and returns errors if any. + Run a command in a subprocess while blocking, the process is killed + if it takes more than 2 seconds to run. Return the Popen object, the + stderr. + """ + try: + proc_compile = subprocess.Popen(cmd, shell=True, stdin=None, + stdout=subprocess.PIPE, + stderr=subprocess.PIPE) + out, err = proc_compile.communicate() + except TimeoutException: + # Runaway code, so kill it. + proc_compile.kill() + # Re-raise exception. + raise + return proc_compile, err + + def _check_c_cpp_code(self, ref_code_path, submit_code_path): + """ Function validates student code using instructor code as + reference.The first argument ref_code_path, is the path to + instructor code, it is assumed to have executable permission. + The second argument submit_code_path, is the path to the student + code, it is assumed to have executable permission. + + Returns + -------- + + returns (True, "Correct answer") : If the student function returns + expected output when called by reference code. + + returns (False, error_msg): If the student function fails to return + expected output when called by reference code. + + Returns (False, error_msg): If mandatory arguments are not files or + if the required permissions are not given to the file(s). + + """ + if not isfile(ref_code_path): + return False, "No file at %s" % ref_code_path + if not isfile(submit_code_path): + return False, 'No file at %s' % submit_code_path + + success = False + output_path = os.getcwd() + '/output' + compile_command = "g++ %s -c -o %s" % (submit_code_path, output_path) + ret = self._compile_command(compile_command) + proc, stdnt_stderr = ret + + # Only if compilation is successful, the program is executed + # And tested with testcases + if stdnt_stderr == '': + executable = os.getcwd() + '/executable' + compile_main = "g++ %s %s -o %s" % (ref_code_path, output_path, + executable) + ret = self._compile_command(compile_main) + proc, main_err = ret + if main_err == '': + args = [executable] + ret = self._run_command(args, stdin=None, + stdout=subprocess.PIPE, + stderr=subprocess.PIPE) + proc, stdout, stderr = ret + if proc.returncode == 0: + success, err = True, "Correct answer" + else: + err = stdout + "\n" + stderr + os.remove(executable) + else: + err = "Error:" + try: + error_lines = main_err.splitlines() + for e in error_lines: + err = err + "\n" + e.split(":", 1)[1] + except: + err = err + "\n" + main_err + os.remove(output_path) + else: + err = "Compilation Error:" + try: + error_lines = stdnt_stderr.splitlines() + for e in error_lines: + if ':' in e: + err = err + "\n" + e.split(":", 1)[1] + else: + err = err + "\n" + e + except: + err = err + "\n" + stdnt_stderr + return success, err + + def run_cplus_code(self, answer, test_code, in_dir=None): + """Tests given C++ code (`answer`) with the `test_code` supplied. + + The testcode is a path to the reference code. + The reference code will call the function submitted by the student. + The reference code will check for the expected output. + + If the path's start with a "/" then we assume they are absolute paths. + If not, we assume they are relative paths w.r.t. the location of this + code_server script. + + If the optional `in_dir` keyword argument is supplied it changes the + directory to that directory (it does not change it back to the original + when done). + + Returns + ------- + + A tuple: (success, error message). + + """ + if in_dir is not None and isdir(in_dir): + os.chdir(in_dir) + + # The file extension must be .cpp + submit_f = open('submitstd.cpp', 'w') + submit_f.write(answer.lstrip()) + submit_f.close() + submit_path = abspath(submit_f.name) + + ref_path = test_code.strip() + if not ref_path.startswith('/'): + ref_path = join(MY_DIR, ref_path) + + # Add a new signal handler for the execution of this code. + old_handler = signal.signal(signal.SIGALRM, timeout_handler) + signal.alarm(SERVER_TIMEOUT) + + # Do whatever testing needed. + success = False + try: + success, err = self._check_c_cpp_code(ref_path, submit_path) + except TimeoutException: + err = self.timeout_msg + except: + type, value = sys.exc_info()[:2] + err = "Error: {0}".format(repr(value)) + finally: + # Set back any original signal handler. + signal.signal(signal.SIGALRM, old_handler) + + # Delete the created file. + os.remove(submit_path) + + # Cancel the signal if any, see signal.alarm documentation. + signal.alarm(0) + + # Put us back into the server pool queue since we are free now. + self.queue.put(self.port) + + return success, err + + def run_java_code(self, answer, test_code, in_dir=None): + """Tests given java code (`answer`) with the `test_code` supplied. + + The testcode is a path to the reference code. + The reference code will call the function submitted by the student. + The reference code will check for the expected output. + + If the path's start with a "/" then we assume they are absolute paths. + If not, we assume they are relative paths w.r.t. the location of this + code_server script. + + If the optional `in_dir` keyword argument is supplied it changes the + directory to that directory (it does not change it back to the original + when done). + + Returns + ------- + + A tuple: (success, error message). + + """ + if in_dir is not None and isdir(in_dir): + os.chdir(in_dir) + + # The file extension must be .java + # The class name and file name must be same in java + submit_f = open('Test.java', 'w') + submit_f.write(answer.lstrip()) + submit_f.close() + submit_path = abspath(submit_f.name) + + ref_path = test_code.strip() + if not ref_path.startswith('/'): + ref_path = join(MY_DIR, ref_path) + + # Add a new signal handler for the execution of this code. + old_handler = signal.signal(signal.SIGALRM, timeout_handler) + signal.alarm(SERVER_TIMEOUT) + + # Do whatever testing needed. + success = False + try: + success, err = self._check_java_code(ref_path, submit_path) + except TimeoutException: + err = self.timeout_msg + except: + type, value = sys.exc_info()[:2] + err = "Error: {0}".format(repr(value)) + finally: + # Set back any original signal handler. + signal.signal(signal.SIGALRM, old_handler) + + # Delete the created file. + os.remove(submit_path) + + # Cancel the signal if any, see signal.alarm documentation. + signal.alarm(0) + + # Put us back into the server pool queue since we are free now. + self.queue.put(self.port) + + return success, err + + def _check_java_code(self, ref_code_path, submit_code_path): + """ Function validates student code using instructor code as + reference.The first argument ref_code_path, is the path to + instructor code, it is assumed to have executable permission. + The second argument submit_code_path, is the path to the student + code, it is assumed to have executable permission. + + Returns + -------- + + returns (True, "Correct answer") : If the student function returns + expected output when called by reference code. + + returns (False, error_msg): If the student function fails to return + expected output when called by reference code. + + Returns (False, error_msg): If mandatory arguments are not files or + if the required permissions are not given to the file(s). + + """ + if not isfile(ref_code_path): + return False, "No file at %s" % ref_code_path + if not isfile(submit_code_path): + return False, 'No file at %s' % submit_code_path + + success = False + compile_command = "javac %s" % (submit_code_path) + ret = self._compile_command(compile_command) + proc, stdnt_stderr = ret + stdnt_stderr = self._remove_null_substitute_char(stdnt_stderr) + + # Only if compilation is successful, the program is executed + # And tested with testcases + if stdnt_stderr == '': + student_directory = os.getcwd() + '/' + student_file_name = "Test" + compile_main = "javac %s -classpath %s -d %s" % (ref_code_path, + student_directory, + student_directory) + ret = self._compile_command(compile_main) + proc, main_err = ret + main_err = self._remove_null_substitute_char(main_err) + + if main_err == '': + main_file_name = (ref_code_path.split('/')[-1]).split('.')[0] + run_command = "java -cp %s %s" % (student_directory, + main_file_name) + ret = self._run_command(run_command, + stdin=None, + shell=True, + stdout=subprocess.PIPE, + stderr=subprocess.PIPE) + proc, stdout, stderr = ret + if proc.returncode == 0: + success, err = True, "Correct answer" + else: + err = stdout + "\n" + stderr + success = False + os.remove("%s%s.class" % (student_directory, main_file_name)) + else: + err = "Error:\n" + try: + error_lines = main_err.splitlines() + for e in error_lines: + if ':' in e: + err = err + "\n" + e.split(":", 1)[1] + else: + err = err + "\n" + e + except: + err = err + "\n" + main_err + os.remove("%s%s.class" % (student_directory, student_file_name)) + else: + err = "Compilation Error:\n" + try: + error_lines = stdnt_stderr.splitlines() + for e in error_lines: + if ':' in e: + err = err + "\n" + e.split(":", 1)[1] + else: + err = err + "\n" + e + except: + err = err + "\n" + stdnt_stderr + return success, err + + def _remove_null_substitute_char(self, string): + """Returns a string without any null and substitute characters""" + stripped = "" + for c in string: + if ord(c) is not 26 and ord(c) is not 0: + stripped = stripped + c + return ''.join(stripped) + + def run_scilab_code(self, answer, test_code, in_dir=None): + """Tests given Scilab function (`answer`) with the `test_code` + supplied. If the optional `in_dir` keyword argument is supplied + it changes the directory to that directory (it does not change + it back to the original when done). This function also timesout + when the function takes more than SERVER_TIMEOUT seconds to run + to prevent runaway code. + + The testcode is a path to the reference code. + The reference code will call the function submitted by the student. + The reference code will check for the expected output. + + If the path's start with a "/" then we assume they are absolute paths. + If not, we assume they are relative paths w.r.t. the location of this + code_server script. + + Returns + ------- + + A tuple: (success, error message). + + """ + if in_dir is not None and isdir(in_dir): + os.chdir(in_dir) + + # Removes all the commands that terminates scilab + answer,i = self._remove_scilab_exit(answer.lstrip()) + + # Throw message if there are commmands that terminates scilab + add_err="" + if i > 0: + add_err = "Please do not use exit, quit and abort commands in your\ + code.\n Otherwise your code will not be evaluated\ + correctly.\n" + + # The file extension should be .sci + submit_f = open('function.sci','w') + submit_f.write(answer) + submit_f.close() + submit_path = abspath(submit_f.name) + + ref_path = test_code.strip() + if not ref_path.startswith('/'): + ref_path = join(MY_DIR, ref_path) + + # Add a new signal handler for the execution of this code. + old_handler = signal.signal(signal.SIGALRM, timeout_handler) + signal.alarm(SERVER_TIMEOUT) + + # Do whatever testing needed. + success = False + try: + cmd = 'printf "lines(0)\nexec(\'{0}\',2);\nquit();"'.format(ref_path) + cmd += ' | timeout 8 scilab-cli -nb' + ret = self._run_command(cmd, + shell=True, + stdout=subprocess.PIPE, + stderr=subprocess.PIPE) + proc, stdout, stderr = ret + + # Get only the error. + stderr = self._get_error(stdout) + if stderr is None: + # Clean output + stdout = self._strip_output(stdout) + if proc.returncode == 5: + success, err = True, "Correct answer" + else: + err = add_err + stdout + else: + err = add_err + stderr + except TimeoutException: + err = self.timeout_msg + except: + type, value = sys.exc_info()[:2] + err = "Error: {0}".format(repr(value)) + finally: + # Set back any original signal handler. + signal.signal(signal.SIGALRM, old_handler) + + # Delete the created file. + os.remove(submit_path) + + # Cancel the signal if any, see signal.alarm documentation. + signal.alarm(0) + + # Put us back into the server pool queue since we are free now. + self.queue.put(self.port) + + return success, err + + def _remove_scilab_exit(self, string): + """ + Removes exit, quit and abort from the scilab code + """ + new_string = "" + i=0 + for line in string.splitlines(): + new_line = re.sub(r"exit.*$","",line) + new_line = re.sub(r"quit.*$","",new_line) + new_line = re.sub(r"abort.*$","",new_line) + if line != new_line: + i=i+1 + new_string = new_string +'\n'+ new_line + return new_string, i + + def _get_error(self, string): + """ + Fetches only the error from the string. + Returns None if no error. + """ + obj = re.search("!.+\n.+",string); + if obj: + return obj.group() + return None + + def _strip_output(self, out): + """ + Cleans whitespace from the output + """ + strip_out = "Message" + for l in out.split('\n'): + if l.strip(): + strip_out = strip_out+"\n"+l.strip() + return strip_out + + def run(self): + """Run XMLRPC server, serving our methods. + """ + server = SimpleXMLRPCServer(("localhost", self.port)) + self.server = server + server.register_instance(self) + self.queue.put(self.port) + server.serve_forever() + + +############################################################################### +# `ServerPool` class. +############################################################################### +class ServerPool(object): + """Manages a pool of CodeServer objects.""" + def __init__(self, ports, pool_port=50000): + """Create a pool of servers. Uses a shared Queue to get available + servers. + + Parameters + ---------- + + ports : list(int) + List of ports at which the CodeServer's should run. + + pool_port : int + Port at which the server pool should serve. + """ + self.my_port = pool_port + self.ports = ports + queue = Queue(maxsize=len(ports)) + self.queue = queue + servers = [] + for port in ports: + server = CodeServer(port, queue) + servers.append(server) + p = Process(target=server.run) + p.start() + self.servers = servers + + def get_server_port(self): + """Get available server port from ones in the pool. This will block + till it gets an available server. + """ + q = self.queue + was_waiting = True if q.empty() else False + port = q.get() + if was_waiting: + print '*'*80 + print "No available servers, was waiting but got server \ + later at %d." % port + print '*'*80 + sys.stdout.flush() + return port + + def run(self): + """Run server which returns an available server port where code + can be executed. + """ + server = SimpleXMLRPCServer(("localhost", self.my_port)) + self.server = server + server.register_instance(self) + server.serve_forever() + + +############################################################################### +def main(): + run_as_nobody() + if len(sys.argv) == 1: + ports = SERVER_PORTS + else: + ports = [int(x) for x in sys.argv[1:]] + + server_pool = ServerPool(ports=ports, pool_port=SERVER_POOL_PORT) + server_pool.run() + +if __name__ == '__main__': + main() diff --git a/testapp/exam/output/README.txt b/testapp/exam/output/README.txt new file mode 100644 index 0000000..3163ed4 --- /dev/null +++ b/testapp/exam/output/README.txt @@ -0,0 +1,4 @@ +This directory contains files generated/saved by users as per their +username. The test executor will chdir into this user directory for each +user when they run the test. Do not delete this directory and ensure that +it is writeable by all. \ No newline at end of file diff --git a/testapp/exam/views.py b/testapp/exam/views.py index 38beb0d..7c9af6c 100644 --- a/testapp/exam/views.py +++ b/testapp/exam/views.py @@ -23,7 +23,7 @@ from exam.xmlrpc_clients import code_server from settings import URL_ROOT # The directory where user data can be saved. -OUTPUT_DIR = abspath(join(dirname(__file__), pardir, 'output')) +OUTPUT_DIR = abspath(join(dirname(__file__), 'output')) def my_redirect(url): diff --git a/testapp/output/README.txt b/testapp/output/README.txt deleted file mode 100644 index 3163ed4..0000000 --- a/testapp/output/README.txt +++ /dev/null @@ -1,4 +0,0 @@ -This directory contains files generated/saved by users as per their -username. The test executor will chdir into this user directory for each -user when they run the test. Do not delete this directory and ensure that -it is writeable by all. \ No newline at end of file -- cgit