newshound 1.0.1 → 1.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 79ace59ee869878db3221ca5d851c9bf10ae50354877d6b4a2b57ccc9489319e
4
- data.tar.gz: 9a0e6d98ce5ac41b433c19d66ae920b207c090d7550df505645068c46f627feb
3
+ metadata.gz: c28e3edb5bdc1e1c6af7b0ec4ea8e171fc912670515c19a1bef53f0a2e78f2c5
4
+ data.tar.gz: e15c37e225e9140e112fd250ac860e555fe02606d1a6dfed40094f435fa94600
5
5
  SHA512:
6
- metadata.gz: 7124a65e125a08eea643486de24db7e84436c981ccd6e9c6fa12b205b33f1e2e30b062d38c766ab0f9df18bda79fd3d093b5bfccf23b5d9938b0c45e45d6a23e
7
- data.tar.gz: d414aa404515671d71525214ebe0f601e456c6704e5bfccf29a49246454ea9f9d83e899576db2903cfe4d0491b8255a915d6b17a4c5cdefb879d5318b0476f66
6
+ metadata.gz: f89d1b069823ba254f663caf2efe01d4667d560bfc47739b04a98f4653fd3f6f747998aa3594be7848a770bf5f26bbeb705dfa0873d937fbb53565f5310dd252
7
+ data.tar.gz: ce5a04dfc26b9782da9a308299d9ccc04273aa3ceb260256b9deb951ddf2f9b25b771cbcbcab5d56f46d33b4155b17821d02ca9e55cb6fafd4772c12388f9425
data/CHANGELOG.md CHANGED
@@ -5,39 +5,21 @@ All notable changes to this project will be documented in this file.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
- ## [1.0.1] - 2026-03-17
9
-
10
- ### Changed
11
-
12
- - The authorize_with initializer will generate with the method inside the configure block. (2d6ef48)
8
+ ## [1.0.2] - 2026-04-03
13
9
 
14
10
  ### Added
15
11
 
16
- - Configurable banner links for exceptions, jobs, and warnings via string path patterns (1df1636)
17
- - Record ID in format_for_banner output for linking to individual records (e06d040)
12
+ - Bugsink exception source adapter for HTTP-based error tracking (6d3e2a1)
13
+ - exception_source_config option for passing connection details to adapters (6d3e2a1)
14
+ - Minimize button for banner (c686227)
18
15
 
19
- ## [0.2.8] - 2026-02-10
16
+ ## [1.0.1] - 2026-03-17
20
17
 
21
18
  ### Changed
22
19
 
23
- - Ruby support to 3.3+ and added Ruby 4.0 to CI matrix (24e5b86)
24
- - Job monitoring uses configurable adapter pattern via config.job_source (8d33d30)
25
-
26
- ### Removed
27
-
28
- - Ruby 3.1 and 3.2 support (24e5b86)
29
- - Hard dependency on que gem (8d33d30)
30
- - QueReporter class (replaced by JobReporter + Jobs adapters) Version: major (8d33d30)
31
-
32
- ### Fixed
33
-
34
- - Set the correct location for the repository on the web. (cb7bb88)
35
- - test_exceptions rake task calling report instead of banner_data (e440188)
36
- - Banner overlaying content in apps with !important body padding-top rules (16f22f1)
20
+ - The authorize_with initializer will generate with the method inside the configure block. (2d6ef48)
37
21
 
38
22
  ### Added
39
23
 
40
- - Jobs adapter pattern with Base class and registry (c50ba9c)
41
- - Jobs::Que adapter for Que job backend (c50ba9c)
42
- - JobReporter that delegates to a configurable job source adapter (c50ba9c)
43
- - ExceptionReporter#formatted_exception_count and #exception_summary helpers (e440188)
24
+ - Configurable banner links for exceptions, jobs, and warnings via string path patterns (1df1636)
25
+ - Record ID in format_for_banner output for linking to individual records (e06d040)
@@ -4,6 +4,7 @@ module Newshound
4
4
  class Configuration
5
5
  attr_accessor :exception_limit, :enabled, :authorized_roles,
6
6
  :current_user_method, :authorization_block, :exception_source,
7
+ :exception_source_config,
7
8
  :warning_source, :warning_limit, :job_source,
8
9
  :exception_links, :job_links, :warning_links
9
10
 
