Commit 3e25c230 by tarokkk

Merge branch 'master' of giccero.cloud.ik.bme.hu:cloud

parents 5267c161 8f212d3c
...@@ -25,9 +25,12 @@ urlpatterns = patterns('', ...@@ -25,9 +25,12 @@ urlpatterns = patterns('',
url(r'^reload/$', 'firewall.views.reload_firewall', name='reload_firewall'), url(r'^reload/$', 'firewall.views.reload_firewall', name='reload_firewall'),
url(r'^fwapi/$', 'firewall.views.firewall_api', name='firewall_api'), url(r'^fwapi/$', 'firewall.views.firewall_api', name='firewall_api'),
url(r'^store/$', 'store.views.index', name='store_index'), url(r'^store/$', 'store.views.index', name='store_index'),
url(r'^store/gui/$', 'store.views.gui', name='store_gui'),
url(r'^store/top/$', 'store.views.toplist', name='store_top'), url(r'^store/top/$', 'store.views.toplist', name='store_top'),
url(r'^ajax/templateWizard$', 'one.views.ajax_template_wizard', name='ajax_template_wizard'), url(r'^ajax/templateWizard$', 'one.views.ajax_template_wizard', name='ajax_template_wizard'),
url(r'^ajax/store/list$', 'store.views.ajax_listfolder', name='store_ajax_listfolder'), url(r'^ajax/store/list$', 'store.views.ajax_listfolder', name='store_ajax_listfolder'),
url(r'^ajax/store/download$', 'store.views.ajax_download', name='store_ajax_download'), url(r'^ajax/store/download$', 'store.views.ajax_download', name='store_ajax_download'),
url(r'^ajax/store/upload$', 'store.views.ajax_upload', name='store_ajax_upload'),
url(r'^ajax/store/delete$', 'store.views.ajax_delete', name='store_ajax_delete'), url(r'^ajax/store/delete$', 'store.views.ajax_delete', name='store_ajax_delete'),
url(r'^ajax/store/newFolder$', 'store.views.ajax_new_folder', name='store_ajax_new_folder'),
) )
...@@ -4,5 +4,6 @@ start on runlevel [2345] ...@@ -4,5 +4,6 @@ start on runlevel [2345]
stop on runlevel [!2345] stop on runlevel [!2345]
respawn respawn
respawn limit 30 30
exec /opt/webadmin/cloud/manage.py runserver 0.0.0.0:8080 exec sudo -u cloud /opt/webadmin/cloud/manage.py runserver 0.0.0.0:8080
...@@ -3,514 +3,156 @@ ...@@ -3,514 +3,156 @@
<title>IK Cloud</title> <title>IK Cloud</title>
<link rel="icon" type="image/png" href="https://cloud.ik.bme.hu/static/favicon.png"> <link rel="icon" type="image/png" href="https://cloud.ik.bme.hu/static/favicon.png">
<link rel="icon" type="image/png" href="https://cloud.ik.bme.hu/one/static/favicon.png"> <link rel="icon" type="image/png" href="https://cloud.ik.bme.hu/one/static/favicon.png">
<link href='http://fonts.googleapis.com/css?family=Metrophobic' rel='stylesheet' type='text/css'> <link href="https://fonts.googleapis.com/css?family=Titillium+Web&amp;subset=latin,latin-ext" rel="stylesheet" type="text/css">
<link href='http://fonts.googleapis.com/css?family=Ubuntu+Condensed&subset=latin,latin-ext' rel='stylesheet' type='text/css'> <style type="text/css" id="less:static-style">
<link href='http://fonts.googleapis.com/css?family=Ubuntu&subset=latin,latin-ext' rel='stylesheet' type='text/css'> body {
<style type="text/css" id="less:static-style">body { word-spacing: 2px;
word-spacing: 3px; letter-spacing: 0.5px;
letter-spacing: 0.5px; min-height: 100%;
min-height: 100%; font-family: 'Titillium Web', sans-serif;
font-family: 'Ubuntu', sans-serif; font-size: 12pt;
font-size: .9em; background: #dadada url(https://cloud.ik.bme.hu/static/site_bgr.png) repeat-x;
background: #dadada url(https://cloud.ik.bme.hu/static/site_bgr.png) repeat-x; background-position: 80px 0;
background-position: 80px 0; margin: 0;
margin: 0; padding: 0;
padding: 0; overflow: scroll;
overflow: scroll;
} }
#content { #content {
width: 970px; width: 970px;
text-align: left; text-align: left;
margin: 0 auto; margin: 0 auto;
} }
.contentblock { .contentblock {
background-color: #ccc; background-color: #ccc;
border-radius: 4px; border-radius: 4px;
border: 1px solid #aaa; border: 1px solid #aaa;
box-shadow: 0 0 30px rgba(0, 0, 0, 0.3); box-shadow: 0 0 30px rgba(0, 0, 0, 0.3);
margin: 20px; margin: 20px;
text-align: center;
} }
.contentblock p, .contentblock p{
.contentblock dl { margin: 15px;
margin: 0; text-align: justify;
padding: 5px;
font-size: 1.3em;
} }
.contentblock h2 { .contentblock img{
background-color: #000; margin: 0px auto;
background-image: url(https://cloud.ik.bme.hu/static/hexabar.png); display: block;
background-position: right center; box-shadow: 0 0 30px rgba(0, 0, 0, 0.3);
background-repeat: no-repeat;
border-radius: 4px;
border-bottom-left-radius: 0px;
border-bottom-right-radius: 0px;
color: #eee;
font-size: 1.5em;
margin-top: 0;
padding: 10px;
} }
.wm-list { .contentblock h2 {
list-style: none; background-color: #000;
background-image: url(https://cloud.ik.bme.hu/static/hexabar.png);
background-position: right center;
background-repeat: no-repeat;
border-radius: 4px;
border-bottom-left-radius: 0px;
border-bottom-right-radius: 0px;
color: #eee;
font-size: 1.5em;
margin-top: 0;
padding: 10px;
} }
#header { #header {
height: 80px; height: 80px;
background-color: #072c61; background-color: #072c61;
background-image: url(https://cloud.ik.bme.hu/static/bme_feher2.png); background-image: url(https://cloud.ik.bme.hu/static/bme_feher2.png);
background-repeat: no-repeat; background-repeat: no-repeat;
background-position: 20px 18px; background-position: 20px 18px;
border-bottom: 3px solid #0B4599; border-bottom: 3px solid #0B4599;
box-shadow: 0 0 30px rgba(0, 0, 0, 0.4); box-shadow: 0 0 30px rgba(0, 0, 0, 0.4);
margin: 0; margin: 0;
padding: 0 0 0 200px; padding: 0 0 0 200px;
} }
#header h1 { #header h1 {
font-size: 2em; font-size: 2em;
line-height: 80px; line-height: 80px;
float: left; float: left;
margin: 0; margin: 0;
padding: 0 1em; padding: 0 1em;
} }
#header h1 a { #header h1 a {
color: #fff; color: #fff;
}
#loginblock {
position: absolute;
right: 0;
top: 0;
background-color: #000;
background-image: url(https://cloud.ik.bme.hu/static/hexabar.png);
background-position: center center;
border-radius: 0 0 0 10px;
color: #fff;
font-weight: 700;
margin: 0;
padding: 7px;
}
#loginblock a {
color: #fff;
text-decoration: underline;
}
#loginblock a:hover {
color: #aaa;
} }
.boxes { .boxes {
width: 480px; width: 480px;
float: left; float: left;
}
.box {
background-color: #000;
background-image: url(https://cloud.ik.bme.hu/static/hexa.png);
background-position: center 30%;
background-repeat: no-repeat;
color: #fff;
font-weight: 700;
line-height: 1.5em;
width: 400px;
border-radius: 10px;
border-top-width: 30px;
margin: 10px 420px 10px 10px;
padding: 2px;
}
.box h3 {
color: #fff;
text-align: center;
margin: 0;
padding: 3px;
}
.box .content {
min-height: 100px;
margin: 0;
padding: 5px;
}
#new-wm-tooltip {
position: relative;
}
#new-wm-tooltip-container {
margin: 10px 10px 5px 150px;
border-radius: 4px;
border: 1px solid #888;
background: #FFFF66;
box-shadow: 0 0 20px rgba(0, 0, 0, 0.2);
}
#new-wm-tooltip-container p {
text-align: left;
font-size: 0.8em;
word-spacing: 2px;
}
#new-wm-tooltip-container:after {
content: "";
position: absolute;
left: 300px;
border-width: 15px;
border-style: solid;
border-color: #FFFF66 transparent transparent transparent;
}
.wm.opened .actions {
display: block !important;
}
.wm .summary {
padding: 15px 5px;
border-top: 1px solid #888;
cursor: pointer;
background-color: #c1c1c1;
}
.wm .summary.unfinished {
background-color: #FFFF66;
}
.wm .summary:hover {
background-color: #b1b1b1;
}
.wm .summary:hover .actions {
display: block;
}
.wm .summary .id {
float: right;
width: 30px;
}
.wm .summary .name {
float: left;
padding-left: 25px;
background-repeat: no-repeat;
background-position: 0 0;
}
.wm .summary .status {
text-align: right;
float: right;
width: 60px;
}
.wm .summary .actions {
float: right;
margin-left: 5px;
display: none;
}
.wm .summary .actions a {
height: 16px;
width: 16px;
display: block;
float: left;
margin-left: 2px;
}
.wm .summary .actions a:hover {
box-shadow: 0 0 10px rgba(0, 0, 0, 0.4);
background-color: rgba(0, 0, 0, 0.4);
}
.wm .details {
border-top: 1px solid #888;
background-color: #d1d1d1;
padding: 15px 5px;
display: none;
}
.wm .details h3 {
font-weight: normal;
}
.wm .details ul {
list-style: none;
margin: 10px 3px;
}
.wm .details li {
margin: 12px 0px;
padding: 3px 0px 3px 20px;
border-bottom: 1px dotted #aaa;
background-repeat: no-repeat;
background-position: 0px 4px;
}
.wm .details a {
text-decoration: underline;
}
.wm .details .name {
float: none;
background-image: url(https://cloud.ik.bme.hu/static/icons/computer.png);
}
.wm .details .os-win {
background-image: url(https://cloud.ik.bme.hu/static/icons/windows.png);
}
.wm .details .os-linux {
background-image: url(https://cloud.ik.bme.hu/static/icons/animal-penguin.png);
}
.wm .details .type {
background-image: url(https://cloud.ik.bme.hu/static/icons/box-share.png);
}
.wm .details .date {
background-image: url(https://cloud.ik.bme.hu/static/icons/calendar-day.png);
}
.wm .details .cpu {
background-image: url(https://cloud.ik.bme.hu/static/icons/processor.png);
}
.wm .details .memory {
background-image: url(https://cloud.ik.bme.hu/static/icons/memory.png);
}
.wm .details .count {
background-image: url(https://cloud.ik.bme.hu/static/icons/documents-stack.png);
}
.wm .details .value {
float: right;
width: 200px;
text-align: right;
}
.wm .details .description {
font-size: inherit;
background-image: url(https://cloud.ik.bme.hu/static/icons/document-snippet.png);
}
.wm .details .description .value {
font-size: 0.8em;
}
.wm.opened .details {
display: block;
}
.wm.new .name {
background-image: url(https://cloud.ik.bme.hu/static/icons/computer--plus.png);
}
.file-list {
list-style: none;
}
.file-list .name {
float: left;
}
.file-list .info {
float: right;
width: 60px;
text-align: right;
}
.filetype-c {
background-image: url(https://cloud.ik.bme.hu/static/icons/document-visual-studio.png);
}
.filetype-text {
background-image: url(https://cloud.ik.bme.hu/static/icons/document.png);
}
.filetype-image {
background-image: url(https://cloud.ik.bme.hu/static/icons/document-image.png);
}
.filetype-zip {
background-image: url(https://cloud.ik.bme.hu/static/icons/folder-zipper.png);
}
.filetype-folder {
background-image: url(https://cloud.ik.bme.hu/static/icons/folder-horizontal.png);
}
.filetype-more {
background-image: url(https://cloud.ik.bme.hu/static/icons/arrow-circle-double.png);
}
.filetype-up {
background-image: url(https://cloud.ik.bme.hu/static/icons/upload-cloud.png);
}
.wm-on {
background-image: url(https://cloud.ik.bme.hu/static/icons/computer-cloud.png);
}
.wm-off {
background-image: url(https://cloud.ik.bme.hu/static/icons/computer-off.png);
}
#template .wm .summary .name {
background-image: url(https://cloud.ik.bme.hu/static/icons/document-template.png);
}
#new-template-button .name {
background-image: url(https://cloud.ik.bme.hu/static/icons/document--plus.png) !important;
}
.wm-list.modal {
border-radius: 4px;
border: 1px solid #666;
}
.wm-list.modal input {
padding: 2px 10px;
}
.wm-list.modal .wm:nth-child(1) .summary {
border-top: none;
}
#modal {
position: absolute;
width: 100%;
height: 100%;
}
#shadow {
position: absolute;
height: 100%;
width: 100%;
background-color: rgba(0, 0, 0, 0.6);
}
#modal-container {
width: 500px;
position: fixed;
left: 50%;
top: 50%;
margin-left: -270px;
margin-top: -200px;
min-height: 200px;
background-color: #fff;
border-radius: 4px;
padding: 20px;
box-shadow: 0 0 30px rgba(0, 0, 0, 0.4);
border: 1px solid #333;
}
#modal-container .container {
max-height: 400px;
overflow: auto;
}
#modal-container ul {
list-style: none;
}
.wizard li {
border-bottom: 1px dotted #999;
}
.wizard label {
float: left;
padding: 5px;
margin: 10px 5px;
}
.wizard h2 {
margin: 10px 0;
}
.wizard .progress {
text-align: center;
}
.wizard .progress .bar {
height: 20px;
background-color: #66c400;
}
.wizard .progress .bar-container {
border: 1px solid #666;
box-shadow: 0 0 20px rgba(0, 0, 0, 0.2);
border-radius: 4px;
height: 20px;
position: absolute;
z-index: -1;
width: 500px;
}
.wizard input[type=text] {
display: block;
float: right;
padding: 5px;
margin: 10px 5px;
width: 200px;
text-align: right;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.3);
border: none;
border-radius: 4px;
}
.wizard input:focus {
box-shadow: 0 0 12px #8080ff;
outline: none;
}
.wizard textarea {
float: right;
padding: 5px;
margin: 10px 5px;
width: 300px;
height: 100px;
font-family: 'Ubuntu', sans-serif;
font-size: 12px;
text-align: right;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.3);
border: none;
}
.wizard nav a {
text-decoration: underline;
display: block;
}
.wizard nav .prev {
float: left;
}
.wizard nav .next {
float: right;
}
.wizard ul.radio {
float: right;
}
.wizard .radio li {
float: left;
padding: 5px;
margin: 10px 5px;
border-bottom: none !important;
}
.wizard .radio label {
float: none !important;
} }
* { * {
margin: 0; margin: 0;
padding: 0; padding: 0;
} }
.clear { .clear {
clear: both; clear: both;
} }
a { a {
text-decoration: none; text-decoration: none;
} }
abbr { abbr {
border-bottom: 1px dotted #666; border-bottom: 1px dotted #666;
} }
a:link, a:link,
a:visited { a:visited {
color: black; color: black;
} }
strong { strong {
font-size: .9em; font-size: .9em;
} }
</style> </style>
<!--<script src="./IK Cloud_files/jquery.min.js"></script>-->
</head> </head>
<body> <body>
<div id="header"> <div id="header">
<h1>
<a href="http://cloud.ik.bme.hu/">IK Cloud</a>
</h1>
<h1><a href="http://cloud.ik.bme.hu/">IK Cloud</a></h1>
</div> </div>
<div id="content"> <div id="content">
<div class="boxes">
<div class="boxes"> <div class="contentblock" id="state">
<div class="contentblock" id="state"> <h2>A projektről</h2>
<h2>A projektről</h2> <div>
<div> <p>Az <strong>IK Cloud</strong> a BME IK és IIT együttműködésében, a VIK
<p>Az <strong>IK Cloud</strong> a BME IK és IIT együttműködésében, a VIK támogatásával hosszabb ideje folyó munka során jött létre.
támogatásával hosszabb ideje folyó munka során jött létre. A kutatás célja <strong>a cloud oktatási-kutatási célú felhasználásának</strong>
A kutatás célja <strong>a cloud oktatási-kutatási célú felhasználásának</strong> vonzóvá tétele.
vonzóvá tétele. </p>
</p> <p>
<p>A rendszerünk segítségével <strong>kiváltható</strong> a tanszéken A nagy kapacitású virtuális infrastruktúra azonban új lehetőséget is nyújt.
működő öregedő szerverpark jelentős része.</p> <strong>Igény szerint</strong> indíthatóak virtuális gépek:
<p> gördülékennyé válik a tantermi és otthoni <strong>hallgatói munka,</strong>
A nagy kapacitású virtuális infrastruktúra azonban új lehetőséget is nyújt. a kutatási <strong>projektek dinamikus IT támogatása.</strong>
<strong>Igény szerint</strong> indíthatóak virtuális gépek: </p>
gördülékennyé válik a tantermi és otthoni <strong>hallgatói munka,</strong> <p><img src="IK Cloud_files/cloud-migration.png" /></p>
a kutatási <strong>projektek dinamikus IT támogatása.</strong> <p>A rendszerünk segítségével <strong>kiváltható</strong> a tanszéken
</p> működő öregedő szerverpark jelentős része.</p>
<p>Lehetőség van <strong>tantárgyra szabott környezet</strong> biztosítására </div>
a tantermi mérések vagy az otthoni feladatok elvégzéséhez, vagy az </div>
önkiszolgáló felületen pillanatok alatt indítható <strong>projektek, önálló
labor, szakdolgozat, diplomaterv, vagy TDK-munka</strong> segítéséhez
virtuális gép.</p>
<p style="text-align:center;"><a href="https://cloud.ik.bme.hu/">Próbálja ki a rendszert most!</a></p>
</div> </div>
</div> <div class="boxes">
<div class="contentblock" id="state">
</div> <h2>Virtuális labor</h2>
<div class="boxes"> <div>
<div class="contentblock" id="state" lang="en"> <p><img src="IK Cloud_files/cloud-lab.png" /></p>
<h2>About the project</h2> <p>Lehetőség van <strong>tantárgyra szabott környezet</strong> biztosítására
<div> a tantermi mérések vagy az otthoni feladatok elvégzéséhez, vagy az
<p>In the cooperation of BME IK and IIT </p> önkiszolgáló felületen pillanatok alatt indítható <strong>projektek, önálló
labor, szakdolgozat, diplomaterv, vagy TDK-munka</strong> segítéséhez
virtuális gép.</p>
<!--<p style="text-align:center;"><a
href="https://cloud.ik.bme.hu/">Próbálja ki a rendszert
most!</a></p>-->
</div>
</div>
<div class="contentblock" id="state" lang="en">
<h2>About the project</h2>
<div>
<p>The project aims to harness the power of cloud computing in
education and research. Our self service portal helps migrating
old servers, and on-demand launching appliances prepared by the
teacher.</p>
</p>
</div>
</div>
</div> </div>
</div>
</div>
<div class="clear"></div> <div class="clear"></div>
</div> </div>
<div id="modal" style="display: none"> </body>
<div id="shadow"></div> </html>
<div id="modal-container">
</div>
</div>
</body></html>
#!/bin/bash
exec >>/tmp/pclog 2>&1
date
id
read old new
old=$(git rev-parse "$old")
new=$(git rev-parse "$new")
for i in $(git rev-list $old..$new)
do
sudo -u www-data /usr/local/bin/trac-admin /srv/trac/cloud/ changeset added cloud "$i"
git log --decorate --date-order --format='%h %d - %an: %s' "$i~..$i" > /home/git/irc/irc.atw.hu/#ik/in
done
#!/bin/bash
rmtag () {
sed -e 's/<[^>]*>//g' -e 's/^[ \t]*//g' -e 's/[ \t]*$//g'
}
wget -q --user=ircbot --password=rahX5eir --no-check-certificate 'https://giccero.cloud.ik.bme.hu/trac/cloud/login?referer=%2Ftrac%2Fcloud%2Ftimeline%3Fmilestone%3Don%26ticket%3Don%26wiki%3Don%26max%3D50%26authors%3D%26daysback%3D1%26format%3Drss' -O-|grep -E '(<guid|<title|<link)' | sed -e '1,4d' |
while read title; read link ;read guid
do
guid=$(rmtag <<<"$guid")
title=$(rmtag <<<"$title")
link=$(rmtag <<<"$link")
if ! grep -qs "$guid" ~/tracrss/old
then
echo "$guid" >> ~/tracrss/old
echo "$title <$link>" >~/irc/irc.atw.hu/#ik/in
fi
done
...@@ -23,6 +23,11 @@ SITE_HOST = config.get('store', 'site_host') ...@@ -23,6 +23,11 @@ SITE_HOST = config.get('store', 'site_host')
SITE_PORT = config.get('store', 'site_port') SITE_PORT = config.get('store', 'site_port')
# Temporary dir for tar.gz # Temporary dir for tar.gz
TEMP_DIR = config.get('store', 'temp_dir') TEMP_DIR = config.get('store', 'temp_dir')
#Redirect
try:
REDIRECT_URL = config.get('store', 'redirect_url')
except:
REDIRECT_URL = "https://cloud.ik.bme.hu"
#ForceSSL #ForceSSL
try: try:
FORCE_SSL = config.get('store', 'force_ssl') == "True" FORCE_SSL = config.get('store', 'force_ssl') == "True"
...@@ -32,15 +37,15 @@ except: ...@@ -32,15 +37,15 @@ except:
def force_ssl(original_function): def force_ssl(original_function):
def new_function(*args, **kwargs): def new_function(*args, **kwargs):
ssl = request.environ.get('SSL_CLIENT_VERIFY', 'NONE') if FORCE_SSL:
if ssl != "SUCCESS": ssl = request.environ.get('SSL_CLIENT_VERIFY', 'NONE')
abort(403, "Forbidden requests. This site need SSL verification! SSL status: "+ssl) if ssl != "SUCCESS":
abort(403, "Forbidden requests. This site need SSL verification! SSL status: "+ssl)
else:
return original_function(*args, **kwargs)
else: else:
return original_function(*args, **kwargs) return original_function(*args, **kwargs)
if FORCE_SSL: return new_function
return new_function
else:
return original_function(*args, **kwargs)
@route('/') @route('/')
@force_ssl @force_ssl
...@@ -288,8 +293,12 @@ def upload(hash_num): ...@@ -288,8 +293,12 @@ def upload(hash_num):
for chunk in fbuffer(file_data.file): for chunk in fbuffer(file_data.file):
f.write(chunk) f.write(chunk)
datalength += len(chunk) datalength += len(chunk)
return 'Upload finished: '+file_name+' - '+str(datalength)+' Byte' try:
redirect_address = request.headers.get('Referer')
except:
redirect_address = REDIRECT_URL
redirect(redirect_address)
#return 'Upload finished: '+file_name+' - '+str(datalength)+' Byte'
......
...@@ -12,7 +12,7 @@ mask = IN_CREATE | IN_MODIFY | IN_DONT_FOLLOW ...@@ -12,7 +12,7 @@ mask = IN_CREATE | IN_MODIFY | IN_DONT_FOLLOW
Register given file to ~/../.top dir as a symbolic link. Register given file to ~/../.top dir as a symbolic link.
""" """
def update_new(name): def update_new(name):
norm = os.path.normpath(name) norm = os.path.realpath(name)
if norm != name: if norm != name:
return # link return # link
name = norm name = norm
...@@ -24,7 +24,7 @@ def update_new(name): ...@@ -24,7 +24,7 @@ def update_new(name):
if not name.startswith(home): if not name.startswith(home):
return # outside home return # outside home
top_dir = os.path.normpath(os.path.join(home, "../.top")) top_dir = os.path.realpath(os.path.join(home, "../.top"))
try: try:
os.mkdir(top_dir) os.mkdir(top_dir)
except OSError: except OSError:
......
...@@ -7,7 +7,7 @@ from django.db import transaction ...@@ -7,7 +7,7 @@ from django.db import transaction
from django.db.models.signals import post_save from django.db.models.signals import post_save
from django import forms from django import forms
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext_lazy as _
from firewall.models import Host, Rule, Vlan from firewall.models import Host, Rule, Vlan, settings
from firewall.tasks import reload_firewall_lock from firewall.tasks import reload_firewall_lock
from one.util import keygen from one.util import keygen
from school.models import Person from school.models import Person
......
body body
{ {
min-height:100%; min-height:100%;
font-family:'Metrophobic',sans-serif; font-family: 'Titillium Web', sans-serif;
font-size:.9em; font-size:.9em;
background:#dadada url(site_bgr.png) repeat-x; background:#dadada url(site_bgr.png) repeat-x;
background-position:80px 0; background-position:80px 0;
...@@ -47,3 +47,90 @@ body ...@@ -47,3 +47,90 @@ body
.wm-list{ .wm-list{
list-style: none; list-style: none;
} }
ul.messagelist
{
text-align:left;
margin:0;
padding:0 0 5px;
}
ul.messagelist li
{
font-size:12px;
display:block;
border-bottom:1px solid #ddd;
color:#666;
background:#ffc url(admin/img/icon_success.gif) 5px .3em no-repeat;
margin:0 0 3px;
padding:4px 5px 4px 25px;
}
ul.messagelist li.warning
{
background-image:url(admin/img/icon_alert.gif);
}
ul.messagelist li.error
{
background-image:url(admin/img/icon_error.gif);
}
.errornote
{
font-size:12px!important;
display:block;
border:1px solid red;
color:red;
background:#ffc url(admin/img/icon_error.gif) 5px .3em no-repeat;
margin:0 0 3px;
padding:4px 5px 4px 25px;
}
.errorlist li
{
font-size:12px!important;
display:block;
border:1px solid red;
color:#FFF;
background:red url(admin/img/icon_alert.gif) 5px .3em no-repeat;
margin:0 0 3px;
padding:4px 5px 4px 25px;
}
.errorlist li a
{
color:#FFF;
text-decoration:underline;
}
td ul.errorlist li
{
margin:0!important;
}
.errors
{
background:#ffc;
}
.errors input,.errors select,.errors textarea
{
border:1px solid red;
}
div.system-message
{
background:#ffc;
font-size:.8em;
margin:10px;
padding:6px 8px;
}
div.system-message p.system-message-title
{
color:red;
background:#ffc url(admin/img/icon_error.gif) 5px .3em no-repeat;
margin:0;
padding:4px 5px 4px 25px;
}
...@@ -138,6 +138,16 @@ ...@@ -138,6 +138,16 @@
} }
} }
} }
#new-folder-form {
float: right;
margin-left: 5px;
display: none;
z-index: 2;
position: relative;
}
}
&.opened #new-folder-form {
display: block;
} }
.details{ .details{
border-top: 1px solid #888; border-top: 1px solid #888;
...@@ -206,9 +216,6 @@ ...@@ -206,9 +216,6 @@
} }
} }
} }
&.opened .details{
display: block;
}
&.new .name{ &.new .name{
background-image: url(icons/computer--plus.png); background-image: url(icons/computer--plus.png);
} }
...@@ -239,7 +246,7 @@ ...@@ -239,7 +246,7 @@
background-image: url(icons/folder-zipper.png); background-image: url(icons/folder-zipper.png);
} }
.filetype-folder { .filetype-folder {
background-image: url(icons/folder-horizontal.png); background-image: url(icons/folder.png);
} }
.filetype-more { .filetype-more {
background-image: url(icons/arrow-circle-double.png); background-image: url(icons/arrow-circle-double.png);
...@@ -247,6 +254,9 @@ ...@@ -247,6 +254,9 @@
.filetype-up { .filetype-up {
background-image: url(icons/upload-cloud.png); background-image: url(icons/upload-cloud.png);
} }
.filetype-new-folder {
background-image: url(icons/folder--plus.png);
}
.filetype-jump-out { .filetype-jump-out {
background-image: url(icons/arrow-curve-090.png); background-image: url(icons/arrow-curve-090.png);
} }
......
var toggleDetails; var toggleDetails;
$(function(){ $(function() {
function getCookie(name) { function getCookie(name) {
var cookieValue = null; var cookieValue = null;
if (document.cookie && document.cookie != '') { if(document.cookie && document.cookie != '') {
var cookies = document.cookie.split(';'); var cookies = document.cookie.split(';');
for (var i = 0; i < cookies.length; i++) { for(var i = 0; i < cookies.length; i++) {
var cookie = jQuery.trim(cookies[i]); var cookie = jQuery.trim(cookies[i]);
if (cookie.substring(0, name.length + 1) == (name + '=')) { if(cookie.substring(0, name.length + 1) == (name + '=')) {
cookieValue = decodeURIComponent(cookie.substring(name.length + 1)); cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
break; break;
} }
...@@ -15,165 +15,230 @@ $(function(){ ...@@ -15,165 +15,230 @@ $(function(){
return cookieValue; return cookieValue;
} }
var csrftoken = getCookie('csrftoken'); var csrftoken = getCookie('csrftoken');
function csrfSafeMethod(method) { function csrfSafeMethod(method) {
return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method)); return(/^(GET|HEAD|OPTIONS|TRACE)$/.test(method));
} }
$.ajaxSetup({ $.ajaxSetup({
crossDomain: false, crossDomain: false,
beforeSend: function(xhr, settings) { beforeSend: function(xhr, settings) {
if (!csrfSafeMethod(settings.type)) { if(!csrfSafeMethod(settings.type)) {
xhr.setRequestHeader("X-CSRFToken", csrftoken); xhr.setRequestHeader("X-CSRFToken", csrftoken);
} }
} }
}); });
toggleDetails=function(){ toggleDetails = function() {
if($(this).next('.details').is(':hidden')){ if($(this).parent('.wm').hasClass('opened')){
$(this).next('.details').slideDown(700); $(this).parent('.wm').removeClass('opened');
$(this).parent('.wm').addClass('opened'); $(this).next('.details').slideUp(700);
} else { } else {
var that=this; console.log('addClass');
$(this).next('.details').slideUp(700,function(){ $(this).parent('.wm').addClass('opened');
$(that).parent('.wm').removeClass('opened'); $(this).next('.details').slideDown(700);
});
} }
} }
$('.wm .summary').unbind('click').click(toggleDetails); $('.wm .summary').unbind('click').click(toggleDetails);
$('#load-more-files').click(function(){ $('#load-more-files').click(function() {
$('.actions', this).show(); $('.actions', this).show();
var that=this; var that = this;
setTimeout(function(){ setTimeout(function() {
$(that).prev('li').slideDown(500,function(){ $(that).prev('li').slideDown(500, function() {
$('.actions', that).hide(); $('.actions', that).hide();
}); });
},2000); }, 2000);
}) })
$('#new-wm-button').click(function(){ $('#new-wm-button').click(function() {
$('#modal').show(); $('#modal').show();
$('#modal-container').html($('#new-wm').html()); $('#modal-container').html($('#new-wm').html());
$('#modal-container .wm .summary').each(function(){ $('#modal-container .wm .summary').each(function() {
this.originalHeight=parseInt($(this).next('.details').css('height')); this.originalHeight = parseInt($(this).next('.details').css('height'));
}) })
$('#modal-container .wm .summary').click(toggleDetails); $('#modal-container .wm .summary').click(toggleDetails);
}); });
$('#new-template-button').click(function(){ $('#new-template-button').click(function() {
$('#modal').show(); $('#modal').show();
$('#modal-container').html($('#new-template').html()); $('#modal-container').html($('#new-template').html());
}); });
$('#shadow').click(function(){ $('#shadow').click(function() {
$('#modal').hide(); $('#modal').hide();
}) })
$('#new-template-button').click(function(){ $('#new-template-button').click(function() {
$.get('/ajax/templateWizard', function(data){ $.get('/ajax/templateWizard', function(data) {
$('#modal-container').html(data); $('#modal-container').html(data);
}) })
$('#modal').show(); $('#modal').show();
}); });
var Model=function(){
var self=this; function Model() {
self.files=ko.observableArray(); var self = this;
self.allFiles=[]; self.files = ko.observableArray();
self.notInRoot=ko.observable(false); self.allFiles = [];
self.fileLimit=5; self.notInRoot = ko.observable(false);
self.jumpUp=function(){ self.fileLimit = 5;
var s=self.currentPath(); function throttle(f) {
self.currentPath(s.substr(0,s.substr(0,s.length-1).lastIndexOf('/')+1)); var disabled = false;
loadFolder(self.currentPath()); return function() {
if(disabled) {
console.log('disabled');
return
};
disabled = true;
setTimeout(function() {
disabled = false;
}, 700);
f.apply(null, arguments);
}
} }
var loadFolder=function(path){ self.jumpUp = function() {
self.fileLimit=5; var s = self.currentPath();
loadFolder(s.substr(0, s.substr(0, s.length - 1).lastIndexOf('/') + 1));
}
var loadFolder = throttle(function(path) {
self.currentPath(path);
self.fileLimit = 5;
$.ajax({ $.ajax({
type: 'POST', type: 'POST',
data: 'path='+path, data: 'path=' + path,
url: '/ajax/store/list', url: '/ajax/store/list',
dataType: 'json', dataType: 'json',
success: function(data){ success: function(data) {
$('.file-list .real').css({left:0,position:'relative'}).animate({left:'-100%'},500).promise().done(function(){ $('.file-list .real').css({
left: 0,
position: 'relative'
}).animate({
left: '-100%'
}, 500).promise().done(function() {
loadFolderDone(data); loadFolderDone(data);
$('.file-list .real').css({left:'-300%',position:'relative'}).animate({left:0},500); $('.file-list .real').css({
left: '-300%',
position: 'relative'
}).animate({
left: 0
}, 500);
}); });
}, },
}) })
} })
var loadFolderDone=function(data){
function loadFolderDone(data) {
var viewData = [];
var added = 0;
self.notInRoot(self.currentPath().lastIndexOf('/') !== 0); self.notInRoot(self.currentPath().lastIndexOf('/') !== 0);
self.files([]); self.files([]);
self.allFiles=data; self.allFiles = data;
var viewData=[]; for(var i in data) {
var added=0;
for(var i in data){
added++; added++;
if(added<6) if(added < 6) addFile(data[i]);
addFile(data[i]);
} }
} }
var addFile=function(d){ function addFile(d) {
var viewData; var viewData;
if(d.TYPE === 'D'){ if(d.TYPE === 'D') {
viewData={ viewData = {
originalName: d.NAME, originalName: d.NAME,
name: d.NAME.length>30?(d.NAME.substr(0,27)+'...'):d.NAME, name: d.NAME.length > 30 ? (d.NAME.substr(0, 27) + '...') : d.NAME,
size: 'katalógus', size: 'katalógus',
type: 'katalógus', type: 'katalógus',
mTime: d.MTIME, mTime: d.MTIME,
getTypeClass: 'name filetype-folder', getTypeClass: 'name filetype-folder',
clickHandler: function(item){ clickHandler: function(item) {
self.currentPath(self.currentPath()+item.originalName+'/'); loadFolder(self.currentPath() + item.originalName + '/');
loadFolder(self.currentPath());
} }
}; };
} else { } else {
viewData={ viewData = {
originalName: d.NAME, originalName: d.NAME,
name: d.NAME.length>30?(d.NAME.substr(0,27)+'...'):d.NAME, name: d.NAME.length > 30 ? (d.NAME.substr(0, 27) + '...') : d.NAME,
size: d.SIZE+'K', size: d.SIZE + 'K',
type: 'fájl', type: 'fájl',
mTime: d.MTIME, mTime: d.MTIME,
getTypeClass: 'name filetype-text', getTypeClass: 'name filetype-text',
clickHandler: function(item, event){ clickHandler: function(item, event) {}
}
}; };
} }
self.files.push(viewData); self.files.push(viewData);
} }
self.fadeIn=function(e){ self.fadeIn = function(e) {
console.log(e,arguments);
$(e).hide().slideDown(500); $(e).hide().slideDown(500);
} }
self.currentPath=ko.observable('/'); self.currentPath = ko.observable('/');
self.showMore=function(){ self.showMore = function() {
for(var i=self.fileLimit;i<self.fileLimit+5;i++){ for(var i = self.fileLimit; i < self.fileLimit + 5; i++) {
if(self.allFiles[i] === undefined) break; if(self.allFiles[i] === undefined) break;
addFile(self.allFiles[i]); addFile(self.allFiles[i]);
} }
self.fileLimit+=5; self.fileLimit += 5;
} }
self.download=function(item){ self.download = function(item) {
$.ajax({ $.ajax({
type: 'POST', type: 'POST',
data: 'dl='+self.currentPath()+item.originalName, data: 'dl=' + self.currentPath() + item.originalName,
url: '/ajax/store/download', url: '/ajax/store/download',
dataType: 'json', dataType: 'json',
success: function(data){ success: function(data) {
window.location.href=data.url; window.location.href = data.url;
} }
}) })
} }
self.delete=function(item){ self.delete = function(item) {
$.ajax({ $.ajax({
type: 'POST', type: 'POST',
data: 'rm='+self.currentPath()+item.originalName, data: 'rm=' + self.currentPath() + item.originalName,
url: '/ajax/store/delete', url: '/ajax/store/delete',
dataType: 'json', dataType: 'json',
success: function(data){ success: function(data) {
loadFolder(self.currentPath()); loadFolder(self.currentPath());
} }
}) })
} }
self.uploadURL=ko.observable('/');
self.getUploadURL=function(){
$.ajax({
type: 'POST',
data: 'ul='+self.currentPath()+'&next='+encodeURI(window.location.href),
url: '/ajax/store/upload',
dataType: 'json',
success: function(data){
self.uploadURL(data.url);
}
}).error(function(){ console.log('asd', arguments)})
}
self.newFolderName=ko.observable();
self.newFolder=throttle(function(i,e){
$(e.target).parent().parent().parent().removeClass('opened');
$.ajax({
type: 'POST',
data: 'new='+self.newFolderName()+'&path='+self.currentPath(),
url: '/ajax/store/newFolder',
dataType: 'json',
success: function(data){
loadFolder(self.currentPath());
}
})
});
loadFolder(self.currentPath()); loadFolder(self.currentPath());
} }
var model=new Model(); var model = new Model();
ko.applyBindings(model); ko.applyBindings(model);
document.addEventListener('dragenter', function(e){console.log(e);e.stopPropagation();e.preventDefault();return false;}); document.addEventListener('dragenter', function(e) {
document.addEventListener('dragover', function(e){console.log(e);e.stopPropagation();e.preventDefault();return false;}); console.log(e);
document.addEventListener('drop', function(e){console.log(e);e.stopPropagation();e.preventDefault();return false;}); e.stopPropagation();
e.preventDefault();
return false;
});
document.addEventListener('dragover', function(e) {
console.log(e);
e.stopPropagation();
e.preventDefault();
return false;
});
document.addEventListener('drop', function(e) {
console.log(e);
e.stopPropagation();
e.preventDefault();
console.log(e.dataTransfer.files)
return false;
});
}) })
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
<html lang="{{lang}}"> <html lang="{{lang}}">
<head> <head>
<title>{% block title %}IK Cloud{% endblock %}</title> <title>{% block title %}IK Cloud{% endblock %}</title>
<link href='http://fonts.googleapis.com/css?family=Metrophobic' rel='stylesheet' type='text/css'> <link href="https://fonts.googleapis.com/css?family=Titillium+Web&amp;subset=latin,latin-ext" rel="stylesheet" type="text/css">
<link rel="icon" type="image/png" href="/static/favicon.png" /> <link rel="icon" type="image/png" href="/static/favicon.png" />
<link rel="icon" type="image/png" href="one/static/favicon.png"> <link rel="icon" type="image/png" href="one/static/favicon.png">
<link rel="stylesheet/less" href="/static/style.less" /> <link rel="stylesheet/less" href="/static/style.less" />
......
<div class="boxes">
<div class="contentblock">
<h2>
Adattár
</h2>
<div class="content">
<ul class="file-list">
<li class="wm small">
<div class="summary">
<div class="name">Jelenlegi hely: <span data-bind="text: currentPath"></span></div>
<div class="clear"></div>
</div>
</li>
<li class="wm real" data-bind="visible: notInRoot, click: jumpUp">
<div class="summary">
<div class="name filetype-jump-out">
..
</div>
<div class="clear"></div>
</div>
</li>
<li class="wm small real" data-bind="visible: files().length == 0">
<div class="summary">
<div class="name">Nincs megjeleníthető fájl.</div>
<div class="clear"></div>
</div>
</li>
<!-- ko foreach: {data:files,afterAdd:fadeIn} -->
<li class="wm real">
<div class="summary" data-bind="click: clickHandler">
<div class="name" data-bind="text: name, attr: {class: getTypeClass}"></div>
<div class="info" data-bind="text: size"></div>
<div class="actions">
<a href="#">
<img src="/static/icons/pencil.png" alt="rename" />
</a>
<a href="#" data-bind="click: $parent.delete, clickBubble: false">
<img src="/static/icons/minus-circle.png" alt="delete" />
</a>
<a href="#" data-bind="click: $parent.download, clickBubble: false">
<img src="/static/icons/download-cloud.png" alt="download" />
</a>
</div>
<div class="clear"></div>
</div>
<div class="details">
<div class="details-container">
<ul>
<li>Módosítva: <span class="value" data-bind="text: mTime"></span></li>
<li>Típus: <span class="value" data-bind="text: type"></span></li>
</ul>
</div>
</div>
</li>
<!-- /ko -->
<li class="file-details wm" id="load-more-files" data-bind="visible: (files().length>0 && files().length != allFiles.length)">
<div class="summary" data-bind="click: showMore">
<div class="name filetype-more">
Mutass több fájlt!
</div>
<div class="clear"></div>
</div>
</li>
<li class="wm">
<div class="summary">
<div class="name filetype-new-folder">Új mappa</div>
<div id="new-folder-form">
<input type="text" placeholder="Új mappa neve" data-bind="value: newFolderName, click: function(m,e){console.log(arguments); e.preventDefault(); e.stopPropagation(); return false;}" />
<input type="submit" data-bind="click: newFolder, clickBubble: false" value="Létrehozás" />
</div>
<div class="clear"></div>
</div>
</li>
<li class="file-upload wm">
<div class="summary" data-bind="click: getUploadURL">
<div class="name filetype-up">Fájlfeltöltés</div>
<div class="clear"></div>
</div>
<div class="details">
<div class="container">
<form method="POST" data-bind="attr: {action: uploadURL}" enctype="multipart/form-data">
{% csrf_token %}
<input name="data" type="file" />
<input type="submit" value="Feltöltés"/>
</form>
</div>
</div>
</li>
<li class="wm small">
<div class="summary">
<div class="quota">
<div class="used" style="background-color: rgba(0,255,0,0.2); width: 2%"></div>
</div>
<div class="name">Kvóta: 20MB/2GB</div>
<div class="clear"></div>
</div>
</li>
</ul>
</div>
</div>
</div>
...@@ -182,77 +182,5 @@ ...@@ -182,77 +182,5 @@
{% endif %} {% endif %}
{% endfor %} {% endfor %}
</div> </div>
<div class="boxes"> {% include "box-filelist.html" %}
<div class="contentblock">
<h2>
Adattár
</h2>
<div class="content">
<ul class="file-list">
<li class="wm small">
<div class="summary">
<div class="name">Jelenlegi hely: <span data-bind="text: currentPath"></span></div>
<div class="clear"></div>
</div>
</li>
<li class="wm real" data-bind="visible: notInRoot, click: jumpUp">
<div class="summary">
<div class="name filetype-jump-out">
..
</div>
<div class="clear"></div>
</div>
</li>
<li class="wm small real" data-bind="visible: files().length == 0">
<div class="summary">
<div class="name">Nincs megjeleníthető fájl.</div>
<div class="clear"></div>
</div>
</li>
<!-- ko foreach: {data:files,afterAdd:fadeIn} -->
<li class="wm real">
<div class="summary" data-bind="click: clickHandler">
<div class="name" data-bind="text: name, attr: {class: getTypeClass}"></div>
<div class="info" data-bind="text: size"></div>
<div class="actions">
<a href="#">
<img src="/static/icons/pencil.png" alt="rename" />
</a>
<a href="#" data-bind="click: $parent.delete, clickBubble: false">
<img src="/static/icons/minus-circle.png" alt="delete" />
</a>
<a href="#" data-bind="click: $parent.download, clickBubble: false">
<img src="/static/icons/download-cloud.png" alt="download" />
</a>
</div>
<div class="clear"></div>
</div>
<div class="details">
<div class="details-container">
<ul>
<li>Módosítva: <span class="value" data-bind="text: mTime"></span></li>
<li>Típus: <span class="value" data-bind="text: type"></span></li>
</ul>
</div>
</div>
</li>
<!-- /ko -->
<li class="file-details wm" id="load-more-files" data-bind="visible: (files().length>0 && files().length != allFiles.length)">
<div class="summary" data-bind="click: showMore">
<div class="name filetype-more">
Mutass több fájlt!
</div>
<div class="clear"></div>
</div>
</li>
<li class="file-upload wm">
<div class="summary">
<div class="name filetype-up">Fájlfeltöltés</div>
<div class="clear"></div>
</div>
</li>
</ul>
</div>
</div>
</div>
{% endblock %} {% endblock %}
from django.contrib import messages
from django.core.exceptions import ValidationError
from django import contrib
from django.utils.translation import ugettext_lazy as _
from school import models
import string
class GroupInline(contrib.admin.TabularInline):
model = models.Group
extra = 3
class CourseAdmin(contrib.admin.ModelAdmin):
model = models.Course
inlines = (GroupInline, )
filter_horizontal = ('owners', )
list_display = ('code', 'name', 'short_name', 'owner_list')
list_editable = ('name', 'short_name')
class GroupAdmin(contrib.admin.ModelAdmin):
model = models.Group
filter_horizontal = ('owners', 'members', )
list_display = ('name', 'course', 'semester', 'owner_list', 'member_count')
list_filter = ('semester', 'course')
class SemesterAdmin(contrib.admin.ModelAdmin):
model = models.Semester
list_display = ('id', 'name', 'start', 'end')
list_editable = ('name', 'start', 'end')
contrib.admin.site.register(models.Course, CourseAdmin)
contrib.admin.site.register(models.Semester, SemesterAdmin)
contrib.admin.site.register(models.Group, GroupAdmin)
# -*- coding: utf-8 -*-
import datetime
from south.db import db
from south.v2 import SchemaMigration
from django.db import models
class Migration(SchemaMigration):
def forwards(self, orm):
# Deleting model 'Entity'
db.delete_table('school_entity')
# Deleting model 'LessonClass'
db.delete_table('school_lessonclass')
# Deleting model 'Lesson'
db.delete_table('school_lesson')
# Deleting model 'Person'
db.delete_table('school_person')
# Deleting model 'Mark'
db.delete_table('school_mark')
# Deleting model 'Course'
db.delete_table('school_course')
# Deleting model 'Semester'
db.delete_table('school_semester')
# Deleting model 'Event'
db.delete_table('school_event')
# Deleting model 'Attendance'
db.delete_table('school_attendance')
# Deleting model 'Group'
db.delete_table('school_group')
def backwards(self, orm):
# Adding model 'Entity'
db.create_table('school_entity', (
('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
('parent', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['school.Group'])),
('name', self.gf('django.db.models.fields.CharField')(max_length=100)),
))
db.send_create_signal('school', ['Entity'])
# Adding model 'LessonClass'
db.create_table('school_lessonclass', (
('group', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['school.Group'])),
('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
))
db.send_create_signal('school', ['LessonClass'])
# Adding model 'Lesson'
db.create_table('school_lesson', (
('group', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['school.Group'])),
('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
('lesson_class', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['school.LessonClass'])),
))
db.send_create_signal('school', ['Lesson'])
# Adding model 'Person'
db.create_table('school_person', (
('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
('language', self.gf('django.db.models.fields.CharField')(default='hu', max_length=6)),
('user', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['auth.User'], unique=True)),
))
db.send_create_signal('school', ['Person'])
# Adding model 'Mark'
db.create_table('school_mark', (
('modified_by', self.gf('django.db.models.fields.related.ForeignKey')(related_name='modified_marks', to=orm['school.Person'])),
('value', self.gf('django.db.models.fields.CharField')(max_length=100)),
('student', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['school.Person'])),
('created_at', self.gf('django.db.models.fields.DateTimeField')(auto_now_add=True, blank=True)),
('modified_at', self.gf('django.db.models.fields.DateTimeField')(auto_now=True, blank=True)),
('event', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['school.Event'])),
('created_by', self.gf('django.db.models.fields.related.ForeignKey')(related_name='created_marks', to=orm['school.Person'])),
('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
))
db.send_create_signal('school', ['Mark'])
# Adding model 'Course'
db.create_table('school_course', (
('entity_ptr', self.gf('django.db.models.fields.related.OneToOneField')(to=orm['school.Entity'], unique=True, primary_key=True)),
))
db.send_create_signal('school', ['Course'])
# Adding model 'Semester'
db.create_table('school_semester', (
('entity_ptr', self.gf('django.db.models.fields.related.OneToOneField')(to=orm['school.Entity'], unique=True, primary_key=True)),
('start', self.gf('django.db.models.fields.DateField')()),
('end', self.gf('django.db.models.fields.DateField')()),
))
db.send_create_signal('school', ['Semester'])
# Adding model 'Event'
db.create_table('school_event', (
('type', self.gf('django.db.models.fields.CharField')(max_length=5)),
('group', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['school.Group'])),
('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
('title', self.gf('django.db.models.fields.CharField')(max_length=100)),
))
db.send_create_signal('school', ['Event'])
# Adding model 'Attendance'
db.create_table('school_attendance', (
('modified_by', self.gf('django.db.models.fields.related.ForeignKey')(related_name='modified_attendances', to=orm['school.Person'])),
('modified_at', self.gf('django.db.models.fields.DateTimeField')(auto_now=True, blank=True)),
('student', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['school.Person'])),
('lesson', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['school.Lesson'])),
('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
('present', self.gf('django.db.models.fields.NullBooleanField')(null=True, blank=True)),
))
db.send_create_signal('school', ['Attendance'])
# Adding model 'Group'
db.create_table('school_group', (
('entity_ptr', self.gf('django.db.models.fields.related.OneToOneField')(to=orm['school.Entity'], unique=True, primary_key=True)),
('recursive_unique', self.gf('django.db.models.fields.BooleanField')(default=False)),
))
db.send_create_signal('school', ['Group'])
models = {
}
complete_apps = ['school']
\ No newline at end of file
# -*- coding: utf-8 -*-
import datetime
from south.db import db
from south.v2 import SchemaMigration
from django.db import models
class Migration(SchemaMigration):
def forwards(self, orm):
# Adding model 'Course'
db.create_table('school_course', (
('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
('code', self.gf('django.db.models.fields.CharField')(unique=True, max_length=10)),
('name', self.gf('django.db.models.fields.CharField')(max_length=80, null=True, blank=True)),
('default_group', self.gf('django.db.models.fields.related.ForeignKey')(blank=True, related_name='default_group_of', null=True, to=orm['school.Group'])),
))
db.send_create_signal('school', ['Course'])
# Adding M2M table for field owners on 'Course'
db.create_table('school_course_owners', (
('id', models.AutoField(verbose_name='ID', primary_key=True, auto_created=True)),
('course', models.ForeignKey(orm['school.course'], null=False)),
('user', models.ForeignKey(orm['auth.user'], null=False))
))
db.create_unique('school_course_owners', ['course_id', 'user_id'])
# Adding model 'Semester'
db.create_table('school_semester', (
('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
('start', self.gf('django.db.models.fields.DateField')()),
('end', self.gf('django.db.models.fields.DateField')()),
))
db.send_create_signal('school', ['Semester'])
# Adding model 'Person'
db.create_table('school_person', (
('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
('user', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['auth.User'], unique=True)),
))
db.send_create_signal('school', ['Person'])
# Adding model 'Group'
db.create_table('school_group', (
('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
('name', self.gf('django.db.models.fields.CharField')(unique=True, max_length=80)),
('course', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['school.Course'], null=True, blank=True)),
('semester', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['school.Semester'])),
))
db.send_create_signal('school', ['Group'])
# Adding M2M table for field owners on 'Group'
db.create_table('school_group_owners', (
('id', models.AutoField(verbose_name='ID', primary_key=True, auto_created=True)),
('group', models.ForeignKey(orm['school.group'], null=False)),
('user', models.ForeignKey(orm['auth.user'], null=False))
))
db.create_unique('school_group_owners', ['group_id', 'user_id'])
# Adding M2M table for field members on 'Group'
db.create_table('school_group_members', (
('id', models.AutoField(verbose_name='ID', primary_key=True, auto_created=True)),
('group', models.ForeignKey(orm['school.group'], null=False)),
('user', models.ForeignKey(orm['auth.user'], null=False))
))
db.create_unique('school_group_members', ['group_id', 'user_id'])
# Adding unique constraint on 'Group', fields ['name', 'course', 'semester']
db.create_unique('school_group', ['name', 'course_id', 'semester_id'])
def backwards(self, orm):
# Removing unique constraint on 'Group', fields ['name', 'course', 'semester']
db.delete_unique('school_group', ['name', 'course_id', 'semester_id'])
# Deleting model 'Course'
db.delete_table('school_course')
# Removing M2M table for field owners on 'Course'
db.delete_table('school_course_owners')
# Deleting model 'Semester'
db.delete_table('school_semester')
# Deleting model 'Person'
db.delete_table('school_person')
# Deleting model 'Group'
db.delete_table('school_group')
# Removing M2M table for field owners on 'Group'
db.delete_table('school_group_owners')
# Removing M2M table for field members on 'Group'
db.delete_table('school_group_members')
models = {
'auth.group': {
'Meta': {'object_name': 'Group'},
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}),
'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'})
},
'auth.permission': {
'Meta': {'ordering': "('content_type__app_label', 'content_type__model', 'codename')", 'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Permission'},
'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '50'})
},
'auth.user': {
'Meta': {'object_name': 'User'},
'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}),
'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}),
'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'})
},
'contenttypes.contenttype': {
'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"},
'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '100'})
},
'school.course': {
'Meta': {'object_name': 'Course'},
'code': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '10'}),
'default_group': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'default_group_of'", 'null': 'True', 'to': "orm['school.Group']"}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '80', 'null': 'True', 'blank': 'True'}),
'owners': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'to': "orm['auth.User']", 'null': 'True', 'blank': 'True'})
},
'school.group': {
'Meta': {'unique_together': "(('name', 'course', 'semester'),)", 'object_name': 'Group'},
'course': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['school.Course']", 'null': 'True', 'blank': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'members': ('django.db.models.fields.related.ManyToManyField', [], {'blank': 'True', 'related_name': "'course_groups'", 'null': 'True', 'symmetrical': 'False', 'to': "orm['auth.User']"}),
'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}),
'owners': ('django.db.models.fields.related.ManyToManyField', [], {'blank': 'True', 'related_name': "'owned_groups'", 'null': 'True', 'symmetrical': 'False', 'to': "orm['auth.User']"}),
'semester': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['school.Semester']"})
},
'school.person': {
'Meta': {'object_name': 'Person'},
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'unique': 'True'})
},
'school.semester': {
'Meta': {'object_name': 'Semester'},
'end': ('django.db.models.fields.DateField', [], {}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'start': ('django.db.models.fields.DateField', [], {})
}
}
complete_apps = ['school']
\ No newline at end of file
# -*- coding: utf-8 -*-
import datetime
from south.db import db
from south.v2 import SchemaMigration
from django.db import models
class Migration(SchemaMigration):
def forwards(self, orm):
# Adding field 'Course.short_name'
db.add_column('school_course', 'short_name',
self.gf('django.db.models.fields.CharField')(max_length=10, null=True, blank=True),
keep_default=False)
# Adding field 'Semester.name'
db.add_column('school_semester', 'name',
self.gf('django.db.models.fields.CharField')(default="semester", unique=True, max_length=20),
keep_default=False)
def backwards(self, orm):
# Deleting field 'Course.short_name'
db.delete_column('school_course', 'short_name')
# Deleting field 'Semester.name'
db.delete_column('school_semester', 'name')
models = {
'auth.group': {
'Meta': {'object_name': 'Group'},
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}),
'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'})
},
'auth.permission': {
'Meta': {'ordering': "('content_type__app_label', 'content_type__model', 'codename')", 'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Permission'},
'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '50'})
},
'auth.user': {
'Meta': {'object_name': 'User'},
'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}),
'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}),
'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'})
},
'contenttypes.contenttype': {
'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"},
'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '100'})
},
'school.course': {
'Meta': {'object_name': 'Course'},
'code': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '10'}),
'default_group': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'default_group_of'", 'null': 'True', 'to': "orm['school.Group']"}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '80', 'null': 'True', 'blank': 'True'}),
'owners': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'to': "orm['auth.User']", 'null': 'True', 'blank': 'True'}),
'short_name': ('django.db.models.fields.CharField', [], {'max_length': '10', 'null': 'True', 'blank': 'True'})
},
'school.group': {
'Meta': {'unique_together': "(('name', 'course', 'semester'),)", 'object_name': 'Group'},
'course': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['school.Course']", 'null': 'True', 'blank': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'members': ('django.db.models.fields.related.ManyToManyField', [], {'blank': 'True', 'related_name': "'course_groups'", 'null': 'True', 'symmetrical': 'False', 'to': "orm['auth.User']"}),
'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}),
'owners': ('django.db.models.fields.related.ManyToManyField', [], {'blank': 'True', 'related_name': "'owned_groups'", 'null': 'True', 'symmetrical': 'False', 'to': "orm['auth.User']"}),
'semester': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['school.Semester']"})
},
'school.person': {
'Meta': {'object_name': 'Person'},
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'unique': 'True'})
},
'school.semester': {
'Meta': {'object_name': 'Semester'},
'end': ('django.db.models.fields.DateField', [], {}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '20'}),
'start': ('django.db.models.fields.DateField', [], {})
}
}
complete_apps = ['school']
# -*- coding: utf-8 -*-
import datetime
from south.db import db
from south.v2 import SchemaMigration
from django.db import models
class Migration(SchemaMigration):
def forwards(self, orm):
# Removing M2M table for field owners on 'Group'
db.delete_table('school_group_owners')
# Removing M2M table for field members on 'Group'
db.delete_table('school_group_members')
# Removing M2M table for field owners on 'Course'
db.delete_table('school_course_owners')
def backwards(self, orm):
# Adding M2M table for field owners on 'Group'
db.create_table('school_group_owners', (
('id', models.AutoField(verbose_name='ID', primary_key=True, auto_created=True)),
('group', models.ForeignKey(orm['school.group'], null=False)),
('user', models.ForeignKey(orm['auth.user'], null=False))
))
db.create_unique('school_group_owners', ['group_id', 'user_id'])
# Adding M2M table for field members on 'Group'
db.create_table('school_group_members', (
('id', models.AutoField(verbose_name='ID', primary_key=True, auto_created=True)),
('group', models.ForeignKey(orm['school.group'], null=False)),
('user', models.ForeignKey(orm['auth.user'], null=False))
))
db.create_unique('school_group_members', ['group_id', 'user_id'])
# Adding M2M table for field owners on 'Course'
db.create_table('school_course_owners', (
('id', models.AutoField(verbose_name='ID', primary_key=True, auto_created=True)),
('course', models.ForeignKey(orm['school.course'], null=False)),
('user', models.ForeignKey(orm['auth.user'], null=False))
))
db.create_unique('school_course_owners', ['course_id', 'user_id'])
models = {
'auth.group': {
'Meta': {'object_name': 'Group'},
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}),
'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'})
},
'auth.permission': {
'Meta': {'ordering': "('content_type__app_label', 'content_type__model', 'codename')", 'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Permission'},
'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '50'})
},
'auth.user': {
'Meta': {'object_name': 'User'},
'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}),
'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}),
'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'})
},
'contenttypes.contenttype': {
'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"},
'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '100'})
},
'school.course': {
'Meta': {'object_name': 'Course'},
'code': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '10'}),
'default_group': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'default_group_of'", 'null': 'True', 'to': "orm['school.Group']"}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '80', 'null': 'True', 'blank': 'True'}),
'short_name': ('django.db.models.fields.CharField', [], {'max_length': '10', 'null': 'True', 'blank': 'True'})
},
'school.group': {
'Meta': {'unique_together': "(('name', 'course', 'semester'),)", 'object_name': 'Group'},
'course': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['school.Course']", 'null': 'True', 'blank': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}),
'semester': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['school.Semester']"})
},
'school.person': {
'Meta': {'object_name': 'Person'},
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'unique': 'True'})
},
'school.semester': {
'Meta': {'object_name': 'Semester'},
'end': ('django.db.models.fields.DateField', [], {}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '20'}),
'start': ('django.db.models.fields.DateField', [], {})
}
}
complete_apps = ['school']
\ No newline at end of file
# -*- coding: utf-8 -*-
import datetime
from south.db import db
from south.v2 import SchemaMigration
from django.db import models
class Migration(SchemaMigration):
def forwards(self, orm):
# Adding M2M table for field owners on 'Group'
db.create_table('school_group_owners', (
('id', models.AutoField(verbose_name='ID', primary_key=True, auto_created=True)),
('group', models.ForeignKey(orm['school.group'], null=False)),
('person', models.ForeignKey(orm['school.person'], null=False))
))
db.create_unique('school_group_owners', ['group_id', 'person_id'])
# Adding M2M table for field members on 'Group'
db.create_table('school_group_members', (
('id', models.AutoField(verbose_name='ID', primary_key=True, auto_created=True)),
('group', models.ForeignKey(orm['school.group'], null=False)),
('person', models.ForeignKey(orm['school.person'], null=False))
))
db.create_unique('school_group_members', ['group_id', 'person_id'])
# Adding M2M table for field owners on 'Course'
db.create_table('school_course_owners', (
('id', models.AutoField(verbose_name='ID', primary_key=True, auto_created=True)),
('course', models.ForeignKey(orm['school.course'], null=False)),
('person', models.ForeignKey(orm['school.person'], null=False))
))
db.create_unique('school_course_owners', ['course_id', 'person_id'])
def backwards(self, orm):
# Removing M2M table for field owners on 'Group'
db.delete_table('school_group_owners')
# Removing M2M table for field members on 'Group'
db.delete_table('school_group_members')
# Removing M2M table for field owners on 'Course'
db.delete_table('school_course_owners')
models = {
'auth.group': {
'Meta': {'object_name': 'Group'},
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}),
'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'})
},
'auth.permission': {
'Meta': {'ordering': "('content_type__app_label', 'content_type__model', 'codename')", 'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Permission'},
'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '50'})
},
'auth.user': {
'Meta': {'object_name': 'User'},
'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}),
'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}),
'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'})
},
'contenttypes.contenttype': {
'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"},
'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '100'})
},
'school.course': {
'Meta': {'object_name': 'Course'},
'code': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '10'}),
'default_group': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'default_group_of'", 'null': 'True', 'to': "orm['school.Group']"}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '80', 'null': 'True', 'blank': 'True'}),
'owners': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'to': "orm['school.Person']", 'null': 'True', 'blank': 'True'}),
'short_name': ('django.db.models.fields.CharField', [], {'max_length': '10', 'null': 'True', 'blank': 'True'})
},
'school.group': {
'Meta': {'unique_together': "(('name', 'course', 'semester'),)", 'object_name': 'Group'},
'course': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['school.Course']", 'null': 'True', 'blank': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'members': ('django.db.models.fields.related.ManyToManyField', [], {'blank': 'True', 'related_name': "'course_groups'", 'null': 'True', 'symmetrical': 'False', 'to': "orm['school.Person']"}),
'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}),
'owners': ('django.db.models.fields.related.ManyToManyField', [], {'blank': 'True', 'related_name': "'owned_groups'", 'null': 'True', 'symmetrical': 'False', 'to': "orm['school.Person']"}),
'semester': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['school.Semester']"})
},
'school.person': {
'Meta': {'object_name': 'Person'},
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'unique': 'True'})
},
'school.semester': {
'Meta': {'object_name': 'Semester'},
'end': ('django.db.models.fields.DateField', [], {}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '20'}),
'start': ('django.db.models.fields.DateField', [], {})
}
}
complete_apps = ['school']
\ No newline at end of file
# -*- coding: utf-8 -*-
import datetime
from south.db import db
from south.v2 import SchemaMigration
from django.db import models
class Migration(SchemaMigration):
def forwards(self, orm):
# Changing field 'Course.code'
db.alter_column('school_course', 'code', self.gf('django.db.models.fields.CharField')(unique=True, max_length=20))
def backwards(self, orm):
# Changing field 'Course.code'
db.alter_column('school_course', 'code', self.gf('django.db.models.fields.CharField')(max_length=10, unique=True))
models = {
'auth.group': {
'Meta': {'object_name': 'Group'},
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}),
'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'})
},
'auth.permission': {
'Meta': {'ordering': "('content_type__app_label', 'content_type__model', 'codename')", 'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Permission'},
'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '50'})
},
'auth.user': {
'Meta': {'object_name': 'User'},
'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}),
'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}),
'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'})
},
'contenttypes.contenttype': {
'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"},
'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '100'})
},
'school.course': {
'Meta': {'object_name': 'Course'},
'code': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '20'}),
'default_group': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'default_group_of'", 'null': 'True', 'to': "orm['school.Group']"}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '80', 'null': 'True', 'blank': 'True'}),
'owners': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'to': "orm['school.Person']", 'null': 'True', 'blank': 'True'}),
'short_name': ('django.db.models.fields.CharField', [], {'max_length': '10', 'null': 'True', 'blank': 'True'})
},
'school.group': {
'Meta': {'unique_together': "(('name', 'course', 'semester'),)", 'object_name': 'Group'},
'course': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['school.Course']", 'null': 'True', 'blank': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'members': ('django.db.models.fields.related.ManyToManyField', [], {'blank': 'True', 'related_name': "'course_groups'", 'null': 'True', 'symmetrical': 'False', 'to': "orm['school.Person']"}),
'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}),
'owners': ('django.db.models.fields.related.ManyToManyField', [], {'blank': 'True', 'related_name': "'owned_groups'", 'null': 'True', 'symmetrical': 'False', 'to': "orm['school.Person']"}),
'semester': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['school.Semester']"})
},
'school.person': {
'Meta': {'object_name': 'Person'},
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'unique': 'True'})
},
'school.semester': {
'Meta': {'object_name': 'Semester'},
'end': ('django.db.models.fields.DateField', [], {}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '20'}),
'start': ('django.db.models.fields.DateField', [], {})
}
}
complete_apps = ['school']
\ No newline at end of file
...@@ -2,63 +2,121 @@ from django.db import models ...@@ -2,63 +2,121 @@ from django.db import models
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext_lazy as _
from django.contrib.auth.models import User from django.contrib.auth.models import User
from django.db.models.signals import post_save from django.db.models.signals import post_save
from django.core.exceptions import ValidationError
from datetime import datetime
def create_user_profile(sender, instance, created, **kwargs): def create_user_profile(sender, instance, created, **kwargs):
if created: if created:
try:
Person.objects.create(user=instance) Person.objects.create(user=instance)
except:
pass
post_save.connect(create_user_profile, sender=User) post_save.connect(create_user_profile, sender=User)
LANGS = [('hu', _('Hungarian')), ('en_US', _('US English'))]
class Person(models.Model): class Person(models.Model):
user = models.ForeignKey(User, null=False, blank=False, unique=True) user = models.ForeignKey(User, null=False, blank=False, unique=True)
language = models.CharField(max_length=6, choices=LANGS, default='hu',
verbose_name=_('Preferred language'))
def __unicode__(self):
return self.user.__unicode__()
class Entity(models.Model): def short_name(self):
parent = models.ForeignKey('school.Group') if self.user.last_name:
name = models.CharField(max_length=100) return self.user.last_name
else:
return self.user.username
def __unicode__(self):
u = self.user
if not u:
return unicode(_("(none)"))
if u.last_name and u.first_name:
return _("%(first)s %(last)s") % {'first': u.first_name,
'last': u.last_name}
else:
return u.username
class Course(models.Model):
code = models.CharField(max_length=20, unique=True)
name = models.CharField(max_length=80, null=True, blank=True)
short_name = models.CharField(max_length=10, null=True, blank=True)
default_group = models.ForeignKey('Group', null=True, blank=True,
related_name='default_group_of')
owners = models.ManyToManyField(Person, blank=True, null=True)
def get_or_create_default_group(self):
if self.default_group:
return self.default_group
else:
default_group = Group(name=_("%s -- default") % self.short(),
semester=Semester.get_current(), course=self)
default_group.save()
self.default_group_id = default_group.id
self.save()
return default_group
def save(self, *args, **kwargs):
if self.default_group:
self.default_group.course = self
self.default_group.save()
self.full_clean()
super(Course, self).save(*args, **kwargs)
class Group(Entity): def __unicode__(self):
recursive_unique = models.BooleanField() if self.short_name:
return u"%s (%s)" % (self.code, self.name)
else:
return self.code
def short(self):
if self.short_name:
return self.short_name
else:
return self.code
def owner_list(self):
if self.owners:
return ", ".join([p.short_name() for p in self.owners.all()])
else:
return _("n/a")
class Course(Entity):
pass
class Semester(Entity): class Semester(models.Model):
name = models.CharField(max_length=20, unique=True, null=False)
start = models.DateField() start = models.DateField()
end = models.DateField() end = models.DateField()
EVENT_CHOICES = [('free', _('free text')), ('num', _('number')), ('int', _('integer'))] def is_on(self, time):
class Event(models.Model): return self.start <= time.date() and self.end >= time.date()
title = models.CharField(max_length=100)
group = models.ForeignKey('school.Group') @classmethod
type = models.CharField(max_length=5, choices=EVENT_CHOICES) def get_current(cls):
n = datetime.now()
class Mark(models.Model): current = [s for s in Semester.objects.all() if s.is_on(n)]
value = models.CharField(max_length=100) try:
student = models.ForeignKey('Person') return current[0]
event = models.ForeignKey('school.Event') except:
created_by = models.ForeignKey('Person', related_name='created_marks') raise ValidationError(_('There is no current semester.'))
created_at = models.DateTimeField(auto_now_add=True)
modified_by = models.ForeignKey('Person', related_name='modified_marks') def __unicode__(self):
modified_at = models.DateTimeField(auto_now=True) return self.name
class Attendance(models.Model):
present = models.NullBooleanField()
student = models.ForeignKey('Person') class Group(models.Model):
lesson = models.ForeignKey('school.Lesson') name = models.CharField(max_length=80, unique=True)
modified_by = models.ForeignKey('Person', course = models.ForeignKey('Course', null=True, blank=True)
related_name='modified_attendances') semester = models.ForeignKey('Semester', null=False, blank=False)
modified_at = models.DateTimeField(auto_now=True) owners = models.ManyToManyField(Person, blank=True, null=True, related_name='owned_groups')
members = models.ManyToManyField(Person, blank=True, null=True, related_name='course_groups')
class LessonClass(models.Model):
group = models.ForeignKey('school.Group') class Meta:
unique_together = (('name', 'course', 'semester', ), )
class Lesson(models.Model):
lesson_class = models.ForeignKey('school.LessonClass') def owner_list(self):
group = models.ForeignKey('school.Group') if self.owners:
return ", ".join([p.short_name() for p in self.owners.all()])
else:
return _("n/a")
def member_count(self):
return self.members.count()
def __unicode__(self):
if self.course:
return "%s (%s)" % (self.name, self.course.short())
else:
return "%s (%s)" % (self.name, self.owner_list())
from datetime import datetime from datetime import datetime
from django.core.exceptions import ValidationError
from django.conf import settings from django.conf import settings
from django.contrib.auth.decorators import login_required from django.contrib.auth.decorators import login_required
from django.contrib.auth.models import User from django.contrib.auth.models import User, Group as AGroup
from django.contrib import messages from django.contrib import messages
from django.core.exceptions import PermissionDenied from django.core.exceptions import PermissionDenied
from django.core import signing from django.core import signing
...@@ -9,7 +10,6 @@ from django.core.mail import mail_managers, send_mail ...@@ -9,7 +10,6 @@ from django.core.mail import mail_managers, send_mail
from django.db import transaction from django.db import transaction
from django.forms import ModelForm, Textarea from django.forms import ModelForm, Textarea
from django.http import Http404 from django.http import Http404
#from django_shibboleth.forms import BaseRegisterForm
from django.shortcuts import render, render_to_response, get_object_or_404, redirect from django.shortcuts import render, render_to_response, get_object_or_404, redirect
from django.template import RequestContext from django.template import RequestContext
from django.template.loader import render_to_string from django.template.loader import render_to_string
...@@ -20,65 +20,94 @@ from django.utils.translation import ugettext_lazy as _ ...@@ -20,65 +20,94 @@ from django.utils.translation import ugettext_lazy as _
from django.views.decorators.http import * from django.views.decorators.http import *
from django.views.generic import * from django.views.generic import *
from one.models import * from one.models import *
from school.models import *
import django.contrib.auth as auth import django.contrib.auth as auth
import logging import logging
from django.views.decorators.csrf import ensure_csrf_cookie
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
def logout(request):
auth.logout(request)
return redirect('/Shibboleth.sso/Logout?return=https%3a%2f%2fcloud.ik.bme.hu%2f')
SHIB_ATTRIBUTE_MAP = { @ensure_csrf_cookie
"HTTP_SHIB_IDENTITY_PROVIDER": (True, "idp"), def login(request):
"email": (True, "email"), try:
"sn": (True, "sn"), user = User.objects.get(username=request.META['niifPersonOrgID'])
"givenName": (True, "givenName"), except KeyError:
"niifPersonOrgID": (True, "niifPersonOrgID"), messages.error(request, _('EduID is not available.'))
} return redirect('/admin')
except User.DoesNotExist:
user = User(username=request.META['niifPersonOrgID'])
user.set_unusable_password()
user.first_name = request.META['givenName']
user.last_name = request.META['sn']
user.email = request.META['email']
user.save()
p, created = Person.objects.get_or_create(user=user)
p.save()
try:
sem = Semester.get_current()
def parse_attributes(META): attended = request.META['HTTP_NIIFEDUPERSONATTENDEDCOURSE']
shib_attrs = {} if attended == '':
error = False attended = []
for header, attr in SHIB_ATTRIBUTE_MAP.items(): else:
required, name = attr attended = attended.split(';')
values = META.get(header, None) for c in attended:
value = None
if values:
# If multiple attributes releases just care about the 1st one
try: try:
value = values.split(';')[0] co = Course.objects.get(code=c)
except: except:
value = values continue
g = co.get_or_create_default_group()
shib_attrs[name] = value if p.course_groups.filter(semester=sem, course=co).count() == 0:
if not value or value == '': try:
if required: g.members.add(p)
error = True g.save()
return shib_attrs, error messages.info(request, _('Course "%s" added.') % g.course)
except Exception as e:
logger.warning("Django ex %s" % e)
except ValidationError as e:
logger.warning("Django ex4 %s" % e)
def logout(request): held = request.META['HTTP_NIIFEDUPERSONHELDCOURSE']
auth.logout(request) if held == '':
return redirect('/Shibboleth.sso/Logout?return=https%3a%2f%2fcloud.ik.bme.hu%2f') held = []
else:
held = held.split(';')
for c in held:
co, created = Course.objects.get_or_create(code=c)
if created:
logger.warning("django Course %s created" % c)
g = co.get_or_create_default_group()
try:
co.owners.add(p)
g.owners.add(p)
messages.info(request, _('Course "%s" ownership added.') % g.course)
except Exception as e:
logger.warning("Django ex %s" % e)
co.save()
g.save()
def login(request): affiliation = request.META['affiliation']
attr, error = parse_attributes(request.META) if affiliation == '':
if not attr['niifPersonOrgID']: affiliation = []
messages.error(request, _('EduID is not available.')) else:
return redirect('/admin') affiliation = affiliation.split(';')
try: for a in affiliation:
user = User.objects.get(username=attr['niifPersonOrgID']) g, created = AGroup.objects.get_or_create(name=a)
except User.DoesNotExist: user.groups.add(g)
user = User(username=attr['niifPersonOrgID'])
user.set_unusable_password()
user.first_name = attr['givenName']
user.last_name = attr['sn']
user.email = attr['email']
user.save() user.save()
p.save()
user.backend = 'django.contrib.auth.backends.ModelBackend' user.backend = 'django.contrib.auth.backends.ModelBackend'
auth.login(request, user) auth.login(request, user)
logger.warning("Shib login with %s" % request.META) logger.warning("Shib login with %s" % request.META)
redirect_to = request.REQUEST.get(auth.REDIRECT_FIELD_NAME, '') redirect_to = request.REQUEST.get(auth.REDIRECT_FIELD_NAME, '')
if not is_safe_url(url=redirect_to, host=request.get_host()): if not is_safe_url(url=redirect_to, host=request.get_host()):
redirect_to = settings.LOGIN_REDIRECT_URL redirect_to = settings.LOGIN_REDIRECT_URL
......
...@@ -16,6 +16,9 @@ class StoreApi: ...@@ -16,6 +16,9 @@ class StoreApi:
# ssl_auth = True # ssl_auth = True
# verify_ssl = False # verify_ssl = False
@staticmethod @staticmethod
def get_host():
return settings['store_host']
@staticmethod
def post_request(url, payload): def post_request(url, payload):
headers = {'content-type': 'application/json'} headers = {'content-type': 'application/json'}
if settings['ssl_auth'] == 'True' and settings['basic_auth'] == 'True': if settings['ssl_auth'] == 'True' and settings['basic_auth'] == 'True':
...@@ -126,6 +129,14 @@ class StoreApi: ...@@ -126,6 +129,14 @@ class StoreApi:
else: else:
return False return False
@staticmethod @staticmethod
def requestquota(neptun):
url = settings['store_url']+'/'+neptun
r = StoreApi.get_request(url)
if r.status_code == requests.codes.ok:
return json.loads(r.content)
else:
return False
@staticmethod
def userexist(neptun): def userexist(neptun):
url = settings['store_url']+'/'+neptun url = settings['store_url']+'/'+neptun
r = StoreApi.get_request(url) r = StoreApi.get_request(url)
......
// using jQuery
function getCookie(name) {
var cookieValue = null;
if (document.cookie && document.cookie != '') {
var cookies = document.cookie.split(';');
for (var i = 0; i < cookies.length; i++) {
var cookie = jQuery.trim(cookies[i]);
// Does this cookie string begin with the name we want?
if (cookie.substring(0, name.length + 1) == (name + '=')) {
cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
break;
}
}
}
return cookieValue;
}
var csrftoken = getCookie('csrftoken');
function postKey(key) {
$.post("/store/gui/", { "KEY" : key },
function (respond) {
alert(respond);
}
)
.error(function (respond) { alert(JSON.stringify(respond)); });
}
function resetKey() {
$.post("/store/gui/", "",
function (respond) {
alert(respond);
}
);
}
$.ajaxSetup({
crossDomain: false, // obviates need for sameOrigin test
beforeSend: function(xhr, settings) {
xhr.setRequestHeader("X-CSRFToken", csrftoken);
}
});
<!DOCTYPE html>
<html>
<head>
<title>Store Gui</title>
<script src="/static/jquery.min.js"></script>
<script type="text/javascript" src="/static/store/gui.js"></script>
</head>
<body>
EZ LESZ A GUI JOL!
<form action="login:{{ username }}:{{ host }}">
<input type=submit name="login_button" id="login_button" value="login"/>
</form>
<form action="mount:true">
<input type=submit name="mount_button" id="mount_button" value="mount" hidden="true"/>
</form>
<form action="umount:true">
<input type=submit name="umount_button" id="umount_button" value="umount" hidden="true"/>
</form>
<form action="logout:{{ username }}:{{ host }}">
<input type=submit name="logout_button" id="logout_button" value="logout" hidden="true"/>
</form>
</body>
</html>
...@@ -8,7 +8,11 @@ ...@@ -8,7 +8,11 @@
<input type="hidden" name="auth" value="True"> <input type="hidden" name="auth" value="True">
</form> </form>
</td> </td>
<td></td> <td>
{% for k,v in quota.items %}
{{ k }} : {{ v }}
{% endfor %}
</td>
<td></td> <td></td>
<td> <td>
<form action="/store/" method="POST" <form action="/store/" method="POST"
......
# Create your views here. # Create your views here.
from django.core.context_processors import csrf
from django.http import HttpResponse from django.http import HttpResponse
from django.shortcuts import render_to_response, redirect from django.shortcuts import render_to_response, redirect
from django.template import RequestContext from django.template import RequestContext
...@@ -8,10 +9,9 @@ from django.contrib.auth.models import User ...@@ -8,10 +9,9 @@ from django.contrib.auth.models import User
from django.views.decorators.csrf import csrf_exempt from django.views.decorators.csrf import csrf_exempt
import os import os
import json import json
import base64
@login_required def estabilish_store_user(user):
def index(request):
user = request.user.username
try: try:
details = request.user.userclouddetails_set.all()[0] details = request.user.userclouddetails_set.all()[0]
password = details.smb_password password = details.smb_password
...@@ -20,13 +20,26 @@ def index(request): ...@@ -20,13 +20,26 @@ def index(request):
key_list.append(key.key) key_list.append(key.key)
except: except:
return HttpResponse('Can not acces to django database!', status_code=404) return HttpResponse('Can not acces to django database!', status_code=404)
if StoreApi.userexist(user) != True:
#Create user #Create user
if not StoreApi.createuser(user,password,key_list): if not StoreApi.createuser(user,password,key_list):
return HttpResponse('User does not exist on store! And could not create!') return HttpResponse('User does not exist on store! And could not create!')
@login_required
def index(request):
user = request.user.username
if StoreApi.userexist(user) != True:
estabilish_store_user(user)
#UpdateAuthorizationInfo #UpdateAuthorizationInfo
try: try:
auth=request.POST['auth'] auth=request.POST['auth']
try:
details = request.user.userclouddetails_set.all()[0]
password = details.smb_password
key_list = []
for key in request.user.sshkey_set.all():
key_list.append(key.key)
except:
return HttpResponse('Can not acces to django database!', status_code=404)
if not StoreApi.updateauthorizationinfo(user,password,key_list): if not StoreApi.updateauthorizationinfo(user,password,key_list):
return HttpResponse('Can not update authorization information!') return HttpResponse('Can not update authorization information!')
except: except:
...@@ -66,23 +79,14 @@ def index(request): ...@@ -66,23 +79,14 @@ def index(request):
#Normalize path (Need double dirname /folder/ -> /folder -> / #Normalize path (Need double dirname /folder/ -> /folder -> /
backpath = os.path.normpath(os.path.dirname(os.path.dirname(path))) backpath = os.path.normpath(os.path.dirname(os.path.dirname(path)))
file_list = StoreApi.listfolder(user,path) file_list = StoreApi.listfolder(user,path)
return render_to_response('store/list.html', RequestContext(request, {'file_list': file_list, 'path' : path, 'backpath' : backpath, 'username' : user})) quota = StoreApi.requestquota(user)
return render_to_response('store/list.html', RequestContext(request, {'file_list': file_list, 'path' : path, 'backpath' : backpath, 'username' : user, 'quota' : quota}))
@login_required @login_required
def ajax_listfolder(request): def ajax_listfolder(request):
user = request.user.username user = request.user.username
try:
details = request.user.userclouddetails_set.all()[0]
password = details.smb_password
key_list = []
for key in request.user.sshkey_set.all():
key_list.append(key.key)
except:
return HttpResponse('Can not acces to django database!', status_code=404)
if StoreApi.userexist(user) != True: if StoreApi.userexist(user) != True:
#Create user estabilish_store_user(user)
if not StoreApi.createuser(user,password,key_list):
return HttpResponse('User does not exist on store! And could not create!', status_code=404)
path = '/' path = '/'
try: try:
path = request.POST['path'] path = request.POST['path']
...@@ -97,17 +101,6 @@ def ajax_listfolder(request): ...@@ -97,17 +101,6 @@ def ajax_listfolder(request):
def ajax_download(request): def ajax_download(request):
user = request.user.username user = request.user.username
try: try:
details = request.user.userclouddetails_set.all()[0]
password = details.smb_password
key_list = []
for key in request.user.sshkey_set.all():
key_list.append(key.key)
except:
return HttpResponse('Can not acces to django database!', status_code=404)
if StoreApi.userexist(user) != True:
if not StoreApi.createuser(user,password,key_list):
return HttpResponse('User does not exist on store! And could not create!', status_code=404)
try:
dl = request.POST['dl'] dl = request.POST['dl']
return HttpResponse(json.dumps({'url':StoreApi.requestdownload(user,dl)})) return HttpResponse(json.dumps({'url':StoreApi.requestdownload(user,dl)}))
except: except:
...@@ -115,19 +108,19 @@ def ajax_download(request): ...@@ -115,19 +108,19 @@ def ajax_download(request):
return HttpResponse('File not found!', status_code=404) return HttpResponse('File not found!', status_code=404)
@login_required @login_required
def ajax_delete(request): def ajax_upload(request):
user = request.user.username user = request.user.username
try: try:
details = request.user.userclouddetails_set.all()[0] ul = request.POST['ul']
password = details.smb_password url = StoreApi.requestupload(user,ul)
key_list = [] return HttpResponse(json.dumps({'url':url}))
for key in request.user.sshkey_set.all():
key_list.append(key.key)
except: except:
return HttpResponse('Can not acces to django database!', status_code=404) pass
if StoreApi.userexist(user) != True: return HttpResponse('Error!', status_code=404)
if not StoreApi.createuser(user,password,key_list):
return HttpResponse('User does not exist on store! And could not create!', status_code=404) @login_required
def ajax_delete(request):
user = request.user.username
try: try:
rm = request.POST['rm'] rm = request.POST['rm']
return HttpResponse(json.dumps({'success':StoreApi.requestremove(user,rm)})) return HttpResponse(json.dumps({'success':StoreApi.requestremove(user,rm)}))
...@@ -136,12 +129,50 @@ def ajax_delete(request): ...@@ -136,12 +129,50 @@ def ajax_delete(request):
return HttpResponse('File not found!', status_code=404) return HttpResponse('File not found!', status_code=404)
@login_required @login_required
def ajax_new_folder(request):
user = request.user.username
try:
path = request.POST['path']
new = request.POST['new']
success = StoreApi.requestnewfolder(user,path+'/'+new)
return HttpResponse(json.dumps({'success':success}))
except:
pass
return HttpResponse('Error!', status_code=404)
@login_required
def toplist(request): def toplist(request):
user = request.user.username user = request.user.username
path = backpath = '/' path = backpath = '/'
file_list = StoreApi.toplist(user) file_list = StoreApi.toplist(user)
return render_to_response('store/list.html', RequestContext(request, {'file_list': file_list, 'path' : path, 'backpath' : backpath, 'username' : user})) return render_to_response('store/list.html', RequestContext(request, {'file_list': file_list, 'path' : path, 'backpath' : backpath, 'username' : user}))
@login_required
def gui(request):
user = request.user.username
if request.method == 'GET':
return render_to_response('store/gui.html', RequestContext(request, {'username' : user, 'host' : StoreApi.get_host()}))
elif request.method == 'POST':
try:
details = request.user.userclouddetails_set.all()[0]
password = details.smb_password
key_list = []
for key in request.user.sshkey_set.all():
key_list.append(key.key)
except:
return HttpResponse('Can not acces to django database!', status_code=404)
try:
lab_key_decoded = base64.b64decode(request.POST['KEY'])
key_list.append(lab_key_decoded)
except:
pass
if not StoreApi.updateauthorizationinfo(user, password, key_list):
return HttpResponse('Can not update authorization information!')
else:
return HttpResponse('Updated key information!')
else:
return HttpResponse('Method not found!', status_code=404)
def logout(request): def logout(request):
auth.logout(request) auth.logout(request)
return redirect('/') return redirect('/')
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment