[Localization] Mechanize posts instead of uploading

Aleksey Lim alsroot at member.fsf.org
Tue Nov 25 07:15:44 EST 2008


...begging pardon (forgot attach file :)

On Tue, Nov 25, 2008 at 12:12:51PM +0000, Aleksey Lim wrote:
> Hi all,
> 
> since thats became very popular to upload huge .po files, and make server
> inaccessible :). I suggest (as temporary solution) use mechanize scripts to
> post .po diffs like one in my attachments
> 
> ---
> Aleksey
> _______________________________________________
> Localization mailing list
> Localization at lists.laptop.org
> http://lists.laptop.org/listinfo/localization
> 
-------------- next part --------------
#!/usr/bin/env ruby

# Usage: poster [options] old.po new.po
#
# Tool to post changes between two .po files to https://dev.laptop.org/translate/
#
# Options:
#
#   -u,--user=USER          login to connect to https://dev.laptop.org/translate/
#                           or use POOTLE_USER environment variable
#   -p,--password=PASSWORD  password to connect to https://dev.laptop.org/translate/
#                           or use POOTLE_PASSWORD environment variable
#   -j,--project=PROJECT    project name (equal to https://dev.laptop.org/translate/ name)
#                           or use POOTLE_PROJECT environment variable
#   -l,--lang=LANG          lang (equal to https://dev.laptop.org/translate/ lang name)
#                           or use POOTLE_LANG environment variable
#   -f,--force              force to overwrite existing translation
#                           or use POOTLE_FORCE environment variable
#   -h,--help               display this help and exit

require 'rubygems'
require 'mechanize'
require 'getoptlong'
require 'rdoc/usage'

MsgidOffset = 2

def load_po(file)
    out = {}
    src = nil
    fuzzy = nil
    index = 0

    File.open(file).read.gsub(/" *\n"/, '').split("\n").each do |i|
        src = $1 if i =~ /^#: (.*)/
        fuzzy = true if i =~ /^#, fuzzy/

        if i =~ /^msgid/
            index = index + 1
            next if index < MsgidOffset

            i =~ /\"(.*)\"/

            out[index-MsgidOffset] = {
                :src => src,
                :fuzzy => fuzzy,
                :msgid => $1.gsub(/\\n/, "\n").gsub(/\\t/, "\t").gsub(/\\"/, '"')
            }

            src = nil
            fuzzy = nil
        end

        if i =~ /^msgstr/
            next if index < MsgidOffset

            if i =~ /"(.*)"/
                out[index-MsgidOffset][:msgstr] = $1.gsub(/\\"/, "\"") 
            end
        end
    end

    return out
end

def exec
    while true
        begin
            return yield
        rescue TypeError
            print '.'
        rescue Timeout::Error
            print '*'
        end
        $stdout.flush
    end
end

options = [
    [ '--help',     '-h',   GetoptLong::NO_ARGUMENT ],
    [ '--user',     '-u',   GetoptLong::REQUIRED_ARGUMENT ],
    [ '--password', '-p',   GetoptLong::REQUIRED_ARGUMENT ],
    [ '--project',  '-j',   GetoptLong::REQUIRED_ARGUMENT ],
    [ '--lang',     '-l',   GetoptLong::REQUIRED_ARGUMENT ],
    [ '--force',    '-f',   GetoptLong::NO_ARGUMENT ],
]

@options = {
    '--user'        => ENV['POOTLE_USER'],
    '--password'    => ENV['POOTLE_PASSWORD'],
    '--project'     => ENV['POOTLE_PROJECT'],
    '--lang'        => ENV['POOTLE_LANG'],
    '--force'       => (not ENV['POOTLE_FORCE'].to_s.empty?)
}

GetoptLong.new(*options).each do |opt, arg|
    @options[opt] = arg || true
end

if @options['--help'] == true or ARGV.size == 0
    RDoc::usage
    exit 0
end

ARGV.length == 2 || raise('missed .po files')

@options.each do |opt, arg|
    if arg.nil? or arg.to_s.empty?
        raise "missed #{opt}"
    end
end

old = load_po(ARGV[0])
new = load_po(ARGV[1])
patch = {}

new.each do |i, s|
    raise if s[:src] != old[i][:src]
    raise if s[:msgid] != old[i][:msgid]

    if not s[:msgstr].empty? and s[:msgstr] != old[i][:msgstr]
        patch[i] = s
    end
end

if patch.empty?
    puts '.po are the same'
    exit
end

agent = WWW::Mechanize.new

page = exec { agent.get('https://dev.laptop.org/translate/login.html') }
form = page.forms.first
form.username = @options['--user']
form.password = @options['--password']
exec { agent.submit(form, form.buttons.first) }

patch.each do |i, s|
    print "#{i}\t"
    $stdout.flush

    lang = @options['--lang']
    proj = @options['--project']
    page = exec { agent.get("https://dev.laptop.org/translate/#{lang}/#{proj}/#{ARGV[1]}?translate=1&item=#{i}&pofilename=#{ARGV[1]}") }

    if not (form = page.form('translate'))
        puts 'no form'
        next
    end

    if not (orig = form.field("orig-pure#{i}.0"))
        puts 'no orig'
        next
    end

    if orig.value != s[:msgid]
        puts 'different msgids'
        puts '--- original msgid'
        puts orig.value
        puts '--- new msgid'
        puts s.value
        next
    end

    if not form.field("trans#{i}").value.empty? and @options['--force'] == false
        puts 'do not overwrite'
        next
    end

    form.field("trans#{i}").value = s[:msgstr]
    exec { agent.submit(form, form.button("submit#{i}")) }
    puts 'ok'
end


More information about the Localization mailing list