mirror of
https://github.com/usmannasir/cyberpanel.git
synced 2025-11-07 13:56:01 +01:00
complete email queue manager
This commit is contained in:
@@ -1144,6 +1144,147 @@ app.controller('mailQueue', function($scope,$http) {
|
|||||||
|
|
||||||
};
|
};
|
||||||
$scope.fetchMailQueue();
|
$scope.fetchMailQueue();
|
||||||
|
|
||||||
|
$scope.fetchMessage = function (id) {
|
||||||
|
$scope.cyberpanelLoading = false;
|
||||||
|
var config = {
|
||||||
|
headers: {
|
||||||
|
'X-CSRFToken': getCookie('csrftoken')
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
var data = {
|
||||||
|
id: id
|
||||||
|
};
|
||||||
|
|
||||||
|
dataurl = "/emailPremium/fetchMessage";
|
||||||
|
|
||||||
|
$http.post(dataurl, data, config).then(ListInitialDatas, cantLoadInitialDatas);
|
||||||
|
|
||||||
|
function ListInitialDatas(response) {
|
||||||
|
$scope.cyberpanelLoading = true;
|
||||||
|
if (response.data.status === 1) {
|
||||||
|
new PNotify({
|
||||||
|
title: 'Success',
|
||||||
|
text: 'Successfully fetched.',
|
||||||
|
type: 'success'
|
||||||
|
});
|
||||||
|
$scope.emailMessageContent = response.data.emailMessageContent;
|
||||||
|
} else {
|
||||||
|
new PNotify({
|
||||||
|
title: 'Operation Failed!',
|
||||||
|
text: response.data.error_message,
|
||||||
|
type: 'error'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function cantLoadInitialDatas(response) {
|
||||||
|
$scope.cyberpanelLoading = true;
|
||||||
|
new PNotify({
|
||||||
|
title: 'Operation Failed!',
|
||||||
|
text: 'Could not connect to server, please refresh this page.',
|
||||||
|
type: 'error'
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
$scope.delete = function (type) {
|
||||||
|
$scope.cyberpanelLoading = false;
|
||||||
|
var config = {
|
||||||
|
headers: {
|
||||||
|
'X-CSRFToken': getCookie('csrftoken')
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
var data = {
|
||||||
|
type: type
|
||||||
|
};
|
||||||
|
|
||||||
|
dataurl = "/emailPremium/delete";
|
||||||
|
|
||||||
|
$http.post(dataurl, data, config).then(ListInitialDatas, cantLoadInitialDatas);
|
||||||
|
|
||||||
|
function ListInitialDatas(response) {
|
||||||
|
$scope.cyberpanelLoading = true;
|
||||||
|
if (response.data.status === 1) {
|
||||||
|
new PNotify({
|
||||||
|
title: 'Success',
|
||||||
|
text: 'Successfully deleted.',
|
||||||
|
type: 'success'
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
new PNotify({
|
||||||
|
title: 'Operation Failed!',
|
||||||
|
text: response.data.error_message,
|
||||||
|
type: 'error'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function cantLoadInitialDatas(response) {
|
||||||
|
$scope.cyberpanelLoading = true;
|
||||||
|
new PNotify({
|
||||||
|
title: 'Operation Failed!',
|
||||||
|
text: 'Could not connect to server, please refresh this page.',
|
||||||
|
type: 'error'
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
$scope.flushQueue = function () {
|
||||||
|
$scope.cyberpanelLoading = false;
|
||||||
|
var config = {
|
||||||
|
headers: {
|
||||||
|
'X-CSRFToken': getCookie('csrftoken')
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
var data = {
|
||||||
|
};
|
||||||
|
|
||||||
|
dataurl = "/emailPremium/flushQueue";
|
||||||
|
|
||||||
|
$http.post(dataurl, data, config).then(ListInitialDatas, cantLoadInitialDatas);
|
||||||
|
|
||||||
|
function ListInitialDatas(response) {
|
||||||
|
$scope.cyberpanelLoading = true;
|
||||||
|
if (response.data.status === 1) {
|
||||||
|
new PNotify({
|
||||||
|
title: 'Success',
|
||||||
|
text: 'Delivery scheduled.',
|
||||||
|
type: 'success'
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
new PNotify({
|
||||||
|
title: 'Operation Failed!',
|
||||||
|
text: response.data.error_message,
|
||||||
|
type: 'error'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function cantLoadInitialDatas(response) {
|
||||||
|
$scope.cyberpanelLoading = true;
|
||||||
|
new PNotify({
|
||||||
|
title: 'Operation Failed!',
|
||||||
|
text: 'Could not connect to server, please refresh this page.',
|
||||||
|
type: 'error'
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
/* Java script code to manage mail queue ends here */
|
/* Java script code to manage mail queue ends here */
|
||||||
@@ -26,7 +26,7 @@
|
|||||||
|
|
||||||
<div class="example-box-wrapper">
|
<div class="example-box-wrapper">
|
||||||
|
|
||||||
<div class="row">
|
<!-- <div class="row">
|
||||||
<div class="col-sm-10">
|
<div class="col-sm-10">
|
||||||
</div>
|
</div>
|
||||||
<div class="col-sm-2">
|
<div class="col-sm-2">
|
||||||
@@ -40,9 +40,15 @@
|
|||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div> -->
|
||||||
|
|
||||||
<table cellpadding="0" cellspacing="0" border="0" class="table table-striped table-bordered"
|
<button ng-click="fetchMailQueue()" class="btn btn-info">{% trans 'Refresh' %}</button>
|
||||||
|
<button ng-click="flushQueue()" class="btn btn-info">{% trans 'Flush Queue' %}</button>
|
||||||
|
<button ng-click="delete('all')" class="btn btn-info">{% trans 'Delete All' %}</button>
|
||||||
|
<button ng-click="delete('deferred')" class="btn btn-info">{% trans 'Delete Deferred' %}</button>
|
||||||
|
|
||||||
|
<table style="margin: 0px; padding: 0px" cellpadding="0" cellspacing="0" border="0"
|
||||||
|
class="table table-striped table-bordered"
|
||||||
id="datatable-example">
|
id="datatable-example">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
@@ -51,7 +57,8 @@
|
|||||||
<th>Size</th>
|
<th>Size</th>
|
||||||
<th>Sender</th>
|
<th>Sender</th>
|
||||||
<th>Recipients</th>
|
<th>Recipients</th>
|
||||||
<th>Time</th>
|
<!--<th>Time</th>-->
|
||||||
|
<th>Deliver</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
@@ -62,30 +69,58 @@
|
|||||||
<td ng-bind="queue.message_size"></td>
|
<td ng-bind="queue.message_size"></td>
|
||||||
<td ng-bind="queue.sender"></td>
|
<td ng-bind="queue.sender"></td>
|
||||||
<td ng-bind="queue.recipients"></td>
|
<td ng-bind="queue.recipients"></td>
|
||||||
<td ng-bind="queue.arrival_time"></td>
|
<!--<td ng-bind="queue.arrival_time"></td>-->
|
||||||
<!--<td>
|
|
||||||
<img style="margin-right: 4%;" ng-show="web.status==1"
|
|
||||||
title="{% trans 'Limits are being Applied!' %}"
|
|
||||||
src="{% static 'mailServer/vpsON.png' %}">
|
|
||||||
<button ng-click="enableDisableEmailLimits(0, web.domain)" ng-show="web.status==1"
|
|
||||||
class="btn ra-100 btn-danger">{% trans 'Disable' %}</button>
|
|
||||||
<img style="margin-right: 4%;" ng-show="web.status==0"
|
|
||||||
title="{% trans 'Limits are not being applied!' %}"
|
|
||||||
src="{% static 'mailServer/vpsOff.png' %}">
|
|
||||||
<button ng-click="enableDisableEmailLimits(1, web.domain)" ng-show="web.status==0"
|
|
||||||
class="btn ra-100 btn-success">{% trans 'Enable' %}</button>
|
|
||||||
</td>
|
|
||||||
<td>
|
<td>
|
||||||
<a href="/emailPremium/{$ web.domain $}">
|
<a data-toggle="modal" data-target="#viewMessage"
|
||||||
<button class="btn ra-100 btn-blue-alt">{% trans 'Manage' %}</button>
|
ng-click="fetchMessage(queue.queue_id)"
|
||||||
</a>
|
class="btn btn-border btn-alt border-green btn-link font-green" href="#"
|
||||||
</td>-->
|
title=""><span>View Message</span></a>
|
||||||
|
<div id="viewMessage" class="modal fade" role="dialog">
|
||||||
|
<div class="modal-dialog">
|
||||||
|
<!-- Modal content-->
|
||||||
|
<div class="modal-content">
|
||||||
|
<div class="modal-header">
|
||||||
|
<button type="button" class="close" data-dismiss="modal">×
|
||||||
|
</button>
|
||||||
|
<h4 class="modal-title">{% trans "Message" %}</h4>
|
||||||
|
</div>
|
||||||
|
<div class="modal-body">
|
||||||
|
|
||||||
|
<form name="containerSettingsForm" action="/" class="form-horizontal">
|
||||||
|
|
||||||
|
<div class="form-group">
|
||||||
|
|
||||||
|
<div class="col-sm-12">
|
||||||
|
<textarea rows="10"
|
||||||
|
class="form-control">{$ emailMessageContent $}</textarea>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</form>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<div class="modal-footer">
|
||||||
|
<button type="button"
|
||||||
|
class="btn btn-primary"
|
||||||
|
ng-click="commitChanges()">Commit <img
|
||||||
|
ng-hide="cyberpanelLoading"
|
||||||
|
src="{% static 'images/loading.gif' %}">
|
||||||
|
</button>
|
||||||
|
<button type="button"
|
||||||
|
class="btn btn-default" data-dismiss="modal">
|
||||||
|
Close
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
|
|
||||||
<div style="margin-top: 2%" class="row">
|
<!-- <div style="margin-top: 2%" class="row">
|
||||||
<div class="col-md-12">
|
<div class="col-md-12">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-md-9">
|
<div class="col-md-9">
|
||||||
@@ -100,8 +135,8 @@
|
|||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div> <!-- end row -->
|
|
||||||
</div>
|
</div>
|
||||||
|
</div> -->
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -35,6 +35,9 @@ urlpatterns = [
|
|||||||
url(r'^savePolicyServerStatus$', views.savePolicyServerStatus, name='savePolicyServerStatus'),
|
url(r'^savePolicyServerStatus$', views.savePolicyServerStatus, name='savePolicyServerStatus'),
|
||||||
url(r'^mailQueue$', views.mailQueue, name='mailQueue'),
|
url(r'^mailQueue$', views.mailQueue, name='mailQueue'),
|
||||||
url(r'^fetchMailQueue$', views.fetchMailQueue, name='fetchMailQueue'),
|
url(r'^fetchMailQueue$', views.fetchMailQueue, name='fetchMailQueue'),
|
||||||
|
url(r'^fetchMessage$', views.fetchMessage, name='fetchMessage'),
|
||||||
|
url(r'^flushQueue$', views.flushQueue, name='flushQueue'),
|
||||||
|
url(r'^delete$', views.delete, name='delete'),
|
||||||
|
|
||||||
url(r'^(?P<domain>(.*))$', views.emailLimits, name='emailLimits'),
|
url(r'^(?P<domain>(.*))$', views.emailLimits, name='emailLimits'),
|
||||||
|
|
||||||
|
|||||||
@@ -1072,3 +1072,98 @@ def fetchMailQueue(request):
|
|||||||
dic = {'status': 0, 'error_message': str(msg)}
|
dic = {'status': 0, 'error_message': str(msg)}
|
||||||
json_data = json.dumps(dic)
|
json_data = json.dumps(dic)
|
||||||
return HttpResponse(json_data)
|
return HttpResponse(json_data)
|
||||||
|
|
||||||
|
def fetchMessage(request):
|
||||||
|
try:
|
||||||
|
userID = request.session['userID']
|
||||||
|
currentACL = ACLManager.loadedACL(userID)
|
||||||
|
|
||||||
|
if currentACL['admin'] == 1:
|
||||||
|
pass
|
||||||
|
else:
|
||||||
|
return ACLManager.loadErrorJson()
|
||||||
|
try:
|
||||||
|
|
||||||
|
data = json.loads(request.body)
|
||||||
|
id = data['id']
|
||||||
|
|
||||||
|
command = 'postcat -vq %s' % (id)
|
||||||
|
emailMessageContent = ProcessUtilities.outputExecutioner(command)
|
||||||
|
|
||||||
|
|
||||||
|
dic = {'status': 1, 'error_message': 'None', 'emailMessageContent': emailMessageContent}
|
||||||
|
json_data = json.dumps(dic)
|
||||||
|
return HttpResponse(json_data)
|
||||||
|
|
||||||
|
except BaseException as msg:
|
||||||
|
dic = {'status': 0, 'error_message': str(msg)}
|
||||||
|
json_data = json.dumps(dic)
|
||||||
|
return HttpResponse(json_data)
|
||||||
|
|
||||||
|
except KeyError as msg:
|
||||||
|
dic = {'status': 0, 'error_message': str(msg)}
|
||||||
|
json_data = json.dumps(dic)
|
||||||
|
return HttpResponse(json_data)
|
||||||
|
|
||||||
|
def flushQueue(request):
|
||||||
|
try:
|
||||||
|
userID = request.session['userID']
|
||||||
|
currentACL = ACLManager.loadedACL(userID)
|
||||||
|
|
||||||
|
if currentACL['admin'] == 1:
|
||||||
|
pass
|
||||||
|
else:
|
||||||
|
return ACLManager.loadErrorJson()
|
||||||
|
try:
|
||||||
|
|
||||||
|
command = 'postqueue -f'
|
||||||
|
ProcessUtilities.executioner(command)
|
||||||
|
|
||||||
|
dic = {'status': 1, 'error_message': 'None'}
|
||||||
|
json_data = json.dumps(dic)
|
||||||
|
return HttpResponse(json_data)
|
||||||
|
|
||||||
|
except BaseException as msg:
|
||||||
|
dic = {'status': 0, 'error_message': str(msg)}
|
||||||
|
json_data = json.dumps(dic)
|
||||||
|
return HttpResponse(json_data)
|
||||||
|
|
||||||
|
except KeyError as msg:
|
||||||
|
dic = {'status': 0, 'error_message': str(msg)}
|
||||||
|
json_data = json.dumps(dic)
|
||||||
|
return HttpResponse(json_data)
|
||||||
|
|
||||||
|
def delete(request):
|
||||||
|
try:
|
||||||
|
userID = request.session['userID']
|
||||||
|
currentACL = ACLManager.loadedACL(userID)
|
||||||
|
|
||||||
|
if currentACL['admin'] == 1:
|
||||||
|
pass
|
||||||
|
else:
|
||||||
|
return ACLManager.loadErrorJson()
|
||||||
|
try:
|
||||||
|
|
||||||
|
data = json.loads(request.body)
|
||||||
|
type = data['type']
|
||||||
|
|
||||||
|
if type == 'all':
|
||||||
|
command = 'postsuper -d ALL'
|
||||||
|
else:
|
||||||
|
command = 'postsuper -d ALL deferred'
|
||||||
|
|
||||||
|
ProcessUtilities.executioner(command)
|
||||||
|
|
||||||
|
dic = {'status': 1, 'error_message': 'None'}
|
||||||
|
json_data = json.dumps(dic)
|
||||||
|
return HttpResponse(json_data)
|
||||||
|
|
||||||
|
except BaseException as msg:
|
||||||
|
dic = {'status': 0, 'error_message': str(msg)}
|
||||||
|
json_data = json.dumps(dic)
|
||||||
|
return HttpResponse(json_data)
|
||||||
|
|
||||||
|
except KeyError as msg:
|
||||||
|
dic = {'status': 0, 'error_message': str(msg)}
|
||||||
|
json_data = json.dumps(dic)
|
||||||
|
return HttpResponse(json_data)
|
||||||
@@ -1144,6 +1144,147 @@ app.controller('mailQueue', function($scope,$http) {
|
|||||||
|
|
||||||
};
|
};
|
||||||
$scope.fetchMailQueue();
|
$scope.fetchMailQueue();
|
||||||
|
|
||||||
|
$scope.fetchMessage = function (id) {
|
||||||
|
$scope.cyberpanelLoading = false;
|
||||||
|
var config = {
|
||||||
|
headers: {
|
||||||
|
'X-CSRFToken': getCookie('csrftoken')
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
var data = {
|
||||||
|
id: id
|
||||||
|
};
|
||||||
|
|
||||||
|
dataurl = "/emailPremium/fetchMessage";
|
||||||
|
|
||||||
|
$http.post(dataurl, data, config).then(ListInitialDatas, cantLoadInitialDatas);
|
||||||
|
|
||||||
|
function ListInitialDatas(response) {
|
||||||
|
$scope.cyberpanelLoading = true;
|
||||||
|
if (response.data.status === 1) {
|
||||||
|
new PNotify({
|
||||||
|
title: 'Success',
|
||||||
|
text: 'Successfully fetched.',
|
||||||
|
type: 'success'
|
||||||
|
});
|
||||||
|
$scope.emailMessageContent = response.data.emailMessageContent;
|
||||||
|
} else {
|
||||||
|
new PNotify({
|
||||||
|
title: 'Operation Failed!',
|
||||||
|
text: response.data.error_message,
|
||||||
|
type: 'error'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function cantLoadInitialDatas(response) {
|
||||||
|
$scope.cyberpanelLoading = true;
|
||||||
|
new PNotify({
|
||||||
|
title: 'Operation Failed!',
|
||||||
|
text: 'Could not connect to server, please refresh this page.',
|
||||||
|
type: 'error'
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
$scope.delete = function (type) {
|
||||||
|
$scope.cyberpanelLoading = false;
|
||||||
|
var config = {
|
||||||
|
headers: {
|
||||||
|
'X-CSRFToken': getCookie('csrftoken')
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
var data = {
|
||||||
|
type: type
|
||||||
|
};
|
||||||
|
|
||||||
|
dataurl = "/emailPremium/delete";
|
||||||
|
|
||||||
|
$http.post(dataurl, data, config).then(ListInitialDatas, cantLoadInitialDatas);
|
||||||
|
|
||||||
|
function ListInitialDatas(response) {
|
||||||
|
$scope.cyberpanelLoading = true;
|
||||||
|
if (response.data.status === 1) {
|
||||||
|
new PNotify({
|
||||||
|
title: 'Success',
|
||||||
|
text: 'Successfully deleted.',
|
||||||
|
type: 'success'
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
new PNotify({
|
||||||
|
title: 'Operation Failed!',
|
||||||
|
text: response.data.error_message,
|
||||||
|
type: 'error'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function cantLoadInitialDatas(response) {
|
||||||
|
$scope.cyberpanelLoading = true;
|
||||||
|
new PNotify({
|
||||||
|
title: 'Operation Failed!',
|
||||||
|
text: 'Could not connect to server, please refresh this page.',
|
||||||
|
type: 'error'
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
$scope.flushQueue = function () {
|
||||||
|
$scope.cyberpanelLoading = false;
|
||||||
|
var config = {
|
||||||
|
headers: {
|
||||||
|
'X-CSRFToken': getCookie('csrftoken')
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
var data = {
|
||||||
|
};
|
||||||
|
|
||||||
|
dataurl = "/emailPremium/flushQueue";
|
||||||
|
|
||||||
|
$http.post(dataurl, data, config).then(ListInitialDatas, cantLoadInitialDatas);
|
||||||
|
|
||||||
|
function ListInitialDatas(response) {
|
||||||
|
$scope.cyberpanelLoading = true;
|
||||||
|
if (response.data.status === 1) {
|
||||||
|
new PNotify({
|
||||||
|
title: 'Success',
|
||||||
|
text: 'Delivery scheduled.',
|
||||||
|
type: 'success'
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
new PNotify({
|
||||||
|
title: 'Operation Failed!',
|
||||||
|
text: response.data.error_message,
|
||||||
|
type: 'error'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function cantLoadInitialDatas(response) {
|
||||||
|
$scope.cyberpanelLoading = true;
|
||||||
|
new PNotify({
|
||||||
|
title: 'Operation Failed!',
|
||||||
|
text: 'Could not connect to server, please refresh this page.',
|
||||||
|
type: 'error'
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
/* Java script code to manage mail queue ends here */
|
/* Java script code to manage mail queue ends here */
|
||||||
@@ -4073,12 +4073,10 @@ StrictHostKeyChecking no
|
|||||||
try:
|
try:
|
||||||
web = Websites.objects.get(domain=self.domain)
|
web = Websites.objects.get(domain=self.domain)
|
||||||
self.web = web
|
self.web = web
|
||||||
externalApp = web.externalApp
|
|
||||||
self.folder = '/home/%s/public_html' % (domain)
|
self.folder = '/home/%s/public_html' % (domain)
|
||||||
self.masterDomain = domain
|
self.masterDomain = domain
|
||||||
except:
|
except:
|
||||||
web = ChildDomains.objects.get(domain=self.domain)
|
web = ChildDomains.objects.get(domain=self.domain)
|
||||||
externalApp = web.master.externalApp
|
|
||||||
self.folder = web.path
|
self.folder = web.path
|
||||||
self.masterDomain = web.master.domain
|
self.masterDomain = web.master.domain
|
||||||
self.web = web.master
|
self.web = web.master
|
||||||
|
|||||||
Reference in New Issue
Block a user