diff --git a/.github/workflows/health_check.yml b/.github/workflows/health_check.yml new file mode 100644 index 0000000..e62095e --- /dev/null +++ b/.github/workflows/health_check.yml @@ -0,0 +1,26 @@ +name: Bang Health Check + +on: + schedule: + # Schedule to run at 15:00 UTC first day of every month + - cron: "0 15 1 * *" + workflow_dispatch: + +jobs: + health_check: + runs-on: ubuntu-latest + steps: + - name: Checkout code + uses: actions/checkout@v3 + with: + fetch-depth: 0 + + - name: Set up Ruby + uses: ruby/setup-ruby@v1 + with: + ruby-version: 3.0 + bundler-cache: true + + - name: Run health check + run: | + bundle exec ruby scripts/health_check.rb diff --git a/Gemfile b/Gemfile index 287e80f..fbf404a 100644 --- a/Gemfile +++ b/Gemfile @@ -1,7 +1,8 @@ -source 'https://rubygems.org' +source "https://rubygems.org" gem "json" gem "rspec", "~> 3.13" -gem 'addressable', '~> 2.8', '>= 2.8.6' +gem "addressable", "~> 2.8", ">= 2.8.6" gem "terminal-table", "~> 3.0" +gem "whirly" diff --git a/Gemfile.lock b/Gemfile.lock index dd7db3a..f7d8231 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -22,6 +22,8 @@ GEM terminal-table (3.0.2) unicode-display_width (>= 1.1.1, < 3) unicode-display_width (2.5.0) + whirly (0.3.0) + unicode-display_width (>= 1.1) PLATFORMS ruby @@ -32,6 +34,7 @@ DEPENDENCIES json rspec (~> 3.13) terminal-table (~> 3.0) + whirly BUNDLED WITH 2.5.4 diff --git a/scripts/health_check.rb b/scripts/health_check.rb new file mode 100644 index 0000000..d653c05 --- /dev/null +++ b/scripts/health_check.rb @@ -0,0 +1,54 @@ +require "json" +require "net/http" +require "uri" +require "whirly" + +bangs_json = JSON.parse(File.read("data/bangs.json")) +kagi_bangs_json = JSON.parse(File.read("data/kagi_bangs.json")) +assist_bangs_json = JSON.parse(File.read("data/assistant_bangs.json")) + +errored = [] +mutex = Mutex.new + +def check_url(bang, errored, mutex) + return if bang["u"].start_with?("/") + + bang_url = bang["u"].gsub("{{{s}}}", "example").strip + url = URI.parse(bang_url) + + Net::HTTP.get_response(url) +rescue => e + mutex.synchronize { errored << [bang, e] } + # puts "#{bang_url} is offline (#{bang["s"]}). Error: \n #{e}" +end + +Whirly.configure spinner: "dots" +Whirly.start + +all_bangs = bangs_json + kagi_bangs_json + assist_bangs_json +threads = [] + +all_bangs.each_with_index do |bang, idx| + Whirly.status = "Bang #{bang["s"]} (#{idx + 1}/#{all_bangs.size})" + + threads << Thread.new { check_url(bang, errored, mutex) } + + # Limit the number of concurrent threads to avoid overwhelming the system + if threads.size >= 100 + threads.each(&:join) + threads.clear + end +end + +# Ensure all remaining threads are completed +threads.each(&:join) + +Whirly.stop + +errored.each do |error| + bang, e = error + + puts "#{bang["u"]} is offline. Error: \n #{e}" +end + +exit 1 if errored.size > 0