Revision c2b3014a
b/edumanage/admin.py | ||
---|---|---|
7 | 7 |
|
8 | 8 |
class NameInline(generic.GenericTabularInline): |
9 | 9 |
model = Name_i18n |
10 |
|
|
11 |
class UrlInline(generic.GenericTabularInline): |
|
12 |
model = URL_i18n |
|
13 |
|
|
10 | 14 |
|
11 | 15 |
class InstitutionAdmin(admin.ModelAdmin): |
12 | 16 |
inlines = [ |
... | ... | |
18 | 22 |
NameInline, |
19 | 23 |
] |
20 | 24 |
|
25 |
class RealmInLine(admin.ModelAdmin): |
|
26 |
inlines = [ |
|
27 |
UrlInline, |
|
28 |
] |
|
21 | 29 |
|
22 | 30 |
|
23 | 31 |
admin.site.register(Name_i18n) |
... | ... | |
32 | 40 |
admin.site.register(ServiceLoc, ServiceLocAdmin) |
33 | 41 |
admin.site.register(Institution, InstitutionAdmin) |
34 | 42 |
admin.site.register(InstitutionDetails) |
35 |
admin.site.register(Realm) |
|
43 |
admin.site.register(Realm, RealmInLine)
|
|
36 | 44 |
admin.site.register(RealmData) |
b/edumanage/forms.py | ||
---|---|---|
19 | 19 |
class Meta: |
20 | 20 |
model = InstServer |
21 | 21 |
|
22 |
class ContactForm(forms.ModelForm): |
|
23 |
|
|
24 |
class Meta: |
|
25 |
model = Contact |
|
26 |
|
|
22 | 27 |
class InstRealmForm(forms.ModelForm): |
23 | 28 |
|
24 | 29 |
class Meta: |
b/edumanage/views.py | ||
---|---|---|
14 | 14 |
from django.contrib.contenttypes.generic import generic_inlineformset_factory |
15 | 15 |
import json |
16 | 16 |
import math |
17 |
from xml.etree import cElementTree as ET
|
|
17 |
from xml.etree import ElementTree as ET |
|
18 | 18 |
|
19 | 19 |
from django.conf import settings |
20 | 20 |
|
... | ... | |
421 | 421 |
return HttpResponse(json.dumps(resp), mimetype='application/json') |
422 | 422 |
|
423 | 423 |
|
424 |
|
|
425 |
@login_required |
|
426 |
def contacts(request): |
|
427 |
user = request.user |
|
428 |
servers = False |
|
429 |
instcontacts = [] |
|
430 |
try: |
|
431 |
profile = user.get_profile() |
|
432 |
inst = profile.institution |
|
433 |
except UserProfile.DoesNotExist: |
|
434 |
inst = False |
|
435 |
if inst: |
|
436 |
instcontacts.extend([x.contact.pk for x in InstitutionContactPool.objects.filter(institution=inst)]) |
|
437 |
print instcontacts |
|
438 |
contacts = Contact.objects.filter(pk__in=instcontacts) |
|
439 |
print contacts |
|
440 |
return render_to_response('edumanage/contacts.html', { 'contacts': contacts}, |
|
441 |
context_instance=RequestContext(request, base_response(request))) |
|
442 |
|
|
443 |
@login_required |
|
444 |
def add_contact(request, contact_pk): |
|
445 |
user = request.user |
|
446 |
server = False |
|
447 |
try: |
|
448 |
profile = user.get_profile() |
|
449 |
inst = profile.institution |
|
450 |
except UserProfile.DoesNotExist: |
|
451 |
inst = False |
|
452 |
|
|
453 |
if request.method == "GET": |
|
454 |
|
|
455 |
# Determine add or edit |
|
456 |
try: |
|
457 |
contactinst = InstitutionContactPool.objects.get(institution=inst, contact__pk=contact_pk) |
|
458 |
contact = contactinst.contact |
|
459 |
form = ContactForm(instance=contact) |
|
460 |
except InstitutionContactPool.DoesNotExist: |
|
461 |
form = ContactForm() |
|
462 |
|
|
463 |
return render_to_response('edumanage/contacts_edit.html', { 'form': form}, |
|
464 |
context_instance=RequestContext(request, base_response(request))) |
|
465 |
elif request.method == 'POST': |
|
466 |
request_data = request.POST.copy() |
|
467 |
try: |
|
468 |
contactinst = InstitutionContactPool.objects.get(institution=inst, contact__pk=contact_pk) |
|
469 |
contact = contactinst.contact |
|
470 |
form = ContactForm(request_data, instance=contact) |
|
471 |
except InstitutionContactPool.DoesNotExist: |
|
472 |
form = ContactForm(request_data) |
|
473 |
|
|
474 |
if form.is_valid(): |
|
475 |
contact = form.save() |
|
476 |
instContPool, created = InstitutionContactPool.objects.get_or_create(contact=contact, institution=inst) |
|
477 |
instContPool.save() |
|
478 |
return HttpResponseRedirect(reverse("contacts")) |
|
479 |
return render_to_response('edumanage/contacts_edit.html', { 'form': form}, |
|
480 |
context_instance=RequestContext(request, base_response(request))) |
|
481 |
|
|
482 |
|
|
483 |
@login_required |
|
484 |
def del_contact(request): |
|
485 |
if request.method == 'GET': |
|
486 |
user = request.user |
|
487 |
req_data = request.GET.copy() |
|
488 |
contact_pk = req_data['contact_pk'] |
|
489 |
profile = user.get_profile() |
|
490 |
institution = profile.institution |
|
491 |
resp = {} |
|
492 |
try: |
|
493 |
contactinst = InstitutionContactPool.objects.get(institution=institution, contact__pk=contact_pk) |
|
494 |
contact = contactinst.contact |
|
495 |
except InstitutionContactPool.DoesNotExist: |
|
496 |
resp['error'] = "Could not get contact or you have no rights to delete" |
|
497 |
return HttpResponse(json.dumps(resp), mimetype='application/json') |
|
498 |
try: |
|
499 |
for service in ServiceLoc.objects.filter(institutionid=institution): |
|
500 |
if (contact in service.contact.all() and len(service.contact.all()) == 1): |
|
501 |
resp['error'] = "Could not delete contact. It is the only contact in service <b>%s</b>.<br>Fix it and try again" %service.get_name(lang="en") |
|
502 |
return HttpResponse(json.dumps(resp), mimetype='application/json') |
|
503 |
if (contact in institution.institutiondetails.contact.all() and len(institution.institutiondetails.contact.all()) == 1): |
|
504 |
resp['error'] = "Could not delete contact. It is the only contact your institution.<br>Fix it and try again" |
|
505 |
return HttpResponse(json.dumps(resp), mimetype='application/json') |
|
506 |
contact.delete() |
|
507 |
except Exception: |
|
508 |
resp['error'] = "Could not delete contact" |
|
509 |
return HttpResponse(json.dumps(resp), mimetype='application/json') |
|
510 |
resp['success'] = "Contact successfully deleted" |
|
511 |
return HttpResponse(json.dumps(resp), mimetype='application/json') |
|
512 |
|
|
513 |
|
|
514 |
|
|
424 | 515 |
@login_required |
425 | 516 |
def base_response(request): |
426 | 517 |
user = request.user |
... | ... | |
428 | 519 |
server = [] |
429 | 520 |
services = [] |
430 | 521 |
instrealms = [] |
522 |
instcontacts = [] |
|
523 |
contacts = [] |
|
431 | 524 |
try: |
432 | 525 |
profile = user.get_profile() |
433 | 526 |
institution = profile.institution |
... | ... | |
435 | 528 |
server = InstServer.objects.filter(instid=institution) |
436 | 529 |
services = ServiceLoc.objects.filter(institutionid=institution) |
437 | 530 |
instrealms = InstRealm.objects.filter(instid=institution) |
531 |
instcontacts.extend([x.contact.pk for x in InstitutionContactPool.objects.filter(institution=institution)]) |
|
532 |
contacts = Contact.objects.filter(pk__in=instcontacts) |
|
438 | 533 |
except UserProfile.DoesNotExist: |
439 | 534 |
pass |
440 | 535 |
|
... | ... | |
443 | 538 |
'servers_num': len(server), |
444 | 539 |
'services_num': len(services), |
445 | 540 |
'realms_num': len(instrealms), |
541 |
'contacts_num': len(contacts), |
|
446 | 542 |
|
447 | 543 |
} |
448 | 544 |
|
... | ... | |
531 | 627 |
closestMarker = {"name": pointname, "lat": pointlat, "lng": pointlng, "text": j[1].text} |
532 | 628 |
return HttpResponse(json.dumps(closestMarker), mimetype='application/json') |
533 | 629 |
|
630 |
|
|
631 |
def instxml(request): |
|
632 |
ET._namespace_map["http://www.w3.org/2001/XMLSchema-instance"] = 'xsi' |
|
633 |
root = ET.Element("institutions") |
|
634 |
NS_XSI = "{http://www.w3.org/2001/XMLSchema-instance}" |
|
635 |
root.set(NS_XSI + "noNamespaceSchemaLocation", "institutions.xsd") |
|
636 |
#root.attrib["xsi:noNamespaceSchemaLocation"] = "institution.xsd" |
|
637 |
institutions = Institution.objects.all() |
|
638 |
for institution in institutions: |
|
639 |
try: |
|
640 |
inst = institution.institutiondetails |
|
641 |
if not inst: |
|
642 |
pass |
|
643 |
except InstitutionDetails.DoesNotExist: |
|
644 |
pass |
|
645 |
|
|
646 |
instElement = ET.SubElement(root, "institution") |
|
647 |
|
|
648 |
instCountry = ET.SubElement(instElement, "country") |
|
649 |
instCountry.text = ("%s" %inst.institution.realmid.country).upper() |
|
650 |
|
|
651 |
instType = ET.SubElement(instElement, "type") |
|
652 |
instType.text = "%s" %inst.ertype |
|
653 |
|
|
654 |
for realm in institution.instrealm_set.all(): |
|
655 |
instRealm = ET.SubElement(instElement, "inst_realm") |
|
656 |
instRealm.text = realm.realm |
|
657 |
|
|
658 |
for name in inst.institution.org_name.all(): |
|
659 |
instOrgName = ET.SubElement(instElement, "org_name") |
|
660 |
instOrgName.attrib["lang"] = name.lang |
|
661 |
instOrgName.text = u"%s" %name.name |
|
662 |
|
|
663 |
instAddress = ET.SubElement(instElement, "address") |
|
664 |
|
|
665 |
instAddrStreet = ET.SubElement(instAddress, "street") |
|
666 |
instAddrStreet.text = inst.address_street |
|
667 |
|
|
668 |
instAddrCity = ET.SubElement(instAddress, "city") |
|
669 |
instAddrCity.text = inst.address_city |
|
670 |
|
|
671 |
for contact in inst.contact.all(): |
|
672 |
instContact = ET.SubElement(instElement, "contact") |
|
673 |
|
|
674 |
instContactName = ET.SubElement(instContact, "name") |
|
675 |
instContactName.text = "%s %s" %(contact.firstname, contact.lastname) |
|
676 |
|
|
677 |
instContactEmail = ET.SubElement(instContact, "email") |
|
678 |
instContactEmail.text = contact.email |
|
679 |
|
|
680 |
instContactPhone = ET.SubElement(instContact, "phone") |
|
681 |
instContactPhone.text = contact.phone |
|
534 | 682 |
|
683 |
for url in inst.url.all(): |
|
684 |
instUrl = ET.SubElement(instElement, "%s_URL"%(url.urltype)) |
|
685 |
instUrl.attrib["lang"] = url.lang |
|
686 |
instUrl.text = url.url |
|
687 |
|
|
688 |
#Let's go to Institution Service Locations |
|
535 | 689 |
|
690 |
for serviceloc in inst.institution.serviceloc_set.all(): |
|
691 |
instLocation = ET.SubElement(instElement, "location") |
|
692 |
|
|
693 |
instLong = ET.SubElement(instLocation, "longitude") |
|
694 |
instLong.text = "%s" %serviceloc.longitude |
|
695 |
|
|
696 |
instLat = ET.SubElement(instLocation, "latitude") |
|
697 |
instLat.text = "%s" %serviceloc.latitude |
|
698 |
|
|
699 |
for instlocname in serviceloc.loc_name.all(): |
|
700 |
instLocName = ET.SubElement(instLocation, "loc_name") |
|
701 |
instLocName.attrib["lang"] = instlocname.lang |
|
702 |
instLocName.text = instlocname.name |
|
703 |
|
|
704 |
instLocAddress = ET.SubElement(instLocation, "address") |
|
705 |
|
|
706 |
instLocAddrStreet = ET.SubElement(instLocAddress, "street") |
|
707 |
instLocAddrStreet.text = serviceloc.address_street |
|
708 |
|
|
709 |
instLocAddrCity = ET.SubElement(instLocAddress, "city") |
|
710 |
instLocAddrCity.text = serviceloc.address_city |
|
711 |
|
|
712 |
instLocSSID = ET.SubElement(instLocation, "SSID") |
|
713 |
instLocSSID.text = serviceloc.SSID |
|
714 |
|
|
715 |
instLocEncLevel = ET.SubElement(instLocation, "enc_level") |
|
716 |
instLocEncLevel.text = serviceloc.enc_level |
|
717 |
|
|
718 |
instLocPortRestrict = ET.SubElement(instLocation, "port_restrict") |
|
719 |
instLocPortRestrict.text = ("%s" %serviceloc.port_restrict).lower() |
|
720 |
|
|
721 |
instLocTransProxy = ET.SubElement(instLocation, "transp_proxy") |
|
722 |
instLocTransProxy.text = ("%s" %serviceloc.transp_proxy).lower() |
|
723 |
|
|
724 |
instLocIpv6 = ET.SubElement(instLocation, "IPv6") |
|
725 |
instLocIpv6.text = ("%s" %serviceloc.IPv6).lower() |
|
726 |
|
|
727 |
instLocNAT = ET.SubElement(instLocation, "NAT") |
|
728 |
instLocNAT.text = ("%s" %serviceloc.NAT).lower() |
|
729 |
|
|
730 |
instLocAP_no = ET.SubElement(instLocation, "AP_no") |
|
731 |
instLocAP_no.text = "%s" %int(serviceloc.AP_no) |
|
732 |
|
|
733 |
instLocWired = ET.SubElement(instLocation, "wired") |
|
734 |
instLocWired.text = ("%s" %serviceloc.wired).lower() |
|
735 |
|
|
736 |
for url in serviceloc.url.all(): |
|
737 |
instLocUrl = ET.SubElement(instLocation, "%s_URL"%(url.urltype)) |
|
738 |
instLocUrl.attrib["lang"] = url.lang |
|
739 |
instLocUrl.text = url.url |
|
740 |
|
|
741 |
instTs = ET.SubElement(instElement, "ts") |
|
742 |
instTs.text = "%s" %inst.ts.isoformat() |
|
743 |
|
|
744 |
return render_to_response("general/institution.xml", {"xml":to_xml(root)},context_instance=RequestContext(request,), mimetype="application/xml") |
|
745 |
|
|
746 |
|
|
747 |
def realmxml(request): |
|
748 |
realm = Realm.objects.all()[0] |
|
749 |
ET._namespace_map["http://www.w3.org/2001/XMLSchema-instance"] = 'xsi' |
|
750 |
root = ET.Element("realms") |
|
751 |
NS_XSI = "{http://www.w3.org/2001/XMLSchema-instance}" |
|
752 |
root.set(NS_XSI + "noNamespaceSchemaLocation", "realm.xsd") |
|
753 |
#root.attrib["xsi:noNamespaceSchemaLocation"] = "institution.xsd" |
|
754 |
realmElement = ET.SubElement(root, "realm") |
|
755 |
|
|
756 |
realmCountry = ET.SubElement(realmElement, "country") |
|
757 |
realmCountry.text = realm.country |
|
758 |
|
|
759 |
realmStype = ET.SubElement(realmElement, "stype") |
|
760 |
realmStype.text = "%s" %realm.stype |
|
761 |
|
|
762 |
for name in realm.org_name.all(): |
|
763 |
realmOrgName = ET.SubElement(realmElement, "org_name") |
|
764 |
realmOrgName.attrib["lang"] = name.lang |
|
765 |
realmOrgName.text = u"%s" %name.name |
|
766 |
|
|
767 |
realmAddress = ET.SubElement(realmElement, "address") |
|
768 |
|
|
769 |
realmAddrStreet = ET.SubElement(realmAddress, "street") |
|
770 |
realmAddrStreet.text = realm.address_street |
|
771 |
|
|
772 |
realmAddrCity = ET.SubElement(realmAddress, "city") |
|
773 |
realmAddrCity.text = realm.address_city |
|
774 |
|
|
775 |
for contact in realm.contact.all(): |
|
776 |
realmContact = ET.SubElement(realmElement, "contact") |
|
777 |
|
|
778 |
realmContactName = ET.SubElement(realmContact, "name") |
|
779 |
realmContactName.text = "%s %s" %(contact.firstname, contact.lastname) |
|
780 |
|
|
781 |
realmContactEmail = ET.SubElement(realmContact, "email") |
|
782 |
realmContactEmail.text = contact.email |
|
783 |
|
|
784 |
realmContactPhone = ET.SubElement(realmContact, "phone") |
|
785 |
realmContactPhone.text = contact.phone |
|
786 |
|
|
787 |
for url in realm.url.all(): |
|
788 |
realmUrl = ET.SubElement(realmElement, "%s_URL"%(url.urltype)) |
|
789 |
realmUrl.attrib["lang"] = url.lang |
|
790 |
realmUrl.text = url.url |
|
791 |
|
|
792 |
return render_to_response("general/realm.xml", {"xml":to_xml(root)},context_instance=RequestContext(request,), mimetype="application/xml") |
|
793 |
|
|
794 |
def realmdataxml(request): |
|
795 |
realm = Realm.objects.all()[0] |
|
796 |
ET._namespace_map["http://www.w3.org/2001/XMLSchema-instance"] = 'xsi' |
|
797 |
root = ET.Element("realm-data") |
|
798 |
NS_XSI = "{http://www.w3.org/2001/XMLSchema-instance}" |
|
799 |
root.set(NS_XSI + "noNamespaceSchemaLocation", "realm-data.xsd") |
|
800 |
|
|
801 |
return render_to_response("general/realm_data.xml", {"xml":to_xml(root)},context_instance=RequestContext(request,), mimetype="application/xml") |
|
802 |
|
|
803 |
def to_xml(ele, encoding="UTF-8"): |
|
804 |
"Convert and return the XML for an *ele* (:class:`~xml.etree.ElementTree.Element`) with specified *encoding*." |
|
805 |
xml = ET.tostring(ele, encoding) |
|
806 |
return xml if xml.startswith('<?xml') else '<?xml version="1.0" encoding="%s"?>%s' % (encoding, xml) |
|
807 |
|
|
808 |
|
|
536 | 809 |
def getInstContacts(inst): |
537 | 810 |
contacts = InstitutionContactPool.objects.filter(institution=inst) |
538 | 811 |
contact_pks = [] |
... | ... | |
549 | 822 |
|
550 | 823 |
|
551 | 824 |
def rad(x): |
552 |
return x*math.pi/180 |
|
825 |
return x*math.pi/180 |
b/templates/edumanage/contacts.html | ||
---|---|---|
1 |
{% extends "edumanage/welcome.html"%} |
|
2 |
{% block crumbs %} |
|
3 |
<li><a href="{% url manage %}">Home</a><span class="divider">/</span></li> |
|
4 |
<li class="active">Contacts</li> |
|
5 |
{% endblock %} |
|
6 |
{% load i18n %} |
|
7 |
{% block extrahead %} |
|
8 |
<script type="text/javascript" src="/static/js/jquery.dataTables.min.js"></script> |
|
9 |
<script type="text/javascript" src="/static/js/datatables_bootstrap.js"></script> |
|
10 |
<script type="text/javascript"> |
|
11 |
$(document).ready(function(){ |
|
12 |
{% if contacts %} |
|
13 |
var oTable = $('#table').dataTable({ |
|
14 |
"sPaginationType": "bootstrap", |
|
15 |
"sDom": "<'row-fluid'<'span6'l><'span6'f>r>t<'row-fluid'<'span6'i><'span6'p>>", |
|
16 |
"aoColumns": [{ |
|
17 |
"bSearchable": true, |
|
18 |
"bSortable": true |
|
19 |
}, { |
|
20 |
"bSearchable": true, |
|
21 |
"bSortable": true |
|
22 |
}, { |
|
23 |
"bSearchable": true, |
|
24 |
"bSortable": true |
|
25 |
}, { |
|
26 |
"bVisible": true, |
|
27 |
"bSearchable": false, |
|
28 |
"bSortable": false |
|
29 |
}], |
|
30 |
"aaSorting": [[0, 'desc']], |
|
31 |
"iDisplayLength": 25, |
|
32 |
"oSearch": {"bSmart": false, "bRegex":true}, |
|
33 |
"oLanguage": { |
|
34 |
"sLengthMenu": '{% trans "Display" %} <select><option value="25">25</option><option value="50">50</option><option value="-1">{% trans "All" %}</option></select> {% trans "contacts" %}', |
|
35 |
"sProcessing": "Processing...", |
|
36 |
"sZeroRecords": '{% trans "No records to display" %}', |
|
37 |
"sInfo": "Showing _START_ to _END_ of _TOTAL_ entries", |
|
38 |
"sInfoEmpty": "{% trans "Showing 0 to 0 of 0 entries" %}", |
|
39 |
"sInfoFiltered": "(filtered from _MAX_ total entries)", |
|
40 |
"sInfoPostFix": "", |
|
41 |
"sSearch": '{% trans "Search:" %}', |
|
42 |
"sUrl": "", |
|
43 |
"oPaginate": { |
|
44 |
"sFirst": '{% trans "First" %}', |
|
45 |
"sPrevious": '{% trans "Previous" %}', |
|
46 |
"sNext": '{% trans "Next" %}', |
|
47 |
"sLast": '{% trans "Last" %}' |
|
48 |
} |
|
49 |
} |
|
50 |
}); |
|
51 |
|
|
52 |
oTable.fnDraw(); |
|
53 |
|
|
54 |
$('[id^=del_contact_]').click(function(){ |
|
55 |
contact_id = (this.id).replace("del_contact_", ''); |
|
56 |
name = this.getAttribute("data-contactname"); |
|
57 |
$("#mymodalbody").html("You are about to delete contact: <b>"+name+"</b><br>Press Delete to proceed or Cancel to cancel deletion"); |
|
58 |
$("#myModalLabel").html("Delete contact "+name); |
|
59 |
$('#myModal').modal('show'); |
|
60 |
$(".modal-footer").show(); |
|
61 |
$("#contact_name_del").html(name) |
|
62 |
return false; |
|
63 |
}); |
|
64 |
|
|
65 |
$("#delcontactSubmit").click(function(){ |
|
66 |
$.ajax({ |
|
67 |
url:"{% url del-contact %}/?contact_pk="+contact_id, |
|
68 |
type: "GET", |
|
69 |
success: function(data){ |
|
70 |
if (data.error){ |
|
71 |
$(".modal-footer").hide(); |
|
72 |
$("#mymodalbody").html("<font style='color:#B94A48'>"+data.error+"</font>"); |
|
73 |
} |
|
74 |
if (data.success){ |
|
75 |
$(".modal-footer").hide(); |
|
76 |
$("#mymodalbody").html("contact "+name+" successfully deleted"); |
|
77 |
window.setTimeout('location.reload()', 1000); |
|
78 |
|
|
79 |
} |
|
80 |
} |
|
81 |
}); |
|
82 |
}); |
|
83 |
|
|
84 |
{% endif %} |
|
85 |
}); |
|
86 |
</script> |
|
87 |
{% endblock %} |
|
88 |
|
|
89 |
{% block navbar %} |
|
90 |
|
|
91 |
{% endblock %} |
|
92 |
|
|
93 |
{% block homeactive %}{% endblock %} |
|
94 |
{% block contactsactive %}class="active"{% endblock %} |
|
95 |
{% block subcontent %} |
|
96 |
|
|
97 |
|
|
98 |
<h4>contacts</h4> |
|
99 |
<hr> |
|
100 |
<div><a href="{% url edit-contacts %}" class="btn btn-primary">Add new contact</a></div> |
|
101 |
<div class="span10"></div> |
|
102 |
{% if contacts %} |
|
103 |
<table cellpadding="0" cellspacing="0" border="0" class="table table-striped table-bordered" width="100%" id="table"> |
|
104 |
<thead> |
|
105 |
<tr> |
|
106 |
<th>Name</th> |
|
107 |
<th>Email</th> |
|
108 |
<th>Phone</th> |
|
109 |
<th style="text-align: center;">Action</th> |
|
110 |
</tr> |
|
111 |
</thead> |
|
112 |
|
|
113 |
<tbody> |
|
114 |
{% for contact in contacts %} |
|
115 |
<tr class="GradeC"> |
|
116 |
<td>{{contact.firstname}} {{contact.lastname}}</td> |
|
117 |
<td>{{contact.email}}</td> |
|
118 |
<td>{{contact.phone}}</td> |
|
119 |
<td style="text-align: center;"><a href="{% url edit-contacts contact.pk %}" class="btn btn-small">edit</a> <a href="#" id="del_contact_{{contact.pk}}" data-contactname="{{contact.firstname}} {{contact.lastname}}" class="btn btn-small btn-warning">delete</a></td> |
|
120 |
</tr> |
|
121 |
{% endfor %} |
|
122 |
</tbody> |
|
123 |
</table> |
|
124 |
{% else %} |
|
125 |
<div>No contacts defined yet (<a href="{% url edit-contacts %}">add</a>)</div> |
|
126 |
{% endif %} |
|
127 |
<div class="modal hide fade" id="myModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true"> |
|
128 |
<div class="modal-header"> |
|
129 |
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button> |
|
130 |
<h3 id="myModalLabel">Delete contact</h3> |
|
131 |
</div> |
|
132 |
<div class="modal-body" id="mymodalbody"> |
|
133 |
|
|
134 |
</div> |
|
135 |
<div class="modal-footer"> |
|
136 |
<button class="btn" data-dismiss="modal" aria-hidden="true">Cancel</button> |
|
137 |
<a class="btn btn-warning" id="delcontactSubmit" href="#">Delete</a> |
|
138 |
</div> |
|
139 |
</div> |
|
140 |
{% endblock %} |
|
141 |
|
b/templates/edumanage/contacts_edit.html | ||
---|---|---|
1 |
{% extends "edumanage/welcome.html"%} |
|
2 |
{% block crumbs %} |
|
3 |
<li><a href="{% url manage %}">Home</a><span class="divider">/</span></li> |
|
4 |
<li><a href="{% url realms %}">Realms</a><span class="divider">/</span></li> |
|
5 |
<li class="active">Add-Edit</li> |
|
6 |
{% endblock %} |
|
7 |
{% block extrahead %} |
|
8 |
<script type="text/javascript" src="/static/js/jquery.min.js"></script> |
|
9 |
<script type="text/javascript" |
|
10 |
src="http://maps.googleapis.com/maps/api/js?sensor=false"></script> |
|
11 |
|
|
12 |
|
|
13 |
|
|
14 |
|
|
15 |
{% endblock %} |
|
16 |
|
|
17 |
{% block homeactive %}{% endblock %} |
|
18 |
{% block contactsactive %}class="active"{% endblock %} |
|
19 |
{% block subcontent %} <h4>Contacts Add/Edit</h4> |
|
20 |
<hr> |
|
21 |
<form method="POST" class="form-horizontal"> |
|
22 |
{% csrf_token %} |
|
23 |
{% if form.non_field_errors %} |
|
24 |
<p class="error"> |
|
25 |
{{ form.non_field_errors}} |
|
26 |
</p> |
|
27 |
{% endif %} |
|
28 |
<div style="display: none"> |
|
29 |
{{form.instid}} |
|
30 |
</div> |
|
31 |
<div class="control-group {% if form.firstname.errors %} error {% endif %}"> |
|
32 |
<label class="control-label" for="id_firstname"><b>First name</b></label> |
|
33 |
<div class="controls"> |
|
34 |
{{ form.firstname }} |
|
35 |
{% if form.firstname.errors %} <span class="help-inline"> {{ form.firstname.errors|join:", " }} </span> |
|
36 |
{% endif %} <span class="help-block"> {{ form.firstname.help_text }}</span> |
|
37 |
</div> |
|
38 |
</div> |
|
39 |
<div class="control-group {% if form.lastname.errors %} error {% endif %}"> |
|
40 |
<label class="control-label" for="id_lastname"><b>Last name</b></label> |
|
41 |
<div class="controls"> |
|
42 |
{{ form.lastname }} |
|
43 |
{% if form.lastname.errors %} <span class="help-inline"> {{ form.lastname.errors|join:", " }} </span> |
|
44 |
{% endif %} <span class="help-block"> {{ form.lastname.help_text }}</span> |
|
45 |
</div> |
|
46 |
</div> |
|
47 |
<div class="control-group {% if form.email.errors %} error {% endif %}"> |
|
48 |
<label class="control-label" for="id_email"><b>Email</b></label> |
|
49 |
<div class="controls"> |
|
50 |
{{ form.email }} |
|
51 |
{% if form.email.errors %} <span class="help-inline"> {{ form.email.errors|join:", " }} </span> |
|
52 |
{% endif %} <span class="help-block"> {{ form.email.help_text }}</span> |
|
53 |
</div> |
|
54 |
</div> |
|
55 |
<div class="control-group {% if form.phone.errors %} error {% endif %}"> |
|
56 |
<label class="control-label" for="id_phone"><b>Phone</b></label> |
|
57 |
<div class="controls"> |
|
58 |
{{ form.phone }} |
|
59 |
{% if form.phone.errors %} <span class="help-inline"> {{ form.phone.errors|join:", " }} </span> |
|
60 |
{% endif %} <span class="help-block"> {{ form.phone.help_text }}</span> |
|
61 |
</div> |
|
62 |
</div> |
|
63 |
<div class="control-group"> |
|
64 |
<div class="controls"> |
|
65 |
<button type="submit" id="applybutton" value="Apply" class="btn btn-large btn-primary"/> |
|
66 |
Apply</button> |
|
67 |
</div> |
|
68 |
</div> |
|
69 |
</form> |
|
70 |
{% endblock %} |
|
71 |
|
b/templates/edumanage/welcome.html | ||
---|---|---|
195 | 195 |
<li {% block realmsactive %}{% endblock %}> |
196 | 196 |
<a href="{% url realms %}">Realms ({{realms_num}})</a> |
197 | 197 |
</li> |
198 |
<li {% block contactsactive %}{% endblock %}> |
|
199 |
<a href="{% url contacts %}">Contacts ({{contacts_num}})</a> |
|
200 |
</li> |
|
198 | 201 |
</ul> |
199 | 202 |
</div><!--/.well --> |
200 | 203 |
</div><!--/span--> |
b/templates/general/institution.xml | ||
---|---|---|
1 |
{% autoescape off %}{{xml}}{% endautoescape %} |
b/templates/general/institution.xsd | ||
---|---|---|
1 |
<?xml version="1.0" encoding="UTF-8"?> |
|
2 |
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"> |
|
3 |
<xs:simpleType name="eduroam_institution_type"> |
|
4 |
<xs:restriction base="xs:int"> |
|
5 |
<xs:enumeration value="1"> |
|
6 |
<xs:annotation> |
|
7 |
<xs:documentation>IdP</xs:documentation> |
|
8 |
</xs:annotation> |
|
9 |
</xs:enumeration> |
|
10 |
<xs:enumeration value="2"> |
|
11 |
<xs:annotation> |
|
12 |
<xs:documentation>SP</xs:documentation> |
|
13 |
</xs:annotation> |
|
14 |
</xs:enumeration> |
|
15 |
<xs:enumeration value="3"> |
|
16 |
<xs:annotation> |
|
17 |
<xs:documentation>SPIdP</xs:documentation> |
|
18 |
</xs:annotation> |
|
19 |
</xs:enumeration> |
|
20 |
</xs:restriction> |
|
21 |
|
|
22 |
</xs:simpleType> |
|
23 |
|
|
24 |
<xs:element name="institutions"> |
|
25 |
<xs:complexType> |
|
26 |
<xs:sequence maxOccurs="unbounded"> |
|
27 |
<xs:element name="institution"> |
|
28 |
<xs:complexType> |
|
29 |
<xs:sequence> |
|
30 |
<xs:element name="country" type="xs:string"/> |
|
31 |
<xs:element name="type" type="eduroam_institution_type"/> |
|
32 |
<xs:element name="inst_realm" type="xs:string" maxOccurs="unbounded" minOccurs="0"/> |
|
33 |
<xs:element name="org_name" minOccurs="1" maxOccurs="unbounded"> |
|
34 |
<xs:complexType> |
|
35 |
<xs:simpleContent> |
|
36 |
<xs:extension base="xs:string"> |
|
37 |
<xs:attribute name="lang" type="xs:string" use="required"/> |
|
38 |
</xs:extension> |
|
39 |
</xs:simpleContent> |
|
40 |
</xs:complexType> |
|
41 |
</xs:element> |
|
42 |
<xs:element name="address"> |
|
43 |
<xs:complexType> |
|
44 |
<xs:sequence> |
|
45 |
<xs:element name="street" type="xs:string"/> |
|
46 |
<xs:element name="city" type="xs:string"/> |
|
47 |
</xs:sequence> |
|
48 |
</xs:complexType> |
|
49 |
</xs:element> |
|
50 |
<xs:element name="contact" maxOccurs="unbounded"> |
|
51 |
<xs:complexType> |
|
52 |
<xs:sequence> |
|
53 |
<xs:element name="name" type="xs:string"/> |
|
54 |
<xs:element name="email" type="xs:string"/> |
|
55 |
<xs:element name="phone" type="xs:string"/> |
|
56 |
</xs:sequence> |
|
57 |
</xs:complexType> |
|
58 |
</xs:element> |
|
59 |
<xs:element name="info_URL" minOccurs="1" maxOccurs="unbounded"> |
|
60 |
<xs:complexType> |
|
61 |
<xs:simpleContent> |
|
62 |
<xs:extension base="xs:anyURI"> |
|
63 |
<xs:attribute name="lang" type="xs:string" use="required"/> |
|
64 |
</xs:extension> |
|
65 |
</xs:simpleContent> |
|
66 |
</xs:complexType> |
|
67 |
</xs:element> |
|
68 |
<xs:element name="policy_URL" maxOccurs="unbounded"> |
|
69 |
<xs:complexType> |
|
70 |
<xs:simpleContent> |
|
71 |
<xs:extension base="xs:anyURI"> |
|
72 |
<xs:attribute name="lang" type="xs:string" use="required"/> |
|
73 |
</xs:extension> |
|
74 |
</xs:simpleContent> |
|
75 |
</xs:complexType> |
|
76 |
</xs:element> |
|
77 |
<xs:element name="ts" type="xs:dateTime"> |
|
78 |
<xs:annotation> |
|
79 |
<xs:documentation> Format: 2008-02-29T12:00:00 </xs:documentation> |
|
80 |
</xs:annotation> |
|
81 |
</xs:element> |
|
82 |
|
|
83 |
<xs:element name="location" maxOccurs="unbounded" minOccurs="0"> |
|
84 |
<xs:complexType> |
|
85 |
<xs:sequence> |
|
86 |
<xs:element name="longitude" type="xs:string"/> |
|
87 |
<xs:element name="latitude" type="xs:string"/> |
|
88 |
<xs:element name="loc_name" minOccurs="0" maxOccurs="unbounded"> |
|
89 |
<xs:complexType> |
|
90 |
<xs:simpleContent> |
|
91 |
<xs:extension base="xs:string"> |
|
92 |
<xs:attribute name="lang" type="xs:string" use="required"/> |
|
93 |
</xs:extension> |
|
94 |
</xs:simpleContent> |
|
95 |
</xs:complexType> |
|
96 |
</xs:element> |
|
97 |
<xs:element name="address"> |
|
98 |
<xs:complexType> |
|
99 |
<xs:sequence> |
|
100 |
<xs:element name="street" type="xs:string"/> |
|
101 |
<xs:element name="city" type="xs:string"/> |
|
102 |
</xs:sequence> |
|
103 |
</xs:complexType> |
|
104 |
</xs:element> |
|
105 |
<xs:element name="contact" maxOccurs="unbounded" minOccurs="0"> |
|
106 |
<xs:complexType> |
|
107 |
<xs:sequence> |
|
108 |
<xs:element name="name" type="xs:string"/> |
|
109 |
<xs:element name="email" type="xs:string"/> |
|
110 |
<xs:element name="phone" type="xs:string"/> |
|
111 |
</xs:sequence> |
|
112 |
</xs:complexType> |
|
113 |
</xs:element> |
|
114 |
<xs:element name="SSID" type="xs:string"/> |
|
115 |
<xs:element name="enc_level" type="xs:string"/> |
|
116 |
<xs:element name="port_restrict" type="xs:boolean" default="0"/> |
|
117 |
<xs:element name="transp_proxy" type="xs:boolean" default="0" minOccurs="0"/> |
|
118 |
<xs:element name="IPv6" type="xs:boolean" default="0" minOccurs="0"/> |
|
119 |
<xs:element name="NAT" type="xs:boolean" default="0" minOccurs="0"/> |
|
120 |
<xs:element name="AP_no" type="xs:int" minOccurs="0"/> |
|
121 |
<xs:element name="wired" type="xs:boolean" default="0" minOccurs="0"/> |
|
122 |
<xs:element name="info_URL" minOccurs="0" maxOccurs="unbounded"> |
|
123 |
<xs:complexType> |
|
124 |
<xs:simpleContent> |
|
125 |
<xs:extension base="xs:anyURI"> |
|
126 |
<xs:attribute name="lang" type="xs:string" use="required"/> |
|
127 |
</xs:extension> |
|
128 |
</xs:simpleContent> |
|
129 |
</xs:complexType> |
|
130 |
</xs:element> |
|
131 |
</xs:sequence> |
|
132 |
</xs:complexType> |
|
133 |
</xs:element> |
|
134 |
</xs:sequence> |
|
135 |
</xs:complexType> |
|
136 |
</xs:element> |
|
137 |
</xs:sequence> |
|
138 |
</xs:complexType> |
|
139 |
</xs:element> |
|
140 |
</xs:schema> |
b/templates/general/realm.xml | ||
---|---|---|
1 |
{% autoescape off %}{{xml}}{% endautoescape %} |
b/templates/general/realm.xsd | ||
---|---|---|
1 |
<?xml version="1.0" encoding="UTF-8"?> |
|
2 |
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"> |
|
3 |
<xs:simpleType name="eduroam_realm_stype"> |
|
4 |
<xs:restriction base="xs:int"> |
|
5 |
<xs:enumeration value="0"> |
|
6 |
<xs:annotation> |
|
7 |
<xs:documentation>FLRS</xs:documentation> |
|
8 |
</xs:annotation> |
|
9 |
</xs:enumeration> |
|
10 |
<xs:enumeration value="1"> |
|
11 |
<xs:annotation> |
|
12 |
<xs:documentation>(E)TLRS</xs:documentation> |
|
13 |
</xs:annotation> |
|
14 |
</xs:enumeration> |
|
15 |
</xs:restriction> |
|
16 |
|
|
17 |
</xs:simpleType> |
|
18 |
|
|
19 |
<xs:element name="realms"> |
|
20 |
<xs:complexType> |
|
21 |
<xs:sequence> |
|
22 |
<xs:element name="realm"> |
|
23 |
<xs:complexType> |
|
24 |
<xs:sequence> |
|
25 |
<xs:element name="country" type="xs:string"/> |
|
26 |
<xs:element name="stype" type="eduroam_realm_stype"/> |
|
27 |
<xs:element name="org_name" maxOccurs="unbounded"> |
|
28 |
<xs:complexType> |
|
29 |
<xs:simpleContent> |
|
30 |
<xs:extension base="xs:string"> |
|
31 |
<xs:attribute name="lang" type="xs:string" use="required"/> |
|
32 |
</xs:extension> |
|
33 |
</xs:simpleContent> |
|
34 |
</xs:complexType> |
|
35 |
</xs:element> |
|
36 |
<xs:element name="address"> |
|
37 |
<xs:complexType> |
|
38 |
<xs:sequence> |
|
39 |
<xs:element name="street" type="xs:string"/> |
|
40 |
<xs:element name="city" type="xs:string"/> |
|
41 |
</xs:sequence> |
|
42 |
</xs:complexType> |
|
43 |
</xs:element> |
|
44 |
<xs:element name="contact" maxOccurs="unbounded"> |
|
45 |
<xs:complexType> |
|
46 |
<xs:sequence> |
|
47 |
<xs:element name="name" type="xs:string"/> |
|
48 |
<xs:element name="email" type="xs:string"/> |
|
49 |
<xs:element name="phone" type="xs:string"/> |
|
50 |
</xs:sequence> |
|
51 |
</xs:complexType> |
|
52 |
</xs:element> |
|
53 |
<xs:element name="info_URL" maxOccurs="unbounded"> |
|
54 |
<xs:complexType> |
|
55 |
<xs:simpleContent> |
|
56 |
<xs:extension base="xs:anyURI"> |
|
57 |
<xs:attribute name="lang" type="xs:string" use="required"/> |
|
58 |
</xs:extension> |
|
59 |
</xs:simpleContent> |
|
60 |
</xs:complexType> |
|
61 |
</xs:element> |
|
62 |
<xs:element name="policy_URL" maxOccurs="unbounded"> |
|
63 |
<xs:complexType> |
|
64 |
<xs:simpleContent> |
|
65 |
<xs:extension base="xs:anyURI"> |
|
66 |
<xs:attribute name="lang" type="xs:string" use="required"/> |
|
67 |
</xs:extension> |
|
68 |
</xs:simpleContent> |
|
69 |
</xs:complexType> |
|
70 |
</xs:element> |
|
71 |
<xs:element name="ts" type="xs:dateTime"> |
|
72 |
<xs:annotation> |
|
73 |
<xs:documentation> Format: 2008-02-29T12:00:00 </xs:documentation> |
|
74 |
</xs:annotation> |
|
75 |
</xs:element> |
|
76 |
</xs:sequence> |
|
77 |
</xs:complexType> |
|
78 |
</xs:element> |
|
79 |
</xs:sequence> |
|
80 |
</xs:complexType> |
|
81 |
</xs:element> |
|
82 |
</xs:schema> |
Also available in: Unified diff