[Localization] Mechanize posts instead of uploading

Aleksey Lim alsroot at member.fsf.org
Thu Nov 27 05:18:29 EST 2008


On Thu, Nov 27, 2008 at 04:05:35AM -0600, Li Zhang wrote:
>  Hi Aleksey,
> 
>      I tried your script to submit the difference between two po files.
> But I think it didn't submit to pootle server finally. I don't know why.
>      I build the ruby script execution environment  and execute the
> command line: poster -u zhangli924 -p ****(my password) -j etoys -l
> zh_CN etoys.po etoys_new.po.
>      The result is :
>       
>  240     no form
> 55      no form
> 
>     Is it right execution result? In fact, in etoys_new.po, I've
oops, I use <new.po> filename as part of submiting url, try new version
and add '-i etoys.po' argument

btw update mechanize (if you use old version, mine is 0.8.5), I had
propblems with old versions
-------------- 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/'s name)
#                           or use POOTLE_PROJECT environment variable
#   -i,--file=FILE          sub-project file name (equal to https://dev.laptop.org/translate/'s .po filename)
#                           or use POOTLE_FILE environment variable
#   -l,--lang=LANG          lang (equal to https://dev.laptop.org/translate/'s 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(/\\"/, '"') \
                            .gsub(/\\\\/, '\\')
            }

            src = nil
            fuzzy = nil
        end

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

            if i =~ /"(.*)"/
                out[index-MsgidOffset][:msgstr] = $1.gsub(/\\"/, "\"") \
                                                    .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 ],
    [ '--file',     '-i',   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'],
    '--file'        => ENV['POOTLE_FILE'],
    '--force'       => (not ENV['POOTLE_FORCE'].to_s.empty?)
}

GetoptLong.new(*options).each do |opt, arg|
    @options[opt] = arg.empty? ? true : arg
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']
    file = @options['--file']
    page = exec { agent.get("https://dev.laptop.org/translate/#{lang}/#{proj}/#{ARGV[1]}?translate=1&item=#{i}&pofilename=#{file}") }

    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[:msgid]
        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