mirror of
https://gitlab.com/allianceauth/allianceauth.git
synced 2026-02-05 06:36:19 +01:00
Compare commits
17 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
10bd77d761 | ||
|
|
192d286cf2 | ||
|
|
8ab9d2d5ad | ||
|
|
3630812b92 | ||
|
|
2f320bc256 | ||
|
|
45b8d42b8e | ||
|
|
bd2d19f867 | ||
|
|
0be404baca | ||
|
|
e6cee9ac83 | ||
|
|
d173a59441 | ||
|
|
8f59f2549a | ||
|
|
630400fee4 | ||
|
|
1ec6929e91 | ||
|
|
8c6bdd8ae2 | ||
|
|
e04138bced | ||
|
|
db5ad85811 | ||
|
|
5b44fd376d |
@@ -25,15 +25,6 @@ dependency_scanning:
|
|||||||
- python -V
|
- python -V
|
||||||
- pip install wheel tox
|
- pip install wheel tox
|
||||||
|
|
||||||
test-3.6-core:
|
|
||||||
image: python:3.6-buster
|
|
||||||
script:
|
|
||||||
- tox -e py36-core
|
|
||||||
artifacts:
|
|
||||||
when: always
|
|
||||||
reports:
|
|
||||||
cobertura: coverage.xml
|
|
||||||
|
|
||||||
test-3.7-core:
|
test-3.7-core:
|
||||||
image: python:3.7-buster
|
image: python:3.7-buster
|
||||||
script:
|
script:
|
||||||
@@ -52,10 +43,10 @@ test-3.8-core:
|
|||||||
reports:
|
reports:
|
||||||
cobertura: coverage.xml
|
cobertura: coverage.xml
|
||||||
|
|
||||||
test-3.6-all:
|
test-3.9-core:
|
||||||
image: python:3.6-buster
|
image: python:3.9-buster
|
||||||
script:
|
script:
|
||||||
- tox -e py36-all
|
- tox -e py39-core
|
||||||
artifacts:
|
artifacts:
|
||||||
when: always
|
when: always
|
||||||
reports:
|
reports:
|
||||||
@@ -79,9 +70,18 @@ test-3.8-all:
|
|||||||
reports:
|
reports:
|
||||||
cobertura: coverage.xml
|
cobertura: coverage.xml
|
||||||
|
|
||||||
|
test-3.9-all:
|
||||||
|
image: python:3.9-buster
|
||||||
|
script:
|
||||||
|
- tox -e py39-all
|
||||||
|
artifacts:
|
||||||
|
when: always
|
||||||
|
reports:
|
||||||
|
cobertura: coverage.xml
|
||||||
|
|
||||||
deploy_production:
|
deploy_production:
|
||||||
stage: deploy
|
stage: deploy
|
||||||
image: python:3.8-buster
|
image: python:3.9-buster
|
||||||
|
|
||||||
before_script:
|
before_script:
|
||||||
- pip install twine wheel
|
- pip install twine wheel
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
# This will make sure the app is always imported when
|
# This will make sure the app is always imported when
|
||||||
# Django starts so that shared_task will use this app.
|
# Django starts so that shared_task will use this app.
|
||||||
|
|
||||||
__version__ = '2.8.4'
|
__version__ = '2.9.0a2'
|
||||||
__title__ = 'Alliance Auth'
|
__title__ = 'Alliance Auth'
|
||||||
__url__ = 'https://gitlab.com/allianceauth/allianceauth'
|
__url__ = 'https://gitlab.com/allianceauth/allianceauth'
|
||||||
NAME = '%s v%s' % (__title__, __version__)
|
NAME = '%s v%s' % (__title__, __version__)
|
||||||
|
|||||||
@@ -42,6 +42,7 @@
|
|||||||
</div>
|
</div>
|
||||||
{% endblock content %}
|
{% endblock content %}
|
||||||
{% block extra_script %}
|
{% block extra_script %}
|
||||||
$(document).ready(function(){
|
$(document).ready(function () {
|
||||||
$("[rel=tooltip]").tooltip();
|
$("[rel=tooltip]").tooltip();
|
||||||
|
});
|
||||||
{% endblock extra_script %}
|
{% endblock extra_script %}
|
||||||
|
|||||||
@@ -44,6 +44,7 @@
|
|||||||
</div>
|
</div>
|
||||||
{% endblock content %}
|
{% endblock content %}
|
||||||
{% block extra_script %}
|
{% block extra_script %}
|
||||||
$(document).ready(function(){
|
$(document).ready(function () {
|
||||||
$("[rel=tooltip]").tooltip();
|
$("[rel=tooltip]").tooltip();
|
||||||
|
});
|
||||||
{% endblock extra_script %}
|
{% endblock extra_script %}
|
||||||
|
|||||||
@@ -83,7 +83,7 @@
|
|||||||
|
|
||||||
{% block extra_script %}
|
{% block extra_script %}
|
||||||
$.fn.dataTable.moment = function(format, locale) {
|
$.fn.dataTable.moment = function(format, locale) {
|
||||||
var types = $.fn.dataTable.ext.type;
|
let types = $.fn.dataTable.ext.type;
|
||||||
|
|
||||||
// Add type detection
|
// Add type detection
|
||||||
types.detect.unshift(function(d) {
|
types.detect.unshift(function(d) {
|
||||||
|
|||||||
@@ -34,17 +34,15 @@
|
|||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block extra_script %}
|
{% block extra_script %}
|
||||||
|
|
||||||
$('#id_start').datetimepicker({
|
$('#id_start').datetimepicker({
|
||||||
setlocale: '{{ LANGUAGE_CODE }}',
|
setlocale: '{{ LANGUAGE_CODE }}',
|
||||||
{% if NIGHT_MODE %}
|
{% if NIGHT_MODE %}
|
||||||
theme: 'dark',
|
theme: 'dark',
|
||||||
{% else %}
|
{% else %}
|
||||||
theme: 'default',
|
theme: 'default',
|
||||||
{% endif %}
|
{% endif %}
|
||||||
mask: true,
|
mask: true,
|
||||||
format: 'Y-m-d H:i',
|
format: 'Y-m-d H:i',
|
||||||
minDate: 0
|
minDate: 0
|
||||||
});
|
});
|
||||||
|
|
||||||
{% endblock extra_script %}
|
{% endblock extra_script %}
|
||||||
|
|||||||
@@ -41,9 +41,10 @@
|
|||||||
|
|
||||||
{% include 'bundles/moment-js.html' with locale=True %}
|
{% include 'bundles/moment-js.html' with locale=True %}
|
||||||
<script src="{% static 'js/timers.js' %}"></script>
|
<script src="{% static 'js/timers.js' %}"></script>
|
||||||
|
|
||||||
<script type="application/javascript">
|
<script type="application/javascript">
|
||||||
// Data
|
// Data
|
||||||
var timers = [
|
let timers = [
|
||||||
{% for op in optimer %}
|
{% for op in optimer %}
|
||||||
{
|
{
|
||||||
'id': {{ op.id }},
|
'id': {{ op.id }},
|
||||||
@@ -52,67 +53,66 @@
|
|||||||
},
|
},
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
];
|
];
|
||||||
</script>
|
|
||||||
<script type="application/javascript">
|
|
||||||
|
|
||||||
timedUpdate();
|
|
||||||
setAllLocalTimes();
|
|
||||||
|
|
||||||
// Start timed updates
|
|
||||||
setInterval(timedUpdate, 1000);
|
|
||||||
|
|
||||||
function timedUpdate() {
|
|
||||||
updateClock();
|
|
||||||
updateAllTimers();
|
|
||||||
}
|
|
||||||
|
|
||||||
function updateAllTimers () {
|
|
||||||
var l = timers.length;
|
|
||||||
for (var i=0; i < l; ++i) {
|
|
||||||
if (timers[i].expired) continue;
|
|
||||||
updateTimer(timers[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Update a timer
|
* Update a timer
|
||||||
* @param timer Timer information
|
* @param timer Timer information
|
||||||
* @param timer.start Date of the timer
|
|
||||||
* @param timer.id Id number of the timer
|
|
||||||
* @param timer.expired
|
|
||||||
*/
|
*/
|
||||||
function updateTimer(timer) {
|
let updateTimer = function (timer) {
|
||||||
if (timer.start.isAfter(Date.now())) {
|
if (timer.start.isAfter(Date.now())) {
|
||||||
var duration = moment.duration(timer.start - moment(), 'milliseconds');
|
let duration = moment.duration(timer.start - moment(), 'milliseconds');
|
||||||
|
|
||||||
document.getElementById("countdown" + timer.id).innerHTML = getDurationString(duration);
|
document.getElementById("countdown" + timer.id).innerHTML = getDurationString(duration);
|
||||||
} else {
|
} else {
|
||||||
timer.expired = true;
|
timer.expired = true;
|
||||||
|
|
||||||
document.getElementById("countdown" + timer.id).innerHTML = "";
|
document.getElementById("countdown" + timer.id).innerHTML = "";
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
|
let updateAllTimers = function () {
|
||||||
|
let l = timers.length;
|
||||||
|
|
||||||
/**
|
|
||||||
* Set all local time fields
|
|
||||||
*/
|
|
||||||
function setAllLocalTimes() {
|
|
||||||
var l = timers.length;
|
|
||||||
for (var i=0; i < l; ++i) {
|
for (var i=0; i < l; ++i) {
|
||||||
setLocalTime(timers[i]);
|
if (timers[i].expired) continue;
|
||||||
|
|
||||||
|
updateTimer(timers[i]);
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the local time info for the timer
|
* Set the local time info for the timer
|
||||||
* @param timer Timer information
|
* @param timer Timer information
|
||||||
* @param timer.start Date of the timer
|
|
||||||
* @param timer.id Id number of the timer
|
|
||||||
*/
|
*/
|
||||||
function setLocalTime(timer) {
|
let setLocalTime = function (timer) {
|
||||||
document.getElementById("localtime" + timer.id).innerHTML = timer.start.format("ddd @ LT");
|
document.getElementById("localtime" + timer.id).innerHTML = timer.start.format("ddd @ LT");
|
||||||
}
|
};
|
||||||
|
|
||||||
function updateClock() {
|
/**
|
||||||
|
* Set all local time fields
|
||||||
|
*/
|
||||||
|
let setAllLocalTimes = function () {
|
||||||
|
let l = timers.length;
|
||||||
|
|
||||||
|
for (var i=0; i < l; ++i) {
|
||||||
|
setLocalTime(timers[i]);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let updateClock = function () {
|
||||||
document.getElementById("current-time").innerHTML = getCurrentEveTimeString();
|
document.getElementById("current-time").innerHTML = getCurrentEveTimeString();
|
||||||
}
|
};
|
||||||
|
|
||||||
|
let timedUpdate = function () {
|
||||||
|
updateClock();
|
||||||
|
updateAllTimers();
|
||||||
|
};
|
||||||
|
|
||||||
|
// Set initial values
|
||||||
|
setAllLocalTimes();
|
||||||
|
timedUpdate();
|
||||||
|
|
||||||
|
// Start timed updates
|
||||||
|
setInterval(timedUpdate, 1000);
|
||||||
</script>
|
</script>
|
||||||
{% endblock content %}
|
{% endblock content %}
|
||||||
|
|||||||
@@ -56,8 +56,9 @@
|
|||||||
|
|
||||||
{% block extra_script %}
|
{% block extra_script %}
|
||||||
$(document).ready(function() {
|
$(document).ready(function() {
|
||||||
var groupColumn = 0;
|
let groupColumn = 0;
|
||||||
var table = $('#tab_permissions_audit').DataTable({
|
|
||||||
|
$('#tab_permissions_audit').DataTable({
|
||||||
columnDefs: [
|
columnDefs: [
|
||||||
{ "visible": false, "targets": groupColumn }
|
{ "visible": false, "targets": groupColumn }
|
||||||
],
|
],
|
||||||
@@ -73,9 +74,9 @@
|
|||||||
bootstrap: true
|
bootstrap: true
|
||||||
},
|
},
|
||||||
drawCallback: function ( settings ) {
|
drawCallback: function ( settings ) {
|
||||||
var api = this.api();
|
let api = this.api();
|
||||||
var rows = api.rows( {page:'current'} ).nodes();
|
let rows = api.rows( {page:'current'} ).nodes();
|
||||||
var last=null;
|
let last = null;
|
||||||
|
|
||||||
api.column(groupColumn, {page:'current'} ).data().each( function ( group, i ) {
|
api.column(groupColumn, {page:'current'} ).data().each( function ( group, i ) {
|
||||||
if ( last !== group ) {
|
if ( last !== group ) {
|
||||||
|
|||||||
@@ -89,8 +89,9 @@
|
|||||||
|
|
||||||
{% block extra_script %}
|
{% block extra_script %}
|
||||||
$(document).ready(function() {
|
$(document).ready(function() {
|
||||||
var groupColumn = 0;
|
let groupColumn = 0;
|
||||||
var table = $('#tab_permissions_overview').DataTable({
|
|
||||||
|
$('#tab_permissions_overview').DataTable({
|
||||||
columnDefs: [
|
columnDefs: [
|
||||||
{ "visible": false, "targets": groupColumn }
|
{ "visible": false, "targets": groupColumn }
|
||||||
],
|
],
|
||||||
@@ -108,9 +109,9 @@
|
|||||||
bootstrap: true
|
bootstrap: true
|
||||||
},
|
},
|
||||||
drawCallback: function ( settings ) {
|
drawCallback: function ( settings ) {
|
||||||
var api = this.api();
|
let api = this.api();
|
||||||
var rows = api.rows( {page:'current'} ).nodes();
|
let rows = api.rows( {page:'current'} ).nodes();
|
||||||
var last=null;
|
let last = null;
|
||||||
|
|
||||||
api.column(groupColumn, {page:'current'} ).data().each( function ( group, i ) {
|
api.column(groupColumn, {page:'current'} ).data().each( function ( group, i ) {
|
||||||
if ( last !== group ) {
|
if ( last !== group ) {
|
||||||
|
|||||||
@@ -262,3 +262,5 @@ LOGGING = {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DEFAULT_AUTO_FIELD = "django.db.models.AutoField"
|
||||||
|
|||||||
@@ -12,20 +12,12 @@ import base64
|
|||||||
import hmac
|
import hmac
|
||||||
import hashlib
|
import hashlib
|
||||||
|
|
||||||
try:
|
from urllib.parse import unquote, urlencode, parse_qs
|
||||||
from urllib import unquote, urlencode
|
|
||||||
except ImportError: #py3
|
|
||||||
from urllib.parse import unquote, urlencode
|
|
||||||
try:
|
|
||||||
from urlparse import parse_qs
|
|
||||||
except ImportError: #py3
|
|
||||||
from urllib.parse import parse_qs
|
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
ACCESS_PERM = 'discourse.access_discourse'
|
ACCESS_PERM = 'discourse.access_discourse'
|
||||||
|
|
||||||
|
|
||||||
@@ -55,7 +47,7 @@ def discourse_sso(request):
|
|||||||
# Validate the payload
|
# Validate the payload
|
||||||
try:
|
try:
|
||||||
payload = unquote(payload).encode('utf-8')
|
payload = unquote(payload).encode('utf-8')
|
||||||
decoded = base64.decodestring(payload).decode('utf-8')
|
decoded = base64.decodebytes(payload).decode('utf-8')
|
||||||
assert 'nonce' in decoded
|
assert 'nonce' in decoded
|
||||||
assert len(payload) > 0
|
assert len(payload) > 0
|
||||||
except AssertionError:
|
except AssertionError:
|
||||||
@@ -86,7 +78,7 @@ def discourse_sso(request):
|
|||||||
if main_char:
|
if main_char:
|
||||||
params['avatar_url'] = main_char.portrait_url(256)
|
params['avatar_url'] = main_char.portrait_url(256)
|
||||||
|
|
||||||
return_payload = base64.encodestring(urlencode(params).encode('utf-8'))
|
return_payload = base64.encodebytes(urlencode(params).encode('utf-8'))
|
||||||
h = hmac.new(key, return_payload, digestmod=hashlib.sha256)
|
h = hmac.new(key, return_payload, digestmod=hashlib.sha256)
|
||||||
query_string = urlencode({'sso': return_payload, 'sig': h.hexdigest()})
|
query_string = urlencode({'sso': return_payload, 'sig': h.hexdigest()})
|
||||||
|
|
||||||
|
|||||||
@@ -43,17 +43,15 @@
|
|||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block extra_script %}
|
{% block extra_script %}
|
||||||
|
|
||||||
$('#id_fleet_time').datetimepicker({
|
$('#id_fleet_time').datetimepicker({
|
||||||
setlocale: '{{ LANGUAGE_CODE }}',
|
setlocale: '{{ LANGUAGE_CODE }}',
|
||||||
{% if NIGHT_MODE %}
|
{% if NIGHT_MODE %}
|
||||||
theme: 'dark',
|
theme: 'dark',
|
||||||
{% else %}
|
{% else %}
|
||||||
theme: 'default',
|
theme: 'default',
|
||||||
{% endif %}
|
{% endif %}
|
||||||
mask: true,
|
mask: true,
|
||||||
format: 'Y-m-d H:i',
|
format: 'Y-m-d H:i',
|
||||||
minDate: 0
|
minDate: 0
|
||||||
});
|
});
|
||||||
|
|
||||||
{% endblock extra_script %}
|
{% endblock extra_script %}
|
||||||
|
|||||||
@@ -206,73 +206,71 @@ ESC to cancel{% endblocktrans %}"id="blah"></i></th>
|
|||||||
{% endblock extra_javascript %}
|
{% endblock extra_javascript %}
|
||||||
|
|
||||||
{% block extra_script %}
|
{% block extra_script %}
|
||||||
$(document).ready(function() {
|
$(document).ready(function() {
|
||||||
$.fn.editable.defaults.mode = 'inline';
|
$.fn.editable.defaults.mode = 'inline';
|
||||||
$.fn.editable.defaults.showbuttons = false;
|
$.fn.editable.defaults.showbuttons = false;
|
||||||
$.fn.editable.defaults.highlight = "#AAFF80";
|
$.fn.editable.defaults.highlight = "#AAFF80";
|
||||||
|
|
||||||
|
$.fn.dataTable.moment = function(format, locale) {
|
||||||
|
let types = $.fn.dataTable.ext.type;
|
||||||
|
|
||||||
$('.srp').editable({
|
// Add type detection
|
||||||
display: function(value, response) {
|
types.detect.unshift(function(d) {
|
||||||
return false;
|
return moment(d, format, locale, true).isValid() ?
|
||||||
},
|
'moment-' + format :
|
||||||
success: function(response, newValue) {
|
null;
|
||||||
newValue = parseInt(newValue);
|
});
|
||||||
newvalue = newValue.toLocaleString() + " ISK";
|
|
||||||
$(this).html(newvalue.bold());
|
|
||||||
},
|
|
||||||
validate: function(value) {
|
|
||||||
if (value === null || value === '') {
|
|
||||||
return 'Empty values not allowed';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
$('.srp').on('hidden', function(e, reason){
|
|
||||||
if(reason === 'save' || reason === 'nochange') {
|
|
||||||
var $next = $(this).closest('tr').next().find('.editable');
|
|
||||||
setTimeout(function() {
|
|
||||||
$next.editable('show');
|
|
||||||
}, 400);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
$(document).ready(function(){
|
// Add sorting method - use an integer for the sorting
|
||||||
$("[rel=tooltip]").tooltip({ placement: 'top'});
|
types.order[ 'moment-' + format+'-pre' ] = function(d) {
|
||||||
});
|
return moment(d, format, locale, true).unix();
|
||||||
|
};
|
||||||
|
};
|
||||||
|
$.fn.dataTable.moment('YYYY-MMM-D, HH:mm');
|
||||||
|
|
||||||
$.fn.dataTable.moment = function(format, locale) {
|
$('.srp').editable({
|
||||||
var types = $.fn.dataTable.ext.type;
|
display: function(value, response) {
|
||||||
|
return false;
|
||||||
|
},
|
||||||
|
success: function(response, newValue) {
|
||||||
|
newValue = parseInt(newValue);
|
||||||
|
let newValueOutput = newValue.toLocaleString() + " ISK";
|
||||||
|
|
||||||
// Add type detection
|
$(this).html(newValueOutput.bold());
|
||||||
types.detect.unshift(function(d) {
|
},
|
||||||
return moment(d, format, locale, true).isValid() ?
|
validate: function(value) {
|
||||||
'moment-'+format :
|
if (value === null || value === '') {
|
||||||
null;
|
return 'Empty values not allowed';
|
||||||
} );
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
// Add sorting method - use an integer for the sorting
|
$('.srp').on('hidden', function(e, reason){
|
||||||
types.order[ 'moment-'+format+'-pre' ] = function(d) {
|
if(reason === 'save' || reason === 'nochange') {
|
||||||
return moment(d, format, locale, true).unix();
|
let $next = $(this).closest('tr').next().find('.editable');
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
$(document).ready( function(){
|
setTimeout(function() {
|
||||||
$.fn.dataTable.moment('YYYY-MMM-D, HH:mm');
|
$next.editable('show');
|
||||||
|
}, 400);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
$('table.srplist').DataTable({
|
$('table.srplist').DataTable({
|
||||||
"order": [[ 6, "asc" ]],
|
"order": [[ 6, "asc" ]],
|
||||||
"paging": false,
|
"paging": false,
|
||||||
"columnDefs": [{
|
"columnDefs": [
|
||||||
"targets": [1, 8],
|
{
|
||||||
"orderable": false
|
"targets": [1, 8],
|
||||||
},
|
"orderable": false
|
||||||
{
|
},
|
||||||
"targets": [4, 5],
|
{
|
||||||
"type": "num"
|
"targets": [4, 5],
|
||||||
}]
|
"type": "num"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
});
|
||||||
|
|
||||||
|
// tooltip
|
||||||
|
$("[rel=tooltip]").tooltip({ placement: 'top'});
|
||||||
});
|
});
|
||||||
});
|
|
||||||
|
|
||||||
{% endblock extra_script %}
|
{% endblock extra_script %}
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
/* global notificationUPdateSettings */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
This script refreshed the unread notification count in the top menu
|
This script refreshed the unread notification count in the top menu
|
||||||
on a regular basis so to keep the user apprised about newly arrived
|
on a regular basis so to keep the user apprised about newly arrived
|
||||||
@@ -6,70 +8,67 @@
|
|||||||
The refresh rate can be changes via the Django setting NOTIFICATIONS_REFRESH_TIME.
|
The refresh rate can be changes via the Django setting NOTIFICATIONS_REFRESH_TIME.
|
||||||
See documentation for details.
|
See documentation for details.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
$(function () {
|
$(function () {
|
||||||
var elem = document.getElementById("dataExport");
|
'use strict';
|
||||||
var notificationsListViewUrl = elem.getAttribute("data-notificationsListViewUrl");
|
|
||||||
var notificationsRefreshTime = elem.getAttribute("data-notificationsRefreshTime");
|
let notificationsListViewUrl = notificationUPdateSettings.notificationsListViewUrl;
|
||||||
var userNotificationsCountViewUrl = elem.getAttribute(
|
let notificationsRefreshTime = notificationUPdateSettings.notificationsRefreshTime;
|
||||||
"data-userNotificationsCountViewUrl"
|
let userNotificationsCountViewUrl = notificationUPdateSettings.userNotificationsCountViewUrl;
|
||||||
);
|
|
||||||
|
|
||||||
// update the notification unread count in the top menu
|
// update the notification unread count in the top menu
|
||||||
function update_notifications() {
|
let updateNotifications = function () {
|
||||||
$.getJSON(userNotificationsCountViewUrl, function (data, status) {
|
$.getJSON(userNotificationsCountViewUrl, function (data, status) {
|
||||||
if (status == 'success') {
|
if (status === 'success') {
|
||||||
var innerHtml = "";
|
let innerHtml = '';
|
||||||
var unread_count = data.unread_count;
|
let unreadCount = data.unread_count;
|
||||||
if (unread_count > 0) {
|
|
||||||
|
if (unreadCount > 0) {
|
||||||
innerHtml = (
|
innerHtml = (
|
||||||
`Notifications <span class="badge">${unread_count}</span>`
|
`Notifications <span class="badge">${unreadCount}</span>`
|
||||||
)
|
);
|
||||||
|
} else {
|
||||||
|
innerHtml = '<i class="far fa-bell"></i>';
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
innerHtml = '<i class="far fa-bell"></i>'
|
$('#menu_item_notifications').html(
|
||||||
}
|
|
||||||
$("#menu_item_notifications").html(
|
|
||||||
`<a href="${notificationsListViewUrl}">${innerHtml}</a>`
|
`<a href="${notificationsListViewUrl}">${innerHtml}</a>`
|
||||||
);
|
);
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
console.error(
|
console.error(
|
||||||
`Failed to load HTMl to render notifications item. Error: `
|
`Failed to load HTMl to render notifications item. Error: ${xhr.status}': '${xhr.statusText}`
|
||||||
`${xhr.status}': '${xhr.statusText}`
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
};
|
||||||
|
|
||||||
var myInterval;
|
let myInterval;
|
||||||
|
|
||||||
// activate automatic refreshing every x seconds
|
// activate automatic refreshing every x seconds
|
||||||
function activate_refreshing() {
|
let activateRefreshing = function () {
|
||||||
if (notificationsRefreshTime > 0) {
|
if (notificationsRefreshTime > 0) {
|
||||||
myInterval = setInterval(
|
myInterval = setInterval(
|
||||||
update_notifications, notificationsRefreshTime * 1000
|
updateNotifications, notificationsRefreshTime * 1000
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
// deactivate automatic refreshing
|
// deactivate automatic refreshing
|
||||||
function deactivate_refreshing() {
|
let deactivateRefreshing = function () {
|
||||||
if ((notificationsRefreshTime > 0) && (typeof myInterval !== 'undefined')) {
|
if ((notificationsRefreshTime > 0) && (typeof myInterval !== 'undefined')) {
|
||||||
clearInterval(myInterval)
|
clearInterval(myInterval);
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
// refreshing only happens on active browser tab
|
// refreshing only happens on active browser tab
|
||||||
$(document).on({
|
$(document).on({
|
||||||
'show': function () {
|
'show': function () {
|
||||||
activate_refreshing()
|
activateRefreshing();
|
||||||
},
|
},
|
||||||
'hide': function () {
|
'hide': function () {
|
||||||
deactivate_refreshing()
|
deactivateRefreshing();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// Initial start of refreshing on script loading
|
// Initial start of refreshing on script loading
|
||||||
activate_refreshing()
|
activateRefreshing();
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,23 +1,49 @@
|
|||||||
|
/* global moment */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get a duration string like countdown.js
|
* Get a duration string like countdown.js
|
||||||
* e.g. "1y 2d 3h 4m 5s"
|
* e.g. "1y 2d 3h 4m 5s"
|
||||||
* @param duration moment.duration
|
*
|
||||||
*/
|
* @param duration
|
||||||
function getDurationString(duration) {
|
* @returns {string}
|
||||||
var out = "";
|
*/
|
||||||
|
let getDurationString = function (duration) {
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
let out = '';
|
||||||
|
|
||||||
if (duration.years()) {
|
if (duration.years()) {
|
||||||
out += duration.years() + 'y ';
|
out += duration.years() + 'y ';
|
||||||
}
|
}
|
||||||
|
|
||||||
if (duration.months()) {
|
if (duration.months()) {
|
||||||
out += duration.months() + 'm ';
|
out += duration.months() + 'm ';
|
||||||
}
|
}
|
||||||
|
|
||||||
if (duration.days()) {
|
if (duration.days()) {
|
||||||
out += duration.days() + 'd ';
|
out += duration.days() + 'd ';
|
||||||
}
|
}
|
||||||
return out + duration.hours() + "h " + duration.minutes() + "m " + duration.seconds() + "s";
|
|
||||||
}
|
|
||||||
|
|
||||||
|
return out + duration.hours() + 'h ' + duration.minutes() + 'm ' + duration.seconds() + 's';
|
||||||
|
};
|
||||||
|
|
||||||
function getCurrentEveTimeString() {
|
/**
|
||||||
return moment().utc().format('dddd LL HH:mm:ss')
|
* returns the current eve time as a formatted string
|
||||||
}
|
*
|
||||||
|
* condition:
|
||||||
|
* only if moment.js is loaded before,
|
||||||
|
* if not this function returns an empty string to avoid JS errors from happening.
|
||||||
|
*
|
||||||
|
* @returns {string}
|
||||||
|
*/
|
||||||
|
let getCurrentEveTimeString = function () {
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
let returnValue = '';
|
||||||
|
|
||||||
|
if (window.moment) {
|
||||||
|
returnValue = moment().utc().format('dddd LL HH:mm:ss');
|
||||||
|
}
|
||||||
|
|
||||||
|
return returnValue;
|
||||||
|
};
|
||||||
|
|||||||
2
allianceauth/static/robots.txt
Normal file
2
allianceauth/static/robots.txt
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
User-agent: *
|
||||||
|
Disallow: /
|
||||||
@@ -46,16 +46,17 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<!-- share data with JS part -->
|
|
||||||
<div
|
|
||||||
id="dataExport"
|
|
||||||
data-notificationsListViewUrl="{% url 'notifications:list' %}"
|
|
||||||
data-notificationsRefreshTime="{% notifications_refresh_time %}"
|
|
||||||
data-userNotificationsCountViewUrl="{% url 'notifications:user_notifications_count' request.user.pk %}"
|
|
||||||
>
|
|
||||||
</div>
|
|
||||||
{% include 'bundles/bootstrap-js.html' %}
|
{% include 'bundles/bootstrap-js.html' %}
|
||||||
{% include 'bundles/jquery-visibility-js.html' %}
|
{% include 'bundles/jquery-visibility-js.html' %}
|
||||||
|
|
||||||
|
<script type="application/javascript">
|
||||||
|
let notificationUPdateSettings = {
|
||||||
|
notificationsListViewUrl: "{% url 'notifications:list' %}",
|
||||||
|
notificationsRefreshTime: "{% notifications_refresh_time %}",
|
||||||
|
userNotificationsCountViewUrl: "{% url 'notifications:user_notifications_count' request.user.pk %}"
|
||||||
|
};
|
||||||
|
</script>
|
||||||
<script src="{% static 'js/refresh_notifications.js' %}"></script>
|
<script src="{% static 'js/refresh_notifications.js' %}"></script>
|
||||||
|
|
||||||
{% block extra_javascript %}
|
{% block extra_javascript %}
|
||||||
|
|||||||
@@ -526,9 +526,7 @@
|
|||||||
{% include 'bundles/moment-js.html' with locale=True %}
|
{% include 'bundles/moment-js.html' with locale=True %}
|
||||||
<script src="{% static 'js/timers.js' %}"></script>
|
<script src="{% static 'js/timers.js' %}"></script>
|
||||||
<script type="application/javascript">
|
<script type="application/javascript">
|
||||||
var locale = "{{ LANGUAGE_CODE }}";
|
let timers = [
|
||||||
|
|
||||||
var timers = [
|
|
||||||
{% for timer in timers %}
|
{% for timer in timers %}
|
||||||
{
|
{
|
||||||
'id': {{ timer.id }},
|
'id': {{ timer.id }},
|
||||||
@@ -545,67 +543,64 @@
|
|||||||
{% endfor %}
|
{% endfor %}
|
||||||
];
|
];
|
||||||
|
|
||||||
moment.locale(locale);
|
/**
|
||||||
|
* Update a timer
|
||||||
|
* @param timer Timer information
|
||||||
|
*/
|
||||||
|
let updateTimer = function (timer) {
|
||||||
|
if (timer.targetDate.isAfter(Date.now())) {
|
||||||
|
let duration = moment.duration(timer.targetDate - moment(), 'milliseconds');
|
||||||
|
|
||||||
// Set initial values
|
document.getElementById("countdown" + timer.id).innerHTML = getDurationString(duration);
|
||||||
setAllLocalTimes();
|
} else {
|
||||||
timedUpdate();
|
timer.expired = true;
|
||||||
|
|
||||||
// Start timed updates
|
document.getElementById("countdown" + timer.id).innerHTML = "";
|
||||||
setInterval(timedUpdate, 1000);
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let updateAllTimers = function () {
|
||||||
|
let l = timers.length;
|
||||||
|
|
||||||
|
for (var i=0; i < l; ++i) {
|
||||||
|
if (timers[i].expired) continue;
|
||||||
|
|
||||||
|
updateTimer(timers[i]);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
function timedUpdate() {
|
function timedUpdate() {
|
||||||
updateClock();
|
updateClock();
|
||||||
updateAllTimers();
|
updateAllTimers();
|
||||||
}
|
}
|
||||||
|
|
||||||
function updateAllTimers () {
|
|
||||||
var l = timers.length;
|
|
||||||
for (var i=0; i < l; ++i) {
|
|
||||||
if (timers[i].expired) continue;
|
|
||||||
updateTimer(timers[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Update a timer
|
* Set the local time info for the timer
|
||||||
* @param timer Timer information
|
* @param timer Timer information
|
||||||
* @param timer.targetDate Date of the timer
|
|
||||||
* @param timer.id Id number of the timer
|
|
||||||
* @param timer.expired
|
|
||||||
*/
|
*/
|
||||||
function updateTimer(timer) {
|
let setLocalTime = function (timer) {
|
||||||
if (timer.targetDate.isAfter(Date.now())) {
|
document.getElementById("localtime" + timer.id).innerHTML = timer.targetDate.format("ddd @ LT");
|
||||||
duration = moment.duration(timer.targetDate - moment(), 'milliseconds');
|
};
|
||||||
document.getElementById("countdown" + timer.id).innerHTML = getDurationString(duration);
|
|
||||||
} else {
|
|
||||||
timer.expired = true;
|
|
||||||
document.getElementById("countdown" + timer.id).innerHTML = "";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set all local time fields
|
* Set all local time fields
|
||||||
*/
|
*/
|
||||||
function setAllLocalTimes() {
|
let setAllLocalTimes = function () {
|
||||||
var l = timers.length;
|
let l = timers.length;
|
||||||
|
|
||||||
for (var i=0; i < l; ++i) {
|
for (var i=0; i < l; ++i) {
|
||||||
setLocalTime(timers[i]);
|
setLocalTime(timers[i]);
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
/**
|
let updateClock = function () {
|
||||||
* Set the local time info for the timer
|
|
||||||
* @param timer Timer information
|
|
||||||
* @param timer.targetDate Date of the timer
|
|
||||||
* @param timer.id Id number of the timer
|
|
||||||
*/
|
|
||||||
function setLocalTime(timer) {
|
|
||||||
document.getElementById("localtime" + timer.id).innerHTML = timer.targetDate.format("ddd @ LT");
|
|
||||||
}
|
|
||||||
|
|
||||||
function updateClock() {
|
|
||||||
document.getElementById("current-time").innerHTML = getCurrentEveTimeString();
|
document.getElementById("current-time").innerHTML = getCurrentEveTimeString();
|
||||||
}
|
};
|
||||||
|
// Set initial values
|
||||||
|
setAllLocalTimes();
|
||||||
|
timedUpdate();
|
||||||
|
|
||||||
|
// Start timed updates
|
||||||
|
setInterval(timedUpdate, 1000);
|
||||||
</script>
|
</script>
|
||||||
{% endblock content %}
|
{% endblock content %}
|
||||||
|
|||||||
@@ -47,15 +47,23 @@ Place your virtual host configuration in the appropriate section within `/etc/ht
|
|||||||
ServerName auth.example.com
|
ServerName auth.example.com
|
||||||
|
|
||||||
ProxyPassMatch ^/static !
|
ProxyPassMatch ^/static !
|
||||||
|
ProxyPassMatch ^/robots.txt !
|
||||||
|
|
||||||
ProxyPass / http://127.0.0.1:8000/
|
ProxyPass / http://127.0.0.1:8000/
|
||||||
ProxyPassReverse / http://127.0.0.1:8000/
|
ProxyPassReverse / http://127.0.0.1:8000/
|
||||||
ProxyPreserveHost On
|
ProxyPreserveHost On
|
||||||
|
|
||||||
Alias "/static" "/var/www/myauth/static"
|
Alias "/static" "/var/www/myauth/static"
|
||||||
|
Alias "/robots.txt" "/var/www/myauth/static/robots.txt"
|
||||||
|
|
||||||
<Directory "/var/www/myauth/static">
|
<Directory "/var/www/myauth/static">
|
||||||
Require all granted
|
Require all granted
|
||||||
</Directory>
|
</Directory>
|
||||||
|
|
||||||
|
<Location "/robots.txt">
|
||||||
|
SetHandler None
|
||||||
|
Require all granted
|
||||||
|
</Location>
|
||||||
</VirtualHost>
|
</VirtualHost>
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|||||||
@@ -69,6 +69,10 @@ server {
|
|||||||
autoindex off;
|
autoindex off;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
location /robots.txt {
|
||||||
|
alias /var/www/myauth/static/robots.txt;
|
||||||
|
}
|
||||||
|
|
||||||
# Gunicorn config goes below
|
# Gunicorn config goes below
|
||||||
location / {
|
location / {
|
||||||
include proxy_params;
|
include proxy_params;
|
||||||
|
|||||||
@@ -18,12 +18,17 @@ To run AA with a newer Python 3 version than your system's default you need to i
|
|||||||
|
|
||||||
```eval_rst
|
```eval_rst
|
||||||
.. note::
|
.. note::
|
||||||
For stability and performance we currently recommend to run AA with Python 3.7. Since at the time of writing Python 3.7 was not available for CentOS through yum install this guide will upgrade to Python 3.6. For Ubuntu one can just replace "3.6" with "3.7" in the installation commands to get Python 3.7.
|
For stability and performance we currently recommend to run AA with Python 3.7. It has proven to be the fastest and most stable version in use currently.
|
||||||
```
|
```
|
||||||
|
|
||||||
To install other Python versions than come with your distro you need to add a new installation repository. Then you can install the specific Python 3 to your system.
|
To install other Python versions than those included with your distribution, you need to add a new installation repository. Then you can install the specific Python 3 to your system.
|
||||||
|
|
||||||
Ubuntu:
|
Ubuntu 1604 1804:
|
||||||
|
|
||||||
|
```eval_rst
|
||||||
|
.. note::
|
||||||
|
Ubuntu 2004 ships with Python 3.8, No updates required.
|
||||||
|
```
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
add-apt-repository ppa:deadsnakes/ppa
|
add-apt-repository ppa:deadsnakes/ppa
|
||||||
@@ -34,23 +39,38 @@ apt-get update
|
|||||||
```
|
```
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
apt-get install python3.6 python3.6-dev python3.6-venv
|
apt-get install python3.7 python3.7-dev python3.7-venv
|
||||||
```
|
```
|
||||||
|
|
||||||
CentOS:
|
CentOS 7/8:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
yum install https://centos7.iuscommunity.org/ius-release.rpm
|
cd ~
|
||||||
```
|
```
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
yum update
|
sudo yum install gcc openssl-devel bzip2-devel libffi-devel wget
|
||||||
```
|
```
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
yum install python36u python36u-pip python36u-devel
|
wget https://www.python.org/ftp/python/3.7.10/Python-3.7.10.tgz
|
||||||
```
|
```
|
||||||
|
|
||||||
|
```bash
|
||||||
|
tar xvf Python-3.7.10.tgz
|
||||||
|
```
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd Python-3.7.10/
|
||||||
|
```
|
||||||
|
|
||||||
|
```bash
|
||||||
|
./configure --enable-optimizations --enable-shared
|
||||||
|
```
|
||||||
|
|
||||||
|
```bash
|
||||||
|
make altinstall
|
||||||
|
```
|
||||||
## Preparing your venv
|
## Preparing your venv
|
||||||
|
|
||||||
Before updating your venv it is important to make sure that your current installation is stable. Otherwise your new venv might not be consistent with your data, which might create problems.
|
Before updating your venv it is important to make sure that your current installation is stable. Otherwise your new venv might not be consistent with your data, which might create problems.
|
||||||
@@ -97,12 +117,6 @@ If you unsure which apps you have installed from repos check `INSTALLED_APPS` in
|
|||||||
pip list
|
pip list
|
||||||
```
|
```
|
||||||
|
|
||||||
Some AA installations might still be running an older version of django-celery-beat. We would recommend to upgrade to the current version before doing the Python update:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
pip install -U 'django-celery-beat<2.00'
|
|
||||||
```
|
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
python manage.py migrate
|
python manage.py migrate
|
||||||
```
|
```
|
||||||
@@ -171,7 +185,7 @@ mv /home/allianceserver/venv/auth /home/allianceserver/venv/auth_old
|
|||||||
Now let's create our new venv with Python 3.6 and activate it:
|
Now let's create our new venv with Python 3.6 and activate it:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
python3.6 -m venv /home/allianceserver/venv/auth
|
python3.7 -m venv /home/allianceserver/venv/auth
|
||||||
```
|
```
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
|
|||||||
11
setup.py
11
setup.py
@@ -22,7 +22,7 @@ install_requires = [
|
|||||||
'celery>=4.3.0,<5.0.0,!=4.4.4', # 4.4.4 is missing a dependency
|
'celery>=4.3.0,<5.0.0,!=4.4.4', # 4.4.4 is missing a dependency
|
||||||
'celery_once>=2.0.1',
|
'celery_once>=2.0.1',
|
||||||
|
|
||||||
'django>=3.1.1,<3.2.0',
|
'django>=3.1.1,<4.0.0',
|
||||||
'django-bootstrap-form',
|
'django-bootstrap-form',
|
||||||
'django-registration>=3.1',
|
'django-registration>=3.1',
|
||||||
'django-sortedm2m',
|
'django-sortedm2m',
|
||||||
@@ -58,7 +58,7 @@ setup(
|
|||||||
extras_require={
|
extras_require={
|
||||||
'testing': testing_extras
|
'testing': testing_extras
|
||||||
},
|
},
|
||||||
python_requires='~=3.6',
|
python_requires='~=3.7',
|
||||||
license='GPLv2',
|
license='GPLv2',
|
||||||
packages=['allianceauth'],
|
packages=['allianceauth'],
|
||||||
url=allianceauth.__url__,
|
url=allianceauth.__url__,
|
||||||
@@ -72,15 +72,20 @@ setup(
|
|||||||
'Environment :: Web Environment',
|
'Environment :: Web Environment',
|
||||||
'Framework :: Django',
|
'Framework :: Django',
|
||||||
'Framework :: Django :: 3.1',
|
'Framework :: Django :: 3.1',
|
||||||
|
'Framework :: Django :: 3.2',
|
||||||
'Intended Audience :: Developers',
|
'Intended Audience :: Developers',
|
||||||
'License :: OSI Approved :: GNU General Public License v2 (GPLv2)',
|
'License :: OSI Approved :: GNU General Public License v2 (GPLv2)',
|
||||||
'Operating System :: POSIX :: Linux',
|
'Operating System :: POSIX :: Linux',
|
||||||
'Programming Language :: Python',
|
'Programming Language :: Python',
|
||||||
'Programming Language :: Python :: 3',
|
'Programming Language :: Python :: 3',
|
||||||
'Programming Language :: Python :: 3.6',
|
|
||||||
'Programming Language :: Python :: 3.7',
|
'Programming Language :: Python :: 3.7',
|
||||||
'Programming Language :: Python :: 3.8',
|
'Programming Language :: Python :: 3.8',
|
||||||
|
'Programming Language :: Python :: 3.9',
|
||||||
'Topic :: Internet :: WWW/HTTP',
|
'Topic :: Internet :: WWW/HTTP',
|
||||||
'Topic :: Internet :: WWW/HTTP :: Dynamic Content',
|
'Topic :: Internet :: WWW/HTTP :: Dynamic Content',
|
||||||
],
|
],
|
||||||
|
project_urls={
|
||||||
|
'Documentation': 'https://allianceauth.readthedocs.io/',
|
||||||
|
},
|
||||||
|
|
||||||
)
|
)
|
||||||
|
|||||||
4
tox.ini
4
tox.ini
@@ -1,16 +1,16 @@
|
|||||||
[tox]
|
[tox]
|
||||||
skipsdist = true
|
skipsdist = true
|
||||||
usedevelop = true
|
usedevelop = true
|
||||||
envlist = py{36,37,38}-{all}
|
envlist = py{37,38,39}-{all}
|
||||||
|
|
||||||
[testenv]
|
[testenv]
|
||||||
setenv =
|
setenv =
|
||||||
all: DJANGO_SETTINGS_MODULE = tests.settings_all
|
all: DJANGO_SETTINGS_MODULE = tests.settings_all
|
||||||
core: DJANGO_SETTINGS_MODULE = tests.settings_core
|
core: DJANGO_SETTINGS_MODULE = tests.settings_core
|
||||||
basepython =
|
basepython =
|
||||||
py36: python3.6
|
|
||||||
py37: python3.7
|
py37: python3.7
|
||||||
py38: python3.8
|
py38: python3.8
|
||||||
|
py39: python3.9
|
||||||
deps=
|
deps=
|
||||||
coverage
|
coverage
|
||||||
install_command = pip install -e ".[testing]" -U {opts} {packages}
|
install_command = pip install -e ".[testing]" -U {opts} {packages}
|
||||||
|
|||||||
Reference in New Issue
Block a user