From 20a08561bc1e08e4637aab7a0cd8cb54807a817c Mon Sep 17 00:00:00 2001 From: Axel Naumann Date: Tue, 29 Mar 2016 18:41:13 +0000 Subject: [PATCH 001/125] Make PgSQL happy ("ActiveRecord::StatementInvalid: PG::ProtocolViolation"). See https://meta.discourse.org/t/install-error-protocol-violation-with-postgresql/35160 --- config/database.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/config/database.yml b/config/database.yml index fb6d923aea..e9a2a50369 100644 --- a/config/database.yml +++ b/config/database.yml @@ -16,6 +16,7 @@ development: # re-generated from your development database when you run "rake". # Do not set this db to the same as development or production. test: + prepared_statements: false adapter: postgresql database: discourse_test min_messages: warning From c0d81a298e543fa14383a554837003a611d88c28 Mon Sep 17 00:00:00 2001 From: Nick Ivanter Date: Fri, 15 Apr 2016 21:59:46 +0300 Subject: [PATCH 002/125] Add 'alt' tag to logo img in digest email The rationale for this is that the logo, as any other image, is not loaded by default by many email clients. In absence of an 'alt' tag, it shows an empty space in the email. Having the site title in there seems better. --- app/views/user_notifications/digest.html.erb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/user_notifications/digest.html.erb b/app/views/user_notifications/digest.html.erb index fe5962f669..acf396294b 100644 --- a/app/views/user_notifications/digest.html.erb +++ b/app/views/user_notifications/digest.html.erb @@ -5,7 +5,7 @@ <%- if logo_url.blank? %> <%= SiteSetting.title %> <%- else %> - + <%- end %> From cd4c34204d9a01f07202e030030c6ee5aa60a20b Mon Sep 17 00:00:00 2001 From: shakti katare Date: Tue, 19 Apr 2016 18:02:01 +0530 Subject: [PATCH 003/125] Fix: Suspensions and Blocks do not give enough details in logs --- app/jobs/regular/export_csv_file.rb | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/app/jobs/regular/export_csv_file.rb b/app/jobs/regular/export_csv_file.rb index ddb6d6b929..7c69a3a3fe 100644 --- a/app/jobs/regular/export_csv_file.rb +++ b/app/jobs/regular/export_csv_file.rb @@ -225,13 +225,15 @@ module Jobs elsif attr == 'staff_user' user = User.find_by(id: staff_action.attributes['acting_user_id']) user.username if !user.nil? + elsif attr == 'subject' + user = User.find_by(id: staff_action.attributes['target_user_id']) + user.nil? ? staff_action.attributes[attr] : "#{user.username} #{staff_action.attributes[attr]}" else staff_action.attributes[attr] end staff_action_array.push(data) end - staff_action_array end From f43f0452f8d65f43193e7001874dda04671187cf Mon Sep 17 00:00:00 2001 From: Jeff Atwood Date: Wed, 20 Apr 2016 16:26:00 -0700 Subject: [PATCH 004/125] we auto-set DB RAM and unicorns now based on detected CPU and RAM --- docs/INSTALL-cloud.md | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/docs/INSTALL-cloud.md b/docs/INSTALL-cloud.md index 4c0faf053c..48a37b3a35 100644 --- a/docs/INSTALL-cloud.md +++ b/docs/INSTALL-cloud.md @@ -63,9 +63,7 @@ We recommend Nano because it's simple; just use your arrow keys to edit. - Place your [Email Server credentials][mailconfig] in `DISCOURSE_SMTP_ADDRESS`, `DISCOURSE_SMTP_PORT`, `DISCOURSE_SMTP_USER_NAME`, `DISCOURSE_SMTP_PASSWORD`. Be sure you remove the comment `#` character and space from the front of these lines as necessary. -- If you are using a 1 GB instance, set `UNICORN_WORKERS` to 2 and `db_shared_buffers` to 128MB so you have more memory room. - - + Please be careful while editing and double check your work; YAML is _very_ sensitive to incorrect spacing and misplaced characters. After completing your edits, press CtrlO then Enter to save and CtrlX to exit. From 3aa8593dabb335ba81de170a5a7dcc5327ad9ae6 Mon Sep 17 00:00:00 2001 From: Neil Lalonde Date: Wed, 20 Apr 2016 19:19:12 -0400 Subject: [PATCH 005/125] Version bump to v1.6.0.beta2 --- lib/version.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/version.rb b/lib/version.rb index 48cc209af3..3431cc5334 100644 --- a/lib/version.rb +++ b/lib/version.rb @@ -5,7 +5,7 @@ module Discourse MAJOR = 1 MINOR = 6 TINY = 0 - PRE = 'beta1' + PRE = 'beta2' STRING = [MAJOR, MINOR, TINY, PRE].compact.join('.') end From f7d0e8461d3c97003dd2b44a1bcc3e864dc51494 Mon Sep 17 00:00:00 2001 From: Dean Taylor Date: Thu, 21 Apr 2016 02:23:58 +0100 Subject: [PATCH 006/125] Minor spelling mistake and language consistency "Return" instead of "Return". "unactivated" changed to "deactivated". Mostly "cannot" is currently used, changed existing "can not" occurrences. "there was no attachments" to "there were no attachments". --- config/locales/server.en.yml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/config/locales/server.en.yml b/config/locales/server.en.yml index c5eab8c7e6..966723f90f 100644 --- a/config/locales/server.en.yml +++ b/config/locales/server.en.yml @@ -43,7 +43,7 @@ en: powered_by_html: 'Powered by Discourse, best viewed with JavaScript enabled' log_in: "Log In" - purge_reason: "Automatically deleted as abandoned, unactivated account" + purge_reason: "Automatically deleted as abandoned, deactivated account" disable_remote_images_download_reason: "Remote images download was disabled because there wasn't enough disk space available." anonymous: "Anonymous" @@ -55,7 +55,7 @@ en: empty_email_error: "Happens when the raw mail we received was blank." no_message_id_error: "Happens when the mail has no 'Message-Id' header." auto_generated_email_error: "Happens when the 'precedence' header is set to: list, junk, bulk or auto_reply, or when any other header contains: auto-submitted, auto-replied or auto-generated." - no_body_detected_error: "Happens when we couldn't extract a body and there was no attachments." + no_body_detected_error: "Happens when we couldn't extract a body and there were no attachments." inactive_user_error: "Happens when the sender is not active." blocked_user_error: "Happens when the sender has been blocked." bad_destination_address: "Happens when none of the email addresses in To/Cc/Bcc fields matched a configured incoming email address." @@ -222,7 +222,7 @@ en: groups: errors: - can_not_modify_automatic: "You can not modify an automatic group" + can_not_modify_automatic: "You cannot modify an automatic group" member_already_exist: "'%{username}' is already a member of this group." invalid_domain: "'%{domain}' is not a valid domain." invalid_incoming_email: "'%{email}' is not a valid email address." @@ -540,7 +540,7 @@ en: continue_button: "Continue to %{site_name}" welcome_to: "Welcome to %{site_name}!" approval_required: "A moderator must manually approve your new account before you can access this forum. You'll get an email when your account is approved!" - missing_session: "We can not detect if your account was created, please ensure you have cookies enabled." + missing_session: "We cannot detect if your account was created, please ensure you have cookies enabled." post_action_types: off_topic: title: 'Off-Topic' @@ -819,7 +819,7 @@ en: title: "The name of this site, as used in the title tag." site_description: "Describe this site in one sentence, as used in the meta description tag." contact_email: "Email address of key contact responsible for this site. Used for critical notifications such as unhandled flags, as well as on the /about contact form for urgent matters." - bounce_email: "Variable Email Return Path used for emails, example: bounce@example.com will cause us to generate bounce+GUID@example.com as the Retrun Path for emails we send. This feature allows us to automatically disable bouncing emails. Requires additional configurations, leave blank if unsure." + bounce_email: "Variable Email Return Path used for emails, example: bounce@example.com will cause us to generate bounce+GUID@example.com as the Return Path for emails we send. This feature allows us to automatically disable bouncing emails. Requires additional configurations, leave blank if unsure." contact_url: "Contact URL for this site. Used on the /about contact form for urgent matters." queue_jobs: "DEVELOPER ONLY! WARNING! By default, queue jobs in sidekiq. If disabled, your site will be broken." crawl_images: "Retrieve images from remote URLs to insert the correct width and height dimensions." From b744306654c716a2306b1c5b2f98c39a3e70d465 Mon Sep 17 00:00:00 2001 From: Guo Xiang Tan Date: Wed, 20 Apr 2016 09:34:30 +0800 Subject: [PATCH 007/125] PERF: Uglify and gzip assets concurrently. --- lib/tasks/assets.rake | 54 +++++++++++++++++++++++++++---------------- 1 file changed, 34 insertions(+), 20 deletions(-) diff --git a/lib/tasks/assets.rake b/lib/tasks/assets.rake index 3e68b4213b..dd71a22f84 100644 --- a/lib/tasks/assets.rake +++ b/lib/tasks/assets.rake @@ -116,6 +116,16 @@ def compress(from,to) end end +def concurrent? + if ENV["CONCURRENT"] == "1" + concurrent_compressors = [] + yield(Proc.new { |&block| concurrent_compressors << Concurrent::Future.execute { block.call } }) + concurrent_compressors.each(&:wait!) + else + yield(Proc.new { |&block| block.call }) + end +end + task 'assets:precompile' => 'assets:precompile:before' do # Run after assets:precompile Rake::Task["assets:precompile:css"].invoke @@ -124,30 +134,34 @@ task 'assets:precompile' => 'assets:precompile:before' do puts "Compressing Javascript and Generating Source Maps" manifest = Sprockets::Manifest.new(assets_path) - to_skip = Rails.configuration.assets.skip_minification || [] - manifest.files - .select{|k,v| k =~ /\.js$/} - .each do |file, info| + concurrent? do |proc| + to_skip = Rails.configuration.assets.skip_minification || [] + manifest.files + .select{|k,v| k =~ /\.js$/} + .each do |file, info| - path = "#{assets_path}/#{file}" - _file = (d = File.dirname(file)) == "." ? "_#{file}" : "#{d}/_#{File.basename(file)}" - _path = "#{assets_path}/#{_file}" + path = "#{assets_path}/#{file}" + _file = (d = File.dirname(file)) == "." ? "_#{file}" : "#{d}/_#{File.basename(file)}" + _path = "#{assets_path}/#{_file}" - if File.exists?(_path) - STDERR.puts "Skipping: #{file} already compressed" - else - STDERR.puts "Compressing: #{file}" + if File.exists?(_path) + STDERR.puts "Skipping: #{file} already compressed" + else + STDERR.puts "Compressing: #{file}" - # We can specify some files to never minify - unless (ENV["DONT_MINIFY"] == "1") || to_skip.include?(info['logical_path']) - FileUtils.mv(path, _path) - compress(_file,file) + proc.call do + # We can specify some files to never minify + unless (ENV["DONT_MINIFY"] == "1") || to_skip.include?(info['logical_path']) + FileUtils.mv(path, _path) + compress(_file,file) + end + + info["size"] = File.size(path) + info["mtime"] = File.mtime(path).iso8601 + gzip(path) + end end - - info["size"] = File.size(path) - info["mtime"] = File.mtime(path).iso8601 - gzip(path) - end + end end # protected From b4e0c5afe03394d6ce5cbde6d7218a2713ca16d4 Mon Sep 17 00:00:00 2001 From: Guo Xiang Tan Date: Thu, 21 Apr 2016 14:45:16 +0800 Subject: [PATCH 008/125] FIX: Fetch stats if it has not been cached. --- app/jobs/scheduled/about_stats.rb | 6 +---- app/jobs/scheduled/dashboard_stats.rb | 6 +---- app/jobs/stats.rb | 9 ------- app/models/concerns/stats_cacheable.rb | 17 ++++++++++++- spec/jobs/about_stats_spec.rb | 12 ++++++--- spec/jobs/dashboard_stats_spec.rb | 16 +++++++++--- .../shared_examples_for_stats_cacheable.rb | 25 +++++++++++-------- 7 files changed, 53 insertions(+), 38 deletions(-) delete mode 100644 app/jobs/stats.rb diff --git a/app/jobs/scheduled/about_stats.rb b/app/jobs/scheduled/about_stats.rb index d745f8a0d6..1ae2a0866a 100644 --- a/app/jobs/scheduled/about_stats.rb +++ b/app/jobs/scheduled/about_stats.rb @@ -1,13 +1,9 @@ module Jobs class AboutStats < Jobs::Scheduled - include Jobs::Stats - every 30.minutes def execute(args) - stats = About.new.stats - set_cache(About, stats) - stats + About.refresh_stats end end end diff --git a/app/jobs/scheduled/dashboard_stats.rb b/app/jobs/scheduled/dashboard_stats.rb index b891b182a4..2b35fc4380 100644 --- a/app/jobs/scheduled/dashboard_stats.rb +++ b/app/jobs/scheduled/dashboard_stats.rb @@ -1,7 +1,5 @@ module Jobs class DashboardStats < Jobs::Scheduled - include Jobs::Stats - every 30.minutes def execute(args) @@ -12,9 +10,7 @@ module Jobs GroupMessage.create(Group[:admins].name, :dashboard_problems, {limit_once_per: 7.days.to_i}) end - stats = AdminDashboardData.fetch_stats - set_cache(AdminDashboardData, stats) - stats + AdminDashboardData.refresh_stats end end end diff --git a/app/jobs/stats.rb b/app/jobs/stats.rb deleted file mode 100644 index 637091cc6a..0000000000 --- a/app/jobs/stats.rb +++ /dev/null @@ -1,9 +0,0 @@ -module Jobs - module Stats - def set_cache(klass, stats) - # Add some extra time to the expiry so that the next job run has plenty of time to - # finish before previous cached value expires. - $redis.setex klass.stats_cache_key, (klass.recalculate_stats_interval + 5).minutes, stats.to_json - end - end -end diff --git a/app/models/concerns/stats_cacheable.rb b/app/models/concerns/stats_cacheable.rb index d7364111f4..150c2a7b20 100644 --- a/app/models/concerns/stats_cacheable.rb +++ b/app/models/concerns/stats_cacheable.rb @@ -18,7 +18,22 @@ module StatsCacheable def fetch_cached_stats # The scheduled Stats job is responsible for generating and caching this. stats = $redis.get(stats_cache_key) - stats ? JSON.parse(stats) : nil + stats = refresh_stats if !stats + JSON.parse(stats).with_indifferent_access + end + + def refresh_stats + stats = fetch_stats.to_json + set_cache(stats) + stats + end + + private + + def set_cache(stats) + # Add some extra time to the expiry so that the next job run has plenty of time to + # finish before previous cached value expires. + $redis.setex stats_cache_key, (recalculate_stats_interval + 5).minutes, stats end end end diff --git a/spec/jobs/about_stats_spec.rb b/spec/jobs/about_stats_spec.rb index 25ae8291f8..85a1020e6d 100644 --- a/spec/jobs/about_stats_spec.rb +++ b/spec/jobs/about_stats_spec.rb @@ -1,10 +1,16 @@ require 'rails_helper' describe Jobs::AboutStats do + after do + $redis.flushall + end + it 'caches the stats' do - stats = { "visited" => 10 } - About.any_instance.expects(:stats).returns(stats) - $redis.expects(:setex).with(About.stats_cache_key, 35.minutes, stats.to_json) + stats = About.fetch_stats.to_json + cache_key = About.stats_cache_key + + expect($redis.get(cache_key)).to eq(nil) expect(described_class.new.execute({})).to eq(stats) + expect($redis.get(cache_key)).to eq(stats) end end diff --git a/spec/jobs/dashboard_stats_spec.rb b/spec/jobs/dashboard_stats_spec.rb index b00130d02d..82ff12edc6 100644 --- a/spec/jobs/dashboard_stats_spec.rb +++ b/spec/jobs/dashboard_stats_spec.rb @@ -1,10 +1,18 @@ require 'rails_helper' describe Jobs::DashboardStats do + after do + $redis.flushall + end + it 'caches the stats' do - json = { "visited" => 10 } - AdminDashboardData.any_instance.expects(:as_json).returns(json) - $redis.expects(:setex).with(AdminDashboardData.stats_cache_key, 35.minutes, json.to_json) - expect(described_class.new.execute({})).to eq(json) + Timecop.freeze do + stats = AdminDashboardData.fetch_stats.to_json + cache_key = AdminDashboardData.stats_cache_key + + expect($redis.get(cache_key)).to eq(nil) + expect(described_class.new.execute({})).to eq(stats) + expect($redis.get(cache_key)).to eq(stats) + end end end diff --git a/spec/support/shared_examples_for_stats_cacheable.rb b/spec/support/shared_examples_for_stats_cacheable.rb index d47877c582..b6a2b4dfef 100644 --- a/spec/support/shared_examples_for_stats_cacheable.rb +++ b/spec/support/shared_examples_for_stats_cacheable.rb @@ -1,22 +1,25 @@ shared_examples_for 'stats cachable' do describe 'fetch_cached_stats' do - it 'returns the cached stats' do - begin - stats = { "visits" => 10 } - $redis.set(described_class.stats_cache_key, stats.to_json) - expect(described_class.fetch_cached_stats).to eq(stats) - ensure - $redis.del(described_class.stats_cache_key) - end + after do + $redis.flushall end - it 'returns nil if no stats has been cached' do - expect(described_class.fetch_cached_stats).to eq(nil) + it 'returns the cached stats' do + stats = described_class.fetch_stats.to_json + $redis.set(described_class.stats_cache_key, stats) + expect(described_class.fetch_cached_stats).to eq(JSON.parse(stats)) + end + + it 'returns fetches the stats if stats has not been cached' do + Timecop.freeze do + $redis.del(described_class.stats_cache_key) + expect(described_class.fetch_cached_stats).to eq(JSON.parse(described_class.fetch_stats.to_json)) + end end end describe 'fetch_stats' do - it 'has been implemented' do + it 'has not been implemented' do expect{ described_class.fetch_stats }.to_not raise_error end end From a556d9ad4eb03ae8a90850a4808546d99a87c73b Mon Sep 17 00:00:00 2001 From: Guo Xiang Tan Date: Thu, 21 Apr 2016 15:04:03 +0800 Subject: [PATCH 009/125] FIX: Expiry should be 3 times polling interval. --- app/jobs/scheduled/poll_mailbox.rb | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/app/jobs/scheduled/poll_mailbox.rb b/app/jobs/scheduled/poll_mailbox.rb index 44dce2adbf..e79ad10edd 100644 --- a/app/jobs/scheduled/poll_mailbox.rb +++ b/app/jobs/scheduled/poll_mailbox.rb @@ -119,7 +119,11 @@ module Jobs end rescue Net::OpenTimeout => e count = $redis.incr(POLL_MAILBOX_TIMEOUT_ERROR_KEY).to_i - $redis.expire(POLL_MAILBOX_TIMEOUT_ERROR_KEY, 300) if count == 1 + + $redis.expire( + POLL_MAILBOX_TIMEOUT_ERROR_KEY, + SiteSetting.pop3_polling_period_mins.minutes * 3 + ) if count == 1 if count > 3 $redis.del(POLL_MAILBOX_TIMEOUT_ERROR_KEY) From cd4ffccb4a748ea4e40a19a56d3cf153d280664f Mon Sep 17 00:00:00 2001 From: Guo Xiang Tan Date: Thu, 21 Apr 2016 16:09:21 +0800 Subject: [PATCH 010/125] Upgrade onebox. --- Gemfile.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Gemfile.lock b/Gemfile.lock index 19ac560327..bc0b32e390 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -213,7 +213,7 @@ GEM omniauth-twitter (1.2.1) json (~> 1.3) omniauth-oauth (~> 1.1) - onebox (1.5.38) + onebox (1.5.39) htmlentities (~> 4.3.4) moneta (~> 0.8) multi_json (~> 1.11) From 89a7a90208697da9240c52a208e8f9a912128522 Mon Sep 17 00:00:00 2001 From: Arpit Jalan Date: Thu, 21 Apr 2016 13:03:23 +0530 Subject: [PATCH 011/125] UX: do not show filter controls for PM admin reports --- .../admin/controllers/admin-reports.js.es6 | 5 +++++ app/assets/javascripts/admin/templates/reports.hbs | 14 ++++++++------ 2 files changed, 13 insertions(+), 6 deletions(-) diff --git a/app/assets/javascripts/admin/controllers/admin-reports.js.es6 b/app/assets/javascripts/admin/controllers/admin-reports.js.es6 index 17d0c1243f..b07e3f69cd 100644 --- a/app/assets/javascripts/admin/controllers/admin-reports.js.es6 +++ b/app/assets/javascripts/admin/controllers/admin-reports.js.es6 @@ -26,6 +26,11 @@ export default Ember.Controller.extend({ return arr.concat(this.site.groups.map((i) => {return {name: i['name'], value: i['id']};})); }, + @computed('model.type') + showFilterOptions(modelType) { + return !modelType.match(/_private_messages$/); + }, + @computed('model.type') showGroupOptions(modelType) { return modelType === "visits" || modelType === "signups" || modelType === "profile_views"; diff --git a/app/assets/javascripts/admin/templates/reports.hbs b/app/assets/javascripts/admin/templates/reports.hbs index 7f0363a2f3..a3b6797f76 100644 --- a/app/assets/javascripts/admin/templates/reports.hbs +++ b/app/assets/javascripts/admin/templates/reports.hbs @@ -1,13 +1,15 @@

{{model.title}}

- {{i18n 'admin.dashboard.reports.start_date'}} {{date-picker-past value=startDate}} - {{i18n 'admin.dashboard.reports.end_date'}} {{date-picker-past value=endDate}} - {{combo-box valueAttribute="value" content=categoryOptions value=categoryId}} - {{#if showGroupOptions}} - {{combo-box valueAttribute="value" content=groupOptions value=groupId}} + {{#if showFilterOptions}} + {{i18n 'admin.dashboard.reports.start_date'}} {{date-picker-past value=startDate}} + {{i18n 'admin.dashboard.reports.end_date'}} {{date-picker-past value=endDate}} + {{combo-box valueAttribute="value" content=categoryOptions value=categoryId}} + {{#if showGroupOptions}} + {{combo-box valueAttribute="value" content=groupOptions value=groupId}} + {{/if}} + {{d-button action="refreshReport" class="btn-primary" label="admin.dashboard.reports.refresh_report" icon="refresh"}} {{/if}} - {{d-button action="refreshReport" class="btn-primary" label="admin.dashboard.reports.refresh_report" icon="refresh"}} {{d-button action="exportCsv" label="admin.export_csv.button_text" icon="download"}}
From ee7ef46b9e29fb01e74f0828163a116818253d4b Mon Sep 17 00:00:00 2001 From: Arpit Jalan Date: Thu, 21 Apr 2016 14:52:41 +0530 Subject: [PATCH 012/125] FEATURE: support filter options for PM report --- .../admin/controllers/admin-reports.js.es6 | 2 +- app/assets/javascripts/admin/templates/reports.hbs | 14 +++++++------- app/models/post.rb | 4 ++-- app/models/report.rb | 2 +- 4 files changed, 11 insertions(+), 11 deletions(-) diff --git a/app/assets/javascripts/admin/controllers/admin-reports.js.es6 b/app/assets/javascripts/admin/controllers/admin-reports.js.es6 index b07e3f69cd..61b46740ac 100644 --- a/app/assets/javascripts/admin/controllers/admin-reports.js.es6 +++ b/app/assets/javascripts/admin/controllers/admin-reports.js.es6 @@ -27,7 +27,7 @@ export default Ember.Controller.extend({ }, @computed('model.type') - showFilterOptions(modelType) { + showCategoryOptions(modelType) { return !modelType.match(/_private_messages$/); }, diff --git a/app/assets/javascripts/admin/templates/reports.hbs b/app/assets/javascripts/admin/templates/reports.hbs index a3b6797f76..12303f27ef 100644 --- a/app/assets/javascripts/admin/templates/reports.hbs +++ b/app/assets/javascripts/admin/templates/reports.hbs @@ -1,15 +1,15 @@

{{model.title}}

- {{#if showFilterOptions}} - {{i18n 'admin.dashboard.reports.start_date'}} {{date-picker-past value=startDate}} - {{i18n 'admin.dashboard.reports.end_date'}} {{date-picker-past value=endDate}} + {{i18n 'admin.dashboard.reports.start_date'}} {{date-picker-past value=startDate}} + {{i18n 'admin.dashboard.reports.end_date'}} {{date-picker-past value=endDate}} + {{#if showCategoryOptions}} {{combo-box valueAttribute="value" content=categoryOptions value=categoryId}} - {{#if showGroupOptions}} - {{combo-box valueAttribute="value" content=groupOptions value=groupId}} - {{/if}} - {{d-button action="refreshReport" class="btn-primary" label="admin.dashboard.reports.refresh_report" icon="refresh"}} {{/if}} + {{#if showGroupOptions}} + {{combo-box valueAttribute="value" content=groupOptions value=groupId}} + {{/if}} + {{d-button action="refreshReport" class="btn-primary" label="admin.dashboard.reports.refresh_report" icon="refresh"}} {{d-button action="exportCsv" label="admin.export_csv.button_text" icon="download"}}
diff --git a/app/models/post.rb b/app/models/post.rb index 83c669fe49..df3d51ed24 100644 --- a/app/models/post.rb +++ b/app/models/post.rb @@ -557,8 +557,8 @@ class Post < ActiveRecord::Base result.group('date(posts.created_at)').order('date(posts.created_at)').count end - def self.private_messages_count_per_day(since_days_ago, topic_subtype) - private_posts.with_topic_subtype(topic_subtype).where('posts.created_at > ?', since_days_ago.days.ago).group('date(posts.created_at)').order('date(posts.created_at)').count + def self.private_messages_count_per_day(start_date, end_date, topic_subtype) + private_posts.with_topic_subtype(topic_subtype).where('posts.created_at >= ? AND posts.created_at <= ?', start_date, end_date).group('date(posts.created_at)').order('date(posts.created_at)').count end def reply_history(max_replies=100, guardian=nil) diff --git a/app/models/report.rb b/app/models/report.rb index e5135dcacf..ecb7c27f3b 100644 --- a/app/models/report.rb +++ b/app/models/report.rb @@ -205,7 +205,7 @@ class Report # Private messages counts: def self.private_messages_report(report, topic_subtype) - basic_report_about report, Post, :private_messages_count_per_day, default_days, topic_subtype + basic_report_about report, Post, :private_messages_count_per_day, report.start_date, report.end_date, topic_subtype add_counts report, Post.private_posts.with_topic_subtype(topic_subtype), 'posts.created_at' end From ded03a1aa4ebf72d73187e7214f72fc57a9a8dac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9gis=20Hanol?= Date: Thu, 21 Apr 2016 20:56:12 +0200 Subject: [PATCH 013/125] ensure pikaday respects our color scheme --- .../discourse/components/date-picker.js.es6 | 34 ++++++++------- .../templates/components/date-picker.hbs | 2 +- .../templates/modal/change-timestamp.hbs | 6 ++- app/assets/stylesheets/desktop/modal.scss | 16 +++++++ app/assets/stylesheets/vendor/pikaday.scss | 42 ++++++++++--------- 5 files changed, 62 insertions(+), 38 deletions(-) diff --git a/app/assets/javascripts/discourse/components/date-picker.js.es6 b/app/assets/javascripts/discourse/components/date-picker.js.es6 index 21825d2ed8..ea86648784 100644 --- a/app/assets/javascripts/discourse/components/date-picker.js.es6 +++ b/app/assets/javascripts/discourse/components/date-picker.js.es6 @@ -9,24 +9,28 @@ export default Em.Component.extend({ @on("didInsertElement") _loadDatePicker() { const input = this.$(".date-picker")[0]; + const container = $("#" + this.get("containerId"))[0]; loadScript("/javascripts/pikaday.js").then(() => { - let default_opts = { - field: input, - container: this.$()[0], - format: "YYYY-MM-DD", - firstDay: moment.localeData().firstDayOfWeek(), - i18n: { - previousMonth: I18n.t('dates.previous_month'), - nextMonth: I18n.t('dates.next_month'), - months: moment.months(), - weekdays: moment.weekdays(), - weekdaysShort: moment.weekdaysShort() - }, - onSelect: date => this.set("value", moment(date).format("YYYY-MM-DD")) - }; + Ember.run.next(() => { + let default_opts = { + field: input, + container: container || this.$()[0], + bound: container === undefined, + format: "YYYY-MM-DD", + firstDay: moment.localeData().firstDayOfWeek(), + i18n: { + previousMonth: I18n.t('dates.previous_month'), + nextMonth: I18n.t('dates.next_month'), + months: moment.months(), + weekdays: moment.weekdays(), + weekdaysShort: moment.weekdaysShort() + }, + onSelect: date => this.set("value", moment(date).format("YYYY-MM-DD")) + }; - this._picker = new Pikaday(_.merge(default_opts, this._opts())); + this._picker = new Pikaday(_.merge(default_opts, this._opts())); + }); }); }, diff --git a/app/assets/javascripts/discourse/templates/components/date-picker.hbs b/app/assets/javascripts/discourse/templates/components/date-picker.hbs index 7d9e48080a..a2c89401ab 100644 --- a/app/assets/javascripts/discourse/templates/components/date-picker.hbs +++ b/app/assets/javascripts/discourse/templates/components/date-picker.hbs @@ -1 +1 @@ - + diff --git a/app/assets/javascripts/discourse/templates/modal/change-timestamp.hbs b/app/assets/javascripts/discourse/templates/modal/change-timestamp.hbs index c76c58e124..5114bd9cf9 100644 --- a/app/assets/javascripts/discourse/templates/modal/change-timestamp.hbs +++ b/app/assets/javascripts/discourse/templates/modal/change-timestamp.hbs @@ -1,4 +1,4 @@ -