Skip to content
Toggle navigation
P
Projects
G
Groups
S
Snippets
Help
Gutyán Gábor
/
circlestack
This project
Loading...
Sign in
Toggle navigation
Go to a project
Project
Repository
Issues
0
Merge Requests
0
Pipelines
Wiki
Snippets
Members
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Commit
4833c479
authored
Jun 27, 2014
by
Kálmán Viktor
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'feature-stacked-activites' into 'master'
Feature Stacked Activites Closes #141
parents
695cd9bd
e6a26476
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
46 additions
and
8 deletions
+46
-8
circle/dashboard/static/dashboard/vm-details.js
+15
-1
circle/dashboard/templates/dashboard/vm-detail/_activity-timeline.html
+6
-4
circle/dashboard/views.py
+4
-3
circle/vm/models/instance.py
+21
-0
No files found.
circle/dashboard/static/dashboard/vm-details.js
View file @
4833c479
...
@@ -328,6 +328,17 @@ function decideActivityRefresh() {
...
@@ -328,6 +328,17 @@ function decideActivityRefresh() {
return
check
;
return
check
;
}
}
/* unescapes html got via the request, also removes whitespaces and replaces all ' with " */
function
unescapeHTML
(
html
)
{
return
html
.
replace
(
/</g
,
'<'
).
replace
(
/>/g
,
'>'
).
replace
(
/&/g
,
'&'
).
replace
(
/–/g
,
"–"
).
replace
(
/
\/
/g
,
""
).
replace
(
/'/g
,
'"'
).
replace
(
/ /g
,
''
);
}
/* the html page contains some tags that were modified via js (titles for example), we delete these
also some html tags are closed with / */
function
changeHTML
(
html
)
{
return
html
.
replace
(
/data-original-title/g
,
"title"
).
replace
(
/title=""/g
,
""
).
replace
(
/
\/
/g
,
''
).
replace
(
/ /g
,
''
);
}
function
checkNewActivity
(
only_status
,
runs
)
{
function
checkNewActivity
(
only_status
,
runs
)
{
// set default only_status to false
// set default only_status to false
only_status
=
typeof
only_status
!==
'undefined'
?
only_status
:
false
;
only_status
=
typeof
only_status
!==
'undefined'
?
only_status
:
false
;
...
@@ -339,7 +350,10 @@ function checkNewActivity(only_status, runs) {
...
@@ -339,7 +350,10 @@ function checkNewActivity(only_status, runs) {
data
:
{
'only_status'
:
only_status
},
data
:
{
'only_status'
:
only_status
},
success
:
function
(
data
)
{
success
:
function
(
data
)
{
if
(
!
only_status
)
{
if
(
!
only_status
)
{
$
(
"#activity-timeline"
).
html
(
data
[
'activities'
]);
a
=
unescapeHTML
(
data
[
'activities'
]);
b
=
changeHTML
(
$
(
"#activity-timeline"
).
html
());
if
(
a
!=
b
)
$
(
"#activity-timeline"
).
html
(
data
[
'activities'
]);
$
(
"#ops"
).
html
(
data
[
'ops'
]);
$
(
"#ops"
).
html
(
data
[
'ops'
]);
$
(
"#disk-ops"
).
html
(
data
[
'disk_ops'
]);
$
(
"#disk-ops"
).
html
(
data
[
'disk_ops'
]);
$
(
"[title]"
).
tooltip
();
$
(
"[title]"
).
tooltip
();
...
...
circle/dashboard/templates/dashboard/vm-detail/_activity-timeline.html
View file @
4833c479
...
@@ -6,16 +6,18 @@
...
@@ -6,16 +6,18 @@
</span>
</span>
<strong
{%
if
user
.
is_superuser
and
a
.
result
%}
title=
"{{ a.result }}"
{%
endif
%}
>
<strong
{%
if
user
.
is_superuser
and
a
.
result
%}
title=
"{{ a.result }}"
{%
endif
%}
>
{% if user.is_superuser %}
<a
href=
"{{ a.get_absolute_url }}"
>
{% endif %}
{% if user.is_superuser %}
<a
href=
"{{ a.get_absolute_url }}"
>
{% endif %}
{% if a.times > 1 %}({{ a.times }}x){% endif %}
{{ a.get_readable_name }}{% if user.is_superuser %}
</a>
{% endif %}
{{ a.get_readable_name }}{% if user.is_superuser %}
</a>
{% endif %}
{% if a.has_percent %}
- {{ a.percentage }}%
{% endif %}
</strong>
</strong>
{
{ a.started|date:"Y-m-d H:i" }
}{% if a.user %},
{
% if a.times
<
2
%}{{
a
.
started
|
date:
"
Y-m-d
H:i
"
}}{%
endif
%
}{%
if
a
.
user
%},
<
a
class=
"no-style-link"
href=
"{% url "
dashboard
.
views
.
profile
"
username=
a.user.username
%}"
>
<
a
class=
"no-style-link"
href=
"{% url "
dashboard
.
views
.
profile
"
username=
a.user.username
%}"
>
{% include "dashboard/_display-name.html" with user=a.user show_org=True %}
{% include "dashboard/_display-name.html" with user=a.user show_org=True %}
</a>
</a>
{% endif %}
{% endif %}
{% if a.has_percent %}
{{ a.percentage }}%
{% endif %}
{% if a.is_abortable_for_user %}
{% if a.is_abortable_for_user %}
<form
action=
"{{ a.instance.get_absolute_url }}"
method=
"POST"
class=
"pull-right"
>
<form
action=
"{{ a.instance.get_absolute_url }}"
method=
"POST"
class=
"pull-right"
>
{% csrf_token %}
{% csrf_token %}
...
...
circle/dashboard/views.py
View file @
4833c479
...
@@ -272,7 +272,8 @@ class VmDetailView(CheckedDetailView):
...
@@ -272,7 +272,8 @@ class VmDetailView(CheckedDetailView):
})
})
# activity data
# activity data
context
[
'activities'
]
=
self
.
object
.
get_activities
(
self
.
request
.
user
)
context
[
'activities'
]
=
self
.
object
.
get_merged_activities
(
self
.
request
.
user
)
context
[
'vlans'
]
=
Vlan
.
get_objects_with_level
(
context
[
'vlans'
]
=
Vlan
.
get_objects_with_level
(
'user'
,
self
.
request
.
user
'user'
,
self
.
request
.
user
...
@@ -2115,7 +2116,7 @@ class LeaseDelete(LoginRequiredMixin, SuperuserRequiredMixin, DeleteView):
...
@@ -2115,7 +2116,7 @@ class LeaseDelete(LoginRequiredMixin, SuperuserRequiredMixin, DeleteView):
@require_GET
@require_GET
def
vm_activity
(
request
,
pk
):
def
vm_activity
(
request
,
pk
):
instance
=
Instance
.
objects
.
get
(
pk
=
pk
)
instance
=
Instance
.
objects
.
get
(
pk
=
pk
)
if
not
instance
.
has_level
(
request
.
user
,
'
own
er'
):
if
not
instance
.
has_level
(
request
.
user
,
'
us
er'
):
raise
PermissionDenied
()
raise
PermissionDenied
()
response
=
{}
response
=
{}
...
@@ -2127,7 +2128,7 @@ def vm_activity(request, pk):
...
@@ -2127,7 +2128,7 @@ def vm_activity(request, pk):
if
only_status
==
"false"
:
# instance activity
if
only_status
==
"false"
:
# instance activity
context
=
{
context
=
{
'instance'
:
instance
,
'instance'
:
instance
,
'activities'
:
instance
.
get_activities
(
request
.
user
),
'activities'
:
instance
.
get_
merged_
activities
(
request
.
user
),
'ops'
:
get_operations
(
instance
,
request
.
user
),
'ops'
:
get_operations
(
instance
,
request
.
user
),
}
}
...
...
circle/vm/models/instance.py
View file @
4833c479
...
@@ -927,6 +927,27 @@ class Instance(AclBase, VirtualMachineDescModel, StatusModel, OperatedMixin,
...
@@ -927,6 +927,27 @@ class Instance(AclBase, VirtualMachineDescModel, StatusModel, OperatedMixin,
user
=
user
)
user
=
user
)
return
acts
return
acts
def
get_merged_activities
(
self
,
user
=
None
):
whitelist
=
(
"create_disk"
,
"download_disk"
)
acts
=
self
.
get_activities
(
user
)
merged_acts
=
[]
latest
=
None
for
a
in
acts
:
if
(
latest
==
a
.
activity_code
and
merged_acts
[
-
1
]
.
result
==
a
.
result
and
a
.
finished
and
merged_acts
[
-
1
]
.
finished
and
a
.
user
==
merged_acts
[
-
1
]
.
user
and
(
merged_acts
[
-
1
]
.
finished
-
a
.
finished
)
.
days
<
7
and
not
a
.
activity_code
.
endswith
(
whitelist
)):
merged_acts
[
-
1
]
.
times
+=
1
else
:
merged_acts
.
append
(
a
)
merged_acts
[
-
1
]
.
times
=
1
latest
=
a
.
activity_code
return
merged_acts
def
get_screenshot
(
self
,
timeout
=
5
):
def
get_screenshot
(
self
,
timeout
=
5
):
queue_name
=
self
.
get_remote_queue_name
(
'vm'
)
queue_name
=
self
.
get_remote_queue_name
(
'vm'
)
return
vm_tasks
.
screenshot
.
apply_async
(
args
=
[
self
.
vm_name
],
return
vm_tasks
.
screenshot
.
apply_async
(
args
=
[
self
.
vm_name
],
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment