Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
C
converse.js
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
nexedi
converse.js
Commits
4979fd85
Commit
4979fd85
authored
Jan 09, 2015
by
Weblate
Browse files
Options
Browse Files
Download
Plain Diff
Merge remote-tracking branch 'origin/master'
parents
3fcc11ed
40b7dddf
Changes
16
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
16 changed files
with
277 additions
and
455 deletions
+277
-455
weblate/html/accounts/user.html
weblate/html/accounts/user.html
+6
-4
weblate/html/activity-tab.html
weblate/html/activity-tab.html
+19
-0
weblate/html/index.html
weblate/html/index.html
+2
-10
weblate/html/js/activity.html
weblate/html/js/activity.html
+0
-7
weblate/html/language.html
weblate/html/language.html
+2
-9
weblate/html/meta-header.html
weblate/html/meta-header.html
+2
-0
weblate/html/project.html
weblate/html/project.html
+2
-10
weblate/html/subproject.html
weblate/html/subproject.html
+2
-10
weblate/html/translation.html
weblate/html/translation.html
+2
-10
weblate/media/chartist.min.css
weblate/media/chartist.min.css
+7
-0
weblate/media/js/chartist.min.js
weblate/media/js/chartist.min.js
+8
-0
weblate/media/loader-bootstrap.js
weblate/media/loader-bootstrap.js
+48
-9
weblate/media/style-bootstrap.css
weblate/media/style-bootstrap.css
+4
-0
weblate/trans/tests/test_charts.py
weblate/trans/tests/test_charts.py
+33
-52
weblate/trans/views/charts.py
weblate/trans/views/charts.py
+104
-267
weblate/urls.py
weblate/urls.py
+36
-67
No files found.
weblate/html/accounts/user.html
View file @
4979fd85
...
...
@@ -40,11 +40,13 @@
{% endif %}
<h4>
{% trans "Activity in last 30 days" %}
</h4>
<img
src=
"{% url 'monthly_user_activity' user=page_user.username %}"
>
<span
class=
"hidden"
id=
"load-activity"
data-yearly=
"{% url 'json_yearly_activity' user=page_user.username %}"
data-monthly=
"{% url 'json_monthly_activity' user=page_user.username %}"
></span>
<h4>
{% trans "Activity in last year" %}
</h4>
<img
src=
"{% url 'yearly_user_activity' user=page_user.username %}"
>
<h3>
{% trans "Activity in last 30 days" %}
</h3>
<div
id=
"activity-month"
class=
"ct-chart ct-double-octave"
></div>
<h3>
{% trans "Activity in last year" %}
</h3>
<div
id=
"activity-year"
class=
"ct-chart ct-double-octave"
></div>
</div>
</div>
...
...
weblate/html/activity-tab.html
0 → 100644
View file @
4979fd85
{% load i18n %}
<div
class=
"tab-pane"
id=
"activity"
>
<div
class=
"panel panel-primary"
>
<div
class=
"panel-heading"
>
<h4
class=
"panel-title"
>
{% trans "Activity" %}
<i
id=
"activity-loading"
class=
"fa fa-spinner fa-spin pull-right flip"
></i>
</h4>
</div>
<div
class=
"panel-body"
>
<h3>
{% trans "Activity in last 30 days" %}
</h3>
<div
id=
"activity-month"
class=
"ct-chart ct-double-octave"
></div>
<h3>
{% trans "Activity in last year" %}
</h3>
<div
id=
"activity-year"
class=
"ct-chart ct-double-octave"
></div>
</div>
</div>
</div>
weblate/html/index.html
View file @
4979fd85
...
...
@@ -30,7 +30,7 @@
{% endif %}
<li><a
href=
"#search"
data-toggle=
"tab"
>
{% trans "Search" %}
</a></li>
<li><a
href=
"#history"
data-toggle=
"tab"
>
{% trans "History" %}
</a></li>
<li><a
href=
"#activity"
data-toggle=
"tab"
data-
href=
"{% url 'view
_activity' %}"
>
{% trans "Activity" %}
</a></li>
<li><a
href=
"#activity"
data-toggle=
"tab"
data-
load=
"activity"
data-yearly=
"{% url 'json_yearly_activity' %}"
data-monthly=
"{% url 'json_monthly
_activity' %}"
>
{% trans "Activity" %}
</a></li>
<li><a
href=
"#stats"
data-toggle=
"tab"
>
{% trans "Statistics" %}
</a></li>
<li
class=
"dropdown"
>
<a
class=
"dropdown-toggle"
data-toggle=
"dropdown"
href=
"#"
>
...
...
@@ -108,15 +108,7 @@
</div>
<div
class=
"tab-pane"
id=
"activity"
>
<div
class=
"panel panel-primary"
>
<div
class=
"panel-heading"
><h4
class=
"panel-title"
>
{% trans "Activity" %}
</h4></div>
<div
class=
"panel-body"
>
<p>
{% trans "Loading…" %}
</p>
</div>
</div>
</div>
{% include "activity-tab.html" %}
<div
class=
"tab-pane"
id=
"stats"
>
<div
class=
"row"
>
...
...
weblate/html/js/activity.html
deleted
100644 → 0
View file @
3fcc11ed
{% load i18n %}
<h3>
{% trans "Activity in last 30 days" %}
</h3>
<img
src=
"{{ monthly_url }}"
>
<h3>
{% trans "Activity in last year" %}
</h3>
<img
src=
"{{ yearly_url }}"
>
weblate/html/language.html
View file @
4979fd85
...
...
@@ -12,7 +12,7 @@
<ul
class=
"nav nav-pills"
>
<li
class=
"active"
><a
href=
"#overview"
data-toggle=
"tab"
>
{% trans "Overview" %}
</a></li>
<li><a
href=
"#history"
data-toggle=
"tab"
>
{% trans "History" %}
</a></li>
<li><a
href=
"#activity"
data-toggle=
"tab"
data-
href=
"{% url 'view_language
_activity' lang=object.code %}"
>
{% trans "Activity" %}
</a></li>
<li><a
href=
"#activity"
data-toggle=
"tab"
data-
load=
"activity"
data-yearly=
"{% url 'json_yearly_activity' lang=object.code %}"
data-monthly=
"{% url 'json_monthly
_activity' lang=object.code %}"
>
{% trans "Activity" %}
</a></li>
<li><a
href=
"#dicts"
data-toggle=
"tab"
>
{% trans "Glossaries" %}
</a></li>
<li
class=
"dropdown"
>
<a
class=
"dropdown-toggle"
data-toggle=
"dropdown"
href=
"#"
>
...
...
@@ -41,14 +41,7 @@
{% include "last-changes.html" %}
</div>
<div
class=
"tab-pane"
id=
"activity"
>
<div
class=
"panel panel-primary"
>
<div
class=
"panel-heading"
><h4
class=
"panel-title"
>
{% trans "Activity" %}
</h4></div>
<div
class=
"panel-body"
>
<p>
{% trans "Loading…" %}
</p>
</div>
</div>
</div>
{% include "activity-tab.html" %}
<div
class=
"tab-pane"
id=
"dicts"
>
<div
class=
"panel panel-primary"
>
...
...
weblate/html/meta-header.html
View file @
4979fd85
...
...
@@ -8,6 +8,7 @@
<link
rel=
"stylesheet"
type=
"text/css"
href=
"{% get_media_prefix %}font-awesome/css/font-awesome.min.css"
/>
<link
rel=
"stylesheet"
type=
"text/css"
href=
"{% get_media_prefix %}font-linux/font-linux.css"
/>
<link
rel=
"stylesheet"
type=
"text/css"
href=
"{% get_media_prefix %}bootstrap/css/datepicker3.css"
/>
<link
rel=
"stylesheet"
type=
"text/css"
href=
"{% get_media_prefix %}chartist.min.css"
/>
<link
rel=
"stylesheet"
type=
"text/css"
href=
"{% get_media_prefix %}style-bootstrap.css"
/>
<script
src=
"{% get_media_prefix %}js/jquery-2.1.1.min.js"
type=
"text/javascript"
></script>
<script
src=
"{% get_media_prefix %}js/jquery.cookie.js"
type=
"text/javascript"
></script>
...
...
@@ -15,6 +16,7 @@
<script
src=
"{% get_media_prefix %}js/jquery.sortElements.js"
type=
"text/javascript"
></script>
<script
src=
"{% get_media_prefix %}js/mousetrap.min.js"
type=
"text/javascript"
></script>
<script
src=
"{% get_media_prefix %}js/mousetrap-global-bind.min.js"
type=
"text/javascript"
></script>
<script
src=
"{% get_media_prefix %}js/chartist.min.js"
type=
"text/javascript"
></script>
<script
src=
"{% get_media_prefix %}bootstrap/js/bootstrap.min.js"
type=
"text/javascript"
></script>
<script
src=
"{% get_media_prefix %}loader-bootstrap.js"
type=
"text/javascript"
></script>
<script
src=
"{% url 'js-catalog' %}"
type=
"text/javascript"
></script>
...
...
weblate/html/project.html
View file @
4979fd85
...
...
@@ -15,7 +15,7 @@
<ul
class=
"nav nav-pills"
>
<li
class=
"active"
><a
href=
"#overview"
data-toggle=
"tab"
>
{% trans "Overview" %}
</a></li>
<li><a
href=
"#history"
data-toggle=
"tab"
>
{% trans "History" %}
</a></li>
<li><a
href=
"#activity"
data-toggle=
"tab"
data-
href=
"{% url 'view_activity_project
' project=object.slug %}"
>
{% trans "Activity" %}
</a></li>
<li><a
href=
"#activity"
data-toggle=
"tab"
data-
load=
"activity"
data-yearly=
"{% url 'json_yearly_activity' project=object.slug %}"
data-monthly=
"{% url 'json_monthly_activity
' project=object.slug %}"
>
{% trans "Activity" %}
</a></li>
<li
class=
"dropdown"
>
<a
class=
"dropdown-toggle"
data-toggle=
"dropdown"
href=
"#"
>
{% trans "Tools" %}
<span
class=
"caret"
></span>
...
...
@@ -126,15 +126,7 @@
{% include "last-changes.html" %}
</div>
<div
class=
"tab-pane"
id=
"activity"
>
<div
class=
"panel panel-primary"
>
<div
class=
"panel-heading"
><h4
class=
"panel-title"
>
{% trans "Activity" %}
</h4></div>
<div
class=
"panel-body"
>
<p>
{% trans "Loading…" %}
</p>
</div>
</div>
</div>
{% include "activity-tab.html" %}
{% if perms.trans.commit_translation or perms.trans.update_translation %}
<div
class=
"tab-pane"
id=
"repository"
>
...
...
weblate/html/subproject.html
View file @
4979fd85
...
...
@@ -17,7 +17,7 @@
<ul
class=
"nav nav-pills"
>
<li
class=
"active"
><a
href=
"#overview"
data-toggle=
"tab"
>
{% trans "Overview" %}
</a></li>
<li><a
href=
"#history"
data-toggle=
"tab"
>
{% trans "History" %}
</a></li>
<li><a
href=
"#activity"
data-toggle=
"tab"
data-
href=
"{% url 'view_activity_subproject
' project=object.project.slug subproject=object.slug %}"
>
{% trans "Activity" %}
</a></li>
<li><a
href=
"#activity"
data-toggle=
"tab"
data-
load=
"activity"
data-yearly=
"{% url 'json_yearly_activity' project=object.project.slug subproject=object.slug %}"
data-monthly=
"{% url 'json_monthly_activity
' project=object.project.slug subproject=object.slug %}"
>
{% trans "Activity" %}
</a></li>
<li
class=
"dropdown"
>
<a
class=
"dropdown-toggle"
data-toggle=
"dropdown"
href=
"#"
>
{% trans "Tools" %}
<span
class=
"caret"
></span>
...
...
@@ -113,15 +113,7 @@
{% include "last-changes.html" %}
</div>
<div
class=
"tab-pane"
id=
"activity"
>
<div
class=
"panel panel-primary"
>
<div
class=
"panel-heading"
><h4
class=
"panel-title"
>
{% trans "Activity" %}
</h4></div>
<div
class=
"panel-body"
>
<p>
{% trans "Loading…" %}
</p>
</div>
</div>
</div>
{% include "activity-tab.html" %}
{% if perms.trans.commit_translation or perms.trans.update_translation %}
<div
class=
"tab-pane"
id=
"repository"
>
...
...
weblate/html/translation.html
View file @
4979fd85
...
...
@@ -20,7 +20,7 @@
<li
class=
"active"
><a
href=
"#overview"
data-toggle=
"tab"
>
{% trans "Overview" %}
</a></li>
<li><a
href=
"#search"
data-toggle=
"tab"
>
{% trans "Search" %}
</a></li>
<li><a
href=
"#history"
data-toggle=
"tab"
>
{% trans "History" %}
</a></li>
<li><a
href=
"#activity"
data-toggle=
"tab"
data-
href=
"{% url 'view_activity_translation
' project=object.subproject.project.slug subproject=object.subproject.slug lang=object.language.code %}"
>
{% trans "Activity" %}
</a></li>
<li><a
href=
"#activity"
data-toggle=
"tab"
data-
load=
"activity"
data-yearly=
"{% url 'json_yearly_activity' project=object.subproject.project.slug subproject=object.subproject.slug lang=object.language.code %}"
data-monthly=
"{% url 'json_monthly_activity
' project=object.subproject.project.slug subproject=object.subproject.slug lang=object.language.code %}"
>
{% trans "Activity" %}
</a></li>
<li><a
href=
"#stats"
data-toggle=
"tab"
>
{% trans "Statistics" %}
</a></li>
<li
class=
"dropdown"
>
<a
class=
"dropdown-toggle"
data-toggle=
"dropdown"
href=
"#"
>
...
...
@@ -341,15 +341,7 @@
</div>
<div
class=
"tab-pane"
id=
"activity"
>
<div
class=
"panel panel-primary"
>
<div
class=
"panel-heading"
><h4
class=
"panel-title"
>
{% trans "Activity" %}
</h4></div>
<div
class=
"panel-body"
>
<p>
{% trans "Loading…" %}
</p>
</div>
</div>
</div>
{% include "activity-tab.html" %}
</div>
...
...
weblate/media/chartist.min.css
0 → 100644
View file @
4979fd85
/* Chartist.js 0.5.0
* Copyright © 2014 Gion Kunz
* Free to use under the WTFPL license.
* http://www.wtfpl.net/
*/
.ct-chart
.ct-label
,
.ct-chart
.ct-label.ct-horizontal
{
display
:
block
;
width
:
100%
;
height
:
100%
;
fill
:
rgba
(
0
,
0
,
0
,
.4
);
color
:
rgba
(
0
,
0
,
0
,
.4
);
font-size
:
.75rem
;
text-align
:
left
}
.ct-chart
.ct-label.ct-vertical
{
display
:
block
;
width
:
100%
;
height
:
100%
;
fill
:
rgba
(
0
,
0
,
0
,
.4
);
color
:
rgba
(
0
,
0
,
0
,
.4
);
font-size
:
.75rem
;
text-align
:
right
}
.ct-chart
.ct-grid
{
stroke
:
rgba
(
0
,
0
,
0
,
.2
);
stroke-width
:
1px
;
stroke-dasharray
:
2px
}
.ct-chart
.ct-point
{
stroke-width
:
10px
;
stroke-linecap
:
round
}
.ct-chart
.ct-line
{
fill
:
none
;
stroke-width
:
4px
}
.ct-chart
.ct-area
{
stroke
:
none
;
fill-opacity
:
.1
}
.ct-chart
.ct-bar
{
fill
:
none
;
stroke-width
:
10px
}
.ct-chart
.ct-slice.ct-donut
{
fill
:
none
;
stroke-width
:
60px
}
.ct-chart
.ct-series.ct-series-a
.ct-bar
,
.ct-chart
.ct-series.ct-series-a
.ct-line
,
.ct-chart
.ct-series.ct-series-a
.ct-point
,
.ct-chart
.ct-series.ct-series-a
.ct-slice.ct-donut
{
stroke
:
#d70206
}
.ct-chart
.ct-series.ct-series-a
.ct-area
,
.ct-chart
.ct-series.ct-series-a
.ct-slice
:not
(
.ct-donut
)
{
fill
:
#d70206
}
.ct-chart
.ct-series.ct-series-b
.ct-bar
,
.ct-chart
.ct-series.ct-series-b
.ct-line
,
.ct-chart
.ct-series.ct-series-b
.ct-point
,
.ct-chart
.ct-series.ct-series-b
.ct-slice.ct-donut
{
stroke
:
#F05B4F
}
.ct-chart
.ct-series.ct-series-b
.ct-area
,
.ct-chart
.ct-series.ct-series-b
.ct-slice
:not
(
.ct-donut
)
{
fill
:
#F05B4F
}
.ct-chart
.ct-series.ct-series-c
.ct-bar
,
.ct-chart
.ct-series.ct-series-c
.ct-line
,
.ct-chart
.ct-series.ct-series-c
.ct-point
,
.ct-chart
.ct-series.ct-series-c
.ct-slice.ct-donut
{
stroke
:
#F4C63D
}
.ct-chart
.ct-series.ct-series-c
.ct-area
,
.ct-chart
.ct-series.ct-series-c
.ct-slice
:not
(
.ct-donut
)
{
fill
:
#F4C63D
}
.ct-chart
.ct-series.ct-series-d
.ct-bar
,
.ct-chart
.ct-series.ct-series-d
.ct-line
,
.ct-chart
.ct-series.ct-series-d
.ct-point
,
.ct-chart
.ct-series.ct-series-d
.ct-slice.ct-donut
{
stroke
:
#453D3F
}
.ct-chart
.ct-series.ct-series-d
.ct-area
,
.ct-chart
.ct-series.ct-series-d
.ct-slice
:not
(
.ct-donut
)
{
fill
:
#453D3F
}
.ct-chart.ct-square
{
display
:
block
;
position
:
relative
;
width
:
100%
}
.ct-chart.ct-square
:before
{
display
:
block
;
float
:
left
;
content
:
""
;
width
:
0
;
height
:
0
;
padding-bottom
:
100%
}
.ct-chart.ct-square
:after
{
content
:
""
;
display
:
table
;
clear
:
both
}
.ct-chart.ct-square
>
svg
{
display
:
block
;
position
:
absolute
;
top
:
0
;
left
:
0
}
.ct-chart.ct-minor-second
{
display
:
block
;
position
:
relative
;
width
:
100%
}
.ct-chart.ct-minor-second
:before
{
display
:
block
;
float
:
left
;
content
:
""
;
width
:
0
;
height
:
0
;
padding-bottom
:
93.75%
}
.ct-chart.ct-minor-second
:after
{
content
:
""
;
display
:
table
;
clear
:
both
}
.ct-chart.ct-minor-second
>
svg
{
display
:
block
;
position
:
absolute
;
top
:
0
;
left
:
0
}
.ct-chart.ct-major-second
{
display
:
block
;
position
:
relative
;
width
:
100%
}
.ct-chart.ct-major-second
:before
{
display
:
block
;
float
:
left
;
content
:
""
;
width
:
0
;
height
:
0
;
padding-bottom
:
88.8888888889%
}
.ct-chart.ct-major-second
:after
{
content
:
""
;
display
:
table
;
clear
:
both
}
.ct-chart.ct-major-second
>
svg
{
display
:
block
;
position
:
absolute
;
top
:
0
;
left
:
0
}
.ct-chart.ct-minor-third
{
display
:
block
;
position
:
relative
;
width
:
100%
}
.ct-chart.ct-minor-third
:before
{
display
:
block
;
float
:
left
;
content
:
""
;
width
:
0
;
height
:
0
;
padding-bottom
:
83.3333333333%
}
.ct-chart.ct-minor-third
:after
{
content
:
""
;
display
:
table
;
clear
:
both
}
.ct-chart.ct-minor-third
>
svg
{
display
:
block
;
position
:
absolute
;
top
:
0
;
left
:
0
}
.ct-chart.ct-major-third
{
display
:
block
;
position
:
relative
;
width
:
100%
}
.ct-chart.ct-major-third
:before
{
display
:
block
;
float
:
left
;
content
:
""
;
width
:
0
;
height
:
0
;
padding-bottom
:
80%
}
.ct-chart.ct-major-third
:after
{
content
:
""
;
display
:
table
;
clear
:
both
}
.ct-chart.ct-major-third
>
svg
{
display
:
block
;
position
:
absolute
;
top
:
0
;
left
:
0
}
.ct-chart.ct-perfect-fourth
{
display
:
block
;
position
:
relative
;
width
:
100%
}
.ct-chart.ct-perfect-fourth
:before
{
display
:
block
;
float
:
left
;
content
:
""
;
width
:
0
;
height
:
0
;
padding-bottom
:
75%
}
.ct-chart.ct-perfect-fourth
:after
{
content
:
""
;
display
:
table
;
clear
:
both
}
.ct-chart.ct-perfect-fourth
>
svg
{
display
:
block
;
position
:
absolute
;
top
:
0
;
left
:
0
}
.ct-chart.ct-perfect-fifth
{
display
:
block
;
position
:
relative
;
width
:
100%
}
.ct-chart.ct-perfect-fifth
:before
{
display
:
block
;
float
:
left
;
content
:
""
;
width
:
0
;
height
:
0
;
padding-bottom
:
66.6666666667%
}
.ct-chart.ct-perfect-fifth
:after
{
content
:
""
;
display
:
table
;
clear
:
both
}
.ct-chart.ct-perfect-fifth
>
svg
{
display
:
block
;
position
:
absolute
;
top
:
0
;
left
:
0
}
.ct-chart.ct-minor-sixth
{
display
:
block
;
position
:
relative
;
width
:
100%
}
.ct-chart.ct-minor-sixth
:before
{
display
:
block
;
float
:
left
;
content
:
""
;
width
:
0
;
height
:
0
;
padding-bottom
:
62.5%
}
.ct-chart.ct-minor-sixth
:after
{
content
:
""
;
display
:
table
;
clear
:
both
}
.ct-chart.ct-minor-sixth
>
svg
{
display
:
block
;
position
:
absolute
;
top
:
0
;
left
:
0
}
.ct-chart.ct-golden-section
{
display
:
block
;
position
:
relative
;
width
:
100%
}
.ct-chart.ct-golden-section
:before
{
display
:
block
;
float
:
left
;
content
:
""
;
width
:
0
;
height
:
0
;
padding-bottom
:
61.804697157%
}
.ct-chart.ct-golden-section
:after
{
content
:
""
;
display
:
table
;
clear
:
both
}
.ct-chart.ct-golden-section
>
svg
{
display
:
block
;
position
:
absolute
;
top
:
0
;
left
:
0
}
.ct-chart.ct-major-sixth
{
display
:
block
;
position
:
relative
;
width
:
100%
}
.ct-chart.ct-major-sixth
:before
{
display
:
block
;
float
:
left
;
content
:
""
;
width
:
0
;
height
:
0
;
padding-bottom
:
60%
}
.ct-chart.ct-major-sixth
:after
{
content
:
""
;
display
:
table
;
clear
:
both
}
.ct-chart.ct-major-sixth
>
svg
{
display
:
block
;
position
:
absolute
;
top
:
0
;
left
:
0
}
.ct-chart.ct-minor-seventh
{
display
:
block
;
position
:
relative
;
width
:
100%
}
.ct-chart.ct-minor-seventh
:before
{
display
:
block
;
float
:
left
;
content
:
""
;
width
:
0
;
height
:
0
;
padding-bottom
:
56.25%
}
.ct-chart.ct-minor-seventh
:after
{
content
:
""
;
display
:
table
;
clear
:
both
}
.ct-chart.ct-minor-seventh
>
svg
{
display
:
block
;
position
:
absolute
;
top
:
0
;
left
:
0
}
.ct-chart.ct-major-seventh
{
display
:
block
;
position
:
relative
;
width
:
100%
}
.ct-chart.ct-major-seventh
:before
{
display
:
block
;
float
:
left
;
content
:
""
;
width
:
0
;
height
:
0
;
padding-bottom
:
53.3333333333%
}
.ct-chart.ct-major-seventh
:after
{
content
:
""
;
display
:
table
;
clear
:
both
}
.ct-chart.ct-major-seventh
>
svg
{
display
:
block
;
position
:
absolute
;
top
:
0
;
left
:
0
}
.ct-chart.ct-octave
{
display
:
block
;
position
:
relative
;
width
:
100%
}
.ct-chart.ct-octave
:before
{
display
:
block
;
float
:
left
;
content
:
""
;
width
:
0
;
height
:
0
;
padding-bottom
:
50%
}
.ct-chart.ct-octave
:after
{
content
:
""
;
display
:
table
;
clear
:
both
}
.ct-chart.ct-octave
>
svg
{
display
:
block
;
position
:
absolute
;
top
:
0
;
left
:
0
}
.ct-chart.ct-major-tenth
{
display
:
block
;
position
:
relative
;
width
:
100%
}
.ct-chart.ct-major-tenth
:before
{
display
:
block
;
float
:
left
;
content
:
""
;
width
:
0
;
height
:
0
;
padding-bottom
:
40%
}
.ct-chart.ct-major-tenth
:after
{
content
:
""
;
display
:
table
;
clear
:
both
}
.ct-chart.ct-major-tenth
>
svg
{
display
:
block
;
position
:
absolute
;
top
:
0
;
left
:
0
}
.ct-chart.ct-major-eleventh
{
display
:
block
;
position
:
relative
;
width
:
100%
}
.ct-chart.ct-major-eleventh
:before
{
display
:
block
;
float
:
left
;
content
:
""
;
width
:
0
;
height
:
0
;
padding-bottom
:
37.5%
}
.ct-chart.ct-major-eleventh
:after
{
content
:
""
;
display
:
table
;
clear
:
both
}
.ct-chart.ct-major-eleventh
>
svg
{
display
:
block
;
position
:
absolute
;
top
:
0
;
left
:
0
}
.ct-chart.ct-major-twelfth
{
display
:
block
;
position
:
relative
;
width
:
100%
}
.ct-chart.ct-major-twelfth
:before
{
display
:
block
;
float
:
left
;
content
:
""
;
width
:
0
;
height
:
0
;
padding-bottom
:
33.3333333333%
}
.ct-chart.ct-major-twelfth
:after
{
content
:
""
;
display
:
table
;
clear
:
both
}
.ct-chart.ct-major-twelfth
>
svg
{
display
:
block
;
position
:
absolute
;
top
:
0
;
left
:
0
}
.ct-chart.ct-double-octave
{
display
:
block
;
position
:
relative
;
width
:
100%
}
.ct-chart.ct-double-octave
:before
{
display
:
block
;
float
:
left
;
content
:
""
;
width
:
0
;
height
:
0
;
padding-bottom
:
25%
}
.ct-chart.ct-double-octave
:after
{
content
:
""
;
display
:
table
;
clear
:
both
}
.ct-chart.ct-double-octave
>
svg
{
display
:
block
;
position
:
absolute
;
top
:
0
;
left
:
0
}
\ No newline at end of file
weblate/media/js/chartist.min.js
0 → 100644
View file @
4979fd85
This diff is collapsed.
Click to expand it.
weblate/media/loader-bootstrap.js
View file @
4979fd85
var
loading
=
0
;
var
mt_loaded
=
false
;
var
activity_loaded
=
false
;
function
inc_loading
()
{
function
inc_loading
(
sel
)
{
if
(
loading
===
0
)
{
$
(
'
#mt-loading
'
).
show
();
$
(
sel
).
show
();
}
loading
++
;
}
function
dec_loading
()
{
function
dec_loading
(
sel
)
{
loading
--
;
if
(
loading
===
0
)
{
$
(
'
#mt-loading
'
).
hide
();
$
(
sel
).
hide
();
}
}
...
...
@@ -42,6 +43,33 @@ jQuery.fn.extend({
}
});
function
load_activity
(
element
)
{
if
(
activity_loaded
)
{
return
;
}
activity_loaded
=
true
;
inc_loading
(
'
#activity-loading
'
);
$
.
ajax
({
url
:
element
.
data
(
'
monthly
'
),
success
:
function
(
data
)
{
new
Chartist
.
Bar
(
'
#activity-month
'
,
data
);
dec_loading
(
'
#activity-loading
'
);
},
dataType
:
'
json
'
});
inc_loading
(
'
#activity-loading
'
);
$
.
ajax
({
url
:
element
.
data
(
'
yearly
'
),
success
:
function
(
data
)
{
new
Chartist
.
Bar
(
'
#activity-year
'
,
data
);
dec_loading
(
'
#activity-loading
'
);
},
dataType
:
'
json
'
});
}
function
init_editor
(
editors
)
{
/* Autosizing */
$
(
'
.translation-editor
'
).
autosize
();
...
...
@@ -92,7 +120,7 @@ function text_change(e) {
}
function
process_machine_translation
(
data
,
textStatus
,
jqXHR
)
{
dec_loading
();
dec_loading
(
'
#mt-loading
'
);
if
(
data
.
responseStatus
==
200
)
{
data
.
translations
.
forEach
(
function
(
el
,
idx
,
ar
)
{
var
new_row
=
$
(
'
<tr/>
'
).
data
(
'
quality
'
,
el
.
quality
);
...
...
@@ -129,16 +157,16 @@ function process_machine_translation(data, textStatus, jqXHR) {
}
function
failed_machine_translation
(
jqXHR
,
textStatus
,
errorThrown
)
{
dec_loading
();
dec_loading
(
'
#mt-loading
'
);
$
(
'
#mt-errors
'
).
append
(
$
(
'
<li>
'
+
gettext
(
'
The request for machine translation has failed:
'
)
+
'
'
+
textStatus
+
'
</li>
'
)
);
}
function
load_mt_translations
(
data
,
textStatus
,
jqXHR
)
{
dec_loading
();
dec_loading
(
'
#mt-loading
'
);
data
.
forEach
(
function
(
el
,
idx
,
ar
)
{
inc_loading
();
inc_loading
(
'
#mt-loading
'
);
$
.
ajax
({
url
:
$
(
'
#js-translate
'
).
attr
(
'
href
'
)
+
'
?service=
'
+
el
,
success
:
process_machine_translation
,
...
...
@@ -287,13 +315,24 @@ $(function () {
);
});
/* Activity charts on tabs */
$
(
document
).
on
(
'
show.bs.tab
'
,
'
[data-load="activity"]
'
,
function
(
e
)
{
load_activity
(
$
(
this
));
});
/* Automatic loading of activity charts on page load */
var
auto_load_activity
=
$
(
'
#load-activity
'
);
if
(
auto_load_activity
.
length
>
0
)
{
load_activity
(
auto_load_activity
);
}
/* Machine translation */
$
(
document
).
on
(
'
show.bs.tab
'
,
'
[data-load="mt"]
'
,
function
(
e
)
{
if
(
mt_loaded
)
{
return
;
}
mt_loaded
=
true
;
inc_loading
();
inc_loading
(
'
#mt-loading
'
);
$
.
ajax
({
url
:
$
(
'
#js-mt-services
'
).
attr
(
'
href
'
),
success
:
load_mt_translations
,
...
...
weblate/media/style-bootstrap.css
View file @
4979fd85
...
...
@@ -225,3 +225,7 @@ img.engage-icon {
#columns-menu
label
{
font-weight
:
normal
;
}
.ct-chart
.ct-series.ct-series-a
.ct-bar
{
stroke
:
#337AB7
;
stroke-width
:
15px
;
}
weblate/trans/tests/test_charts.py
View file @
4979fd85
...
...
@@ -24,111 +24,92 @@ Tests for charts and widgets.
from
weblate.trans.tests.test_views
import
ViewTestCase
from
django.core.urlresolvers
import
reverse
import
json
class
ChartsTest
(
ViewTestCase
):
'''
Testing of charts.
'''
def
test_activity_html
(
self
):
'''
Test of html for activity charts.
'''
response
=
self
.
client
.
get
(
reverse
(
'view_activity'
)
)
self
.
assertContains
(
response
,
'img src="/activity'
)
response
=
self
.
client
.
get
(
reverse
(
'view_activity_project'
,
kwargs
=
self
.
kw_project
)
)
self
.
assertContains
(
response
,
'img src="/activity'
)
response
=
self
.
client
.
get
(
reverse
(
'view_activity_subproject'
,
kwargs
=
self
.
kw_subproject
)
)
self
.
assertContains
(
response
,
'img src="/activity'
)
response
=
self
.
client
.
get
(
reverse
(
'view_activity_translation'
,
kwargs
=
self
.
kw_translation
)
)
self
.
assertContains
(
response
,
'img src="/activity'
)
response
=
self
.
client
.
get
(
reverse
(
'view_language_activity'
,
kwargs
=
{
'lang'
:
'cs'
})
)
self
.
assertContains
(
response
,
'img src="/activity'
)
def
assert_json_chart_data
(
self
,
response
):
"""
Tests whether response has valid json chart data.
"""
self
.
assertEquals
(
response
.
get
(
'Content-Type'
),
'application/json'
)
data
=
json
.
loads
(
response
.
content
)
self
.
assertTrue
(
'series'
in
data
)
self
.
assertTrue
(
'labels'
in
data
)
def
test_activity_monthly
(
self
):
'''
Test of monthly activity charts.
'''
response
=
self
.
client
.
get
(
reverse
(
'monthly_activity'
)
reverse
(
'
json_
monthly_activity'
)
)
self
.
assert
PNG
(
response
)
self
.
assert
_json_chart_data
(
response
)
response
=
self
.
client
.
get
(
reverse
(
'
monthly_activity_project
'
,
kwargs
=
self
.
kw_project
)
reverse
(
'
json_monthly_activity
'
,
kwargs
=
self
.
kw_project
)
)
self
.
assert
PNG
(
response
)
self
.
assert
_json_chart_data
(
response
)
response
=
self
.
client
.
get
(
reverse
(
'
monthly_activity_subproject
'
,
kwargs
=
self
.
kw_subproject
)
reverse
(
'
json_monthly_activity
'
,
kwargs
=
self
.
kw_subproject
)
)
self
.
assert
PNG
(
response
)
self
.
assert
_json_chart_data
(
response
)
response
=
self
.
client
.
get
(
reverse
(
'
monthly_activity_translation
'
,
kwargs
=
self
.
kw_translation
)
reverse
(
'
json_monthly_activity
'
,
kwargs
=
self
.
kw_translation
)
)
self
.
assert
PNG
(
response
)
self
.
assert
_json_chart_data
(
response
)
response
=
self
.
client
.
get
(
reverse
(
'
monthly_language
_activity'
,
kwargs
=
{
'lang'
:
'cs'
})
reverse
(
'
json_monthly
_activity'
,
kwargs
=
{
'lang'
:
'cs'
})
)
self
.
assert
PNG
(
response
)
self
.
assert
_json_chart_data
(
response
)
response
=
self
.
client
.
get
(
reverse
(
'
monthly_user
_activity'
,
'
json_monthly
_activity'
,
kwargs
=
{
'user'
:
self
.
user
.
username
}
)
)
self
.
assert
PNG
(
response
)
self
.
assert
_json_chart_data
(
response
)
def
test_activity_yearly
(
self
):
'''
Test of yearly activity charts.
'''
response
=
self
.
client
.
get
(
reverse
(
'yearly_activity'
)
reverse
(
'
json_
yearly_activity'
)
)
self
.
assert
PNG
(
response
)
self
.
assert
_json_chart_data
(
response
)
response
=
self
.
client
.
get
(
reverse
(
'
yearly_activity_project
'
,
kwargs
=
self
.
kw_project
)
reverse
(
'
json_yearly_activity
'
,
kwargs
=
self
.
kw_project
)
)
self
.
assert
PNG
(
response
)
self
.
assert
_json_chart_data
(
response
)
response
=
self
.
client
.
get
(
reverse
(
'
yearly_activity_subproject
'
,
kwargs
=
self
.
kw_subproject
)
reverse
(
'
json_yearly_activity
'
,
kwargs
=
self
.
kw_subproject
)
)
self
.
assert
PNG
(
response
)
self
.
assert
_json_chart_data
(
response
)
response
=
self
.
client
.
get
(
reverse
(
'
yearly_activity_translation
'
,
kwargs
=
self
.
kw_translation
)
reverse
(
'
json_yearly_activity
'
,
kwargs
=
self
.
kw_translation
)
)
self
.
assert
PNG
(
response
)
self
.
assert
_json_chart_data
(
response
)
response
=
self
.
client
.
get
(
reverse
(
'
yearly_language
_activity'
,
kwargs
=
{
'lang'
:
'cs'
})
reverse
(
'
json_yearly
_activity'
,
kwargs
=
{
'lang'
:
'cs'
})
)
self
.
assert
PNG
(
response
)
self
.
assert
_json_chart_data
(
response
)
response
=
self
.
client
.
get
(
reverse
(
'
yearly_user
_activity'
,
'
json_yearly
_activity'
,
kwargs
=
{
'user'
:
self
.
user
.
username
}
)
)
self
.
assert
PNG
(
response
)
self
.
assert
_json_chart_data
(
response
)
weblate/trans/views/charts.py
View file @
4979fd85
...
...
@@ -24,288 +24,125 @@ Charting library for Weblate.
from
weblate.trans.models
import
Change
from
weblate.lang.models
import
Language
from
weblate.trans.views.helper
import
get_project_translation
from
django.shortcuts
import
render
,
get_object_or_404
from
django.shortcuts
import
get_object_or_404
from
django.http
import
HttpResponse
from
django.contrib.auth.models
import
User
from
cStringIO
import
StringIO
from
django.core.urlresolvers
import
reverse
from
PIL
import
Image
,
ImageDraw
from
weblate.trans.fonts
import
get_font
def
render_activity
(
activity
):
'''
Helper for rendering activity charts.
'''
# Preprocess data for chart
maximum
=
max
([
l
[
1
]
for
l
in
activity
]
+
[
1
])
step
=
780.0
/
len
(
activity
)
# Prepare image
image
=
Image
.
new
(
'RGB'
,
(
800
,
100
),
'white'
)
draw
=
ImageDraw
.
Draw
(
image
)
# Render axises
draw
.
line
(((
15
,
5
),
(
15
,
85
),
(
795
,
85
)),
fill
=
'black'
)
# Load font
font
=
get_font
(
11
)
# Create Y axis label
y_label
=
str
(
maximum
)
text
=
Image
.
new
(
'L'
,
font
.
getsize
(
y_label
),
'white'
)
draw_txt
=
ImageDraw
.
Draw
(
text
)
draw_txt
.
text
((
0
,
0
),
y_label
,
font
=
font
,
fill
=
'black'
)
text
=
text
.
transpose
(
Image
.
ROTATE_90
)
image
.
paste
(
text
,
(
2
,
5
))
# Counter for rendering ticks
last
=
-
40
# Render activity itself
for
offset
,
value
in
enumerate
(
activity
):
# Calculate position
current
=
offset
*
step
# Render bar
draw
.
rectangle
(
(
20
+
current
,
84
,
20
+
current
+
(
step
/
2
),
84
-
value
[
1
]
*
78.0
/
maximum
),
fill
=
(
0
,
67
,
118
)
)
# Skip axis labels if they are too frequent
if
current
<
last
+
40
:
continue
last
=
current
# X-Axis ticks
draw
.
text
(
(
15
+
current
,
86
),
value
[
0
].
strftime
(
'%m/%d'
),
font
=
font
,
fill
=
'black'
from
django.utils.translation
import
pgettext
import
json
def
get_json_stats
(
request
,
days
,
step
,
project
=
None
,
subproject
=
None
,
lang
=
None
,
user
=
None
):
"""
Parse json stats URL params.
"""
if
project
is
None
and
lang
is
None
and
user
is
None
:
project
=
None
subproject
=
None
translation
=
None
language
=
None
user
=
None
elif
user
is
not
None
:
project
=
None
subproject
=
None
translation
=
None
language
=
None
user
=
get_object_or_404
(
User
,
username
=
user
)
elif
project
is
None
:
project
=
None
subproject
=
None
translation
=
None
language
=
get_object_or_404
(
Language
,
code
=
lang
)
user
=
None
else
:
# Process parameters
project
,
subproject
,
translation
=
get_project_translation
(
request
,
project
,
subproject
,
lang
)
# Render surface to PNG
out
=
StringIO
()
image
.
convert
(
'P'
,
palette
=
Image
.
ADAPTIVE
).
save
(
out
,
'PNG'
)
# Return response
return
HttpResponse
(
content_type
=
'image/png'
,
content
=
out
.
getvalue
())
def
monthly_activity
(
request
,
project
=
None
,
subproject
=
None
,
lang
=
None
):
'''
Show monthly activity chart.
'''
# Process parameters
project
,
subproject
,
translation
=
get_project_translation
(
request
,
project
,
subproject
,
lang
)
language
=
None
user
=
None
# Get actual stats
activity
=
Change
.
objects
.
month_stats
(
project
,
subproject
,
translation
)
# Render chart
return
render_activity
(
activity
)
def
yearly_activity
(
request
,
project
=
None
,
subproject
=
None
,
lang
=
None
):
'''
Show yearly activity chart.
'''
# Process parameters
project
,
subproject
,
translation
=
get_project_translation
(
request
,
return
Change
.
objects
.
base_stats
(
days
,
step
,
project
,
subproject
,
lang
)
# Get actual stats
activity
=
Change
.
objects
.
year_stats
(
project
,
subproject
,
translation
)
# Render chart
return
render_activity
(
activity
)
def
monthly_language_activity
(
request
,
lang
):
'''
Show monthly activity chart.
'''
# Process parameters
language
=
get_object_or_404
(
Language
,
code
=
lang
)
# Get actual stats
activity
=
Change
.
objects
.
month_stats
(
language
=
language
)
# Render chart
return
render_activity
(
activity
)
def
yearly_language_activity
(
request
,
lang
):
'''
Show yearly activity chart.
'''
# Process parameters
language
=
get_object_or_404
(
Language
,
code
=
lang
)
# Get actual stats
activity
=
Change
.
objects
.
year_stats
(
language
=
language
translation
,
language
,
user
)
# Render chart
return
render_activity
(
activity
)
def
monthly_user_activity
(
request
,
user
):
'''
Show monthly activity chart.
'''
# Process parameters
user
=
get_object_or_404
(
User
,
username
=
user
)
# Get actual stats
activity
=
Change
.
objects
.
month_stats
(
user
=
user
def
json_yearly_activity
(
request
,
project
=
None
,
subproject
=
None
,
lang
=
None
,
user
=
None
):
"""
Returns yearly activity for matching changes as json.
"""
activity
=
get_json_stats
(
request
,
365
,
7
,
project
,
subproject
,
lang
)
# Render chart
return
render_activity
(
activity
)
def
yearly_user_activity
(
request
,
user
):
'''
Show yearly activity chart.
'''
# Process parameters
user
=
get_object_or_404
(
User
,
username
=
user
)
# Get actual stats
activity
=
Change
.
objects
.
year_stats
(
user
=
user
# Format
serie
=
[]
labels
=
[]
month
=
-
1
for
item
in
activity
:
serie
.
append
(
item
[
1
])
if
month
!=
item
[
0
].
month
:
labels
.
append
(
pgettext
(
'Format string for yearly activity chart'
,
'{month}/{year}'
).
format
(
month
=
item
[
0
].
month
,
year
=
item
[
0
].
year
,
)
)
month
=
item
[
0
].
month
else
:
labels
.
append
(
''
)
return
HttpResponse
(
content_type
=
'application/json'
,
content
=
json
.
dumps
({
'series'
:
[
serie
],
'labels'
:
labels
})
)
# Render chart
return
render_activity
(
activity
)
def
view_activity
(
request
,
project
=
None
,
subproject
=
None
,
lang
=
None
):
'''
Show html with activity charts.
'''
# Process parameters
project
,
subproject
,
translation
=
get_project_translation
(
request
,
project
,
subproject
,
lang
)
if
translation
is
not
None
:
kwargs
=
{
'project'
:
project
.
slug
,
'subproject'
:
subproject
.
slug
,
'lang'
:
translation
.
language
.
code
,
}
monthly_url
=
reverse
(
'monthly_activity_translation'
,
kwargs
=
kwargs
)
yearly_url
=
reverse
(
'yearly_activity_translation'
,
kwargs
=
kwargs
)
elif
subproject
is
not
None
:
kwargs
=
{
'project'
:
project
.
slug
,
'subproject'
:
subproject
.
slug
,
}
monthly_url
=
reverse
(
'monthly_activity_subproject'
,
kwargs
=
kwargs
)
yearly_url
=
reverse
(
'yearly_activity_subproject'
,
kwargs
=
kwargs
)
elif
project
is
not
None
:
kwargs
=
{
'project'
:
project
.
slug
,
}
monthly_url
=
reverse
(
'monthly_activity_project'
,
kwargs
=
kwargs
)
yearly_url
=
reverse
(
'yearly_activity_project'
,
kwargs
=
kwargs
)
else
:
monthly_url
=
reverse
(
'monthly_activity'
,
)
yearly_url
=
reverse
(
'yearly_activity'
,
)
return
render
(
request
,
'js/activity.html'
,
{
'yearly_url'
:
yearly_url
,
'monthly_url'
:
monthly_url
,
}
)
def
view_language_activity
(
request
,
lang
):
'''
Show html with activity charts.
'''
# Process parameters
language
=
get_object_or_404
(
Language
,
code
=
lang
)
monthly_url
=
reverse
(
'monthly_language_activity'
,
kwargs
=
{
'lang'
:
language
.
code
},
)
yearly_url
=
reverse
(
'yearly_language_activity'
,
kwargs
=
{
'lang'
:
language
.
code
},
def
json_monthly_activity
(
request
,
project
=
None
,
subproject
=
None
,
lang
=
None
,
user
=
None
):
"""
Returns monthly activity for matching changes as json.
"""
activity
=
get_json_stats
(
request
,
31
,
1
,
project
,
subproject
,
lang
)
return
render
(
request
,
'js/activity.html'
,
{
'yearly_url'
:
yearly_url
,
'monthly_url'
:
monthly_url
,
}
# Format
serie
=
[]
labels
=
[]
for
pos
,
item
in
enumerate
(
activity
):
serie
.
append
(
item
[
1
])
if
pos
%
5
==
0
:
labels
.
append
(
pgettext
(
'Format string for monthly activity chart'
,
'{day}/{month}'
).
format
(
day
=
item
[
0
].
day
,
month
=
item
[
0
].
month
,
year
=
item
[
0
].
year
,
)
)
else
:
labels
.
append
(
''
)
return
HttpResponse
(
content_type
=
'application/json'
,
content
=
json
.
dumps
({
'series'
:
[
serie
],
'labels'
:
labels
})
)
weblate/urls.py
View file @
4979fd85
...
...
@@ -202,99 +202,68 @@ urlpatterns = patterns(
name
=
'delete-user'
,
),
# Activity HTML
url
(
r'^activity/html/$'
,
'weblate.trans.views.charts.view_activity'
,
name
=
'view_activity'
,
),
# Monthly activity
url
(
r'^activity
/html/'
+
PROJECT
+
'
$'
,
'weblate.trans.views.charts.
view
_activity'
,
name
=
'
view_activity_project
'
,
r'^activity
-json/month/
$'
,
'weblate.trans.views.charts.
json_monthly
_activity'
,
name
=
'
json_monthly_activity
'
,
),
url
(
r'^activity
/html/'
+
SUB
PROJECT
+
'$'
,
'weblate.trans.views.charts.
view
_activity'
,
name
=
'
view_activity_subproject
'
,
r'^activity
-json/month/'
+
PROJECT
+
'$'
,
'weblate.trans.views.charts.
json_monthly
_activity'
,
name
=
'
json_monthly_activity
'
,
),
url
(
r'^activity
/html/'
+
TRANSLATION
+
'$'
,
'weblate.trans.views.charts.
view
_activity'
,
name
=
'
view_activity_translation
'
,
r'^activity
-json/month/'
+
SUBPROJECT
+
'$'
,
'weblate.trans.views.charts.
json_monthly
_activity'
,
name
=
'
json_monthly_activity
'
,
),
# Monthly activity
url
(
r'^activity
/month/
$'
,
'weblate.trans.views.charts.monthly_activity'
,
name
=
'monthly_activity'
,
r'^activity
-json/month/'
+
TRANSLATION
+
'
$'
,
'weblate.trans.views.charts.
json_
monthly_activity'
,
name
=
'
json_
monthly_activity'
,
),
url
(
r'^activity
/month/'
+
PROJECT
+
'
$'
,
'weblate.trans.views.charts.monthly_activity'
,
name
=
'
monthly_activity_project
'
,
r'^activity
-json/language/month/'
+
LANGUAGE
+
'/
$'
,
'weblate.trans.views.charts.
json_
monthly_activity'
,
name
=
'
json_monthly_activity
'
,
),
url
(
r'^activity/month/'
+
SUBPROJECT
+
'$'
,
'weblate.trans.views.charts.monthly_activity'
,
name
=
'monthly_activity_subproject'
,
),
url
(
r'^activity/month/'
+
TRANSLATION
+
'$'
,
'weblate.trans.views.charts.monthly_activity'
,
name
=
'monthly_activity_translation'
,
r'^activity/user/month/(?P<user>[^/]+)/$'
,
'weblate.trans.views.charts.json_monthly_activity'
,
name
=
'json_monthly_activity'
,
),
# Yearly activity
url
(
r'^activity/year/$'
,
'weblate.trans.views.charts.yearly_activity'
,
name
=
'yearly_activity'
,
r'^activity
-json
/year/$'
,
'weblate.trans.views.charts.
json_
yearly_activity'
,
name
=
'
json_
yearly_activity'
,
),
url
(
r'^activity/year/'
+
PROJECT
+
'$'
,
'weblate.trans.views.charts.yearly_activity'
,
name
=
'
yearly_activity_project
'
,
r'^activity
-json
/year/'
+
PROJECT
+
'$'
,
'weblate.trans.views.charts.
json_
yearly_activity'
,
name
=
'
json_yearly_activity
'
,
),
url
(
r'^activity/year/'
+
SUBPROJECT
+
'$'
,
'weblate.trans.views.charts.yearly_activity'
,
name
=
'
yearly_activity_subproject
'
,
r'^activity
-json
/year/'
+
SUBPROJECT
+
'$'
,
'weblate.trans.views.charts.
json_
yearly_activity'
,
name
=
'
json_yearly_activity
'
,
),
url
(
r'^activity/year/'
+
TRANSLATION
+
'$'
,
'weblate.trans.views.charts.yearly_activity'
,
name
=
'
yearly_activity_translation
'
,
r'^activity
-json
/year/'
+
TRANSLATION
+
'$'
,
'weblate.trans.views.charts.
json_
yearly_activity'
,
name
=
'
json_yearly_activity
'
,
),
# Per language activity
url
(
r'^activity/language/html/'
+
LANGUAGE
+
'/$'
,
'weblate.trans.views.charts.view_language_activity'
,
name
=
'view_language_activity'
,
),
url
(
r'^activity/language/month/'
+
LANGUAGE
+
'/$'
,
'weblate.trans.views.charts.monthly_language_activity'
,
name
=
'monthly_language_activity'
,
),
url
(
r'^activity/language/year/'
+
LANGUAGE
+
'/$'
,
'weblate.trans.views.charts.yearly_language_activity'
,
name
=
'yearly_language_activity'
,
),
# Per user activity
url
(
r'^activity/user/month/(?P<user>[^/]+)/$'
,
'weblate.trans.views.charts.monthly_user_activity'
,
name
=
'monthly_user_activity'
,
r'^activity-json/language/year/'
+
LANGUAGE
+
'/$'
,
'weblate.trans.views.charts.json_yearly_activity'
,
name
=
'json_yearly_activity'
,
),
url
(
r'^activity/user/year/(?P<user>[^/]+)/$'
,
'weblate.trans.views.charts.
yearly_user
_activity'
,
name
=
'
yearly_user
_activity'
,
'weblate.trans.views.charts.
json_yearly
_activity'
,
name
=
'
json_yearly
_activity'
,
),
# Comments
...
...
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