Skip to content

Instantly share code, notes, and snippets.

@hightemp
Last active August 29, 2015 14:00
Show Gist options
  • Save hightemp/11165563 to your computer and use it in GitHub Desktop.
Save hightemp/11165563 to your computer and use it in GitHub Desktop.
sublime 2 package manager
#!/usr/bin/env ruby
# Commands:
# sl2pm add PACKAGE_NAME # add one of the available packages
# sl2pm add_all STRING N_PAGES # add all packages that matches string
# sl2pm add_popular FROM_PAGE N_PAGES MASK # add popular packages
# sl2pm clear_cache # clear cache
# sl2pm help [COMMAND] # Describe available commands or one spec...
# sl2pm list MASK # list all of the available packages
# sl2pm open PACKAGE_NAME # open in browser package description
# sl2pm popular N_PAGES # lit all popular packages
# sl2pm remove PACKAGE_NAME # remove package
# sl2pm search STRING N_PAGES # search for the available packages
require 'net/https'
require 'uri'
require 'oj'
require 'thor'
require 'pp'
class SL2App < Thor
def initialize(*args)
super
settings_file = "~/Library/Application Support/Sublime Text 2/Packages/User/Package Control.sublime-settings"
settings_file = File.expand_path(settings_file)
@ip = "installed_packages"
@config = { @ip => [] }
@options = {
:file_cache => "/tmp/sl2pm.%s.%s.%d.cache",
:cache_mask => "/tmp/sl2pm*",
:file_installed => settings_file,
:file_result => settings_file
}
@url = "https://sublime.wbond.net/%s/%s?page=%d"
end
option :update, :type => :boolean, :desc => "update cache"
desc "add PACKAGE_NAME", "add one of the available packages"
def add(name)
load()
@config[@ip] = [] unless @config[@ip]
@config[@ip] += [name]
@config[@ip].uniq!
save()
list()
end
desc "add_all STRING N_PAGES", "add all packages that matches string"
def add_all(str, pages=1)
load()
@config[@ip] = [] unless @config[@ip]
@config[@ip] += get_from_to("search", str, 1, 1+pages.to_i)
@config[@ip].uniq!
save()
list()
end
desc "add_popular FROM_PAGE N_PAGES MASK", "add popular packages"
def add_popular(from=1, pages=1, mask="*")
load()
popular = get_from_to("browse", "popular", from.to_i, from.to_i+pages.to_i)
popular.delete_if { |item| not (item =~ mask_to_regexp(mask)) }
@config[@ip] = [] unless @config[@ip]
@config[@ip] += popular
@config[@ip].uniq!
save()
list()
end
desc "remove PACKAGE_NAME", "remove package"
def remove(name)
load()
@config[@ip] = [] unless @config[@ip]
@config[@ip] -= [name]
save()
list()
end
desc "list MASK", "list all of the available packages"
def list(mask="*")
load()
result = @config[@ip].clone
result.delete_if { |item| not (item =~ mask_to_regexp(mask)) }
pp result
end
desc "popular N_PAGES", "lit all popular packages"
def popular(pages=10)
pp get_from_to("browse", "popular", 1, 1+pages.to_i)
end
desc "search STRING N_PAGES", "search for the available packages"
def search(str, pages=10)
pp get_from_to("search", str, 1, 1+pages.to_i)
end
desc "clear_cache", "clear cache"
def clear_cache()
system("rm -f #{@options[:cache_mask]}")
end
desc "open PACKAGE_NAME", "open in browser package description"
def open(name)
link = "https://sublime.wbond.net/packages/#{name}"
if RbConfig::CONFIG['host_os'] =~ /mswin|mingw|cygwin/
system "start '#{link}'"
elsif RbConfig::CONFIG['host_os'] =~ /darwin/
system "open '#{link}'"
elsif RbConfig::CONFIG['host_os'] =~ /linux|bsd/
system "xdg-open '#{link}'"
end
end
private
def mask_to_regexp(mask)
Regexp.new(mask.gsub("*",".*").gsub("?",".?"))
end
def load()
@config = Oj.load(File.read(@options[:file_installed]), :mode => :strict)
end
def save()
File.open(@options[:file_result], "w") do |f|
f.write(Oj.dump(@config, :mode => :strict))
end
end
def get_from_to(param1, param2, from, to)
result = []
for i in from..to
items = get(param1, param2, i)
break if items.empty?
result += items
end
result.uniq
end
def get(param1, param2, i=1)
result = []
cache_filename = @options[:file_cache] % [
param1.gsub(' ', '_'),
param2.gsub(' ', '_'),
i
]
if (not File.exist?(cache_filename) || options[:update])
uri = URI.parse(@url % [param1, param2, i])
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
http.start {
http.request_get(uri.to_s) { |res|
result += res.body.scan(/<h3><a[^>]*>(.*?)<\/a>/).flatten
}
}
result.map! { |i| i.gsub(/<\/?[^>]+>/, "") }
File.open(cache_filename, 'w') do |file|
Marshal.dump(result, file)
end
else
result = Marshal.load(File.read(cache_filename))
end
result
end
end
SL2App.start(ARGV)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment