Skip to content
This repository was archived by the owner on Jun 7, 2023. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions runestone/external/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
from .external import *
109 changes: 109 additions & 0 deletions runestone/external/css/external.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
.modal-profile {
display:none;
min-height: 300px;
overflow: hidden;
width: 700px;
padding:25px;
border:1px solid #fff;
box-shadow: 0px 2px 7px #292929;
-moz-box-shadow: 0px 2px 7px #292929;
-webkit-box-shadow: 0px 2px 7px #292929;
border-radius:10px;
-moz-border-radius:10px;
-webkit-border-radius:10px;
background: #f2f2f2;
z-index:50;
}

.modal-lightsout {
display:none;
position:absolute;
top:0;
left:0;
width:100%;
z-index:25;
background:#000 ;
}

.modal-close-profile {
display:none;
position:absolute;
height: 43px;
width: 43px;
background-image: url('close.png');
top:1px;
right:0.5px;
}


.ac_actions{
text-align: center;
}

.ac_sep {
background: #000;
display: inline-block;
margin: -15px 10px;
width: 1px;
height: 35px;
padding: 0;
border: 0;
}
.ac_section{
position: relative;
clear:both;
}
.ac_section>* {
max-width: 500pt;
margin-left: auto;
margin-right: auto;
position:relative;
}
.ac_section .clearfix{
position: initial;
}
.ac_output{
display:none;
max-width: 450px;
}

.ac_caption {
text-align: center;
font-weight: bold;
}

.ac_caption_text {
font-weight: normal;
}
.ac_caption:before {
content: "ActiveCode: " counter(activecode) " ";
counter-increment: activecode;
}

.active_out {
background-color:#dcdcdc;
border-radius: 6px;
min-width: 20em;
max-height: 300px;
overflow: auto;
}

.visible-ac-canvas {
border: 2px solid black;
}

.ac_section>.col-md-12 {
max-width: 100% !important;
}

.full_width ol {
max-width: 100% !important;
}

.ac-disabled {
pointer-events: none;
}

.ac-feedback {
border: 1px solid black;
}
110 changes: 110 additions & 0 deletions runestone/external/external.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
# Copyright (C) 2011 Bradley N. Miller
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#

from docutils import nodes
from docutils.parsers.rst import directives
from runestone.common.runestonedirective import RunestoneDirective
from docutils.parsers.rst import Directive
from sqlalchemy import create_engine, Table, MetaData, select, delete
from runestone.server import get_dburl
from runestone.server.componentdb import addQuestionToDB, addHTMLToDB
from runestone.common.runestonedirective import RunestoneDirective

try:
from html import escape # py3
except ImportError:
from cgi import escape # py2

__author__ = 'jczetta'
# Code template is directly from question.py at the moment, which is (c) Bradley N. Miller.
#This is intended as the basis for a potential new gradeable directive class, still potential TODO.


def setup(app):
app.add_directive('external', ExternalDirective)

app.add_node(ExternalNode, html=(visit_external_node, depart_external_node))


class ExternalNode(nodes.General, nodes.Element):
def __init__(self, content):
super(ExternalNode, self).__init__()
self.external_options = content


def visit_external_node(self, node):
# Set options and format templates accordingly
# env = node.document.settings.env

res = TEMPLATE_START % node.external_options
self.body.append(res)

addHTMLToDB(node.external_options['divid'],
node.external_options['basecourse'],
"".join(""))

# self.body.remove(node.delimiter)


def depart_external_node(self, node):
# Set options and format templates accordingly
res = TEMPLATE_END % node.external_options
delimiter = "_start__{}_".format(node.external_options['divid'])

self.body.append(res)


# Templates to be formatted by node options
TEMPLATE_START = '''
<div data-component="external" class="full-width container external" id="%(divid)s" >
<li class="alert alert-warning">

'''
TEMPLATE_END = '''
</li>
</div>
'''


class ExternalDirective(RunestoneDirective):
"""
.. external:: identifier

Content Everything here is part of the activity
Content Can include links...
"""
required_arguments = 1
optional_arguments = 0
final_argument_whitespace = True
has_content = True
option_spec = RunestoneDirective.option_spec.copy()
option_spec.update({'number': directives.positive_int})

def run(self):
addQuestionToDB(self)

self.assert_has_content() # make sure activity has something in it
self.options['divid'] = self.arguments[0]
self.options['basecourse'] = self.state.document.settings.env.config.html_context.get('basecourse', "unknown")

self.options['name'] = self.arguments[0].strip()

external_node = ExternalNode(self.options)
self.add_name(external_node)

self.state.nested_parse(self.content, self.content_offset, external_node)

return [external_node]