Skip to content

Instantly share code, notes, and snippets.

@skull-squadron
Forked from nogweii/ddg_bangs.rb
Last active February 7, 2025 13:17
Show Gist options
  • Save skull-squadron/f53c38c678045660a36a5fcd1f50196a to your computer and use it in GitHub Desktop.
Save skull-squadron/f53c38c678045660a36a5fcd1f50196a to your computer and use it in GitHub Desktop.
get a list of all of duckduckgo's bangs in a programmatic manner, useful for scripting
# frozen_string_literal: true
require 'cgi'
require 'json'
require 'open-uri'
require 'yaml'
UA = 'Ruby script to read the full list of bangs/2.0 ; https://gist.github.com/skull-squadron/f53c38c678045660a36a5fcd1f50196a'
module Flow
refine BasicObject do
def flow(*, **, &)
block_given? ? yield(self, *, **) : self
end
end
end
class DDGBang < Struct.new(:category, :sub_category, :bang, :full_name, :visit_domain, :search_url_template, :rank)
def initialize(**options)
self.category = options.delete('c')
self.sub_category = options.delete('sc')
self.bang = options.delete('t')
self.full_name = options.delete('s')
self.visit_domain = options.delete('d')
self.search_url_template = options.delete('u')
self.rank = options.delete('r')
raise ArgumentError, "Unknown options #{options.keys.inspect}" unless options.empty?
end
def to_json(*)
values.to_json
end
def as_url(*search_string)
return visit_domain if search_string.empty?
search_url_template.sub('{{{s}}}', CGI.escape(search_string[0]))
end
end
class DDGAllBangs
using Flow
def bangs
@bangs ||= URI.open('https://duckduckgo.com/bang.js', 'User-Agent' => UA)
.flow { |body| JSON.load(body) }
.flow { |js| js.map { |object| DDGBang.new(**object) } }
end
def to_json
JSON.pretty_generate(bangs)
end
def to_yaml
bangs.map(&:to_h).to_yaml
end
end
ddg_bangs = DDGAllBangs.new
IO.write('/tmp/ddg_bangs.yaml', ddg_bangs.to_yaml)
IO.write('/tmp/ddg_bangs.json', ddg_bangs.to_json)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment