New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[Feature] Statistics page #5464
Conversation
3aa6510
to
a7eaa24
Compare
end | ||
|
||
def datas | ||
@@result = { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please don't use class variables, also data is an uncountable noun, there's zero need for a sideffet method here and I think you should just use a hash or even use the existing presenter, so @data = StatisticsPresenter.new
Please use Bootstrap. Also I think that's a bit plain, how about some boxes:
in a fluid grid? |
@@ -47,6 +47,7 @@ en: | |||
_contacts: "Contacts" | |||
welcome: "Welcome!" | |||
_terms: "terms" | |||
_statistics: "Statistics :" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hm, yeah, french syntax, sorry :P
I think a simple controller test would be nice that just checks that the response was a success, so we notice that we break the page by for example changing the presenter. |
Yeah, sure. This is really wip. I wanted to use boxes too. And for statistics_controller.rb, I will talk about with @augier. |
respond_to :json | ||
|
||
|
||
respond_to :html |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This needs to respond to :json
too, as it did before, otherwise that will break a few pod lists ;)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh, ok. Thx :)
a7eaa24
to
b60577c
Compare
%h4 | ||
= t('statistics.registrations') | ||
%br | ||
= @as_registrations |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think there's a way to loop here. TODO.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If you use the presenter you could probably utilize its as_json method which returns a hash.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We can do that indeed.
I think overall larger font sizes would look good. |
border-radius: 5px; | ||
} | ||
|
||
.page-statistics .span-3 .data{ margin-top: 15px; } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actually why not apply some of SCSS features, most notably nesting:
.page-statistics {
h1 {
}
.span-3 {
.data {
}
}
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Argh! It's just because I don't used to use framework. Thanks :)
Even if the route is "statistics", those informations are more or less the characteristics of the pods (registration, services enabled (you're missing them btw), version...). Maybe we could present it a little bit differently? With another more global title for example. And then, we could add a link to that page on diasporafoundation.org / poduti.me to help users choose their pod. |
Yeah, maybe even larger and maybe larger for the values. |
posts: "Local posts" | ||
comments: "Local comments" | ||
version: "Version" | ||
registrations: "Registrations opened" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe just Registrations
- if the result is Open/Closed
Also, some of the lines are all capital letters, some only first capital letter. The latter I think should be correct, so just first word has capital letter :)
Looks ok to me. I have to find an elegant way to translate "true" values to "open". |
|
||
result | ||
end | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@jhass : I find this part a bit over-engineered. I have the feeling that there's a better way to do that, especially deal with translations but this is the least ugly way I found.
Please make sure to use two spaces for indentation, no tabs. Also please try to avoid using the datastructure of things in in their names, that generally leads to bad names. I guess it's time to refactor the presenter a bit, something like (completely untested): class StatisticsPresenter
def as_json options={}
base_data.merge(user_counts)
.merge(post_counts)
.merge(comment_counts)
.merge(services)
.merge(legacy_services) # Remove in 0.6
end
def base_data
{
'name' => name,
'network' => 'Diaspora',
'version' => version,
'registrations_open' => open_registrations?,
'services' => available_services
}
end
def name
AppConfig.settings.pod_name
end
def version
AppConfig.version_string
end
def open_registrations?
AppConfig.settings.enable_registrations
end
def user_counts
return {} unless expose_user_counts?
{
'total_users' => total_users,
'active_users_monthly' => monthly_users,
'active_users_halfyear' => halfyear_users
}
end
def expose_user_counts?
AppConfig.privacy.statistics.user_counts?
end
def total_users
@total_users ||= User.joins(:person)
.where(people: {closed_account: false})
.where.not(username: nil)
end
def monthly_users
@monthly_users ||= User.halfyear_actives.count
end
def halfyear_users
@halfyear_users ||= User.monthly_actives.count
end
def post_counts
return {} unless expose_posts_counts?
{
'local_posts' => local_posts
}
end
def local_posts
@local_posts ||= Post.where(type: "StatusMessage")
.joins(:author)
.where("owner_id IS NOT null")
.count
end
def expose_posts_counts?
AppConfig.privacy.statistics.post_counts?
end
def comment_counts
return {} unless expose_comment_counts?
{
'local_comments' => local_comments
}
end
def expose_comment_counts?
AppConfig.privacy.statistics.comment_counts?
end
def local_comments
@local_comments ||= Comment.joins(:author)
.where("owner_id IS NOT null")
.count
end
def available_services
Configuration::KNOWN_SERVICES.select {|service|
AppConfig["services.#{service}.enable"]
}.map(&:to_s)
end
def legacy_services
Configuration::KNOWN_SERVICES.each_with_object({}) {|service, result|
result[service.to_s] = AppConfig["services.#{service}.enable"]
}
end
end Then a controller like class StatisticsController < ApplicationController
respond_to :html, :json
use_bootstrap_for :statistics
def statistics
@statistics = StatisticsPresenter.new
respond_to do |format|
format.json { render json: @statistics }
format.html { render layout: "application" }
end
end
end With a = render 'statistics/statistic', locals: {name: t('.name'), value: @statistics.name}
= render 'statistics/statistic', locals: {name: t('.version'), value: @statistics.version}
= render 'statistics/statistic', locals: {name: t('.registrations'), value: registrations_status(@statistics)}
- if @statistics.expose_user_counts?
= render 'statistics/statistic', locals {name: t('.total_users'), value: @statistics.total_users}
// and so on and a .span-3
%h3
= name
.data
= value and a module StatisticsHelper
def registrations_status statistics
if statistics.open_registrations?
I18n.t('statistics.registrations.enabled')
else
I18n.t('statistics.registrations.disabled')
end
end
end I don't think it hurts that much to repeat listing the available keys in the view, since the representation between the JSON and the HTML can differ quite a lot. |
Thanks for the advice and having taken time to improve this. |
This PR will be run only by pod with 0.5 or more so we don't need to add compatibility with the 0.4.1 format do we? |
We decided in #5296 to keep the old format in 0.5, you even voted in favor of that. See also changelog. |
I see |
The convention is |
Then the heading shouldn't say "Available services", but just "Services" and the values should be "Available" / "Not available" or "Unavailable". |
I find "Available" and "Not available" not explicit. |
@AugierLe42e ah ! You see ? ;) I think "available" is more explicite than "enabled" too.
True. |
This is a stats page for podmins, right? If so, I agree that
but think the values should be 'Enabled' / 'Not enabled' (rather than 'Available' / 'Not available') as all these services are available to the podmin if the podmin enables them. (They'd be unavailable to users of the pod if the podmin hasn't enabled them, but to say 'Not available' to a podmin suggest that the service can't be connected, so I think 'Not enabled' is better.) |
I wouldn't say this is specifically for podmins. Podmins have their own stats in the admin panel. |
Ah, I thought this was a new design for stats in the admin panel. So this is a public view for the JSON stats, then? In which case, 'Available' / 'Not available' would be appropriate, I agree. |
Yes, it's a public HTML representation for /statistics.json basically. |
f9a537f
to
e4e1bea
Compare
@AugierLe42e cleaned up the code (thx mate). |
@SansPseudoFix : ya welcome buddy ! |
%h1 | ||
= t('statistics.services') | ||
- Configuration::KNOWN_SERVICES.each do |service| | ||
= render 'statistics/statistic', name: "#{service.capitalize}", value: service_status(service, @statistics.available_services), activated: service_class(service, @statistics.available_services) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Did you get an error when requesting the mobile format, or why do you have an exact duplicate here?
If so, instead of duplicating the template, try rendering the same one for both formats:
respond_to do |format|
format.json { }
format.any(:html, :mobile) { render 'statistics/statistics.html.haml' }
end
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Did you get an error when requesting the mobile format, or why do you have an exact duplicate here?
No, just we didn't know how to do that.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I did neither, just googled it ;)
@jhass : Fixed, you can merge. |
Thanks! |
Yeah \o/ |
Argh... Last time I tried, no. I'll try today. |
Confirmed. This is |
Looks like a problem with bootstrap and the rendering line. |
How the hell do you guys success to mix git that way? This page now shows only two files modified when https://github.com/diaspora/diaspora/pull/5587/files shows a lot... I'm sorry, but it looks like you break stuff, including the statistics.json route which now invert the monthly and the 6 monthly active users... see https://diaspora-fr.org/statistics.json for example. |
Don't sweat @Flaburgan - mistakes happen to everyone, and part of the blame is the people who review the PR's. This is not a critical issue, but of course needs to be fixed, issue here: #5589 |
We create a more readable page for stats. At the moment, it's basic. But we prefer be sure to do it well.
I dont' know for others pods, but framasphere's users like check stats :)