@@ -14,6 +15,7 @@ module Newshound
14
15
  @current_user_method = :current_user
15
16
  @authorization_block = nil
16
17
  @exception_source = :exception_track
18
+ @exception_source_config = {}
17
19
  @warning_source = nil
18
20
  @warning_limit = 10
19
21
  @job_source = nil
@@ -51,7 +51,7 @@ module Newshound
51
51
 
52
52
  def resolve_exception_source(source)
53
53
  source ||= @configuration.exception_source
54
- source.is_a?(Symbol) ? Exceptions.source(source) : source
54
+ source.is_a?(Symbol) ? Exceptions.source(source, @configuration.exception_source_config) : source
55
55
  end
56
56
 
57
57
  def recent_exceptions
@@ -10,6 +10,10 @@ module Newshound
10
10
  # - #format_for_report(exception) - Formats a single exception for Slack/report display
11
11
  # - #format_for_banner(exception) - Formats a single exception for banner UI
12
12
  class Base
13
+ def initialize(config = {})
14
+ @config = config
15
+ end
16
+
13
17
  # Fetches recent exceptions from the exception tracking system
14
18
  #
15
19
  # @param time_range [ActiveSupport::Duration] Time duration to look back (e.g., 24.hours)
@@ -0,0 +1,77 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "net/http"
4
+ require "json"
5
+ require "uri"
6
+ require "time"
7
+
8
+ module Newshound
9
+ module Exceptions
10
+ class Bugsink < Base
11
+ def self.required_keys
12
+ %i[url token project_id].freeze
13
+ end
14
+
15
+ def initialize(config = {})
16
+ super
17
+ config = config.transform_keys(&:to_sym)
18
+
19
+ missing = self.class.required_keys.select { |key| config[key].nil? }
20
+ if missing.any?
21
+ raise ArgumentError,
22
+ "Bugsink requires #{missing.map { |k| ":#{k}" }.join(", ")} in exception_source_config"
23
+ end
24
+
25
+ @url = config[:url]
26
+ @token = config[:token]
27
+ @project_id = config[:project_id]
28
+ end
29
+
30
+ def recent(time_range:, limit:)
31
+ issues = fetch_issues
32
+ cutoff = Time.now.utc - time_range
33
+
34
+ issues
35
+ .select { |i| Time.parse(i["last_seen"]) >= cutoff }
36
+ .first(limit)
37
+ end
38
+
39
+ def format_for_report(issue, number)
40
+ <<~TEXT
41
+ *#{number}. #{issue["calculated_type"] || "Unknown"}*
42
+ • *Time:* #{Time.parse(issue["last_seen"]).strftime("%I:%M %p")}
43
+ • *Message:* `#{(issue["calculated_value"] || "").truncate(100)}`
44
+ TEXT
45
+ end
46
+
47
+ def format_for_banner(issue)
48
+ {
49
+ id: issue["id"],
50
+ title: issue["calculated_type"] || "Unknown",
51
+ message: (issue["calculated_value"] || "").truncate(100),
52
+ location: issue["transaction"] || "",
53
+ time: Time.parse(issue["last_seen"]).strftime("%I:%M %p")
54
+ }
55
+ end
56
+
57
+ private
58
+
59
+ def fetch_issues
60
+ uri = URI("#{@url.chomp("/")}/api/canonical/0/issues/")
61
+ uri.query = URI.encode_www_form(project: @project_id, sort: "last_seen", order: "desc")
62
+
63
+ request = Net::HTTP::Get.new(uri)
64
+ request["Authorization"] = "Bearer #{@token}"
65
+ request["Accept"] = "application/json"
66
+
67
+ response = Net::HTTP.start(uri.hostname, uri.port, use_ssl: uri.scheme == "https") do |http|
68
+ http.request(request)
69
+ end
70
+
71
+ raise "Bugsink API error: #{response.code}" unless response.is_a?(Net::HTTPSuccess)
72
+
73
+ JSON.parse(response.body)["results"] || []
74
+ end
75
+ end
76
+ end
77
+ end
@@ -2,11 +2,11 @@ Dir[File.join(__dir__, "exceptions", "*.rb")].each { |file| require file }
2
2
 
3
3
  module Newshound
4
4
  module Exceptions
5
- def self.source(source)
5
+ def self.source(source, config = {})
6
6
  constant = constants.find { |c| c.to_s.gsub(/(?<!^)([A-Z])/, "_\\1").downcase == source.to_s }
7
7
  raise "Invalid exception source: #{source}" unless constant
8
8
 
9
- const_get(constant).new
9
+ const_get(constant).new(config)
10
10
  end
11
11
  end
12
12
  end
@@ -75,13 +75,19 @@ module Newshound
75
75
  🐕 Newshound
76
76
  #{summary_badge(exception_data, job_data, warning_data)}
77
77
  </span>
78
- <span class="newshound-toggle">▼</span>
78
+ <span class="newshound-header-controls">
79
+ <span class="newshound-minimize" onclick="event.stopPropagation(); document.getElementById('newshound-banner').classList.add('newshound-minimized'); localStorage.setItem('newshound-minimized','1'); window.newshoundUpdatePadding();" title="Minimize">−</span>
80
+ <span class="newshound-toggle">▼</span>
81
+ </span>
79
82
  </div>
80
83
  <div class="newshound-content">
81
84
  #{render_exceptions(exception_data)}
82
85
  #{render_warnings(warning_data)}
83
86
  #{render_jobs(job_data)}
84
87
  </div>
88
+ <div class="newshound-restore" onclick="document.getElementById('newshound-banner').classList.remove('newshound-minimized'); localStorage.removeItem('newshound-minimized'); window.newshoundUpdatePadding();" title="Restore Newshound">
89
+ 🐕
90
+ </div>
85
91
  </div>
86
92
  #{render_script}
87
93
  HTML
@@ -91,6 +97,11 @@ module Newshound
91
97
  <<~JS
92
98
  <script>
93
99
  (function() {
100
+ // Restore minimized state from localStorage
101
+ if (localStorage.getItem('newshound-minimized')) {
102
+ document.getElementById('newshound-banner').classList.add('newshound-minimized');
103
+ }
104
+
94
105
  var cachedPriority, cachedBodyRule;
95
106
 
96
107
  // Detect once whether any non-newshound stylesheet uses !important on body padding-top
@@ -290,6 +301,48 @@ module Newshound
290
301
  a.newshound-stat:hover {
291
302
  background: rgba(255,255,255,0.2);
292
303
  }
304
+ .newshound-header-controls {
305
+ display: flex;
306
+ align-items: center;
307
+ gap: 12px;
308
+ }
309
+ .newshound-minimize {
310
+ cursor: pointer;
311
+ font-size: 18px;
312
+ font-weight: 700;
313
+ line-height: 1;
314
+ opacity: 0.7;
315
+ padding: 0 4px;
316
+ }
317
+ .newshound-minimize:hover {
318
+ opacity: 1;
319
+ }
320
+ .newshound-restore {
321
+ display: none;
322
+ }
323
+ .newshound-banner.newshound-minimized .newshound-header {
324
+ display: none;
325
+ }
326
+ .newshound-banner.newshound-minimized .newshound-content {
327
+ max-height: 0;
328
+ overflow: hidden;
329
+ border-top: none;
330
+ }
331
+ .newshound-banner.newshound-minimized .newshound-restore {
332
+ display: flex;
333
+ align-items: center;
334
+ justify-content: center;
335
+ width: 36px;
336
+ height: 36px;
337
+ cursor: pointer;
338
+ font-size: 16px;
339
+ user-select: none;
340
+ }
341
+ .newshound-banner.newshound-minimized {
342
+ left: auto;
343
+ border-radius: 0 0 0 8px;
344
+ box-shadow: -2px 2px 6px rgba(0,0,0,0.2);
345
+ }
293
346
  </style>
294
347
  CSS
295
348
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Newshound
4
- VERSION = "1.0.1"
4
+ VERSION = "1.0.2"
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: newshound
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.1
4
+ version: 1.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Savannah Moore
@@ -49,6 +49,7 @@ files:
49
49
  - lib/newshound/exception_reporter.rb
50
50
  - lib/newshound/exceptions.rb
51
51
  - lib/newshound/exceptions/base.rb
52
+ - lib/newshound/exceptions/bugsink.rb
52
53
  - lib/newshound/exceptions/exception_track.rb
53
54
  - lib/newshound/exceptions/solid_errors.rb
54
55
  - lib/newshound/job_reporter.rb