diff options
Diffstat (limited to 'gnowsys-ndf')
28 files changed, 2096 insertions, 346 deletions
diff --git a/gnowsys-ndf/gnowsys_ndf/ndf/management/commands/sync_existing_documents.py b/gnowsys-ndf/gnowsys_ndf/ndf/management/commands/sync_existing_documents.py index 5c28b7c4..44757d73 100644 --- a/gnowsys-ndf/gnowsys_ndf/ndf/management/commands/sync_existing_documents.py +++ b/gnowsys-ndf/gnowsys_ndf/ndf/management/commands/sync_existing_documents.py @@ -61,7 +61,7 @@ class Command(BaseCommand): # -------------------------------------------------------------------------- # Adding <'moderation_level': -1> field to Group objects - node_collection.collection.update({'_type': {'$in': ['Group']}}, {'$set': {'moderation_level': -1 }}, upsert=False, multi=True) + node_collection.collection.update({'_type': {'$in': ['Group']}, 'edit_policy': {'$nin': ['EDITABLE_MODERATED']}}, {'$set': {'moderation_level': -1 }}, upsert=False, multi=True) if res['updatedExisting']: # and res['nModified']: print "\n Added 'moderation_level' field to " + res['n'].__str__() + " Group instances." diff --git a/gnowsys-ndf/gnowsys_ndf/ndf/models.py b/gnowsys-ndf/gnowsys_ndf/ndf/models.py index 2572d136..c48fb986 100644 --- a/gnowsys-ndf/gnowsys_ndf/ndf/models.py +++ b/gnowsys-ndf/gnowsys_ndf/ndf/models.py @@ -108,7 +108,7 @@ to_reduce_doc_requirement = u'storing_to_be_reduced_doc' indexed_word_list_requirement = u'storing_indexed_words' # CUSTOM DATA-TYPE DEFINITIONS -STATUS_CHOICES_TU = IS(u'DRAFT', u'HIDDEN', u'PUBLISHED', u'DELETED') +STATUS_CHOICES_TU = IS(u'DRAFT', u'HIDDEN', u'PUBLISHED', u'DELETED', u'MODERATION') STATUS_CHOICES = tuple(str(qtc) for qtc in STATUS_CHOICES_TU) QUIZ_TYPE_CHOICES_TU = IS(u'Short-Response', u'Single-Choice', u'Multiple-Choice') diff --git a/gnowsys-ndf/gnowsys_ndf/ndf/static/ndf/css/themes/metastudio/styles.css b/gnowsys-ndf/gnowsys_ndf/ndf/static/ndf/css/themes/metastudio/styles.css index b66c1c29..76378e90 100644 --- a/gnowsys-ndf/gnowsys_ndf/ndf/static/ndf/css/themes/metastudio/styles.css +++ b/gnowsys-ndf/gnowsys_ndf/ndf/static/ndf/css/themes/metastudio/styles.css @@ -9624,26 +9624,35 @@ article h1:not(.subheader) div input:hover { .card > *.published hr { border-color: #7ee2a8; } -/* line 564, ../../../scss/_app_styles.scss */ +/* line 565, ../../../scss/_app_styles.scss */ +.card > *.moderation { + opacity: 1; + background-color: #efefef; +} +/* line 570, ../../../scss/_app_styles.scss */ +.card > *.moderation hr { + border-color: #bcbcbc; +} +/* line 575, ../../../scss/_app_styles.scss */ .card > *.unapproved { opacity: 1; border-style: solid; border-color: #f04124; } -/* line 570, ../../../scss/_app_styles.scss */ +/* line 581, ../../../scss/_app_styles.scss */ .card > *:hover { border-style: solid; opacity: 1; } -/* line 576, ../../../scss/_app_styles.scss */ +/* line 587, ../../../scss/_app_styles.scss */ .card > *:hover i { opacity: 0.3; } -/* line 579, ../../../scss/_app_styles.scss */ +/* line 590, ../../../scss/_app_styles.scss */ .card > *:hover footer .age { display: block; } -/* line 584, ../../../scss/_app_styles.scss */ +/* line 595, ../../../scss/_app_styles.scss */ .card > * > i { position: absolute; top: -10px; @@ -9652,34 +9661,34 @@ article h1:not(.subheader) div input:hover { color: #0eacb5; opacity: 0.3; } -/* line 593, ../../../scss/_app_styles.scss */ +/* line 604, ../../../scss/_app_styles.scss */ .card > * .preview { float: left; padding-right: 5px; padding-top: 4px; } -/* line 598, ../../../scss/_app_styles.scss */ +/* line 609, ../../../scss/_app_styles.scss */ .card > * header { overflow: hidden; } -/* line 601, ../../../scss/_app_styles.scss */ +/* line 612, ../../../scss/_app_styles.scss */ .card > * h5 { white-space: nowrap; text-overflow: ellipsis; margin-bottom: 0; } -/* line 606, ../../../scss/_app_styles.scss */ +/* line 617, ../../../scss/_app_styles.scss */ .card > * .label, .card > * .label-list:empty:before { opacity: 0.5; } -/* line 609, ../../../scss/_app_styles.scss */ +/* line 620, ../../../scss/_app_styles.scss */ .card > * p { color: #555; height: 80px; background-repeat: no-repeat; font-size: 80%; } -/* line 615, ../../../scss/_app_styles.scss */ +/* line 626, ../../../scss/_app_styles.scss */ .card > * .th { margin: 20px auto; width: 80px; @@ -9687,23 +9696,23 @@ article h1:not(.subheader) div input:hover { overflow: hidden; display: none; } -/* line 621, ../../../scss/_app_styles.scss */ +/* line 632, ../../../scss/_app_styles.scss */ .card > * .th:hover { width: 150px; height: 150px; } -/* line 625, ../../../scss/_app_styles.scss */ +/* line 636, ../../../scss/_app_styles.scss */ .card > * .th img { width: 100%; } -/* line 629, ../../../scss/_app_styles.scss */ +/* line 640, ../../../scss/_app_styles.scss */ .card > * footer { margin-top: 1rem; font-size: 70%; clear: both; color: #e01818; } -/* line 634, ../../../scss/_app_styles.scss */ +/* line 645, ../../../scss/_app_styles.scss */ .card > * footer .age { display: none; position: absolute; @@ -9713,7 +9722,7 @@ article h1:not(.subheader) div input:hover { width: 100%; } -/* line 645, ../../../scss/_app_styles.scss */ +/* line 656, ../../../scss/_app_styles.scss */ .edit-card { position: relative; background-color: white; @@ -9722,36 +9731,36 @@ article h1:not(.subheader) div input:hover { } /* Content Tabs */ -/* line 658, ../../../scss/_app_styles.scss */ +/* line 669, ../../../scss/_app_styles.scss */ article .tabs { display: inline-block; } -/* line 660, ../../../scss/_app_styles.scss */ +/* line 671, ../../../scss/_app_styles.scss */ article .tabs dd a { border-radius: 4px; border: 1px transparent; } -/* line 664, ../../../scss/_app_styles.scss */ +/* line 675, ../../../scss/_app_styles.scss */ article .tabs dd.active a { color: #10c1cb; border: 1px solid; } -/* line 668, ../../../scss/_app_styles.scss */ +/* line 679, ../../../scss/_app_styles.scss */ article .tabs dd:hover a { color: #10c1cb; } -/* line 672, ../../../scss/_app_styles.scss */ +/* line 683, ../../../scss/_app_styles.scss */ article .tabs i { margin-right: 5px; font-size: 1.3rem; } -/* line 678, ../../../scss/_app_styles.scss */ +/* line 689, ../../../scss/_app_styles.scss */ article section.content { background-color: white; border: 1px solid #eee; } -/* line 685, ../../../scss/_app_styles.scss */ +/* line 696, ../../../scss/_app_styles.scss */ .card > div:hover { box-shadow: 0 0 10px lightgray; transition: 0.9s; @@ -9760,31 +9769,31 @@ article section.content { } /* Default card */ -/* line 693, ../../../scss/_app_styles.scss */ +/* line 704, ../../../scss/_app_styles.scss */ .card > :hover .label, .card > :hover .label-list:empty:before { opacity: 1; } -/* line 698, ../../../scss/_app_styles.scss */ +/* line 709, ../../../scss/_app_styles.scss */ .gallery .card .th { display: block; } /* Inline label list */ -/* line 706, ../../../scss/_app_styles.scss */ +/* line 717, ../../../scss/_app_styles.scss */ .label-list { display: inline-block; text-align: left; margin-bottom: 0.1rem; } -/* line 710, ../../../scss/_app_styles.scss */ +/* line 721, ../../../scss/_app_styles.scss */ .label-list:empty:before { content: "UNTAGGED"; opacity: 0.2 !important; padding: 2px; background-color: transparent; } -/* line 718, ../../../scss/_app_styles.scss */ +/* line 729, ../../../scss/_app_styles.scss */ .label-list .label, .label-list .label-list:empty:before { background-color: transparent; padding: 2px; @@ -9792,20 +9801,20 @@ article section.content { /*************************** 2. Custom CSS overrides ***********************/ /* Content area */ -/* line 727, ../../../scss/_app_styles.scss */ +/* line 738, ../../../scss/_app_styles.scss */ article { padding-bottom: 4rem; } -/* line 731, ../../../scss/_app_styles.scss */ +/* line 742, ../../../scss/_app_styles.scss */ article > header { border-bottom: 1px solid #ddd; } -/* line 735, ../../../scss/_app_styles.scss */ +/* line 746, ../../../scss/_app_styles.scss */ article > footer { border-top: 1px dotted #ddd; } -/* line 747, ../../../scss/_app_styles.scss */ +/* line 758, ../../../scss/_app_styles.scss */ textarea { min-height: 6rem; } @@ -9826,44 +9835,44 @@ textarea { }*/ /*************************** 3. Custom CSS Below ***********************/ /*CSS fix for tables generated via orgitdown*/ -/* line 767, ../../../scss/_app_styles.scss */ +/* line 778, ../../../scss/_app_styles.scss */ #content table td, #content colgroup col { float: none !important; } -/* line 772, ../../../scss/_app_styles.scss */ +/* line 783, ../../../scss/_app_styles.scss */ .user { color: inherit; } -/* line 775, ../../../scss/_app_styles.scss */ +/* line 786, ../../../scss/_app_styles.scss */ .user { color: inherit; } -/* line 778, ../../../scss/_app_styles.scss */ +/* line 789, ../../../scss/_app_styles.scss */ .user i { margin-right: 3px; } -/* line 781, ../../../scss/_app_styles.scss */ +/* line 792, ../../../scss/_app_styles.scss */ .user:hover i { opacity: 1; } -/* line 785, ../../../scss/_app_styles.scss */ +/* line 796, ../../../scss/_app_styles.scss */ a.node { display: block; } -/* line 789, ../../../scss/_app_styles.scss */ +/* line 800, ../../../scss/_app_styles.scss */ .button.edit { margin-bottom: 0; } /************ Forms **************/ /* Node edit */ -/* line 797, ../../../scss/_app_styles.scss */ +/* line 808, ../../../scss/_app_styles.scss */ input.node-title { font-size: 3rem; height: 4rem; @@ -9871,13 +9880,13 @@ input.node-title { } /* view-graph in node_details_base.html */ -/* line 804, ../../../scss/_app_styles.scss */ +/* line 815, ../../../scss/_app_styles.scss */ .graph-height { height: 70%; } /*for graph and location*/ -/* line 809, ../../../scss/_app_styles.scss */ +/* line 820, ../../../scss/_app_styles.scss */ .graph-div { height: 90%; width: -webkit-calc(100% - 10px); @@ -9891,13 +9900,13 @@ input.node-title { } /*for graph and location*/ -/* line 819, ../../../scss/_app_styles.scss */ +/* line 830, ../../../scss/_app_styles.scss */ .graph-div h3 { border-bottom: 2px inset #154534; padding: 0.25em 0; } -/* line 824, ../../../scss/_app_styles.scss */ +/* line 835, ../../../scss/_app_styles.scss */ #view-map-widget .close-reveal-modal, #view-map-edit-widget .close-reveal-modal { z-index: 1; background-color: captiontext; @@ -9908,7 +9917,7 @@ input.node-title { box-shadow: 0 1px 10px 2px #A9A9A9; } -/* line 835, ../../../scss/_app_styles.scss */ +/* line 846, ../../../scss/_app_styles.scss */ #view-map-widget .close-reveal-modal:hover, #view-map-edit-widget .close-reveal-modal:hover { background-color: white; border-radius: 30px; @@ -9921,7 +9930,7 @@ input.node-title { /****************** CUSTOM *********************/ /* UI Button */ -/* line 850, ../../../scss/_app_styles.scss */ +/* line 861, ../../../scss/_app_styles.scss */ .ui.button { margin-right: 0.5rem; border: 1px solid rgba(0, 0, 0, 0.2); @@ -9931,56 +9940,56 @@ input.node-title { padding: 0.5vw 0.75vw; z-index: 500; } -/* line 861, ../../../scss/_app_styles.scss */ +/* line 872, ../../../scss/_app_styles.scss */ .ui.button label { color: #666; } -/* line 864, ../../../scss/_app_styles.scss */ +/* line 875, ../../../scss/_app_styles.scss */ .ui.button small { margin-left: 2px; display: inline; } -/* line 868, ../../../scss/_app_styles.scss */ +/* line 879, ../../../scss/_app_styles.scss */ .ui.button:hover, .ui.button:active { border-color: rgba(255, 255, 255, 0.2); background-color: rgba(0, 0, 0, 0.9); } -/* line 871, ../../../scss/_app_styles.scss */ +/* line 882, ../../../scss/_app_styles.scss */ .ui.button:hover label, .ui.button:active label { color: #ddd; } -/* line 874, ../../../scss/_app_styles.scss */ +/* line 885, ../../../scss/_app_styles.scss */ .ui.button:hover small, .ui.button:active small { display: inline; } -/* line 877, ../../../scss/_app_styles.scss */ +/* line 888, ../../../scss/_app_styles.scss */ .ui.button:hover:focus, .ui.button:active:focus { font-weight: bold; } -/* line 886, ../../../scss/_app_styles.scss */ +/* line 897, ../../../scss/_app_styles.scss */ aside#help h4 { color: black; } -/* line 889, ../../../scss/_app_styles.scss */ +/* line 900, ../../../scss/_app_styles.scss */ aside#help p, aside#help h5, aside#help h6 { color: #ddd; padding: 0.3rem 0.9375rem; } -/* line 896, ../../../scss/_app_styles.scss */ +/* line 907, ../../../scss/_app_styles.scss */ .align-center { margin: 0 auto; display: block; } -/* line 902, ../../../scss/_app_styles.scss */ +/* line 913, ../../../scss/_app_styles.scss */ #profile-img { height: 40px; margin-right: 5px; } -/* line 911, ../../../scss/_app_styles.scss */ +/* line 922, ../../../scss/_app_styles.scss */ #replies-area .disc-replies { padding: 10px; background-color: #dffbfd; @@ -9989,11 +9998,11 @@ aside#help p, aside#help h5, aside#help h6 { margin-left: 48px; margin-top: 10px; } -/* line 920, ../../../scss/_app_styles.scss */ +/* line 931, ../../../scss/_app_styles.scss */ #replies-area .disc-replies .reply-btn { cursor: pointer; } -/* line 924, ../../../scss/_app_styles.scss */ +/* line 935, ../../../scss/_app_styles.scss */ #replies-area .disc-replies .reply-btn:hover { font-weight: bold; } diff --git a/gnowsys-ndf/gnowsys_ndf/ndf/static/ndf/css/themes/nroer/styles.css b/gnowsys-ndf/gnowsys_ndf/ndf/static/ndf/css/themes/nroer/styles.css index 51532158..1e806abe 100644 --- a/gnowsys-ndf/gnowsys_ndf/ndf/static/ndf/css/themes/nroer/styles.css +++ b/gnowsys-ndf/gnowsys_ndf/ndf/static/ndf/css/themes/nroer/styles.css @@ -9776,26 +9776,35 @@ article h1:not(.subheader) div input:hover { .card > *.published hr { border-color: #7ee2a8; } -/* line 564, ../../../scss/_app_styles.scss */ +/* line 565, ../../../scss/_app_styles.scss */ +.card > *.moderation { + opacity: 1; + background-color: #efefef; +} +/* line 570, ../../../scss/_app_styles.scss */ +.card > *.moderation hr { + border-color: #bcbcbc; +} +/* line 575, ../../../scss/_app_styles.scss */ .card > *.unapproved { opacity: 1; border-style: solid; border-color: #f04124; } -/* line 570, ../../../scss/_app_styles.scss */ +/* line 581, ../../../scss/_app_styles.scss */ .card > *:hover { border-style: solid; opacity: 1; } -/* line 576, ../../../scss/_app_styles.scss */ +/* line 587, ../../../scss/_app_styles.scss */ .card > *:hover i { opacity: 0.3; } -/* line 579, ../../../scss/_app_styles.scss */ +/* line 590, ../../../scss/_app_styles.scss */ .card > *:hover footer .age { display: block; } -/* line 584, ../../../scss/_app_styles.scss */ +/* line 595, ../../../scss/_app_styles.scss */ .card > * > i { position: absolute; top: -10px; @@ -9804,34 +9813,34 @@ article h1:not(.subheader) div input:hover { color: #0eacb5; opacity: 0.3; } -/* line 593, ../../../scss/_app_styles.scss */ +/* line 604, ../../../scss/_app_styles.scss */ .card > * .preview { float: left; padding-right: 5px; padding-top: 4px; } -/* line 598, ../../../scss/_app_styles.scss */ +/* line 609, ../../../scss/_app_styles.scss */ .card > * header { overflow: hidden; } -/* line 601, ../../../scss/_app_styles.scss */ +/* line 612, ../../../scss/_app_styles.scss */ .card > * h5 { white-space: nowrap; text-overflow: ellipsis; margin-bottom: 0; } -/* line 606, ../../../scss/_app_styles.scss */ +/* line 617, ../../../scss/_app_styles.scss */ .card > * .label, .card > * .label-list:empty:before { opacity: 0.5; } -/* line 609, ../../../scss/_app_styles.scss */ +/* line 620, ../../../scss/_app_styles.scss */ .card > * p { color: #555; height: 80px; background-repeat: no-repeat; font-size: 80%; } -/* line 615, ../../../scss/_app_styles.scss */ +/* line 626, ../../../scss/_app_styles.scss */ .card > * .th { margin: 20px auto; width: 80px; @@ -9839,23 +9848,23 @@ article h1:not(.subheader) div input:hover { overflow: hidden; display: none; } -/* line 621, ../../../scss/_app_styles.scss */ +/* line 632, ../../../scss/_app_styles.scss */ .card > * .th:hover { width: 150px; height: 150px; } -/* line 625, ../../../scss/_app_styles.scss */ +/* line 636, ../../../scss/_app_styles.scss */ .card > * .th img { width: 100%; } -/* line 629, ../../../scss/_app_styles.scss */ +/* line 640, ../../../scss/_app_styles.scss */ .card > * footer { margin-top: 1rem; font-size: 70%; clear: both; color: #e01818; } -/* line 634, ../../../scss/_app_styles.scss */ +/* line 645, ../../../scss/_app_styles.scss */ .card > * footer .age { display: none; position: absolute; @@ -9865,7 +9874,7 @@ article h1:not(.subheader) div input:hover { width: 100%; } -/* line 645, ../../../scss/_app_styles.scss */ +/* line 656, ../../../scss/_app_styles.scss */ .edit-card { position: relative; background-color: white; @@ -9874,36 +9883,36 @@ article h1:not(.subheader) div input:hover { } /* Content Tabs */ -/* line 658, ../../../scss/_app_styles.scss */ +/* line 669, ../../../scss/_app_styles.scss */ article .tabs { display: inline-block; } -/* line 660, ../../../scss/_app_styles.scss */ +/* line 671, ../../../scss/_app_styles.scss */ article .tabs dd a { border-radius: 4px; border: 1px transparent; } -/* line 664, ../../../scss/_app_styles.scss */ +/* line 675, ../../../scss/_app_styles.scss */ article .tabs dd.active a { color: #10c1cb; border: 1px solid; } -/* line 668, ../../../scss/_app_styles.scss */ +/* line 679, ../../../scss/_app_styles.scss */ article .tabs dd:hover a { color: #10c1cb; } -/* line 672, ../../../scss/_app_styles.scss */ +/* line 683, ../../../scss/_app_styles.scss */ article .tabs i { margin-right: 5px; font-size: 1.3rem; } -/* line 678, ../../../scss/_app_styles.scss */ +/* line 689, ../../../scss/_app_styles.scss */ article section.content { background-color: white; border: 1px solid #eee; } -/* line 685, ../../../scss/_app_styles.scss */ +/* line 696, ../../../scss/_app_styles.scss */ .card > div:hover { box-shadow: 0 0 10px lightgray; transition: 0.9s; @@ -9912,31 +9921,31 @@ article section.content { } /* Default card */ -/* line 693, ../../../scss/_app_styles.scss */ +/* line 704, ../../../scss/_app_styles.scss */ .card > :hover .label, .card > :hover .label-list:empty:before { opacity: 1; } -/* line 698, ../../../scss/_app_styles.scss */ +/* line 709, ../../../scss/_app_styles.scss */ .gallery .card .th { display: block; } /* Inline label list */ -/* line 706, ../../../scss/_app_styles.scss */ +/* line 717, ../../../scss/_app_styles.scss */ .label-list { display: inline-block; text-align: left; margin-bottom: 0.1rem; } -/* line 710, ../../../scss/_app_styles.scss */ +/* line 721, ../../../scss/_app_styles.scss */ .label-list:empty:before { content: "UNTAGGED"; opacity: 0.2 !important; padding: 2px; background-color: transparent; } -/* line 718, ../../../scss/_app_styles.scss */ +/* line 729, ../../../scss/_app_styles.scss */ .label-list .label, .label-list .label-list:empty:before { background-color: transparent; padding: 2px; @@ -9944,20 +9953,20 @@ article section.content { /*************************** 2. Custom CSS overrides ***********************/ /* Content area */ -/* line 727, ../../../scss/_app_styles.scss */ +/* line 738, ../../../scss/_app_styles.scss */ article { padding-bottom: 4rem; } -/* line 731, ../../../scss/_app_styles.scss */ +/* line 742, ../../../scss/_app_styles.scss */ article > header { border-bottom: 1px solid #ddd; } -/* line 735, ../../../scss/_app_styles.scss */ +/* line 746, ../../../scss/_app_styles.scss */ article > footer { border-top: 1px dotted #ddd; } -/* line 747, ../../../scss/_app_styles.scss */ +/* line 758, ../../../scss/_app_styles.scss */ textarea { min-height: 6rem; } @@ -9978,44 +9987,44 @@ textarea { }*/ /*************************** 3. Custom CSS Below ***********************/ /*CSS fix for tables generated via orgitdown*/ -/* line 767, ../../../scss/_app_styles.scss */ +/* line 778, ../../../scss/_app_styles.scss */ #content table td, #content colgroup col { float: none !important; } -/* line 772, ../../../scss/_app_styles.scss */ +/* line 783, ../../../scss/_app_styles.scss */ .user { color: inherit; } -/* line 775, ../../../scss/_app_styles.scss */ +/* line 786, ../../../scss/_app_styles.scss */ .user { color: inherit; } -/* line 778, ../../../scss/_app_styles.scss */ +/* line 789, ../../../scss/_app_styles.scss */ .user i { margin-right: 3px; } -/* line 781, ../../../scss/_app_styles.scss */ +/* line 792, ../../../scss/_app_styles.scss */ .user:hover i { opacity: 1; } -/* line 785, ../../../scss/_app_styles.scss */ +/* line 796, ../../../scss/_app_styles.scss */ a.node { display: block; } -/* line 789, ../../../scss/_app_styles.scss */ +/* line 800, ../../../scss/_app_styles.scss */ .button.edit { margin-bottom: 0; } /************ Forms **************/ /* Node edit */ -/* line 797, ../../../scss/_app_styles.scss */ +/* line 808, ../../../scss/_app_styles.scss */ input.node-title { font-size: 3rem; height: 4rem; @@ -10023,13 +10032,13 @@ input.node-title { } /* view-graph in node_details_base.html */ -/* line 804, ../../../scss/_app_styles.scss */ +/* line 815, ../../../scss/_app_styles.scss */ .graph-height { height: 70%; } /*for graph and location*/ -/* line 809, ../../../scss/_app_styles.scss */ +/* line 820, ../../../scss/_app_styles.scss */ .graph-div { height: 90%; width: -webkit-calc(100% - 10px); @@ -10043,13 +10052,13 @@ input.node-title { } /*for graph and location*/ -/* line 819, ../../../scss/_app_styles.scss */ +/* line 830, ../../../scss/_app_styles.scss */ .graph-div h3 { border-bottom: 2px inset #154534; padding: 0.25em 0; } -/* line 824, ../../../scss/_app_styles.scss */ +/* line 835, ../../../scss/_app_styles.scss */ #view-map-widget .close-reveal-modal, #view-map-edit-widget .close-reveal-modal { z-index: 1; background-color: captiontext; @@ -10060,7 +10069,7 @@ input.node-title { box-shadow: 0 1px 10px 2px #A9A9A9; } -/* line 835, ../../../scss/_app_styles.scss */ +/* line 846, ../../../scss/_app_styles.scss */ #view-map-widget .close-reveal-modal:hover, #view-map-edit-widget .close-reveal-modal:hover { background-color: white; border-radius: 30px; @@ -10073,7 +10082,7 @@ input.node-title { /****************** CUSTOM *********************/ /* UI Button */ -/* line 850, ../../../scss/_app_styles.scss */ +/* line 861, ../../../scss/_app_styles.scss */ .ui.button { margin-right: 0.5rem; border: 1px solid rgba(0, 0, 0, 0.2); @@ -10083,56 +10092,56 @@ input.node-title { padding: 0.5vw 0.75vw; z-index: 500; } -/* line 861, ../../../scss/_app_styles.scss */ +/* line 872, ../../../scss/_app_styles.scss */ .ui.button label { color: #666; } -/* line 864, ../../../scss/_app_styles.scss */ +/* line 875, ../../../scss/_app_styles.scss */ .ui.button small { margin-left: 2px; display: inline; } -/* line 868, ../../../scss/_app_styles.scss */ +/* line 879, ../../../scss/_app_styles.scss */ .ui.button:hover, .ui.button:active { border-color: rgba(255, 255, 255, 0.2); background-color: rgba(0, 0, 0, 0.9); } -/* line 871, ../../../scss/_app_styles.scss */ +/* line 882, ../../../scss/_app_styles.scss */ .ui.button:hover label, .ui.button:active label { color: #ddd; } -/* line 874, ../../../scss/_app_styles.scss */ +/* line 885, ../../../scss/_app_styles.scss */ .ui.button:hover small, .ui.button:active small { display: inline; } -/* line 877, ../../../scss/_app_styles.scss */ +/* line 888, ../../../scss/_app_styles.scss */ .ui.button:hover:focus, .ui.button:active:focus { font-weight: bold; } -/* line 886, ../../../scss/_app_styles.scss */ +/* line 897, ../../../scss/_app_styles.scss */ aside#help h4 { color: black; } -/* line 889, ../../../scss/_app_styles.scss */ +/* line 900, ../../../scss/_app_styles.scss */ aside#help p, aside#help h5, aside#help h6 { color: #ddd; padding: 0.3rem 0.9375rem; } -/* line 896, ../../../scss/_app_styles.scss */ +/* line 907, ../../../scss/_app_styles.scss */ .align-center { margin: 0 auto; display: block; } -/* line 902, ../../../scss/_app_styles.scss */ +/* line 913, ../../../scss/_app_styles.scss */ #profile-img { height: 40px; margin-right: 5px; } -/* line 911, ../../../scss/_app_styles.scss */ +/* line 922, ../../../scss/_app_styles.scss */ #replies-area .disc-replies { padding: 10px; background-color: #dffbfd; @@ -10141,11 +10150,11 @@ aside#help p, aside#help h5, aside#help h6 { margin-left: 48px; margin-top: 10px; } -/* line 920, ../../../scss/_app_styles.scss */ +/* line 931, ../../../scss/_app_styles.scss */ #replies-area .disc-replies .reply-btn { cursor: pointer; } -/* line 924, ../../../scss/_app_styles.scss */ +/* line 935, ../../../scss/_app_styles.scss */ #replies-area .disc-replies .reply-btn:hover { font-weight: bold; } diff --git a/gnowsys-ndf/gnowsys_ndf/ndf/static/ndf/css/themes/tiss/styles.css b/gnowsys-ndf/gnowsys_ndf/ndf/static/ndf/css/themes/tiss/styles.css index b66c1c29..76378e90 100644 --- a/gnowsys-ndf/gnowsys_ndf/ndf/static/ndf/css/themes/tiss/styles.css +++ b/gnowsys-ndf/gnowsys_ndf/ndf/static/ndf/css/themes/tiss/styles.css @@ -9624,26 +9624,35 @@ article h1:not(.subheader) div input:hover { .card > *.published hr { border-color: #7ee2a8; } -/* line 564, ../../../scss/_app_styles.scss */ +/* line 565, ../../../scss/_app_styles.scss */ +.card > *.moderation { + opacity: 1; + background-color: #efefef; +} +/* line 570, ../../../scss/_app_styles.scss */ +.card > *.moderation hr { + border-color: #bcbcbc; +} +/* line 575, ../../../scss/_app_styles.scss */ .card > *.unapproved { opacity: 1; border-style: solid; border-color: #f04124; } -/* line 570, ../../../scss/_app_styles.scss */ +/* line 581, ../../../scss/_app_styles.scss */ .card > *:hover { border-style: solid; opacity: 1; } -/* line 576, ../../../scss/_app_styles.scss */ +/* line 587, ../../../scss/_app_styles.scss */ .card > *:hover i { opacity: 0.3; } -/* line 579, ../../../scss/_app_styles.scss */ +/* line 590, ../../../scss/_app_styles.scss */ .card > *:hover footer .age { display: block; } -/* line 584, ../../../scss/_app_styles.scss */ +/* line 595, ../../../scss/_app_styles.scss */ .card > * > i { position: absolute; top: -10px; @@ -9652,34 +9661,34 @@ article h1:not(.subheader) div input:hover { color: #0eacb5; opacity: 0.3; } -/* line 593, ../../../scss/_app_styles.scss */ +/* line 604, ../../../scss/_app_styles.scss */ .card > * .preview { float: left; padding-right: 5px; padding-top: 4px; } -/* line 598, ../../../scss/_app_styles.scss */ +/* line 609, ../../../scss/_app_styles.scss */ .card > * header { overflow: hidden; } -/* line 601, ../../../scss/_app_styles.scss */ +/* line 612, ../../../scss/_app_styles.scss */ .card > * h5 { white-space: nowrap; text-overflow: ellipsis; margin-bottom: 0; } -/* line 606, ../../../scss/_app_styles.scss */ +/* line 617, ../../../scss/_app_styles.scss */ .card > * .label, .card > * .label-list:empty:before { opacity: 0.5; } -/* line 609, ../../../scss/_app_styles.scss */ +/* line 620, ../../../scss/_app_styles.scss */ .card > * p { color: #555; height: 80px; background-repeat: no-repeat; font-size: 80%; } -/* line 615, ../../../scss/_app_styles.scss */ +/* line 626, ../../../scss/_app_styles.scss */ .card > * .th { margin: 20px auto; width: 80px; @@ -9687,23 +9696,23 @@ article h1:not(.subheader) div input:hover { overflow: hidden; display: none; } -/* line 621, ../../../scss/_app_styles.scss */ +/* line 632, ../../../scss/_app_styles.scss */ .card > * .th:hover { width: 150px; height: 150px; } -/* line 625, ../../../scss/_app_styles.scss */ +/* line 636, ../../../scss/_app_styles.scss */ .card > * .th img { width: 100%; } -/* line 629, ../../../scss/_app_styles.scss */ +/* line 640, ../../../scss/_app_styles.scss */ .card > * footer { margin-top: 1rem; font-size: 70%; clear: both; color: #e01818; } -/* line 634, ../../../scss/_app_styles.scss */ +/* line 645, ../../../scss/_app_styles.scss */ .card > * footer .age { display: none; position: absolute; @@ -9713,7 +9722,7 @@ article h1:not(.subheader) div input:hover { width: 100%; } -/* line 645, ../../../scss/_app_styles.scss */ +/* line 656, ../../../scss/_app_styles.scss */ .edit-card { position: relative; background-color: white; @@ -9722,36 +9731,36 @@ article h1:not(.subheader) div input:hover { } /* Content Tabs */ -/* line 658, ../../../scss/_app_styles.scss */ +/* line 669, ../../../scss/_app_styles.scss */ article .tabs { display: inline-block; } -/* line 660, ../../../scss/_app_styles.scss */ +/* line 671, ../../../scss/_app_styles.scss */ article .tabs dd a { border-radius: 4px; border: 1px transparent; } -/* line 664, ../../../scss/_app_styles.scss */ +/* line 675, ../../../scss/_app_styles.scss */ article .tabs dd.active a { color: #10c1cb; border: 1px solid; } -/* line 668, ../../../scss/_app_styles.scss */ +/* line 679, ../../../scss/_app_styles.scss */ article .tabs dd:hover a { color: #10c1cb; } -/* line 672, ../../../scss/_app_styles.scss */ +/* line 683, ../../../scss/_app_styles.scss */ article .tabs i { margin-right: 5px; font-size: 1.3rem; } -/* line 678, ../../../scss/_app_styles.scss */ +/* line 689, ../../../scss/_app_styles.scss */ article section.content { background-color: white; border: 1px solid #eee; } -/* line 685, ../../../scss/_app_styles.scss */ +/* line 696, ../../../scss/_app_styles.scss */ .card > div:hover { box-shadow: 0 0 10px lightgray; transition: 0.9s; @@ -9760,31 +9769,31 @@ article section.content { } /* Default card */ -/* line 693, ../../../scss/_app_styles.scss */ +/* line 704, ../../../scss/_app_styles.scss */ .card > :hover .label, .card > :hover .label-list:empty:before { opacity: 1; } -/* line 698, ../../../scss/_app_styles.scss */ +/* line 709, ../../../scss/_app_styles.scss */ .gallery .card .th { display: block; } /* Inline label list */ -/* line 706, ../../../scss/_app_styles.scss */ +/* line 717, ../../../scss/_app_styles.scss */ .label-list { display: inline-block; text-align: left; margin-bottom: 0.1rem; } -/* line 710, ../../../scss/_app_styles.scss */ +/* line 721, ../../../scss/_app_styles.scss */ .label-list:empty:before { content: "UNTAGGED"; opacity: 0.2 !important; padding: 2px; background-color: transparent; } -/* line 718, ../../../scss/_app_styles.scss */ +/* line 729, ../../../scss/_app_styles.scss */ .label-list .label, .label-list .label-list:empty:before { background-color: transparent; padding: 2px; @@ -9792,20 +9801,20 @@ article section.content { /*************************** 2. Custom CSS overrides ***********************/ /* Content area */ -/* line 727, ../../../scss/_app_styles.scss */ +/* line 738, ../../../scss/_app_styles.scss */ article { padding-bottom: 4rem; } -/* line 731, ../../../scss/_app_styles.scss */ +/* line 742, ../../../scss/_app_styles.scss */ article > header { border-bottom: 1px solid #ddd; } -/* line 735, ../../../scss/_app_styles.scss */ +/* line 746, ../../../scss/_app_styles.scss */ article > footer { border-top: 1px dotted #ddd; } -/* line 747, ../../../scss/_app_styles.scss */ +/* line 758, ../../../scss/_app_styles.scss */ textarea { min-height: 6rem; } @@ -9826,44 +9835,44 @@ textarea { }*/ /*************************** 3. Custom CSS Below ***********************/ /*CSS fix for tables generated via orgitdown*/ -/* line 767, ../../../scss/_app_styles.scss */ +/* line 778, ../../../scss/_app_styles.scss */ #content table td, #content colgroup col { float: none !important; } -/* line 772, ../../../scss/_app_styles.scss */ +/* line 783, ../../../scss/_app_styles.scss */ .user { color: inherit; } -/* line 775, ../../../scss/_app_styles.scss */ +/* line 786, ../../../scss/_app_styles.scss */ .user { color: inherit; } -/* line 778, ../../../scss/_app_styles.scss */ +/* line 789, ../../../scss/_app_styles.scss */ .user i { margin-right: 3px; } -/* line 781, ../../../scss/_app_styles.scss */ +/* line 792, ../../../scss/_app_styles.scss */ .user:hover i { opacity: 1; } -/* line 785, ../../../scss/_app_styles.scss */ +/* line 796, ../../../scss/_app_styles.scss */ a.node { display: block; } -/* line 789, ../../../scss/_app_styles.scss */ +/* line 800, ../../../scss/_app_styles.scss */ .button.edit { margin-bottom: 0; } /************ Forms **************/ /* Node edit */ -/* line 797, ../../../scss/_app_styles.scss */ +/* line 808, ../../../scss/_app_styles.scss */ input.node-title { font-size: 3rem; height: 4rem; @@ -9871,13 +9880,13 @@ input.node-title { } /* view-graph in node_details_base.html */ -/* line 804, ../../../scss/_app_styles.scss */ +/* line 815, ../../../scss/_app_styles.scss */ .graph-height { height: 70%; } /*for graph and location*/ -/* line 809, ../../../scss/_app_styles.scss */ +/* line 820, ../../../scss/_app_styles.scss */ .graph-div { height: 90%; width: -webkit-calc(100% - 10px); @@ -9891,13 +9900,13 @@ input.node-title { } /*for graph and location*/ -/* line 819, ../../../scss/_app_styles.scss */ +/* line 830, ../../../scss/_app_styles.scss */ .graph-div h3 { border-bottom: 2px inset #154534; padding: 0.25em 0; } -/* line 824, ../../../scss/_app_styles.scss */ +/* line 835, ../../../scss/_app_styles.scss */ #view-map-widget .close-reveal-modal, #view-map-edit-widget .close-reveal-modal { z-index: 1; background-color: captiontext; @@ -9908,7 +9917,7 @@ input.node-title { box-shadow: 0 1px 10px 2px #A9A9A9; } -/* line 835, ../../../scss/_app_styles.scss */ +/* line 846, ../../../scss/_app_styles.scss */ #view-map-widget .close-reveal-modal:hover, #view-map-edit-widget .close-reveal-modal:hover { background-color: white; border-radius: 30px; @@ -9921,7 +9930,7 @@ input.node-title { /****************** CUSTOM *********************/ /* UI Button */ -/* line 850, ../../../scss/_app_styles.scss */ +/* line 861, ../../../scss/_app_styles.scss */ .ui.button { margin-right: 0.5rem; border: 1px solid rgba(0, 0, 0, 0.2); @@ -9931,56 +9940,56 @@ input.node-title { padding: 0.5vw 0.75vw; z-index: 500; } -/* line 861, ../../../scss/_app_styles.scss */ +/* line 872, ../../../scss/_app_styles.scss */ .ui.button label { color: #666; } -/* line 864, ../../../scss/_app_styles.scss */ +/* line 875, ../../../scss/_app_styles.scss */ .ui.button small { margin-left: 2px; display: inline; } -/* line 868, ../../../scss/_app_styles.scss */ +/* line 879, ../../../scss/_app_styles.scss */ .ui.button:hover, .ui.button:active { border-color: rgba(255, 255, 255, 0.2); background-color: rgba(0, 0, 0, 0.9); } -/* line 871, ../../../scss/_app_styles.scss */ +/* line 882, ../../../scss/_app_styles.scss */ .ui.button:hover label, .ui.button:active label { color: #ddd; } -/* line 874, ../../../scss/_app_styles.scss */ +/* line 885, ../../../scss/_app_styles.scss */ .ui.button:hover small, .ui.button:active small { display: inline; } -/* line 877, ../../../scss/_app_styles.scss */ +/* line 888, ../../../scss/_app_styles.scss */ .ui.button:hover:focus, .ui.button:active:focus { font-weight: bold; } -/* line 886, ../../../scss/_app_styles.scss */ +/* line 897, ../../../scss/_app_styles.scss */ aside#help h4 { color: black; } -/* line 889, ../../../scss/_app_styles.scss */ +/* line 900, ../../../scss/_app_styles.scss */ aside#help p, aside#help h5, aside#help h6 { color: #ddd; padding: 0.3rem 0.9375rem; } -/* line 896, ../../../scss/_app_styles.scss */ +/* line 907, ../../../scss/_app_styles.scss */ .align-center { margin: 0 auto; display: block; } -/* line 902, ../../../scss/_app_styles.scss */ +/* line 913, ../../../scss/_app_styles.scss */ #profile-img { height: 40px; margin-right: 5px; } -/* line 911, ../../../scss/_app_styles.scss */ +/* line 922, ../../../scss/_app_styles.scss */ #replies-area .disc-replies { padding: 10px; background-color: #dffbfd; @@ -9989,11 +9998,11 @@ aside#help p, aside#help h5, aside#help h6 { margin-left: 48px; margin-top: 10px; } -/* line 920, ../../../scss/_app_styles.scss */ +/* line 931, ../../../scss/_app_styles.scss */ #replies-area .disc-replies .reply-btn { cursor: pointer; } -/* line 924, ../../../scss/_app_styles.scss */ +/* line 935, ../../../scss/_app_styles.scss */ #replies-area .disc-replies .reply-btn:hover { font-weight: bold; } diff --git a/gnowsys-ndf/gnowsys_ndf/ndf/static/ndf/scss/_app_styles.scss b/gnowsys-ndf/gnowsys_ndf/ndf/static/ndf/scss/_app_styles.scss index d14e02cd..e7b647e9 100644 --- a/gnowsys-ndf/gnowsys_ndf/ndf/static/ndf/scss/_app_styles.scss +++ b/gnowsys-ndf/gnowsys_ndf/ndf/static/ndf/scss/_app_styles.scss @@ -561,6 +561,17 @@ article{ border-color: lighten(#2ecc71, 20%); } } + + &.moderation{ + opacity: 1; + // background-color: darken($bg-color,5%); + background-color: #efefef; + + hr{ + border-color: darken(#efefef, 20%); + } + } + &.unapproved{ opacity: 1; border-style: solid; diff --git a/gnowsys-ndf/gnowsys_ndf/ndf/templates/ndf/all_under_moderation_status.html b/gnowsys-ndf/gnowsys_ndf/ndf/templates/ndf/all_under_moderation_status.html new file mode 100644 index 00000000..ba9851b7 --- /dev/null +++ b/gnowsys-ndf/gnowsys_ndf/ndf/templates/ndf/all_under_moderation_status.html @@ -0,0 +1,30 @@ +{% extends "ndf/base.html" %} +{% load i18n %} +{% load ndf_tags %} +{% get_group_name groupid as group_name_tag %} + + +{% block title %} {{title}} {% endblock %} + + +{% block style %} +{% endblock %} + +{% block body_content %} + + <h4>Following resources are under moderation</h4> + + <div class="tabs-content gallery"> + + {% group_type_info groupid request.user as grouptype %} + + <!-- Tab View #1 - All --> + <div class="content row active" id="view-all" data-filetype="all"> + + {% include "ndf/file_list_tab.html" with resource_type=files detail_urlname="moderation_status" filetype="all" res_type_name="" page_info=file_pages dont_show_error=dont_show_error%} + + </div> + + </div> + +{% endblock %} diff --git a/gnowsys-ndf/gnowsys_ndf/ndf/templates/ndf/create_group.html b/gnowsys-ndf/gnowsys_ndf/ndf/templates/ndf/create_group.html index 4a2d802d..a6a4fb18 100644 --- a/gnowsys-ndf/gnowsys_ndf/ndf/templates/ndf/create_group.html +++ b/gnowsys-ndf/gnowsys_ndf/ndf/templates/ndf/create_group.html @@ -3,6 +3,257 @@ {% load ndf_tags %} {% load cache %} +{% block title %} Create New Group {% endblock %} + +{% block meta_content %} + {% blocktrans %} + <h3>Types of Groups</h3> + <hr/> + <h5>Open Groups</h5> + <p class="subheader">Open groups are ideal for projects that require a high level of collaboration and participation. Any metastudio user can join this group without prior approval</p> + <h5>Closed Groups</h5> + <p class="subheader">Closed groups are ideal for projects that require restricted access to content and documents. Users can only join after their membership request is approved or have been invited.</p> + {% endblocktrans %} +{% endblock %} + + +{% block body_content %} + + <h2 class="text-center"><small>{% trans "Create New Group" %}</small></h2> + <br/> + + <form id="create_group" class="" method="post" action="{% url 'create_group' group_id %}" data-abide> + {% csrf_token %} + + <!-- name --> + <div class="row"> + <div class="small-4 columns"> + <label for="right-label" class="right inline">{% trans "Group Name" %}</label> + </div> + <div class="small-4 small-pull-4 columns"> + <input type="text" name="groupname" id="group_name" required placeholder="{% trans 'Enter the unique group name' %}"> + <label id="message" style="display:none; color:red"></label> + <small class="error">Group Name is required and it must be a string.</small> + </div> + </div> + + <!-- altname --> + <div class="row"> + <div class="small-4 columns"> + <label for="right-label" class="right inline">{% trans "Alternate Group Name" %}</label> + </div> + <div class="small-4 small-pull-4 columns"> + <input type="text" name="alt_groupname" id="alt_group_name" placeholder="{% trans 'Provide display/alternate group name' %}"> + </div> + </div> + + <br/> + + <!-- type --> + <div class="row"> + <div class="small-4 columns"> + <label for="right-label" class="right inline">{% trans "Group Type" %}</label> + </div> + <div class="small-4 small-pull-4 columns"> + <select name="group_type" class="gtype"> + <option id="PUBLIC">{% trans "PUBLIC" %}</option> + <option id="PRIVATE">{% trans "PRIVATE" %}</option> + <option id="ANONYMOUS">{% trans "ANONYMOUS" %}</option> + </select> + <small class="error">Please select group type.</small> + </div> + </div> + + <!-- editing policy --> + <div class="row"> + <div class="small-4 columns"> + <label for="right-label" class="right inline">{% trans "Group Editing Policy" %}</label> + </div> + <div class="small-4 small-pull-4 columns"> + <select name="edit_policy" id="editp"> + <option id="EDITABLE_NON_MODERATED">{% trans "EDITABLE_NON_MODERATED" %}</option> + <option id="EDITABLE_MODERATED">{% trans "EDITABLE_MODERATED" %}</option> + <option id="NON_EDITABLE">{% trans "NON_EDITABLE" %}</option> + </select> + <small class="error">Please select group editing policy.</small> + </div> + </div> + + <!-- moderation level --> + <div class="row hide" id="moderation-level"> + <div class="small-4 columns"> + <label for="right-label" class="right inline">{% trans "Level of moderation" %}</label> + </div> + <div class="small-4 small-pull-4 columns"> + <select name="moderation_level"> + <option value="0">{% trans "--- Select Level ---" %}</option> + <option value="1">{% trans "One Level" %}</option> + <option value="2">{% trans "Two Level" %}</option> + <option value="3">{% trans "Three Level" %}</option> + </select> + <small class="error">{% trans "Please select group editing policy." %}</small> + </div> + </div> + + <!-- following fields are comented because of groups are not implemented accordingly --> + {% comment %} + <br/> + + <!-- subscription policy --> + <div class="row"> + <div class="small-4 columns"> + <label for="right-label" class="right inline">{% trans "Group Subscription Policy" %}</label> + </div> + <div class="small-4 small-pull-4 columns"> + <select name="subscription" class="subscptn" disabled="disabled"> + <option id="OPEN">{% trans "OPEN" %}</option> + <option id="BY_REQUEST">{% trans "BY_REQUEST" %}</option> + <option id="BY_INVITATION">{% trans "BY_INVITATION" %}</option> + </select> + <small class="error">Please select subscription policy.</small> + </div> + </div> + + <!-- member visibility --> + <div class="row"> + <div class="small-4 columns"> + <label for="right-label" class="right inline">{% trans "Group Member Visibility" %}</label> + </div> + <div class="small-4 small-pull-4 columns"> + <select name="disclosure_policy" class="mem" disabled="disabled"> + <option id="DISCLOSED_TO_MEM">{% trans "DISCLOSED_TO_MEM" %}</option> + <option id="NOT_DISCLOSED_TO_MEM">{% trans "NOT_DISCLOSED_TO_MEM" %}</option> + </select> + <small class="error">Please select group member visibility.</small> + </div> + </div> + + <!-- Group Encryption policy --> + <div class="row"> + <div class="small-4 columns"> + <label for="right-label" class="right inline">{% trans "Group Encryption policy" %}</label> + </div> + <div class="small-4 small-pull-4 columns"> + <select name="encryption_policy" class="encr" disabled="disabled"> + <option id="NOT_ENCRYPTED">{% trans "NOT_ENCRYPTED" %}</option> + <option id="ENCRYPTED">{% trans "ENCRYPTED" %}</option> + </select> + <small class="error">Please select group encryption policy.</small> + </div> + </div> + + <!-- Group Existance visibility --> + <div class="row"> + <div class="small-4 columns"> + <label for="right-label" class="right inline">{% trans "Group Existance visibility" %}</label> + </div> + <div class="small-4 small-pull-4 columns"> + <select name="visibility_policy" class="visibility_policy" disabled="disabled"> + <option id="ANNOUNCED">{% trans "ANNOUNCED" %}</option> + <option id="NOT_ANNOUNCED">{% trans "NOT_ANNOUNCED" %}</option> + </select> + <small class="error">Please select group visibility policy.</small> + </div> + </div> + {% endcomment %} + + <br/> + + <!-- agency type --> + <div class="row"> + <div class="small-4 columns"> + <label for="right-label" class="right inline">{% trans "Group Agency Types" %}</label> + </div> + {% get_group_agency_types as agency_types %} + <div class="small-4 small-pull-4 columns"> + <select name="agency_type" class="agencygrp"> + {% for each in agency_types %} + <option id="{{each}}">{{each}}</option> + {% endfor %} + </select> + <small class="error">Please select group agency type.</small> + </div> + </div> + + <br/> + + <div class="row"> + <div class="small-6 small-push-2 columns"> + <input type="submit" value="Create Group" id="grpsubmit" class="button expand"> + </div> + </div> + + </form> +{% endblock %} + +{% block script %} +// <script type="text/javascript"> + + document.getElementById("group_name").focus(); + + function moderatedEditPolicy () { + var selectedPolicy = this.value; + var moderationLevel = document.getElementById("moderation-level"); + + if(selectedPolicy == "EDITABLE_MODERATED") + { + moderationLevel.classList.remove("hide"); + } + else + { + moderationLevel.classList.add("hide"); + } + } + + var editPolicy = document.getElementById("editp"); + editPolicy.onblur = moderatedEditPolicy; + + $("#create_group").submit(function(event){ + + var name = $("#group_name").val().trim().toLowerCase(); + var nodes = {{nodes_list|safe}} + var val_chk = name.search(/mod$/gi) + + $("#message").css("display", "none"); + + if (name != "") + { + if(val_chk == -1){ + if (nodes.indexOf(name) >= 0) + { + $("#message").css("display", "block"); + $("#message").text("Group '"+ name +"' already exist. Please choose another name"); + event.preventDefault(); + } + } + else if (val_chk != -1){ + $("#message").css("display", "block"); + $("#message").text("Group name cannot include 'Mod' or 'mod' text at end."); + event.preventDefault(); + } + } + else if (name == ""){ + $("#message").css("display", "block"); + $("#message").text("Group name cannot be empty."); + event.preventDefault(); + } + }); + +// </script> +{% endblock %} + + + + + +<!-- ================== following is commented old template structure ================== --> + + + + + +{% comment %} + {% cache 300 create_group request.LANGUAGE_CODE %} {% block title %} Create a new group {% endblock %} @@ -73,7 +324,7 @@ <font size="3" >Group Subscription policy</font> </div> <div style='display:table-cell;'> - <select name="subscription" class="subscptn" disabled="disabled"> + <select name="subscription_policy" class="subscptn" disabled="disabled"> <option id="OPEN">{% trans "OPEN" %}</option> <option id="BY_REQUEST">{% trans "BY_REQUEST" %}</option> <option id="BY_INVITATION">{% trans "BY_INVITATION" %}</option> @@ -255,3 +506,4 @@ }); {% endblock %} +{% endcomment %}
\ No newline at end of file diff --git a/gnowsys-ndf/gnowsys_ndf/ndf/templates/ndf/data_review.html b/gnowsys-ndf/gnowsys_ndf/ndf/templates/ndf/data_review.html index 1ed8f59c..9fd5dee1 100644 --- a/gnowsys-ndf/gnowsys_ndf/ndf/templates/ndf/data_review.html +++ b/gnowsys-ndf/gnowsys_ndf/ndf/templates/ndf/data_review.html @@ -1,10 +1,23 @@ {% extends "ndf/base.html" %} {% load i18n %} {% load ndf_tags %} + +{% block title %} {{title}} {% endblock %} + {% get_group_name groupid as group_name_tag %} +{% get_group_object groupid as group_object %} {% block style %} + #data-review-table thead{ + border-bottom: 2px solid rgb(221, 221, 221); + background-color: #EFEFEF; + } + + #data-review-table thead > tr:nth-child(2){ + background-color: #F5F5F5; + } + #data-review-table td, th { border-right: solid thin #eee; } @@ -136,7 +149,7 @@ {% endblock %} {% block body_content %} - + {% check_user_join request groupid as user_is_joined %} {% user_access_policy groupid request.user as user_access %} @@ -144,10 +157,19 @@ <form method="GET" action="{% url 'data_review_search' group_name_tag %}"> <div class="row"> - <div class="small-4 columns"> + <div class="small-9 columns"> + <!-- kept for future-use/filters --> + <h3 class="text-center"> + {{group_object.altnames|default_if_none:group_object.name}} + <small> + (<span id="data-resources-count">{{page_info.count}}</span>) + </small> + </h3> + </div> + <div class="small-3 columns"> <div class="row collapse"> <div class="small-10 columns"> - <input type="text" id="dr-search" name="search_text" placeholder="Search in the Data Review" value="{{search_text}}"> + <input type="text" id="dr-search" name="search_text" placeholder="Search in the {{group_object.altnames|default_if_none:group_object.name}}" value="{{search_text}}" title="Search in the '{{group_object.altnames|default_if_none:group_object.name}}'"> </div> <div class="small-2 columns"> <!-- <div id="dr-search-btn" class="button postfix">Search</div> --> @@ -155,9 +177,6 @@ </div> </div> </div> - <div class="small-8 columns"> - <!-- kept for future-use/filters --> - </div> </div> </form> diff --git a/gnowsys-ndf/gnowsys_ndf/ndf/templates/ndf/data_review_table.html b/gnowsys-ndf/gnowsys_ndf/ndf/templates/ndf/data_review_table.html index dabfef67..73131972 100644 --- a/gnowsys-ndf/gnowsys_ndf/ndf/templates/ndf/data_review_table.html +++ b/gnowsys-ndf/gnowsys_ndf/ndf/templates/ndf/data_review_table.html @@ -14,6 +14,9 @@ <th class="text-center right-border" colspan="3">Alignment & Level</th> <th class="text-center right-border" colspan="7">Curate</th> <th class="text-center right-border" colspan="3">Advance</th> + {% if title == "moderation" %} + <th class="text-center right-border" colspan="3">Moderation</th> + {% endif %} </tr> <tr class="bottom-border"> @@ -61,7 +64,14 @@ <!-- Advance --> <th class="expand-width-3">Reading Level</th> <th>Time Required</th> - <th class="expand-width-3">Text Complexity</th> + <th class="expand-width-3 right-border">Text Complexity</th> + + <!-- moderation --> + {% if title == "moderation" %} + <th class="expand-width-2">Discuss</th> + <th class="expand-width-2">Approve</th> + <th class="expand-width-3">Reject</th> + {% endif %} </tr> diff --git a/gnowsys-ndf/gnowsys_ndf/ndf/templates/ndf/data_review_tbody.html b/gnowsys-ndf/gnowsys_ndf/ndf/templates/ndf/data_review_tbody.html index d55ed3f9..3c8d8a6f 100644 --- a/gnowsys-ndf/gnowsys_ndf/ndf/templates/ndf/data_review_tbody.html +++ b/gnowsys-ndf/gnowsys_ndf/ndf/templates/ndf/data_review_tbody.html @@ -75,9 +75,27 @@ <td class="view">{{ resource.timerequired }}</td> <td class="right-border">{{ resource.textcomplexity }}</td> -</tr> + <!-- moderation --> + {% if title == "moderation" %} + + <td class="view"> <!-- editorial discussion --> + 0 | Replies + <!-- get the count of editorial discussion here --> + </td> + <td class="view"> <!-- approval --> + Not Approved + </td> + <td class="view right-border"> <!-- approval --> + Not Rejected + </td> + + {% endif %} + +</tr> +<!-- ======================================= --> <tr id="blank-row-{{resource.pk}}"></tr> +<!-- ======================================= --> <tr id="edit-row-{{resource.pk}}" data-row-name="{{resource.name}}"> @@ -238,7 +256,8 @@ </select> </td> <td class="hide-el" data-field="status"> - <select name="status" {% if not user_is_joined == "author" or not user.is_superuser %}disabled{%endif%}> + <!-- <select name="status" {% if not user_is_joined == "author" or not user.is_superuser %}disabled{%endif%}> --> + <select name="status" {% if not user.is_superuser %}disabled{%endif%}> <option value="{{resource.status}}"> -- Select -- </option> {% for each_status in static_status %} <option {%if each_status == resource.status %}selected="selected"{%endif%} value="{{ each_status }}">{{ each_status }}</option> @@ -261,7 +280,7 @@ <td class="hide-el" data-field="timerequired"> <input type="text" class="time-required" value="{{resource.timerequired}}"/> </td> - <td class="hide-el" data-field="textcomplexity" class="right-border"> + <td class="hide-el right-border" data-field="textcomplexity" class="right-border"> <select name="textcomplexity"> <option value="{{resource.textcomplexity}}"> -- Select -- </option> {% for each_tc in static_textcomplexity %} @@ -272,4 +291,24 @@ </option> --> </select> </td> + + {% if title == "moderation" %} + + <!-- editorial discussion --> + <td class="hide-el"> + <input type="button" data-reveal-id="editorial_discussion_overlay" class="button tiny expand" data-id="editorial-discussion" value="Discuss" data-action="editorial-discussion"/> + <!-- get the count of editorial discussion here --> + </td> + + <!-- approval --> + <td class="hide-el"> + <input type="button" class="button tiny expand success" data-approve-id="{{resource.pk}}" data-id="action-btn-approve-{{resource.pk}}" value="Approve" data-action="approve" onclick="approveResource('{{resource.pk}}')"> + </td> + + <!-- rejection --> + <td class="hide-el"> + <input type="button" class="button tiny expand alert" data-approve-id="{{resource.pk}}" value="Reject" data-id="action-btn-reject-{{resource.pk}}" data-action="reject" onclick="rejectResource('{{resource.pk}}')"> + </td> + + {% endif %} </tr> diff --git a/gnowsys-ndf/gnowsys_ndf/ndf/templates/ndf/file_list_tab.html b/gnowsys-ndf/gnowsys_ndf/ndf/templates/ndf/file_list_tab.html index 0be36a3c..8b4e6182 100644 --- a/gnowsys-ndf/gnowsys_ndf/ndf/templates/ndf/file_list_tab.html +++ b/gnowsys-ndf/gnowsys_ndf/ndf/templates/ndf/file_list_tab.html @@ -29,15 +29,19 @@ <div class="draft"> {% elif each_res.status == "PUBLISHED" %} <div class="published"> + {% elif each_res.status == "MODERATION" %} + <div class="moderation"> {% endif %} + {% elif each_res.status == "MODERATION" %} + <div class='moderation'> {% else %} <div class='{% if each_res.status == "PUBLISHED" %}published{% endif %}'> {% endif %} {% if "Pandora_video" in each.member_of_names_list %} - <a href="{% url detail_urlname group_name_tag each_res %}?vid_id={{src_id}}"> + <a href="{% url detail_urlname group_id each_res %}?vid_id={{src_id}}"> {% else %} - <a href="{% url detail_urlname group_name_tag each_res %}"> + <a href="{% url detail_urlname group_id each_res %}"> {% endif %} <div class="row"> @@ -79,6 +83,14 @@ <div class="small-6 columns">{{each_res.mime_type|truncatechars:15}}</div> <div class="small-6 columns"><div class="right"><strong>{{each_res.file_size.size}}</strong> {{each_res.file_size.unit}}</div></div> </footer> + <footer> + <div class="age"> + {{ each_res.member_of_names_list|join:', ' }} created {{each_res.created_at|timesince}} ago + <br/> + <span><strong>{{each_res.contributors|length}}</strong> Contributor{{each_res.contributors|pluralize}} | </span> + by <span class="user" href="{% url 'dashboard' each_res.created_by %}" data-gnow="">{{each_res.user_details_dict.created_by}}</span> + </div> + </footer> </a> <div class="label-list small-12 columns"> @@ -97,15 +109,16 @@ {% if not searching %} <div class="row"> <div class="small-11 small-offset-1 columns"> - {% if res_type_name == "collection" %} <h5> {% trans "This group doesn't have any collections." %}</h5> {% elif filter_result == "False" %} <h5> {% trans "Sorry, No resources found with selected filters :(" %}</h5> {% else %} + {% if not dont_show_error %} <h5> {% blocktrans %}This group doesn't have any files. <b>Be the first to upload a file!</b>{% endblocktrans %} </h5> + {% endif %} {% endif %} </div> diff --git a/gnowsys-ndf/gnowsys_ndf/ndf/templates/ndf/header.html b/gnowsys-ndf/gnowsys_ndf/ndf/templates/ndf/header.html index 30f116ec..38056985 100644 --- a/gnowsys-ndf/gnowsys_ndf/ndf/templates/ndf/header.html +++ b/gnowsys-ndf/gnowsys_ndf/ndf/templates/ndf/header.html @@ -1,8 +1,9 @@ -{% load get_nroer_menu get_user_group get_existing_groups_excluded get_profile_pic get_gapps_iconbar from ndf_tags %} +{% load get_nroer_menu get_user_group get_group_object get_existing_groups_excluded get_profile_pic get_gapps_iconbar from ndf_tags %} {% load i18n %} {% load cache %} + {% get_group_object groupid as group_object %} <!-- <div class="contain-to-grid sticky"> --> <div class="row" id="top-headers"> @@ -29,7 +30,7 @@ <!-- Left Nav Section --> <!-- add GSTUDIO_SITE_NAME = "NROER" in the local_settings.py file, to check locally --> - {% cache 3600 top_header request.LANGUAGE_CODE request.path request.user.username %} + <!-- {#% cache 3600 top_header request.LANGUAGE_CODE request.path request.user.username %} --> {% if site.SITE_NAME == "NROER" %} <!-- NROER level one menu --> @@ -139,7 +140,7 @@ </ul> {% endif %} - {% endcache %} + <!-- {#% endcache %} --> <!-- Closes Left Nav section --> @@ -194,7 +195,7 @@ </a> {% else %} - <a class="user" data-gnow="#aabb44" href="{% url 'dashboard' request.user.pk %}"> + <a class="user" href="{% url 'dashboard' request.user.pk %}"> {{ user.username }} </a> {% endif %} @@ -253,14 +254,15 @@ <!-- closing of first nav --> <!-- =========| divider between two nav's/header's |=========== --> - <!-- start of second nav or group level header--> - <div class="contain-to-grid {% if request.path != '/welcome' %}{% if not is_ac_url %}sticky{% endif %}{% endif %} drop-shadow" id="group-level-header"> - + <div class="contain-to-grid {% if request.path != '/welcome' %}{% if group_object.edit_policy != 'EDITABLE_MODERATED' %}{% if not is_ac_url %}sticky{% endif %}{% endif %}{% endif %} drop-shadow" id="group-level-header"> + <nav class="top-bar" data-topbar data-options="sticky_on: large" role="navigation"> + <!-- don't show this app bar for groups with editable moderated --> + {% if "ModeratingGroup" not in group_object.member_of_names_list %} {% if not is_ac_url %} {% if request.path != "/welcome" %} - {% cache 3600 group_header request.LANGUAGE_CODE request.path request.user.username %} + <!-- #{#% cache 3600 group_header request.LANGUAGE_CODE request.path request.user.username %} --> <ul class="title-area"> <li class="name"> <h1><a href="{{site.HOME_PAGE|default_if_none:'/home/'}}"><i class="fi-home"></i></a></h1> @@ -353,10 +355,12 @@ </ul> </section> - {% endcache %} + <!-- {#% endcache %} --> {% endif %} <!-- end of "/welcome" landing page check --> {% endif %} <!-- end of "accounts" urls check --> </nav> + + {% endif %} <!-- end of "group's edit_policy" urls check --> </div> <!-- end of second nav --> diff --git a/gnowsys-ndf/gnowsys_ndf/ndf/templates/ndf/moderation_data_review.html b/gnowsys-ndf/gnowsys_ndf/ndf/templates/ndf/moderation_data_review.html new file mode 100644 index 00000000..06505c0b --- /dev/null +++ b/gnowsys-ndf/gnowsys_ndf/ndf/templates/ndf/moderation_data_review.html @@ -0,0 +1,79 @@ +{% extends "ndf/data_review.html" %} +{% load i18n %} +{% load ndf_tags %} + +{% get_group_name groupid as group_name_tag %} +{% get_group_object groupid as group_object %} + +{% block body_content %} +{{ block.super }} + +<div id="editorial_discussion_overlay" class="reveal-modal text-center" data-reveal> + Editorial Discussion: + <br/> + <hr/> + Feature under process! + <a class="close-reveal-modal">×</a> +</div> + +{% endblock body_content %} + +{% block script %} +{{ block.super }} +// <script type="text/javascript"> + +function approveResource (oid) { + var msg = "Resource having ID: " + String(oid) + " will be approved from this group\n\n- Press 'OK' to Approve the resource\n- Press 'Cancel' to cancel the action" + + approveConfirm = window.confirm(msg); + + if(approveConfirm) + { + $.ajax({ + type: "POST", + url: "{% url 'approve_resource' group_id %}", + data:{ + node_oid: oid, + csrfmiddlewaretoken: '{{ csrf_token }}' + }, + success: function(data){ + if(parseInt(data)) + { + alert("Resource is successfully approved from this group."); + + // fetching resource blank seperator row + var $resBlankRow = $("tr#blank-row-" + "5577ed2b90b5502857a8e67d"); + // fetching resource object VIEW row + var $resViewRow = $("tr#view-row-" + oid); + // fetching resource object EDIT row + var $resEditRow = $("tr#edit-row-" + oid); + + $($resEditRow).add($resViewRow).add($resBlankRow).animate({ + opacity: 0.1 + }, 1000).fadeOut(1000); + + setCurrEditRowToNone(oid) + + // changing/reducing total count of resources in the page + var $resCount = $("#data-resources-count"); + var resourcesCount = parseInt($resCount.text()); + $resCount.text(--resourcesCount); + } + else + { + alert("Resource is NOT approved.\nSomething went wrong!"); + } + } + }) + } + // else {/*alert("Cancelled");*/ } +} + +function rejectResource (oid) { + alert("Feature under progress!") +} + + + +// </script> +{% endblock script %} diff --git a/gnowsys-ndf/gnowsys_ndf/ndf/templates/ndf/node_ajax_view.html b/gnowsys-ndf/gnowsys_ndf/ndf/templates/ndf/node_ajax_view.html index 298ec6e6..13e8bd31 100644 --- a/gnowsys-ndf/gnowsys_ndf/ndf/templates/ndf/node_ajax_view.html +++ b/gnowsys-ndf/gnowsys_ndf/ndf/templates/ndf/node_ajax_view.html @@ -318,7 +318,14 @@ ul#navigation li a.last { </ul> {% endif %} - <h1><span itemprop="{{schema.1.name}}" class='node'>{{node.name}}</span> + {% if node.status == 'MODERATION' %} + <h4><small> + Note: Following Resource is Under Moderation - + <a href="{% url 'moderation_status' group_id node.pk %}">Check the current status of Moderation</a> + </small></h4> + {% endif %} + + <h1><span itemprop="{{schema.1.name}}" class='node'>{{node.altnames|default_if_none:node.name}}</span> {% if node %} {% get_publish_policy request groupid node as group_policy %} {% if group_policy == "allow" %} @@ -1263,12 +1270,13 @@ ul#navigation li a.last { <!-- Modal links for associated views like graphs and map--> <ul class="side-nav"> <div class="panel" style="background-color:#ddd;"> + {% get_group_object groupid as group_object %} {% user_access_policy groupid request.user as user_access %} {% if user.is_authenticated %} - <b>{% trans "Actions" %}</b><br/> - <div class="row"> + <b>{% trans "Actions" %}</b><br/> + <div class="row"> <div class="medium-6 columns"> {% edit_policy groupid node request.user as status %} @@ -1287,7 +1295,6 @@ ul#navigation li a.last { <a href="{% url edit_url group_id node %}" class="tiny round button edit"><i class="fi-pencil"></i> {% trans "Edit" %}</a> {% endif %} {% endif %} - {% endif %} </div> <div class="medium-6 columns"> @@ -1376,14 +1383,16 @@ ul#navigation li a.last { {% endif %} </div> + {% endif %} {% if node %} {% check_group node as is_group %} {% if is_group %} - + {% get_group_policy node request.user as policy %} {% get_prior_post_node group_id as groupname %} + {% if group_object.edit_policy == 'EDITABLE_MODERATED' and "Group" in group_object.member_of_names_list %} <input type="hidden" id="groupname" value="{{node}}"> {% if user.is_authenticated %} {% if user_access == "allow" %} @@ -1417,6 +1426,7 @@ ul#navigation li a.last { {% endif %} + {% endif %} <!-- Triggers the modals --> <li><a href="#" id ="btn_list_member" data-reveal-id="firstModal">{% trans "List Members" %}</a></li> @@ -1425,7 +1435,10 @@ ul#navigation li a.last { {% check_is_gstaff groupid request.user as is_gstaff %} {% if is_gstaff %} - {% include "ndf/invite_users.html" %} + + {% ifnotequal group_object.edit_policy "EDITABLE_MODERATED" %} + {% include "ndf/invite_users.html" %} + {% endifnotequal %} {% include "ndf/invite_admins.html" %} {% endif %} @@ -1435,6 +1448,18 @@ ul#navigation li a.last { </div> {% endif %} + {% ifequal group_object.edit_policy "EDITABLE_MODERATED" %} + {% if request.user.id in group_object.group_admin or request.user.is_superuser or request.user.id == group_object.created_by %} + <a class="tiny expand button" href="{% url 'moderation' group_name_tag %}"> + Moderate Resources + </a> + + <a class="tiny expand button" href="{% url 'all_under_moderation' group_id %}"> + Moderation Status + </a> + {% endif %} + {% endifequal %} + <!-- This button converts collection into module --> {% comment %} {% if node.collection_set and user.is_authenticated %} @@ -1477,6 +1502,7 @@ ul#navigation li a.last { </li> --> + {% ifnotequal group_object.edit_policy "EDITABLE_MODERATED" %} <br/> <div class="label-list"> <b>{% trans "Tags" %}</b><br/> @@ -1521,6 +1547,7 @@ ul#navigation li a.last { {% endif %} </ul> </div> + {% endifnotequal %} {% if user.is_authenticated %} {% switch_group_conditions request.user group_id as switch_conditions %} @@ -1529,10 +1556,10 @@ ul#navigation li a.last { {% endif %} {% if not is_group %} - <div class="row"> - <div class="small-12 columns"> - <a id="switch_group" class="tiny button" data-reveal-id="publish_resource"> + <!-- if resource is already under moderation, dont show publish to other button --> + {% if node.status != "MODERATION" %} + <a id="switch_group" class="tiny button expand" data-reveal-id="publish_resource"> <span>{% trans "Publish this resource in other group/s" %} </span> </a> <div id="publish_resource" class="reveal-modal" data-reveal style="position:absolute;"> @@ -1548,11 +1575,10 @@ ul#navigation li a.last { <a class="close-reveal-modal">×</a> </div> + {% endif %} - </div> - </div> {% endif %} - {% endif %} + {% endif %} </div> </ul> diff --git a/gnowsys-ndf/gnowsys_ndf/ndf/templates/ndf/node_edit_base.html b/gnowsys-ndf/gnowsys_ndf/ndf/templates/ndf/node_edit_base.html index dfb34b78..64b3cdb1 100644 --- a/gnowsys-ndf/gnowsys_ndf/ndf/templates/ndf/node_edit_base.html +++ b/gnowsys-ndf/gnowsys_ndf/ndf/templates/ndf/node_edit_base.html @@ -73,7 +73,7 @@ i.remove-tag{ {% endif %} </span></h3> - <input tabindex="1" id="name_id" name="name" type="text" value="{{node.name}}" placeholder="Give the {{title}} a name.." required> + <input tabindex="1" id="name_id" name="name" type="text" value="{{node.name}}" placeholder="Give the {{title}} a name.." {% if node.group_type %}disabled=disabled{% endif %} required> <label id="message" style="display:none; color:red"></label> <small class="error">{% trans "Please give your page a descriptive name. It's helpful for others and for yourself." %}</small> diff --git a/gnowsys-ndf/gnowsys_ndf/ndf/templates/ndf/theme.html b/gnowsys-ndf/gnowsys_ndf/ndf/templates/ndf/theme.html index dac786a9..280f231c 100644 --- a/gnowsys-ndf/gnowsys_ndf/ndf/templates/ndf/theme.html +++ b/gnowsys-ndf/gnowsys_ndf/ndf/templates/ndf/theme.html @@ -472,7 +472,7 @@ <hr/> {% if node %} - {% cache 300 theme_tree node.name request.LANGUAGE_CODE %} + {% cache 300 theme_tree node.pk request.LANGUAGE_CODE %} <!-- If "Theme" node --> <div id="app-set-item" class="themes" data-url="{% url 'get_tree_hierarchy' groupid node.pk %}"></div> diff --git a/gnowsys-ndf/gnowsys_ndf/ndf/templates/ndf/under_moderation.html b/gnowsys-ndf/gnowsys_ndf/ndf/templates/ndf/under_moderation.html new file mode 100644 index 00000000..f5007d13 --- /dev/null +++ b/gnowsys-ndf/gnowsys_ndf/ndf/templates/ndf/under_moderation.html @@ -0,0 +1,151 @@ +{% extends "ndf/base.html" %} +{% load i18n %} +{% load ndf_tags %} +{% get_group_name groupid as group_name_tag %} + +{% block style %} + {{block.super}} + .current-group{ + color: green; + } +{% endblock %} + +{% block title %} {{title}} {% endblock %} + +{% block body_content %} + + {% if request.user.id == node.created_by or user.is_superuser %} + + {% if is_under_moderation %} + <h3> Hello {{request.user.username}},</h3> + <h4> "{{node.name}}" resource is successfully uploaded!</h4> + <h4><small> + As resource has been uploaded in the Moderated group, it will undergo moderation process and then published to "{{top_group_name}}". We will intimate you as on when resource gets published to this group. + Till that time resource is accesible to your user group. + </small></h4> + <br/> + + {% group_type_info group_id request.user as grouptype %} + <div class="row"> + <div class="small-6 columns"> + + <ul class="small-block-grid-1 medium-block-grid-1 large-block-grid-2"> + + <li class="card"></li> + <li class="card"> + {% if grouptype == "Moderated" %} + {% if node.status == "DRAFT" %} + <div class="draft"> + {% elif node.status == "PUBLISHED" %} + <div class="published"> + {% endif %} + {% else %} + <div class='{% if node.status == "PUBLISHED" %}published{% endif %}'> + {% endif %} + + <a href="{% url 'file_detail' request.user.username node %}"> + + <div class="row"> + <div class="small-8 column"> + <b> + {{ node.name }} {% if node.collection_set %} <i class="fi-page-multiple"></i> {% endif %} + </b> + </div> + <div class="small-4 column"> + {% if "image" in node.mime_type %} + <img src="{% url 'getFileThumbnail' group_id node.pk %}" alt="No thumbnail available!" /> + {% elif "audio" in node.mime_type %} + <span class="fi-music" style="font-size:40px"></span> + {% elif "Pandora_video" in node.member_of_names_list and "video" in node.mime_type %} + {% get_source_id node.pk as source_id %} + <img src="http://wetube.gnowledge.org/{{source_id}}/icon128.jpg"/> + {% elif "video" in node.mime_type and node.member_of_names_list|join:', ' != "Pandora_video" %} + {% get_source_id node.pk as source_id %} + {% if source_id %} + <img src="http://wetube.gnowledge.org/{{source_id}}/icon128.jpg"/> + {% endif %} + <img src="{% url 'getFileThumbnail' group_id node.pk %}" alt="No thumbnail available!"/> + {% comment %} + <!-- + <video width="100px" src="{% url 'getFileThumbnail' group_id node.pk %}"> + No thumbnail available! + </video> + --> + {% endcomment %} + {% else %} + <span class="fi-page-filled" style="font-size:40px"></span> + {% endif %} + </div> + </div> + <hr/> + <span style="font-size:12px;">{{ node.html_content|default_if_none:"Add some description."|safe|striptags|truncatechars:75 }}</span></br> + + <footer> + <div class="small-6 columns">{{node.mime_type|truncatechars:15}}</div> + <div class="small-6 columns"><div class="right"><strong>{{node.file_size.size}}</strong> {{node.file_size.unit}}</div></div> + </footer> + <footer> + <div class="age"> + {{ node.member_of_names_list|join:', ' }} created {{node.created_at|timesince}} ago + <br/> + <span><strong>{{node.contributors|length}}</strong> Contributor{{node.contributors|pluralize}} | </span> + by <span class="user" href="{% url 'dashboard' node.created_by %}" data-gnow="">{{node.user_details_dict.created_by}}</span> + </div> + </footer> + </a> + + <div class="label-list small-12 columns"> + {% for tag in node.tags|slice:":3" %} + <a href="{% url 'tag_info' group_name_tag tag %}"> + <span class="label" style="background-color:yellow">{{tag}}</span> + </a>{% endfor %} + </div> + + + </div> + </li> + <!-- end new --> + </ul> + </div> + + <div class="small-6 columns"> + + <b>Resource will pass moderated through following moderation levels:</b> + <br/> + <br/> + <ol> + {% for each_group in group_hierarchy_obj_list %} + {% if not forloop.first %} + <li {% if each_group.pk == current_mod_group_obj.pk %} class="current-group" {% endif %} > + "{{each_group.altnames}}"</li> + {% endif %} + {% endfor %} + </ol> + <hr/> + Currently, resource is in "{{current_mod_group_obj.altnames}}". + </div> + + </div> + + {% else %} + + <h3> Hello {{request.user.username}}, "{{node.name}}" resource is successfully moderated!</h3> + <h4><small> + Resource has undergone moderation process and then published to "{{top_group_name}}". + </small></h4> + + {% endif %} <!-- is_under_moderation bool check --> + + {% else %} + + <h3> Hello {{request.user.username}}, </h3> + <br/> + <h4><small> + "{{node.name}}" resource is successfully moderated! + <br/> + Resource has undergone moderation process and then published to "{{top_group_name}}". + </small></h4> + + {% endif %} <!-- is creator/superuser check --> + +{% endblock%}
\ No newline at end of file diff --git a/gnowsys-ndf/gnowsys_ndf/ndf/templatetags/ndf_tags.py b/gnowsys-ndf/gnowsys_ndf/ndf/templatetags/ndf_tags.py index dd5ee6b8..122ec242 100644 --- a/gnowsys-ndf/gnowsys_ndf/ndf/templatetags/ndf_tags.py +++ b/gnowsys-ndf/gnowsys_ndf/ndf/templatetags/ndf_tags.py @@ -2216,7 +2216,8 @@ def str_to_dict(str1): for k1, v1 in each.items(): for rel in v1: rel = node_collection.one({'_id':ObjectId(rel)}) - att_dic[k1] = rel.name + if rel: + att_dic[k1] = rel.name dict_format[k] = att_dic if k in keys_by_filesize: diff --git a/gnowsys-ndf/gnowsys_ndf/ndf/urls/__init__.py b/gnowsys-ndf/gnowsys_ndf/ndf/urls/__init__.py index c8867cb4..0fad1de1 100644 --- a/gnowsys-ndf/gnowsys_ndf/ndf/urls/__init__.py +++ b/gnowsys-ndf/gnowsys_ndf/ndf/urls/__init__.py @@ -66,6 +66,7 @@ urlpatterns = patterns('', (r'^(?P<group_id>[^/]+)/data-review', include('gnowsys_ndf.ndf.urls.data_review')), (r'^(?P<group_id>[^/]+)/observation', include('gnowsys_ndf.ndf.urls.observation')), (r'^(?P<group_id>[^/]+)/compare', include('gnowsys_ndf.ndf.urls.version')), + (r'^(?P<group_id>[^/]+)/moderation', include('gnowsys_ndf.ndf.urls.moderation')), url(r'^(?P<group_id>[^/]+)/topic_details/(?P<app_Id>[\w-]+)', 'gnowsys_ndf.ndf.views.topics.topic_detail_view', name='topic_details'), diff --git a/gnowsys-ndf/gnowsys_ndf/ndf/urls/moderation.py b/gnowsys-ndf/gnowsys_ndf/ndf/urls/moderation.py new file mode 100644 index 00000000..927b0ee2 --- /dev/null +++ b/gnowsys-ndf/gnowsys_ndf/ndf/urls/moderation.py @@ -0,0 +1,28 @@ +from django.conf.urls import patterns, url + +from django.views.generic import TemplateView + +urlpatterns = patterns('gnowsys_ndf.ndf.views.moderation', + + # simple moderation having data-review view with/without page no. + url(r'^[/]$', 'moderation', name='moderation'), + + # showing the status of all objects under moderation + url(r'^/status/all-under-moderation/$', 'all_under_moderation', name='all_under_moderation'), + + # showing the status of under moderation object + url(r'^/status/(?P<node_id>[\w-]+)$', 'moderation_status', name='moderation_status'), + + # dr: data_review + url(r'^/page-no=(?P<page_no>\d+)/$', 'moderation', name='moderation_dr_page'), + + # to publish resource to next/parent(if last group) moderated group + url(r'^/approve/$', 'approve_resource', name='approve_resource'), + + # # to save edited data-review row + # url(r'^/save/$', 'data_review_save', name='data_review_save'), + + # # to render search result with and without page no. + # url(r'^/search$', 'get_dr_search_result_dict', name="data_review_search"), + # url(r'^/search/search_text=(?P<search_text>[^/]+)/page-no=(?P<page_no>\d+)/$', 'get_dr_search_result_dict', name="data_review_search_page"), + )
\ No newline at end of file diff --git a/gnowsys-ndf/gnowsys_ndf/ndf/views/data_review.py b/gnowsys-ndf/gnowsys_ndf/ndf/views/data_review.py index b37ff02e..07e9039c 100644 --- a/gnowsys-ndf/gnowsys_ndf/ndf/views/data_review.py +++ b/gnowsys-ndf/gnowsys_ndf/ndf/views/data_review.py @@ -52,34 +52,26 @@ page_id = node_collection.find_one({'_type': "GSystemType", "name": "Page"}, {"_ # data review in File app @login_required @get_execution_time -def data_review(request, group_id, page_no=1): +def data_review(request, group_id, page_no=1, **kwargs): ''' To get all the information related to every resource object in the group. - ''' - # getting group obj from name - - # group_obj = node_collection.one({"_type": {"$in": ["Group", "Author"]}, "name": unicode(group_id)}) - - # # checking if passed group_id is group name or group Id - # if group_obj and (group_id == group_obj.name): - # # group_name = group_id - # group_id = group_obj._id - - # else: # passes group_id is _id and not name - # ins_objectid = ObjectId() - # if ins_objectid.is_valid(group_id): - # # retrieve Obj by _id - # group_obj = node_collection.one({"_id": ObjectId(group_id)}) - # if group_obj: - # # group_name = group_obj.name - # group_id = group_id # for clarity - - group_name, group_id = get_group_name_id(group_id) + To get processed context_variables into another variable, + pass <get_paged_resources=True> as last arg. + + e.g: + context_variables = data_review(request, group_id, page_no, get_paged_resources=True) + ''' + + try: + group_id = ObjectId(group_id) + except: + group_name, group_id = get_group_name_id(group_id) + files_obj = node_collection.find({'$or': [ {'member_of': {'$in': [ObjectId(file_id._id), ObjectId(page_id._id)]}, # '_type': 'File', 'fs_file_ids': {'$ne': []}, - 'group_set': {'$all': [ObjectId(group_id)]}, + 'group_set': {'$in': [ObjectId(group_id)]}, '$or': [ {'access_policy': u"PUBLIC"}, {'$and': [ @@ -99,17 +91,17 @@ def data_review(request, group_id, page_no=1): files_list = [] for each_resource in paged_resources.items: - each_resource, ver = get_page(request, each_resource) + # each_resource, ver = get_page(request, each_resource) each_resource.get_neighbourhood(each_resource.member_of) files_list.append(node_collection.collection.GSystem(each_resource)) + # print "==============", each_resource.name, " : ", each_resource.group_set # print "\n\n\n========", each_resource.keys() # for each, val in each_resource.iteritems(): # print each, "--", val,"\n" files_obj.close() - return render_to_response("ndf/data_review.html", - { + context_variables = { "group_id": group_id, "groupid": group_id, "files": files_list, "page_info": paged_resources, "urlname": "data_review_page", "second_arg": "", @@ -124,7 +116,16 @@ def data_review(request, group_id, page_no=1): "static_audience": GSTUDIO_RESOURCES_AUDIENCE, "static_status": list(STATUS_CHOICES), "static_textcomplexity": GSTUDIO_RESOURCES_TEXT_COMPLEXITY - }, + } + + if kwargs.get('get_paged_resources', False): + return context_variables + + template_name = "ndf/data_review.html" + + return render_to_response( + template_name, + context_variables, context_instance=RequestContext(request) ) # ---END of data review in File app @@ -132,8 +133,11 @@ def data_review(request, group_id, page_no=1): @get_execution_time def get_dr_search_result_dict(request, group_id, search_text=None, page_no=1): - group_name, group_id = get_group_name_id(group_id) - + try: + group_id = ObjectId(group_id) + except: + group_name, group_id = get_group_name_id(group_id) + # check if request is from form or from next page if request.GET.has_key("search_text"): search_text = request.GET.get("search_text", "") @@ -194,7 +198,11 @@ def data_review_save(request, group_id): userid = request.user.pk - group_name, group_id = get_group_name_id(group_id) + try: + group_id = ObjectId(group_id) + except: + group_name, group_id = get_group_name_id(group_id) + group_obj = node_collection.one({"_id": ObjectId(group_id)}) node_oid = request.POST.get("node_oid", "") diff --git a/gnowsys-ndf/gnowsys_ndf/ndf/views/file.py b/gnowsys-ndf/gnowsys_ndf/ndf/views/file.py index 46643da8..90881204 100644 --- a/gnowsys-ndf/gnowsys_ndf/ndf/views/file.py +++ b/gnowsys-ndf/gnowsys_ndf/ndf/views/file.py @@ -1,4 +1,3 @@ - ''' -- Imports from python libraries -- ''' import json import hashlib @@ -45,6 +44,7 @@ from gnowsys_ndf.ndf.models import node_collection, triple_collection, gridfs_co from gnowsys_ndf.ndf.org2any import org2html from gnowsys_ndf.ndf.views.methods import get_node_metadata, get_node_common_fields, set_all_urls # , get_page from gnowsys_ndf.ndf.views.methods import create_gattribute +from gnowsys_ndf.ndf.views.moderation import create_moderator_task, get_moderator_group_set ############################################ @@ -671,19 +671,24 @@ def submitDoc(request, group_id): """ submit files for saving into gridfs and creating object """ - ins_objectid = ObjectId() - if ins_objectid.is_valid(group_id) is False : - group_ins = node_collection.find_one({'_type': "Group","name": group_id}) - auth = node_collection.one({'_type': 'Author', 'name': unicode(request.user.username) }) - if group_ins: - group_id = str(group_ins._id) - else : - auth = node_collection.one({'_type': 'Author', 'name': unicode(request.user.username) }) - if auth : - group_id = str(auth._id) - else : - # print group_id - pass + # ins_objectid = ObjectId() + # if ins_objectid.is_valid(group_id) is False : + # group_ins = node_collection.find_one({'_type': "Group","name": group_id}) + # auth = node_collection.one({'_type': 'Author', 'name': unicode(request.user.username) }) + # if group_ins: + # group_id = str(group_ins._id) + # else : + # auth = node_collection.one({'_type': 'Author', 'name': unicode(request.user.username) }) + # if auth : + # group_id = str(auth._id) + # else : + # # print group_id + # pass + + try: + group_id = ObjectId(group_id) + except: + group_name, group_id = get_group_name_id(group_id) alreadyUploadedFiles = [] str1 = '' @@ -716,30 +721,46 @@ def submitDoc(request, group_id): i = i + 1 else: title = each.name - f = save_file(each,title,userid,group_id, content_org, tags, img_type, language, usrname, access_policy, oid=True) - if not obj_id_instance.is_valid(f): + f, is_video = save_file(each,title,userid,group_id, content_org, tags, img_type, language, usrname, access_policy) + # print "f: ", f + # if not obj_id_instance.is_valid(f): + # check if file is already uploaded file + if isinstance(f, list): alreadyUploadedFiles.append(f) title = mtitle # str1 = alreadyUploadedFiles if img_type != "": + # print "----------1-----------" return HttpResponseRedirect(reverse('dashboard', kwargs={'group_id': int(userid)})) elif topic_file != "": + # print "----------2-----------" return HttpResponseRedirect(reverse('add_file', kwargs={'group_id': group_id })) else: if alreadyUploadedFiles: # return HttpResponseRedirect(page_url+'?var='+str1) # if (type(alreadyUploadedFiles[0][0]).__name__ == "ObjectId"): - return HttpResponseRedirect(reverse("file_detail", kwargs={'group_id': group_id, "_id": alreadyUploadedFiles[0][0].__str__() })) + # print "----------3-----------", alreadyUploadedFiles[0][1] + return HttpResponseRedirect(reverse("file_detail", kwargs={'group_id': group_id, "_id": alreadyUploadedFiles[0][1].__str__() })) # else: # if alreadyUploadedFiles[0][1]: # return HttpResponseRedirect(reverse("file_detail", kwargs={'group_id': group_id, "_id": alreadyUploadedFiles[0][0].__str__() })) else: - return HttpResponseRedirect(reverse('file', kwargs={'group_id': group_id })) + group_object = node_collection.one({'_id': ObjectId(group_id)}) + + if group_object.edit_policy == 'EDITABLE_MODERATED' and isinstance(f, ObjectId): + # print "----------4-----------" + fileobj = node_collection.one({'_id': ObjectId(f)}) + # newly appended group id in group_set is at last + create_moderator_task(request, fileobj.group_set[len(fileobj.group_set)-1], fileobj._id) + return HttpResponseRedirect(reverse('moderation_status', kwargs={'group_id': group_id, 'node_id': f })) + else: + # print "----------5-----------" + return HttpResponseRedirect(reverse('file', kwargs={'group_id': group_id })) # if is_video == "True": # return HttpResponseRedirect(page_url+'?'+'is_video='+is_video) @@ -747,6 +768,7 @@ def submitDoc(request, group_id): # return HttpResponseRedirect(page_url) else: + # print "----------6-----------" return HttpResponseRedirect(reverse('homepage',kwargs={'group_id': group_id, 'groupid':group_id})) @@ -787,7 +809,8 @@ def save_file(files,title, userid, group_id, content_org, tags, img_type = None, # e.g : {u'docid': ObjectId('539a999275daa21eb7c048af')} return cur_oid["docid"], 'True' else: - return [files.name, new_name.name], 'True' + # print "already Uploaded file" + return [files.name, new_name._id], 'True' else: try: @@ -816,7 +839,14 @@ def save_file(files,title, userid, group_id, content_org, tags, img_type = None, group_object = node_collection.one({'_id': ObjectId(group_id)}) if group_object._id not in fileobj.group_set: - fileobj.group_set.append(group_object._id) # group id stored in group_set field + # group id stored in group_set field + fileobj.group_set.append(group_object._id) + + # if group is of EDITABLE_MODERATED, update group_set accordingly + if group_object.edit_policy == "EDITABLE_MODERATED": + fileobj.group_set = get_moderator_group_set(fileobj.group_set, group_object._id) + fileobj.status = u'MODERATION' + if usrname: user_group_object = node_collection.one({'$and': [{'_type': u'Author'},{'name': usrname}]}) if user_group_object: @@ -916,6 +946,7 @@ def save_file(files,title, userid, group_id, content_org, tags, img_type = None, mid_img_id = fileobj.fs.files.put(mid_size_img, filename=filename+"-mid_size_img", content_type=filetype) node_collection.find_and_modify({'_id': fileobj._id}, {'$push': {'fs_file_ids':mid_img_id}}) count = count + 1 + # print "----- fileobj._id", fileobj._id return fileobj._id, is_video except Exception as e: print "Some Exception:", files.name, "Execption:", e diff --git a/gnowsys-ndf/gnowsys_ndf/ndf/views/group.py b/gnowsys-ndf/gnowsys_ndf/ndf/views/group.py index 5bc917b0..1bcdd915 100644 --- a/gnowsys-ndf/gnowsys_ndf/ndf/views/group.py +++ b/gnowsys-ndf/gnowsys_ndf/ndf/views/group.py @@ -11,6 +11,7 @@ from django.template import RequestContext # from django.template.defaultfilters import slugify from django.contrib.auth.decorators import login_required from django.contrib.auth.models import User +from django.views.generic import View try: from bson import ObjectId @@ -28,20 +29,589 @@ from gnowsys_ndf.ndf.views.methods import * # ###################################################################################################################################### -gst_group = node_collection.one({"_type": "GSystemType", 'name': "Group"}) +gst_group = node_collection.one({"_type": "GSystemType", 'name': u"Group"}) app = gst_group # ###################################################################################################################################### # V I E W S D E F I N E D F O R G A P P -- ' G R O U P ' # ###################################################################################################################################### +class CreateGroup(object): + """ + Creates group. + Instantiate group with request as argument + """ + def __init__(self, request): + super(CreateGroup, self).__init__() + self.request = request + + + def is_group_exists(self, arg_group_name): + ''' + checks if group with the given name exists. + Returns True: If group exists. + ''' + name = arg_group_name + group = node_collection.find_one({ + '_type': 'Group', + 'name': unicode(name) + }) + if group: + return True + else: + return False + + + def get_group_fields(self, group_name, **kwargs): + ''' + function to fill the empty group object with values supplied. + group information may be sent either from "request" or from "kwargs". + + # If arg is kwargs, provide following dict as kwargs arg to this function. + group_fields = { + 'group_altnames': '', 'group_type': '', 'edit_policy': '', + 'agency_type': '', 'moderation_level': '' + } + # call in following way + class_instance_var.get_group_fields(group_name, **group_fields) + ''' + + # getting the data into variables + name = group_name + + if kwargs.get('group_altnames', ''): + altnames = kwargs.get('group_altnames', name) + else: + altnames = self.request.POST.get('alt_groupname', "").strip() + + if kwargs.get('group_type', ''): + group_type = kwargs.get('group_type', '') + else: + group_type = self.request.POST.get('group_type', '') + + if kwargs.get('access_policy', ''): + access_policy = kwargs.get('access_policy', group_type) + else: + access_policy = self.request.POST.get('access_policy', group_type) + + if kwargs.get('edit_policy', ''): + edit_policy = kwargs.get('edit_policy', '') + else: + edit_policy = self.request.POST.get('edit_policy', '') + + if kwargs.get('subscription_policy', ''): + subscription_policy = kwargs.get('subscription_policy', 'OPEN') + else: + subscription_policy = self.request.POST.get('subscription_policy', "OPEN") + + if kwargs.get('visibility_policy', ''): + visibility_policy = kwargs.get('visibility_policy', 'ANNOUNCED') + else: + visibility_policy = self.request.POST.get('visibility_policy', 'ANNOUNCED') + + if kwargs.get('disclosure_policy', ''): + disclosure_policy = kwargs.get('disclosure_policy', 'DISCLOSED_TO_MEM') + else: + disclosure_policy = self.request.POST.get('disclosure_policy', 'DISCLOSED_TO_MEM') + + if kwargs.get('encryption_policy', ''): + encryption_policy = kwargs.get('encryption_policy', 'NOT_ENCRYPTED') + else: + encryption_policy = self.request.POST.get('encryption_policy', 'NOT_ENCRYPTED') + + if kwargs.get('agency_type', ''): + agency_type = kwargs.get('agency_type', 'Other') + else: + agency_type = self.request.POST.get('agency_type', 'Other') + + # whenever we are passing int: 0, condition gets false + # therefor casting to str + if str(kwargs.get('moderation_level', '')): + moderation_level = kwargs.get('moderation_level', '-1') + else: + moderation_level = self.request.POST.get('moderation_level', '-1') + + # instantiated empty group object + group_obj = node_collection.collection.Group() + + # filling the values with variables in empty group object + group_obj.name = unicode(name) + group_obj.altnames = unicode(altnames) + group_obj.member_of.append(gst_group._id) + group_obj.type_of.append(gst_group._id) + + user_id = int(self.request.user.id) + group_obj.created_by = user_id + group_obj.modified_by = user_id + if user_id not in group_obj.author_set: + group_obj.author_set.append(user_id) + if user_id not in group_obj.contributors: + group_obj.contributors.append(user_id) + if user_id not in group_obj.group_admin: + group_obj.group_admin.append(user_id) + + group_obj.group_type = group_type + group_obj.access_policy = access_policy + group_obj.edit_policy = edit_policy + group_obj.subscription_policy = subscription_policy + group_obj.visibility_policy = visibility_policy + group_obj.disclosure_policy = disclosure_policy + group_obj.encryption_policy = encryption_policy + group_obj.agency_type = agency_type + + # decision for adding moderation_level + if group_obj.edit_policy == "EDITABLE_MODERATED": + group_obj.moderation_level = int(moderation_level) + else: + group_obj.moderation_level = -1 + + group_obj.status == u"PUBLISHED" + + # returning basic fields filled group object + return group_obj + + # --- END --- get_group_fields() ------ + + + def create_group(self, group_name, **kwargs): + ''' + Creates group with given args. + Returns tuple containing True/False, sub_group_object/error. + ''' + + # checking if group exists with same name + if not self.is_group_exists(group_name): + + group_obj = self.get_group_fields(group_name, **kwargs) + + try: + group_obj.save() + except Exception, e: + return False, e + + # group created successfully + return True, group_obj + + else: + return False, 'Group with same name exists.' + + # --- END --- create_group() ------ + + + def get_group_edit_policy(self, group_id): + ''' + Returns "edit_policy" of the group. + ''' + group_obj = node_collection.one({'_id': ObjectId(group_id)}) + if group_obj: + return group_obj.edit_policy + else: + return False + # --- END --- get_group_edit_policy() ------ + + def get_group_type(self, group_id): + ''' + Returns "group_type" of the group. + ''' + group_obj = node_collection.one({'_id': ObjectId(group_id)}) + if group_obj: + return group_obj.group_type + else: + return False + # --- END --- get_group_type() ------ + + def get_all_subgroups_obj_list(self, group_id): + ''' + Returns mongokit (find) cursor of sub-group documents. + ''' + group_obj = node_collection.one({'_id': ObjectId(group_id)}) + + # check if group has post_node. Means it has sub-group/s + if group_obj and group_obj.post_node: + return node_collection.find({'_id': {'$in': group_obj.post_node} }) + else: + return False + # --- END --- get_all_subgroups_obj_list() ------ + + def get_all_subgroups_member_of_list(self, group_id): + ''' + Returns list of names of "member_of" of sub-groups. + ''' + sg_member_of_list = [] + all_sg = self.get_all_subgroups_obj_list(group_id) + + if all_sg: + # getting parent's sub group's member_of in a list + for each_sg in all_sg: + sg_member_of_list += each_sg.member_of_names_list + + return sg_member_of_list + # --- END --- get_all_subgroups_member_of_list() ------ + +# --- END of class CreateGroup --- +# -------------------------------- + + +class CreateSubGroup(CreateGroup): + """ + Create sub-group of any type + (e.g: Moderated, Normal, programe_event, course_event) + Instantiate group with request as argument + """ + def __init__(self, request): + super(CreateSubGroup, self).__init__(request) + self.request = request + + + def get_subgroup_fields(self, parent_group_id, sub_group_name, sg_member_of, **kwargs): + ''' + Get empty group object filled with values supplied in arguments. + "parent_group_id" and "sub_group_id" and "sg_member_of" are compulsory args. + ''' + + # get basic fields filled group object + group_obj = self.get_group_fields(sub_group_name, **kwargs) + + if sg_member_of in ['ProgramEventGroup', 'CourseEventGroup', 'PartnerGroup', 'ModeratingGroup']: + + # overriding member_of field of subgroup + member_of_group = node_collection.one({'_type': u'GSystemType', 'name': unicode(sg_member_of)}) + group_obj.member_of = [ObjectId(member_of_group._id)] + + # for subgroup's of this types, group_type must be PRIVATE and EDITABLE_MODERATED + group_obj.group_type = 'PRIVATE' + group_obj.access_policy = u'PRIVATE' + group_obj.edit_policy = 'EDITABLE_MODERATED' + + else: # for normal sub-groups + if not group_obj.group_type: + group_obj.group_type = self.get_group_type(parent_group_id) + + if not group_obj.edit_policy: + group_obj.edit_policy = self.get_group_edit_policy(parent_group_id) + + # check if group object's prior_node has _id of parent group, otherwise add one. + if ObjectId(parent_group_id) not in group_obj.prior_node: + group_obj.prior_node.append(ObjectId(parent_group_id)) + + return group_obj + + + def create_subgroup(self, parent_group_id, sub_group_name, sg_member_of, **kwargs): + ''' + Creates sub-group with given args. + Returns tuple containing True/False, sub_group_object/error. + ''' + # print "kwargs : ", kwargs + + try: + parent_group_id = ObjectId(parent_group_id) + + except: + parent_group_name, parent_group_id = get_group_name_id(group_id) + # except: # it's parent group's name (str). so dereference to get "_id" + # parent_group_obj = node_collection.one({"_type": {"$in": ["Group", "Author"] }, "name": unicode(parent_group_id)}) + # # checking if group_obj is valid + # if parent_group_obj: + # parent_group_id = parent_group_obj._id + + # checking feasible conditions to add this sub-group + if not self.check_subgroup_feasibility(parent_group_id, sg_member_of): + return False, "It's not feasible to make sub-group with given values" + + if not self.is_group_exists(sub_group_name): + + # getting sub-group object filled with basic fields of (group + subgroup) levels + group_obj = self.get_subgroup_fields(parent_group_id, sub_group_name, sg_member_of, **kwargs) + + try: + group_obj.save() + except Exception, e: + # if any errors return tuple with False and error + return False, e + + # after sub-group get created/saved successfully: + self.add_subgroup_to_parents_postnode(parent_group_id, group_obj._id, sg_member_of) + + return True, group_obj + + else: + return False, 'Group with same name exists.' + + + def check_subgroup_feasibility(self, parent_group_id, sg_member_of): + ''' + method to check feasibility of adding sub group to parent group + according to their following properties: + - parent group's edit_policy + - child group's member_of + Returns True if it is OK to create sub-group with suplied fields. + ''' + if sg_member_of == 'Group': + return True + + elif sg_member_of in ['ProgramEventGroup', 'CourseEventGroup', 'PartnerGroup', 'ModeratingGroup']: + if self.get_group_edit_policy(parent_group_id) == 'EDITABLE_MODERATED': + + # if current sub-groups member_of is in parent's any one of the sub-group, + # means sub-group with current property exists in/for parent group. + # And no sibling with these property can exists together (like normal sub-groups). + + if sg_member_of in self.get_all_subgroups_member_of_list(parent_group_id): + return False + else: + return True + else: + return False + + + def add_subgroup_to_parents_postnode(self, parent_group_id, sub_group_id, sg_member_of): + ''' + Adding sub-group's _id in post_node of parent_group. + ''' + + # fetching parent group obj + parent_group_object = node_collection.one({'_id': ObjectId(parent_group_id)}) + + # adding sub group's id in post node of parent node + if ObjectId(sub_group_id) not in parent_group_object.post_node: + parent_group_object.post_node.append(ObjectId(sub_group_id)) + + # adding normal sub-group to collection_set of parent group: + if sg_member_of == 'Group': + parent_group_object.collection_set.append(ObjectId(sub_group_id)) + + parent_group_object.save() + return True + + # sub-groups "_id" already exists in parent_group. + return False + + + def get_particular_member_of_subgroup(self, group_id, member_of): + ''' + Returns sub-group having particular member_of. + Else return False + ''' + member_of = node_collection.one({'_type': 'GSystemType', 'name': unicode(member_of)}) + + group_obj = node_collection.one({ + '_type': 'Group', + 'prior_node': {'$in': [ObjectId(group_id)]}, + 'member_of': member_of._id + }) + + if group_obj: + return group_obj + else: + return False + +# --- END of class CreateSubGroup --- +# -------------------------------- + + +class CreateModeratedGroup(CreateSubGroup): + """ + Creates moderated sub-groups. + Instantiate with request. + """ + def __init__(self, request): + super(CreateSubGroup, self).__init__(request) + self.request = request + self.edit_policy = 'EDITABLE_MODERATED' + self.altnames = { + 'ModeratingGroup': [u'Clearing House', u'Curation House'], + 'ProgramEventGroup': [], + 'CourseEventGroup': [] + } + + def create_new_moderated_group(self, group_name, moderation_level=1, **kwargs): + ''' + Creates top level group with given args. + Returns tuple containing True/False, sub_group_object/error. + ''' + + if not self.is_group_exists(group_name): + # values will be taken from POST form fields + group_obj = self.get_group_fields(group_name) + + try: + group_obj.save() + except Exception, e: + # if any errors return tuple with False and error + print e + return False, e + + # self.add_subgroup_to_parents_postnode(parent_group_id, group_obj._id, sg_member_of) + parent_group_id = group_obj._id + for each_sg_iter in range(0, int(moderation_level)): + result = self.add_moderation_level(parent_group_id, 'ModeratingGroup') + # result is tuple of (bool, newly-created-sub-group-obj) + if result[0]: + parent_group_id = result[1]._id + else: + # if result is False, means sub-group is not created. + # In this case, there is no point to go ahead and create subsequent sub-group. + break + + return True, group_obj + + else: + return False, 'Group with same name exists.' + + + def add_moderation_level(self, parent_group_id, sg_member_of, increment_mod_level=False): + ''' + Adds the moderation sub group to parent group. + - expects "_id/name" of parent and sub_group's "member_of". + - increment_mod_level: If you want to add next moderation subgroup, despite of + moderation_level is 0. + In this case, if value is True, + moderation_level of all top hierarchy groups will be updated by 1. + ''' + parent_group_object = get_group_name_id(parent_group_id, get_obj=True) + + # pg: parent group + pg_name = parent_group_object.name + pg_moderation_level = parent_group_object.moderation_level + + sg_name = pg_name + unicode('_mod') + + # no need to check following here, because it's being checked at sub-group creation time. + # but keep this following code for future perspective. + # + # if self.is_group_exists(sg_name): + # # checking for group with name exists + # return False, 'Group with name: ' + sg_name + ' exists.' + + # elif not self.check_subgroup_feasibility(sg_member_of): + # # checking if any of the sub-group has same member_of field. + # return False, 'Sub-Group with type of group' + sg_member_of + ' exists.' + + if (pg_moderation_level == 0) and not increment_mod_level: + # if parent_group's moderation_level is reached to leaf; means to 0. Then return False + + return False, 'Parent group moderation level is: ' + pg_moderation_level \ + + '. So, further moderation group cannot be created!' + + elif (pg_moderation_level > 0) or increment_mod_level: + # valid condition to create a sub group + + if (pg_moderation_level == 0) and increment_mod_level: + # needs to increase moderation_level of all group hierarchy + self.increment_hierarchy_mod_level(parent_group_id) + pg_moderation_level += 1 + + try: + sg_altnames = self.altnames[sg_member_of][pg_moderation_level-1] \ + + u" of " + pg_name + except Exception, e: + sg_altnames = sg_name + + # create new sub-group and append it to parent group: + sub_group = self.create_subgroup(parent_group_id, sg_name, \ + sg_member_of, moderation_level=(pg_moderation_level-1), \ + group_altnames=sg_altnames) + + return sub_group + + + def increment_hierarchy_mod_level(self, group_id): + ''' + Raises moderation_level by one of all the groups in the hierarchy. + ''' + + try: + group_id = ObjectId(group_id) + + except: + group_name, group_id = get_group_name_id(group_id) + + result = self.get_all_group_hierarchy(group_id) + + if result[0]: + group_list = result[1] + is_updated = False + + for each_group in group_list: + is_updated = True + # adding +1 to existing moderation_level + each_group.moderation_level += 1 + each_group.save() + + if is_updated: + return True + else: + return False + + # something went wrong to get group list + else: + return False + + + def get_all_group_hierarchy(self, group_id): + ''' + Provide _id of any of the group and get list of all groups. + Order will be from top to bottom. + e.g: [top_gr_obj, sub_gr_obj, sub_sub_gr_obj, ..., ...] + NOTE: this function will return hierarchy of + only groups with edit_policy: 'EDITABLE_MODERATED' + ''' + top_group = self.get_top_group_of_hierarchy(group_id) + + if top_group[0]: + # getting object of top group + top_group = top_group[1] + + else: # fail to get top group + return top_group + + all_sub_group_list = [top_group] + + group_obj = top_group + + while group_obj and group_obj.post_node: + group_obj = self.get_particular_member_of_subgroup(group_obj._id, 'ModeratingGroup') + if group_obj: + all_sub_group_list.append(group_obj) + else: + return False, [top_group] + + return True, all_sub_group_list + + + def get_top_group_of_hierarchy(self, group_id): + ''' + getting top group object of hierarchy. + Returns mongokit object of top group. + ''' + curr_group_obj = node_collection.one({'_id': ObjectId(group_id)}) + + # loop till there is no end of prior_node or till reaching at top group. + while curr_group_obj and curr_group_obj.prior_node: + curr_group_obj = node_collection.one({'_id': curr_group_obj.prior_node[0]}) + + if curr_group_obj.edit_policy != 'EDITABLE_MODERATED': + return False, "One of the group: " + str(curr_group_obj._id) \ + + " is not with edit_policy: EDITABLE_MODERATED." + + # send overwritten/first curr_group_obj's "_id" + return True, curr_group_obj + +# --- END of class CreateModeratedGroup --- +# ----------------------------------------- + + @get_execution_time def group(request, group_id, app_id=None, agency_type=None): """Renders a list of all 'Group-type-GSystems' available within the database. """ - group_name, group_id = get_group_name_id(group_id) + try: + group_id = ObjectId(group_id) + except: + group_name, group_id = get_group_name_id(group_id) query_dict = {} if (app_id == "agency_type") and (agency_type in GSTUDIO_GROUP_AGENCY_TYPES): @@ -173,97 +743,136 @@ def group(request, group_id, app_id=None, agency_type=None): }, context_instance=RequestContext(request)) + @login_required @get_execution_time def create_group(request,group_id): - ins_objectid = ObjectId() - if ins_objectid.is_valid(group_id) is False : - group_ins = node_collection.find_one({'_type': "Group","name": group_id}) - auth = node_collection.one({'_type': 'Author', 'name': unicode(request.user.username) }) - if group_ins: - group_id = str(group_ins._id) - else: - auth = node_collection.one({'_type': 'Author', 'name': unicode(request.user.username) }) - if auth: - group_id = str(auth._id) - else : - pass + + try: + group_id = ObjectId(group_id) + except: + group_name, group_id = get_group_name_id(group_id) + + # a = CreateSubGroup(request, "home", "moderated") + # print "======= ", a.is_group_exists("jhjh") + # print "--------- ", a.create_group(group_name="kjhk") + # print ".... ", a.get_group_edit_policy(group_id) + # print ".... ", a.get_subgroup_fields(group_id, "jhgjhg") + # print ".... ", a.get_group_edit_policy(group_id) + # try: + # print "--------" + # # print a.create_subgroup('home', "a-3", "Group") + # m = CreateModeratedGroup(request, request.POST.get('groupname', "").strip(), request.POST.get('group_type', "")) + # m.create_new_moderated_group(request.POST.get('groupname', "").strip(), moderation_level=2) + # print "--------", m + # except Exception, e: + # pass + if request.method == "POST": - colg = node_collection.collection.Group() - Mod_colg = node_collection.collection.Group() + # colg = node_collection.collection.Group() cname = request.POST.get('groupname', "").strip() - colg.altnames = cname - colg.name = unicode(cname) - colg.member_of.append(gst_group._id) - usrid = int(request.user.id) + edit_policy = request.POST.get('edit_policy', "") + group_type = request.POST.get('group_type', "") + moderation_level = request.POST.get('moderation_level', '1') + + if request.POST.get('edit_policy', "") == "EDITABLE_MODERATED": + + # instantiate moderated group + mod_group = CreateModeratedGroup(request) + + # calling method to create new group + result = mod_group.create_new_moderated_group(cname, moderation_level) + + else: + + # instantiate moderated group + group = CreateGroup(request) + + # calling method to create new group + result = group.create_group(cname) + + if result[0]: + colg = result[1] + + # colg.altnames = cname + # colg.altnames = request.POST.get('alt_groupname', "").strip() + # colg.name = unicode(cname) + # colg.member_of.append(gst_group._id) + # usrid = int(request.user.id) - colg.created_by = usrid - if usrid not in colg.author_set: - colg.author_set.append(usrid) - - colg.modified_by = usrid - if usrid not in colg.contributors: - colg.contributors.append(usrid) - - colg.group_type = request.POST.get('group_type', "") - colg.edit_policy = request.POST.get('edit_policy', "") - colg.subscription_policy = request.POST.get('subscription', "OPEN") - colg.visibility_policy = request.POST.get('existance', 'ANNOUNCED') - colg.disclosure_policy = request.POST.get('member', 'DISCLOSED_TO_MEM') - colg.encryption_policy = request.POST.get('encryption', 'NOT_ENCRYPTED') - colg.agency_type=request.POST.get('agency_type', "") - colg.save() - - if colg.edit_policy == "EDITABLE_MODERATED": - Mod_colg.altnames = cname + "Mod" - Mod_colg.name = cname + "Mod" - Mod_colg.group_type = "PRIVATE" - - Mod_colg.created_by = usrid - if usrid not in Mod_colg.author_set: - Mod_colg.author_set.append(usrid) - - Mod_colg.modified_by = usrid - if usrid not in Mod_colg.contributors: - Mod_colg.contributors.append(usrid) - - Mod_colg.prior_node.append(colg._id) - Mod_colg.save() - - colg.post_node.append(Mod_colg._id) - colg.save() + # colg.created_by = usrid + # if usrid not in colg.author_set: + # colg.author_set.append(usrid) - auth = node_collection.one({'_type': 'Author', 'name': unicode(request.user.username) }) + # colg.modified_by = usrid + # if usrid not in colg.contributors: + # colg.contributors.append(usrid) + + # colg.group_type = request.POST.get('group_type', "") + # colg.edit_policy = request.POST.get('edit_policy', "") + # colg.subscription_policy = request.POST.get('subscription', "OPEN") + # colg.visibility_policy = request.POST.get('existance', 'ANNOUNCED') + # colg.disclosure_policy = request.POST.get('member', 'DISCLOSED_TO_MEM') + # colg.encryption_policy = request.POST.get('encryption', 'NOT_ENCRYPTED') + # colg.agency_type = request.POST.get('agency_type', "") + # if colg.edit_policy == "EDITABLE_MODERATED": + # colg.moderation_level = request.POST.get('moderation_level', '1') + # # colg.save() + + # if colg.edit_policy == "EDITABLE_MODERATED": + # Mod_colg = node_collection.collection.Group() + # Mod_colg.altnames = cname + "_mod" + # Mod_colg.name = cname + "Mod" + # Mod_colg.group_type = "PRIVATE" + + # Mod_colg.created_by = usrid + # if usrid not in Mod_colg.author_set: + # Mod_colg.author_set.append(usrid) - has_shelf_RT = node_collection.one({'_type': 'RelationType', 'name': u'has_shelf' }) + # Mod_colg.modified_by = usrid + # if usrid not in Mod_colg.contributors: + # Mod_colg.contributors.append(usrid) + + # Mod_colg.prior_node.append(colg._id) + # Mod_colg.save() + + # colg.post_node.append(Mod_colg._id) + # # colg.save() + + # auth = node_collection.one({'_type': 'Author', 'name': unicode(request.user.username) }) + + # has_shelf_RT = node_collection.one({'_type': 'RelationType', 'name': u'has_shelf' }) shelves = [] shelf_list = {} - if auth: - shelf = triple_collection.find({'_type': 'GRelation', 'subject': ObjectId(auth._id), 'relation_type.$id': has_shelf_RT._id }) - - if shelf: - for each in shelf: - shelf_name = node_collection.one({'_id': ObjectId(each.right_subject)}) - shelves.append(shelf_name) - - shelf_list[shelf_name.name] = [] - for ID in shelf_name.collection_set: - shelf_item = node_collection.one({'_id': ObjectId(ID) }) - shelf_list[shelf_name.name].append(shelf_item.name) + # if auth: + # shelf = triple_collection.find({'_type': 'GRelation', 'subject': ObjectId(auth._id), 'relation_type.$id': has_shelf_RT._id }) + + # if shelf: + # for each in shelf: + # shelf_name = node_collection.one({'_id': ObjectId(each.right_subject)}) + # shelves.append(shelf_name) + + # shelf_list[shelf_name.name] = [] + # for ID in shelf_name.collection_set: + # shelf_item = node_collection.one({'_id': ObjectId(ID) }) + # shelf_list[shelf_name.name].append(shelf_item.name) - else: - shelves = [] + # else: + # shelves = [] - return render_to_response("ndf/groupdashboard.html", {'groupobj': colg, 'appId': app._id, 'node': colg, 'user': request.user, - 'groupid': colg._id, 'group_id': colg._id, - 'shelf_list': shelf_list,'shelves': shelves - },context_instance=RequestContext(request)) + return render_to_response("ndf/groupdashboard.html", + {'groupobj': colg, 'appId': app._id, 'node': colg, + 'user': request.user, + 'groupid': colg._id, 'group_id': colg._id, + 'shelf_list': shelf_list,'shelves': shelves + },context_instance=RequestContext(request)) + # for rendering empty form page: available_nodes = node_collection.find({'_type': u'Group'}) nodes_list = [] for each in available_nodes: @@ -750,5 +1359,3 @@ def create_sub_group(request,group_id): return render_to_response("ndf/create_sub_group.html", {'groupid':group_id,'maingroup':grpname,'group_id':group_id,'nodes_list': nodes_list},RequestContext(request)) except Exception as e: print "Exception in create subgroup "+str(e) - - diff --git a/gnowsys-ndf/gnowsys_ndf/ndf/views/home.py b/gnowsys-ndf/gnowsys_ndf/ndf/views/home.py index e7d72cbe..906f9bf1 100644 --- a/gnowsys-ndf/gnowsys_ndf/ndf/views/home.py +++ b/gnowsys-ndf/gnowsys_ndf/ndf/views/home.py @@ -95,7 +95,7 @@ def landing_page(request): context_instance=RequestContext(request) ) else: - return HttpResponseRedirect( reverse('groupchange', kwargs={"group_id": "home"}) ) + return HttpResponseRedirect( reverse('groupchange', kwargs={"group_id": "home", "groupid": "home"}) ) diff --git a/gnowsys-ndf/gnowsys_ndf/ndf/views/methods.py b/gnowsys-ndf/gnowsys_ndf/ndf/views/methods.py index 50f1833f..a9e003d4 100644 --- a/gnowsys-ndf/gnowsys_ndf/ndf/views/methods.py +++ b/gnowsys-ndf/gnowsys_ndf/ndf/views/methods.py @@ -112,6 +112,7 @@ def get_group_name_id(group_name_or_id, get_obj=False): # if cached result exists return it if not get_obj: slug = slugify(group_name_or_id) + # for unicode strings like hindi-text slugify doesn't works cache_key = 'get_group_name_id_' + str(slug) if slug else str(abs(hash(group_name_or_id))) cache_result = cache.get(cache_key) @@ -154,7 +155,7 @@ def get_group_name_id(group_name_or_id, get_obj=False): else: # setting cache with both ObjectId and group_name cache.set(cache_key, (group_name, group_id), 60*60) - cache_key = u'get_group_name_id_' + slugify(group_id) + cache_key = u'get_group_name_id_' + slugify(group_name) cache.set(cache_key, (group_name, group_id), 60*60) return group_name, group_id diff --git a/gnowsys-ndf/gnowsys_ndf/ndf/views/moderation.py b/gnowsys-ndf/gnowsys_ndf/ndf/views/moderation.py new file mode 100644 index 00000000..4ddada27 --- /dev/null +++ b/gnowsys-ndf/gnowsys_ndf/ndf/views/moderation.py @@ -0,0 +1,412 @@ +''' -- imports from python libraries -- ''' +# import os -- Keep such imports here +import json + +''' -- imports from installed packages -- ''' +from django.http import HttpResponseRedirect +from django.http import HttpResponse +from django.http import Http404 +from django.core.urlresolvers import reverse +from django.shortcuts import render_to_response # , render +from django.template import RequestContext +# from django.template.defaultfilters import slugify +from django.contrib.auth.decorators import login_required +from django.contrib.auth.models import User +from django.views.generic import View + +try: + from bson import ObjectId +except ImportError: # old pymongo + from pymongo.objectid import ObjectId + +''' -- imports from application folders/files -- ''' +from gnowsys_ndf.settings import GAPPS, GSTUDIO_GROUP_AGENCY_TYPES, GSTUDIO_NROER_MENU, GSTUDIO_NROER_MENU_MAPPINGS + +# from gnowsys_ndf.ndf.models import GSystemType, GSystem, Group, Triple +from gnowsys_ndf.ndf.models import node_collection, triple_collection +from gnowsys_ndf.ndf.views.ajax_views import set_drawer_widget +from gnowsys_ndf.ndf.templatetags.ndf_tags import get_all_user_groups # get_existing_groups +from gnowsys_ndf.ndf.views.methods import * +from gnowsys_ndf.ndf.views.data_review import data_review +from gnowsys_ndf.ndf.views.group import CreateModeratedGroup + + +@login_required +def moderation_status(request, group_id, node_id): + + node = node_collection.one({'_id': ObjectId(node_id)}) + + if not node: # invalid ObjectId + return render_to_response('ndf/under_moderation.html', { + 'group_id': group_id, 'groupid': group_id, 'title': 'Under Moderation Status', + }, RequestContext(request)) + + node_status = node.status + node_group_set = node.group_set + current_mod_group_obj = None + is_under_moderation = True + top_group_name = "" + + mod_group_instance = CreateModeratedGroup(request) + + selected_group = None + for each_group_id in node_group_set: + each_group_obj = node_collection.one({'_id': ObjectId(each_group_id), '_type': 'Group'}) + if each_group_obj: + selected_group = each_group_obj._id + + selected_group = selected_group if selected_group else group_id + + group_hierarchy_result = mod_group_instance.get_all_group_hierarchy(selected_group) + # returns result in <True, all_sub_group_list> format + + if group_hierarchy_result[0]: + group_hierarchy_obj_list = group_hierarchy_result[1] + group_hierarchy_id_list = [g._id for g in group_hierarchy_obj_list] + top_group_id = group_hierarchy_id_list[0] + top_group_name = group_hierarchy_obj_list[0].name + # print group_hierarchy_obj_list + + cntr = 0 + for each_group_id in node_group_set: + cntr += 1 + if each_group_id in group_hierarchy_id_list: + if ObjectId(each_group_id) == ObjectId(top_group_id): + is_under_moderation = False + else: + is_under_moderation = True + current_mod_group_obj = group_hierarchy_obj_list[cntr] + + elif node_status == u'MODERATION': + is_under_moderation = True + + else: + is_under_moderation = False + + # print "is_under_moderation : ", is_under_moderation + print "=== ", current_mod_group_obj._id + + return render_to_response('ndf/under_moderation.html', { + 'group_id': group_id, 'groupid': group_id, 'node': node, 'title': 'Under Moderation Status', + 'is_under_moderation': is_under_moderation, 'current_mod_group_obj': current_mod_group_obj, + 'group_hierarchy_obj_list': group_hierarchy_obj_list, 'top_group_name': top_group_name + }, RequestContext(request)) + + +def all_under_moderation(request, group_id): + + group_obj = get_group_name_id(group_id, get_obj=True) + + if not group_obj.edit_policy == 'EDITABLE_MODERATED': + raise Http404(error_message) + + mod_group_instance = CreateModeratedGroup(request) + group_hierarchy_result = mod_group_instance.get_all_group_hierarchy(group_obj._id) + + if group_hierarchy_result[0]: + group_hierarchy_obj_list = group_hierarchy_result[1] + group_hierarchy_id_list = [g._id for g in group_hierarchy_obj_list] + file_gst = node_collection.one({'_type': 'GSystemType', 'name': 'File'}) + page_gst = node_collection.one({'_type': 'GSystemType', 'name': 'Page'}) + + all_resources = node_collection.find({'member_of': {'$in': [file_gst._id, page_gst._id]}, 'group_set': {'$in': group_hierarchy_id_list[1:]} }) + + # print "=== ", res_cur.count() + # print [x.name for x in all_resources] + + return render_to_response('ndf/all_under_moderation_status.html', { + "group_id": group_id, "groupid": group_id, "title": "All Under Moderation Resources", + "files": all_resources, "detail_urlname": "moderation_status", "filetype": "all", + "dont_show_error": True + }, RequestContext(request)) + + else: + raise Http404(error_message) + +@login_required +def moderation(request, group_id, page_no=1): + # try: + # group_id = ObjectId(group_id) + # except: + # group_name, group_id = get_group_name_id(group_id) + + context_variables = data_review(request, group_id, page_no, get_paged_resources=True) + # adding title in context_variables + context_variables['title'] = 'moderation' + + template_name = "ndf/moderation_data_review.html" + + return render_to_response(template_name, context_variables, context_instance=RequestContext(request)) + + +@login_required +def approve_resource(request, group_id): + ''' + Method to approve resorce. + Means resource will get published by moderator to next moderated or parent group. + ''' + node_id = request.POST.get('node_oid', '') + node_obj = node_collection.one({'_id': ObjectId(node_id)}) + flag = 0 # good to check at JS/front-end level + + if node_obj: + node_group_set = node_obj.group_set + # make deep copy of object and not to copy it's reference with [:]. + group_set_details_dict = get_moderator_group_set(node_group_set[:], group_id, get_details=True) + updated_group_set = group_set_details_dict['updated_group_set'] + print "==== updated_group_set : ", updated_group_set + print "==== node_group_set : ", node_group_set + print "==== group_set_details_dict : ", group_set_details_dict + + # if set(node_group_set) != set(updated_group_set): + if group_set_details_dict['is_group_set_updated']: + + node_obj.group_set = updated_group_set + + # ---| checking for top group. \ + # If not top group and it's fond to be sub group create task |--- + # one way: + # group_obj = get_group_name_id(updated_group_set[len(updated_group_set) - 1], get_obj=True) + # print "===== group_obj.member_of_names_list : ", group_obj.member_of_names_list + # if group_obj.member_of_names_list[0] in ['ProgramEventGroup', 'CourseEventGroup', 'PartnerGroup', 'ModeratingGroup']: + # second way: + if group_set_details_dict['is_new_group_top_group']: + # means, resource is passed through curation flow and \ + # therefore change the status from 'MODERATION' to 'PUBLISHED' + node_obj.status = u'PUBLISHED' + + # intimate creator of object/resource and creator of parent group + node_creator_username = User.objects.get(id=node_obj.created_by).username + + task_content_org = u"Congratulations " + unicode(node_creator_username) + \ + u",\n\n Your contribution is moderated and it's published to " + \ + group_set_details_dict['newly_appended_group_name'] + \ + u". \n\nWe appreciate your efforts and thank you for your contribution!" + create_moderator_task(request, \ + group_set_details_dict['newly_appended_group_id'],\ + node_obj._id, task_type_creation='multiple', \ + task_type='Other', task_content_org=task_content_org,\ + created_by_name=node_creator_username) + + + else: + # resource is in curation flow hence, create a task + create_moderator_task(request, \ + group_set_details_dict['newly_appended_group_id'],\ + node_obj._id) + # node_obj.modified_by = int(request.user.id) + node_obj.save() + + flag = 1 + else: + flag = 0 + + else: + flag = 0 + + return HttpResponse(flag) + + +@login_required +def create_moderator_task(request, group_id, node_id, \ + task_type_creation='group', task_type='Moderation', task_content_org="", \ + created_by_name=""): + ''' + Method to create task to group admins or moderators of the moderated groups. + ''' + # def create_task(task_dict, task_type_creation="single"): + # task_dict + # - Required keys: _id[optional], name, group_set, created_by, modified_by, contributors, content_org, + # created_by_name, Status, Priority, start_time, end_time, Assignee, has_type + + node_obj = node_collection.one({'_id': ObjectId(node_id)}) + + # last group is next appended group + group_obj = get_group_name_id(group_id, get_obj=True) + + + if task_type == "Moderation": + task_title = u"Moderate Resource: " + node_obj.name + else: + task_title = u"\n\nResource " + node_obj.name + \ + u" is successfully moderated and published to " + group_obj.name + + glist_gst = node_collection.one({'_type': "GSystemType", 'name': "GList"}) + task_type_list = [] + task_type_list.append(node_collection.one({'member_of': glist_gst._id, 'name':unicode(task_type)})._id) + + site = Site.objects.get(pk=1) + site = unicode(site.name.__str__()) + + if task_content_org: + pass + + else: + url = u"http://" + site + "/"+ unicode(group_obj._id) \ + + u"/moderation#" + unicode(node_obj._id.__str__()) + + task_content_org = u'\n\nModerate resource: "' + unicode(node_obj.name) \ + + u'" having id: "' + unicode(node_obj._id.__str__()) + '"' \ + + u'\n\nPlease moderate resource accesible at following link: \n'\ + + unicode(url) + + task_dict = { + "name": task_title, + "group_set": [group_obj._id], + "created_by": node_obj.created_by, + "modified_by": request.user.id, + "contributors": [request.user.id], + "content_org": unicode(task_content_org), + # "created_by_name": unicode(created_by_name), + "created_by_name": unicode(request.user.username), + "Status": u"New", + "Priority": u"Normal", + # "start_time": "", + # "end_time": "", + "Assignee": list(group_obj.group_admin[:] + [node_obj.created_by]), + "has_type": task_type_list + } + + task_obj = create_task(task_dict, task_type_creation) + + if task_obj: + return True + + +def get_moderator_group_set(node_group_set, curr_group_id, get_details=False): + ''' + Returns the "group_set". + Takes two arguments: + - node_group_set: existing/current group_set of node object. + - curr_group_id: current group in which this node resides. + Pass the deep copy of group_set and not the reference. + e.g: + updated_group_set = get_moderator_group_set(node_group_set[:], group_id) + ------------ + if there is need of extra information along with group_set, pass <get_details=True> as last arg. + e.g: + updated_group_set = get_moderator_group_set(node_group_set[:], group_id, get_details=True) + Along with group_set following details will be returned in DICT format: + { + "updated_group_set": updated_group_set, + "is_group_set_updated": is_group_set_updated, + "removed_group_id": removed_group_id, + "newly_appended_group_id": newly_appended_group_id, + "newly_appended_group_name": newly_appended_group_name, + "is_new_group_top_group": is_new_group_top_group + } + ''' + + curr_group_obj = node_collection.one({'_id': ObjectId(curr_group_id)}) + group_set = node_group_set[:] + is_group_set_updated = False + is_new_group_top_group = False + + # initializing dict with defaults: + details_dict = { + "updated_group_set": group_set, + "is_group_set_updated": is_group_set_updated, + "removed_group_id": None, + "newly_appended_group_id": None, + "newly_appended_group_name": None, + "is_new_group_top_group": is_new_group_top_group + } + + # check if current group having edit policy of EDITABLE_MODERATED. + # if no return group_set as it was + if not curr_group_obj.edit_policy == 'EDITABLE_MODERATED': + if get_details: + return details_dict + else: + return node_group_set + + # ---| getting appropriate member_of group |--- + # for top level of moderated group + if len(curr_group_obj.member_of) == 1 and 'Group' in curr_group_obj.member_of_names_list: + member_of = node_collection.one({'_type': 'GSystemType', 'name': u'ModeratingGroup'}) + + # for sub-group falling under one of following categories: + elif curr_group_obj.member_of_names_list[0] in ['ProgramEventGroup', 'CourseEventGroup', 'PartnerGroup', 'ModeratingGroup']: + member_of = node_collection.one({'_id': curr_group_obj.member_of[0]}) + + # final fallback option + else: + # GST of "ModeratingGroup" + member_of = node_collection.one({'_type': 'GSystemType', 'name': u'ModeratingGroup'}) + + # getting sub-group having: + # curr_group in prior_node + # and member_of as fetched above + # and moderation_level > -1 + sub_mod_group_obj = node_collection.one({ + '_type': 'Group', + 'prior_node': {'$in': [ObjectId(curr_group_obj._id)]}, + 'member_of': {'$in': [ObjectId(member_of._id)]}, + 'moderation_level': {'$gt': -1} + }) + # print "curr_group_obj._id : ", curr_group_obj._id + # print "member_of._id : ", member_of._id + # print "sub_mod_group_obj.name : ", sub_mod_group_obj.name + + # proper sub-group found + if sub_mod_group_obj: + + if ObjectId(curr_group_id) in group_set: + # remove current group's _id + removed_group_id = group_set.pop(group_set.index(ObjectId(curr_group_id))) + + if not ObjectId(sub_mod_group_obj._id) in group_set: + # add next/sub-group's _id + group_set.append(sub_mod_group_obj._id) + newly_appended_group_id = sub_mod_group_obj._id.__str__() + newly_appended_group_name = sub_mod_group_obj.name + is_group_set_updated = True + + # if no sub-group found or it's last sub-group of hierarchy + else: + is_top_group, top_group_obj = get_top_group_of_hierarchy(curr_group_id) + + if ObjectId(curr_group_id) in group_set: + # remove current group's _id + removed_group_id = group_set.pop(group_set.index(ObjectId(curr_group_id))) + + if is_top_group and (not ObjectId(top_group_obj._id) in group_set): + # add parent/top group's _id + group_set.append(top_group_obj._id) + newly_appended_group_id = top_group_obj._id.__str__() + newly_appended_group_name = top_group_obj.name + is_group_set_updated = True + is_new_group_top_group = True + + if get_details: + details_dict = { + "updated_group_set": group_set, + "is_group_set_updated": is_group_set_updated, + "removed_group_id": removed_group_id, + "newly_appended_group_id": newly_appended_group_id, + "newly_appended_group_name": newly_appended_group_name, + "is_new_group_top_group": is_new_group_top_group + } + return details_dict + + # print group_set + return group_set + + +def get_top_group_of_hierarchy(group_id): + ''' + getting top group object of hierarchy. + Returns mongokit object of top group. + ''' + curr_group_obj = node_collection.one({'_id': ObjectId(group_id)}) + + # loop till there is no end of prior_node or till reaching at top group. + while curr_group_obj and curr_group_obj.prior_node: + curr_group_obj = node_collection.one({'_id': curr_group_obj.prior_node[0]}) + + if curr_group_obj.edit_policy != 'EDITABLE_MODERATED': + return False, "One of the group: " + str(curr_group_obj._id) \ + + " is not with edit_policy: EDITABLE_MODERATED." + + # send overwritten/first curr_group_obj's "_id" + return True, curr_group_obj diff --git a/gnowsys-ndf/gnowsys_ndf/settings.py b/gnowsys-ndf/gnowsys_ndf/settings.py index 4494f282..4c4c5473 100644 --- a/gnowsys-ndf/gnowsys_ndf/settings.py +++ b/gnowsys-ndf/gnowsys_ndf/settings.py @@ -609,7 +609,7 @@ GSTUDIO_RESOURCES_AGE_RANGE = ["5-10", "11-20", "21-30", "31-40", "41 and above" GSTUDIO_RESOURCES_READING_LEVEL = [] -GSTUDIO_TASK_TYPES = ["Bug", "Feature", "Support", "UI Feature", "Other"] +GSTUDIO_TASK_TYPES = ["Bug", "Feature", "Support", "UI Feature", "Moderation", "Other"] GSTUDIO_NROER_MENU = [{"Repository": []}, {"Partners": ["States", "Institutions", "Individuals"]}, {"Groups":["Teachers", "Interest Groups", "Schools"]}] |