Created
March 29, 2011 07:07
-
-
Save edvakf/891925 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env ruby | |
=begin | |
Opera's browser.js history in a git tree! | |
* http://get.geo.opera.com/res/servicefiles/userjsfiles/all/ | |
Requirements: | |
* Unix-like system (cygwin is fine) | |
* Ruby | |
* Git command | |
Usage: | |
Download this script and run | |
> ruby browserjs.rb | |
On the first run, it creates two directories; repo and file. | |
* 'repo' is the git repository | |
* 'file' contains all files that was stored in the git repo | |
From the next time, it only updates the differences. | |
=end | |
require 'time' | |
require 'open-uri' | |
require 'fileutils' | |
class GitWrapper | |
def initialize(git_command, dir) | |
@git = git_command | |
@dir = dir | |
end | |
def exec(args, show_command=false, no_color=true, show_stderr=false) | |
FileUtils.cd(@dir) | |
command = "#{@git} #{args}" | |
puts command if show_command | |
#puts "> " + command | |
command += ' --no-color' if no_color | |
command += ' 2> /dev/null' unless show_stderr | |
`#{command}` | |
end | |
def add(file) | |
exec("add #{file}", false, false) | |
end | |
def commit(message, date=nil) | |
date = date.nil? ? "" : " --date=#{date}" | |
exec("commit#{date} -m '#{message}'", true, false) | |
end | |
def init | |
exec('init', true, false, true) | |
end | |
def branch_create(name) | |
exec("branch #{name}", true) | |
end | |
def branch_list | |
l = exec("branch") | |
branches = [] | |
l.lines.each {|b| | |
if b =~ /^\*?\s*(.*)\s*$/ | |
branches.push(Version.new($1)) | |
end | |
} | |
return branches | |
end | |
def current_branch | |
l = exec("branch") | |
l.lines.each {|b| | |
if b =~ /^\*\s*(.*)\s*$/ | |
return $1 | |
end | |
} | |
end | |
def checkout(name) | |
exec("checkout #{name}", true, false) | |
end | |
def log1 | |
exec("log -1") | |
end | |
end | |
class BrowserJSCommit | |
DefaultFilename = 'browser.js' | |
attr_reader :version, :time | |
def initialize(version, time, filename, parent_url, save_dir, repo_dir) | |
@version = version | |
@time = time | |
@url = "#{parent_url}/#{filename}" | |
@save_file = File.join(save_dir, filename) | |
@file = File.join(repo_dir, DefaultFilename) | |
end | |
def download_or_restore | |
if File.exist?(@save_file) && File.mtime(@save_file) == @time | |
puts "restoring #{@save_file}" | |
else | |
puts "downloading #{@url}" | |
download | |
end | |
FileUtils.cp(@save_file, @file) | |
return self | |
end | |
def download | |
open(@save_file, 'w') {|f| | |
open(@url) {|u| | |
f.print(u.read) | |
} | |
} | |
File.utime(@time, @time, @save_file) | |
end | |
def commit(git) | |
git.add(DefaultFilename) | |
git.commit("#{@version} / #{@time.to_s}", @time.to_i) | |
end | |
def <=>(other) | |
@time <=> other.time | |
end | |
end | |
class Version < String | |
attr_reader :major, :minor | |
def initialize(version_string) | |
super(version_string) | |
@major, @minor = version_string.split('.').map{|v| v.to_i} | |
end | |
def <=>(other) | |
if @major != other.major | |
return @major <=> other.major | |
else | |
return @minor <=> other.minor | |
end | |
end | |
end | |
class BrowserJS2Git | |
IndexURL = 'http://get.geo.opera.com/res/servicefiles/userjsfiles/all/' | |
Line = %r!<tr>.*<td><a href="(.*?)">.*?</a></td><td align="right">(.*?)</td>.*</tr>! | |
RepoDir = "repo" | |
FileDir = "file" | |
def initialize | |
@root = File.dirname(File.expand_path(__FILE__)) | |
@branches = [] | |
@commits = [] | |
git = `which git 2> /dev/null`.chop | |
if git.empty? | |
puts "git not found" | |
exit(1) | |
end | |
@git = GitWrapper.new(git, File.join(@root, RepoDir)) | |
end | |
def start | |
prepare_directories | |
prepare_repository | |
get_branches | |
check_last_commit | |
prepare_commits | |
update | |
end | |
def prepare_directories | |
[RepoDir, FileDir].each {|dir| | |
repo = File.join(@root, dir) | |
FileUtils.mkdir(repo) unless File.exist?(repo) | |
} | |
end | |
def prepare_repository | |
dot_git = File.join("#{@root}", RepoDir, ".git") | |
unless File.directory?(dot_git) | |
puts "initializing repository" | |
@git.init | |
FileUtils.touch('browser.js') | |
@git.add("browser.js") | |
@git.commit('master branch will not be used', 100000000) | |
end | |
end | |
def get_branches | |
branches = @git.branch_list | |
puts "existing branches : #{branches.join(", ")}" | |
@branches = branches.delete_if {|b| b == "master"}.sort{|a,b| a <=> b} | |
@git.checkout(@branches.last || "master") | |
end | |
def check_last_commit | |
last_commit = @git.log1 | |
if last_commit.empty? | |
@last_commit_time = Time.at(0) # epoch zero | |
else | |
puts "last commit log :\n#{last_commit}" | |
@last_commit_time = Time.parse(last_commit.grep(/^Date:/)[0].sub(/^Date:/,'').chop) | |
end | |
end | |
def prepare_commits | |
open(IndexURL) {|u| | |
html = u.read | |
html.scan(Line) {|m| | |
file = m[0] | |
version = version_string(file) | |
next if version.nil? | |
version = Version.new(version) | |
time = Time.parse(m[1] + " UTC") | |
next if time <= @last_commit_time | |
@commits.push(BrowserJSCommit.new(version, time, file, IndexURL, | |
File.join(@root, FileDir), | |
File.join(@root, RepoDir))) | |
} | |
} | |
end | |
def update | |
@commits.sort.each { |co| | |
puts "------" | |
version = co.version | |
if @branches.include?(version) | |
@git.checkout(version) | |
else | |
# branch from the latest version not exceeding the committing version | |
@branches.push(version).sort!{|a,b| a <=> b} | |
idx = @branches.index(version) | |
@git.checkout(@branches[idx - 1]) if idx > 0 | |
# create new branch | |
@git.branch_create(version) | |
@git.checkout(version) | |
end | |
co.download_or_restore.commit(@git) | |
sleep 0.5 | |
} | |
end | |
def version_string(filename) | |
#if filename =~ /^browser-(\d\.\d\d)-/ | |
#return $1 | |
#if filename =~ /^browser-(\d)(\d\d)-/ | |
#return "#{$1}.#{$2}" | |
#end | |
if filename =~ /^browserjs-desktop-(\d\d?\.\d\d)-/ | |
return $1 | |
end | |
return nil | |
end | |
end | |
BrowserJS2Git.new.start | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment