#!/usr/bin/env ruby # -*- coding: utf-8 -*- require 'sqlite3' require 'cgi' require 'kconv' require 'tmpdir' require 'json' db = "../viewerdb/db/viewer_prc.sq3" c = CGI.new(:accept_charset=>'utf-8') mydir=File.dirname($0) @mapdb = SQLite3::Database.new(db) @mapdb.results_as_hash = true @tmpdir = ENV["TMPDIR"] || "tmp" @resizepx = 1280 @imgprocscript = "%s/imgpublisher.sh" % mydir updater = nil reqpars = { 'ename' => /^[-a-z_.0-9]+$/, 'name' => /./, 'addr' => /.../, 'latlon' => /^\d+\.\d+,\s*\d+\.\d+$/, 'maptype' => /^[-a-z_.0-9]+$/, 'description' => /...../ } def content(file) open(file){|f| f.read.toutf8} end def cat(file) print(content(file)) end def db2options(selection) opts = "" @mapdb.execute("SELECT DISTINCT #{selection}") do |row| opts += sprintf("<option value=\"%s\">%s</option>\n", CGI.escapeHTML(row[0].toutf8.gsub('"', "")), CGI.escapeHTML(row[1]||row[0]||"")) end opts end def process_data(cgi) test(?w, @tmpdir) or abort "Cannot output files to #{@tmpdir}" basename = cgi.params["ename"][0].strip.gsub(/\s/, "") filenames = [] dir = Dir.mktmpdir(nil, File.expand_path(@tmpdir)) cgi.params["photo"].each do |img| ext = File.extname(img.original_filename).downcase.sub(/jpeg$/, "jpg") fn = sprintf("%s-%d%s", basename, 1 + filenames.length, ext) open(dir+"/"+fn, "w"){|f| f.write(img.read)} filenames << fn end Dir.chdir(dir) do # system "ls -lF" pid = fork { exec(@imgprocscript, "-l", cgi["latlon"]) } $stdout.close end end def prepareJSdata() globalvar = "entInit_mapitems" data = {} r = @mapdb.execute(<<-EOF) SELECT ename, name, addr, lat, lon FROM mapitem NATURAL JOIN maptype EOF r.each do |row| ename = row['ename'] data[ename] ||= {} ["name", "addr", "lat", "lon"].each do |i| data[ename][i] = row[i] data[ename]["latlon"] = row['lat'].to_s+", "+row['lon'].to_s end end printf(<<-EOF, globalvar, JSON.pretty_generate(data)) <script type="text/javascript" charset="utf-8"> <!-- var %s = %s; // --> </script> EOF end def updatedb(params) ename, name, addr, latlon, maptype, description = params['ename'][0], params['name'][0], params['addr'][0], params['latlon'][0], params['maptype'][0], params['description'][0] lat, lon = latlon.scan(/(\d+.\d+),\s*(\d+.\d+)/)[0] # p ename, description puts "<pre>" printf("%s|%s|%s|%s|%s|%s", *[ename, name, addr, lat, lon, description]) @mapdb.transaction do |d| d.execute(<<-EOF, ename, name, addr, lat.to_f, lon.to_f) REPLACE INTO mapitem(ename, name, addr, lat, lon) VALUES (?, ?, ?, ?, ?); EOF d.execute(<<-EOF, ename, 'description', description) REPLACE INTO attribute(ename, attr, value) VALUES (?, ?, ?); EOF puts "</pre>" end end def returnJSON(entity) data = {} entity.gsub!(/[^-0-9a-z._]/, "") print "Content-type: text/plain; charset=UTF-8\n\n" r = @mapdb.execute(<<-EOF, entity)[0] SELECT i.ename, name, addr, lat, lon, printf("%s, %s", lat, lon) as latlon, attr, value as description FROM mapitem i LEFT JOIN attribute a ON i.ename=a.ename AND a.attr='description' WHERE i.ename=? EOF if r STDERR.puts JSON.generate(r) print JSON.generate(r) else puts "[]" end end # ARGV[0]=="get/ENTITY" returns its attributes in JSON format if ARGV[0] && %r,^get/([-0-9a-z._]+)$,i =~ ARGV[0] returnJSON($1) exit 0 end print "Content-type: text/html; charset=utf-8\n\n" ef = content("ent-form.html") if c.params['submitting'][0] invalid = false # Validating parameters reqpars.each do |par, ptn| classholder = "__%sIV__" % par.upcase if !c.params[par][0] || ptn !~ c.params[par][0] invalid = true ef.gsub!(classholder, ' class="e"') else ef.gsub!(classholder, '') end end if invalid ef.gsub!("__INVALMSG__", "赤地の部分の記入が不十分です。") else ef.gsub!("__INVALMSG__", "") description = c['description'].chomp+"\n" if c.params["photo"][0] != "" # XXX: is it OK? i, o = IO.pipe pid = fork do # i.close $stdout.reopen(o) # We should substitute stdio here $stdin.close # to avoid blocking to web-client process_data(c) end o.close while line=i.gets # Reading repetition of {{IMGURL}} if %r,{{.*\/(\S+.jpg)}}, =~ line if !description.index($1) # Already desc. contains no filename # THINK! Adding at the BOTTOM is nice or not!? description += line end end end end # Then update DB! updater = lambda{updatedb(c.params.merge({'description'=>[description]}))} end else ef.gsub!(/__\w+IV__/, "") end for v in reqpars.keys ef.gsub!("__"+v.upcase+"__", CGI.escapeHTML(c.params[v][0]||"")) end cat("ent-header.html") print ef.gsub(/__{(.*)}__/) {db2options($1)} prepareJSdata updater and updater.call cat("footer.html")