Files
rogaining_srv/LineBot/MobServer_gifuroge.rb

8075 lines
245 KiB
Ruby
Raw Normal View History

2024-11-03 19:53:23 +09:00
$:.unshift File.dirname(__FILE__) # ロードパスにカレントディレクトリを追加
require 'sinatra/base'
require "line/bot"
require "date"
require "rexml/document"
require "json"
require 'nkf'
require 'time'
require "fileutils"
require "rmagick"
require 'open-uri'
require 'uri'
require 'csv'
require '/var/www/lib/aws.rb'
require '/var/www/lib/userpostgres.rb'
require '/var/www/lib/appexeExcelDoc.rb'
require 'httparty'
#=====================================
# queue用メソッド
#=====================================
#=====================================
# queueconfig
#=====================================
def set_dbname
return "gifuroge"
end
def set_commonbase # 画像やスコアボードを保存している場所
return "/var/www/html/images/gifuRoge"
end
def set_commonbase2 # 画像やスコアボードを保存している場所をアドレスにしたもの
return "/var/www/html/images/gifuRoge"
#return "https://rogaining.sumasen.net/images/gifuRoge"
end
def set_originbase # 汎用的な画像を格納している場所。基本的に弄らなくていいはず
return "/var/www/html/images/gifuRoge/asset"
#return "https://rogaining.sumasen.net/images/gifuRoge/asset"
end
def queue_error_log_base # キューでエラーが出た時にそれを格納するテキストファイルの場所
return "/home/ubuntu/gifuRogePrintQueError.log"
end
def s3_key
return "AKIA6LVMTADSVEB5LZ2H"
end
def s3_Skey
return "KIbm47dqVBxSmeHygrh5ENV1uXzJMc7fLnJOvtUm"
end
def s3_bucket
return "sumasenrogaining"
end
def s3_region
return "us-west-2"
end
def s3_domain
return "https://sumasenrogaining.s3.us-west-2.amazonaws.com"
end
def get_team_name(zekken_number, event_code)
@pgconn = UserPostgres.new
dbname = set_dbname()
@pgconn.connectPg("localhost", "mobilous", 0, dbname)
team_table = UserPostgresTable.new
team_table.useTable(@pgconn, 'team_table')
where = "zekken_number = '#{zekken_number}' AND event_code = '#{event_code}'"
record = team_table.find2(where).first # 期待するのは1レコードだけなので、firstを使って最初のものを取得
if record
return record["team_name"]
else
return nil # team_nameが見つからない場合
end
end
def get_class_name(zekken_number, event_code)
@pgconn = UserPostgres.new
dbname = set_dbname()
@pgconn.connectPg("localhost", "mobilous", 0, dbname)
team_table = UserPostgresTable.new
team_table.useTable(@pgconn, 'team_table')
where = "zekken_number = '#{zekken_number}' AND event_code = '#{event_code}'"
record = team_table.find2(where).first # 期待するのは1レコードだけなので、firstを使って最初のものを取得
if record
return record["class_name"]
else
return nil # team_nameが見つからない場合
end
end
def get_unique_event_codes(pgconn)
anytable = UserPostgresTable.new
anytable.useTable(pgconn, 'gps_information')
records = anytable.find2(nil, nil, "DISTINCT event_code")
records.map { |row| row["event_code"] }
end
def get_top_users(pgconn, event_code, class_name)
anytable = UserPostgresTable.new
anytable.useTable(pgconn, 'gps_information')
# テーブル構造に合わせてクエリを修正
where_clause = "event_code = '#{event_code}'"
order_clause = "zekken_number ASC, create_at DESC"
records = anytable.find2(where_clause, order_clause)
# クラス名でフィルタリング(データベースに class_name カラムがない場合)
filtered_records = records.select { |r| r["class_name"] == class_name }
# Simulate DISTINCT ON by filtering in Ruby
top_users = filtered_records.group_by { |r| r["zekken_number"] }
.map { |_, user_records| user_records.first }
.first(3)
top_users.map do |user|
{
"zekken_number" => user["zekken_number"],
"team_name" => user["team_name"],
"class_name" => class_name,
"colabo_company_memo" => user["colabo_company_memo"]
}
end
end
def get_top_users_by_class(pgconn, event_code)
gps_table = UserPostgresTable.new
gps_table.useTable(pgconn, 'gps_information')
checkpoint_table = UserPostgresTable.new
checkpoint_table.useTable(pgconn, 'checkpoint_table')
team_table = UserPostgresTable.new
team_table.useTable(pgconn, 'team_table')
gps_records = gps_table.find2("event_code = '#{event_code}' AND colabo_company_memo = 'FC岐阜'")
checkpoint_records = checkpoint_table.find2("event_code = '#{event_code}'")
team_records = team_table.find2("event_code = '#{event_code}'")
checkpoint_data = checkpoint_records.group_by { |r| r["cp_number"] }
team_data = team_records.group_by { |r| r["zekken_number"] }
user_data = gps_records.group_by { |r| r["zekken_number"] }.map do |zekken_number, records|
team_info = team_data[zekken_number]&.first || {}
daily_scores = calculate_daily_scores(records, checkpoint_data)
best_score = daily_scores.max_by { |_, score| score[:point] }
{
"zekken_number" => zekken_number,
"event_code" => event_code,
"team_name" => team_info["team_name"],
"class_name" => team_info["class_name"],
"best_score" => best_score[1][:point],
"best_cp_count" => best_score[1][:cp_count],
"best_late_point" => best_score[1][:late_point],
"best_overtime_penalty" => best_score[1][:overtime_penalty],
"best_duration_minutes" => best_score[1][:duration_minutes],
"last_checkin" => best_score[1][:end_time],
"daily_scores" => daily_scores.transform_keys { |k| k.to_s }
}
end
user_data.group_by { |u| u["class_name"] }.transform_values do |users|
users.sort_by { |u| [-u["best_score"], -u["best_cp_count"]] }.first(3)
end
end
def get_all_users_by_class(pgconn, event_code)
gps_table = UserPostgresTable.new
gps_table.useTable(pgconn, 'gps_information')
checkpoint_table = UserPostgresTable.new
checkpoint_table.useTable(pgconn, 'checkpoint_table')
team_table = UserPostgresTable.new
team_table.useTable(pgconn, 'team_table')
gps_records = gps_table.find2("event_code = '#{event_code}' AND colabo_company_memo = 'FC岐阜'")
checkpoint_records = checkpoint_table.find2("event_code = '#{event_code}'")
team_records = team_table.find2("event_code = '#{event_code}'")
checkpoint_data = checkpoint_records.group_by { |r| r["cp_number"] }
team_data = team_records.group_by { |r| r["zekken_number"] }
user_data = gps_records.group_by { |r| r["zekken_number"] }.map do |zekken_number, records|
team_info = team_data[zekken_number]&.first || {}
daily_scores = calculate_daily_scores(records, checkpoint_data)
best_score = daily_scores.max_by { |_, score| score[:point] }
{
"zekken_number" => zekken_number,
"event_code" => event_code,
"team_name" => team_info["team_name"],
"class_name" => team_info["class_name"],
"best_score" => best_score[1][:point],
"best_cp_count" => best_score[1][:cp_count],
"best_late_point" => best_score[1][:late_point],
"best_overtime_penalty" => best_score[1][:overtime_penalty],
"best_duration_minutes" => best_score[1][:duration_minutes],
"last_checkin" => best_score[1][:end_time],
"daily_scores" => daily_scores.transform_keys { |k| k.to_s }
}
end
user_data.group_by { |u| u["class_name"] }.transform_values do |users|
users.sort_by { |u| [-u["best_score"], -u["best_cp_count"]] }
end
end
def calculate_daily_scores(records, checkpoint_data)
records.group_by { |r| Date.parse(r["create_at"]) }.transform_values do |day_records|
photo_point = 0
buy_point = 0
late_point = 0
cp_count = 0
# 開始時間と終了時間を特定
start_time = Time.parse(day_records.min_by { |r| r["create_at"] }["create_at"])
end_time = Time.parse(day_records.max_by { |r| r["create_at"] }["create_at"])
day_records.each do |r|
cp_info = checkpoint_data[r["cp_number"]]&.first || {}
if r["cp_number"].to_i > 0
cp_count += 1
if !r["buy_flag"] && !r["minus_photo_flag"]
photo_point += cp_info["photo_point"].to_i
end
if r["buy_flag"]
buy_point += cp_info["buy_point"].to_i
end
end
late_point += r["late_point"].to_i
end
# 超過時間のペナルティ計算
duration_seconds = (end_time - start_time).to_i
overtime_seconds = [duration_seconds - 18000, 0].max # 5時間 = 18000秒
overtime_penalty = if overtime_seconds > 0
base_penalty = 50 # 1秒でも超えたら50点引く
additional_penalty = (overtime_seconds / 60.0).floor * 50 # 1分ごとに追加で50点引く
base_penalty + additional_penalty
else
0
end
point = photo_point + buy_point - late_point - overtime_penalty
{
point: point,
cp_count: cp_count,
late_point: late_point,
overtime_penalty: overtime_penalty,
start_time: start_time.strftime("%Y-%m-%d %H:%M:%S"),
end_time: end_time.strftime("%Y-%m-%d %H:%M:%S"),
duration_minutes: (duration_seconds / 60.0).ceil
}
end
end
# get_top_users_by_class メソッドは変更なし
def calculate_points(records, checkpoint_data)
photo_point = 0
buy_point = 0
late_point = 0
cp_count = 0
records.each do |r|
cp_info = checkpoint_data[r["cp_number"]]&.first || {}
if r["cp_number"].to_i > 0
cp_count += 1
if !r["buy_flag"] && !r["minus_photo_flag"]
photo_point += cp_info["photo_point"].to_i
end
if r["buy_flag"]
buy_point += cp_info["buy_point"].to_i
end
end
late_point += r["late_point"].to_i
end
point = photo_point + buy_point - late_point
[point, cp_count, late_point]
end
def calculate_user_scores(pgconn, zekken_number, event_code)
gps_table = UserPostgresTable.new
gps_table.useTable(pgconn, 'gps_information')
today = Date.today
start_date = Date.new(today.year, today.month, 1)
end_date = Date.new(today.year, today.month, -1) # 月末日
where_clause = "zekken_number = '#{zekken_number}' AND event_code = '#{event_code}' " \
"AND create_at >= '#{start_date}' AND create_at <= '#{end_date}' " \
"AND colabo_company_memo = 'FC岐阜'"
records = gps_table.find2(where_clause)
total_score = records.count { |r| r["cp_number"].to_i > 0 }
last_checkin = records.map { |r| r["create_at"] }.max
{
"best_score" => total_score,
"total_score" => total_score,
"last_checkin" => last_checkin
}
end
##移動経路画像作成
# 1. 上位ユーザーの移動データを取得する関数
def get_top_users_routes(pgconn, event_code, class_name, limit = 3)
anytable = UserPostgresTable.new
anytable.useTable(pgconn, 'gps_information')
top_users = get_top_users(pgconn, event_code, class_name)
routes = {}
top_users.each do |user|
zekken_number = user["zekken_number"]
where = "zekken_number = '#{zekken_number}' AND event_code = '#{event_code}' ORDER BY create_at ASC"
route = anytable.find2(where)
routes[zekken_number] = route.map do |point|
{
latitude: point['latitude'].to_f,
longitude: point['longitude'].to_f,
timestamp: point['create_at']
}
end
end
routes
end
# 2. 移動経路を描画する関数
def draw_route(image, route, color)
draw = Magick::Draw.new
draw.stroke(color)
draw.stroke_width(2)
points = route.map do |point|
[point['longitude'].to_f, point['latitude'].to_f]
end
draw.polyline(*points.flatten)
draw.draw(image)
end
# 3. 画像生成と保存を行う関数
def generate_route_image(routes, event_code)
width = 800
height = 600
image = Magick::Image.new(width, height) { self.background_color = 'white' }
# ルートの座標を正規化するための関数
normalize = lambda do |val, min, max|
(val - min) / (max - min)
end
# すべてのルートの座標範囲を取得
all_points = routes.values.flatten
min_lat = all_points.map { |p| p['latitude'].to_f }.min
max_lat = all_points.map { |p| p['latitude'].to_f }.max
min_lon = all_points.map { |p| p['longitude'].to_f }.min
max_lon = all_points.map { |p| p['longitude'].to_f }.max
colors = ['red', 'blue', 'green']
routes.each_with_index do |(zekken_number, route), index|
normalized_route = route.map do |point|
x = normalize.call(point['longitude'].to_f, min_lon, max_lon) * width
y = height - normalize.call(point['latitude'].to_f, min_lat, max_lat) * height
[x, y]
end
draw_route(image, normalized_route, colors[index])
end
filename = "top_routes_#{event_code}_#{Time.now.strftime('%Y%m%d%H%M%S')}.png"
image.write(filename)
filename
end
#=====================================
# queue:util
#=====================================
def to_boolean str
str.to_s.downcase == "true"
end
#=====================================
# queueDB
#=====================================
# SELECT
def getFinalReport zekken_number, event_code
@pgconn=UserPostgres.new
dbname = set_dbname()
@pgconn.connectPg("localhost","mobilous",0,dbname)
anytable=UserPostgresTable.new
anytable.useTable( @pgconn,'report_list' )
where = "zekken_number = '#{zekken_number}' AND event_code = '#{event_code}'"
list = anytable.find2(where)
result = ""
list.each { |rec|
result = rec["report_address"]
}
@pgconn.disconnect
if result == "" || result == nil then
return "no report"
end
return result
end
def getGpsInfo zekken_number, event_code
@pgconn=UserPostgres.new
dbname = set_dbname()
@pgconn.connectPg("localhost","mobilous",0,dbname)
anytable=UserPostgresTable.new
anytable.useTable( @pgconn,'gps_information' )
where = "zekken_number = '#{zekken_number}' AND event_code = '#{event_code}' ORDER BY serial_number"
p "where : #{where}"
list = anytable.find2(where)
result = []
p "list : #{list}"
if list == nil then
@pgconn.disconnect
return []
end
count = 0
list.each { |rec|
result[count] = {"cp_number" => rec['cp_number']}
count += 1
}
@pgconn.disconnect
if result != "" && result != nil then
return result
else
return []
end
end
def getPhotoFromRR zekken_number, event_code, num #RR => RouteResult
@pgconn=UserPostgres.new
dbname = set_dbname()
@pgconn.connectPg("localhost","mobilous",0,dbname)
if num <= 60
table = 'route_result'
else
table = 'route_result_2'
end
anytable=UserPostgresTable.new
anytable.useTable( @pgconn,table )
where = "zekken_number = '#{zekken_number}' AND event_code = '#{event_code}'"
list = anytable.find2(where)
result = {}
if list == nil then
return {"result" => "ERROR"}
end
docpath = set_commonbase() + '/' + event_code + '/' + zekken_number
if( !Dir.exist?(docpath) )then
if( Dir.mkdir( docpath,0755 ) == 0 ) then
end
end
list.each { |rec|
for i in 1..num do
begin
if rec["cp#{i}_ph"].include?(s3_domain()) then
extension = result["cp#{i}_ph"].to_s.split('.').last
result["cp#{i}_ph"] = rec["cp#{i}_ph"].gsub(s3_domain(),set_commonbase()).gsub(".#{extension}","_th.#{extension}")
elsif rec["cp#{i}_ph"].include?(set_commonbase2()) then
result["cp#{i}_ph"] = rec["cp#{i}_ph"].gsub(set_commonbase2(),set_commonbase())
else
result["cp#{i}_ph"] = "#{set_commonbase()}/asset/photo_none.png"
end
rescue => e
p "error : #{e}, result[cp#{i}_ph] :#{result["cp#{i}_ph"]}"
result["cp#{i}_ph"] = "#{set_commonbase()}/asset/photo_none.png"
end
if result["cp#{i}_ph"].include?("asset/asset") then
result["cp#{i}_ph"].gsub!('asset/asset', 'asset')
end
if File.exist?(result["cp#{i}_ph"]) == false then
begin
filename = rec["cp#{i}_ph"].split('/').last
fullpath = docpath + '/' + filename
fullpath2 = s3_domain + '/' + URI.encode_www_form_component(event_code, enc=nil) + '/' + zekken_number + '/' + filename
URI.open(fullpath2) do |image|
File.open(fullpath, 'w') do |file|
file.write(image.read)
end
end
extension = filename.split('.').last
filenameTh = filename.gsub(".#{extension}","_th.#{extension}")
imageOri = Magick::Image.read(fullpath).first
imageTh = imageOri.scale(image_size_width(), image_size_height())
imageTh.write("temp/#{filenameTh}")
nextpath = docpath + '/' + filenameTh
FileUtils.mv("/var/www/temp/#{filenameTh}",nextpath)
# File.delete(fullpath)
result["cp#{i}_ph"] = nextpath
rescue => e
p "error : #{e}, rec[cp#{i}_ph] :#{rec["cp#{i}_ph"]}"
result["cp#{i}_ph"] = "#{set_commonbase()}/asset/photo_none.png"
end
end
begin
result["cp#{i}_p"] = rec["cp#{i}_p"]
rescue => e
p "error : #{e}, result[cp#{i}_p] : #{result["cp#{i}_p"]}"
end
begin
result["cp#{i}_s"] = rec["cp#{i}_s"].gsub(set_commonbase2(),set_commonbase())
rescue => e
p "error : #{e}, result[cp#{i}_s] : #{result["cp#{i}_s"]}"
result["cp#{i}_s"] = "#{set_commonbase()}/asset/photo_none.png"
end
if result["cp#{i}_s"].include?("asset/asset") then
result["cp#{i}_s"].gsub!('asset/asset', 'asset')
end
if File.exist?(result["cp#{i}_s"]) == false then
result["cp#{i}_s"] = "#{set_commonbase()}/asset/photo_none.png"
end
end
}
@pgconn.disconnect
if result == [] || result == nil then
return {"result" => "ERROR"}
end
result["result"] = "OK"
return result
end
def getPrintQueueMemory
@pgconn=UserPostgres.new
dbname = set_dbname()
@pgconn.connectPg("localhost","mobilous",0,dbname)
anytable=UserPostgresTable.new
anytable.useTable( @pgconn,'print_queue_memory' )
where = "0 = 0"
list = anytable.find2(where)
result = []
list.each { |rec|
result.push(rec)
}
@pgconn.disconnect
return result
end
# INSERT
def inputFinalReport zekken_number, event_code, pdf_address
@pgconn=UserPostgres.new
dbname = set_dbname()
@pgconn.connectPg("localhost","mobilous",0,dbname)
anytable=UserPostgresTable.new
anytable.useTable( @pgconn,'report_list' )
title = ["zekken_number", "event_code", "report_address"]
record = {"zekken_number" => zekken_number, "event_code" => event_code, "report_address" => pdf_address}
sql = anytable.makeInsertKeySet(title,record)
begin
ret = anytable.exec(sql) # true or false
rescue => error
p error
end
@pgconn.disconnect
return "200 OK"
end
# UPDATE
def changeFinalReport zekken_number, event_code, pdf_address
@pgconn=UserPostgres.new
dbname = set_dbname()
@pgconn.connectPg("localhost","mobilous",0,dbname)
rec = {"report_address" => pdf_address}
where = "zekken_number = '#{zekken_number}' AND event_code = '#{event_code}'"
begin
@pgconn.update("report_list",rec,where)
rescue => e
p e
@pgconn.disconnect
return "UPDATE ERROR"
end
@pgconn.disconnect
return "OK"
end
def removeQueueMemory
@pgconn=UserPostgres.new
dbname = set_dbname()
@pgconn.connectPg("localhost","mobilous",0,dbname)
anytable=UserPostgresTable.new
anytable.useTable( @pgconn,'print_queue_memory' )
where = "serial_number = (SELECT min(serial_number) FROM print_queue_memory)"
begin
p anytable.remove(where)
@pgconn.disconnect
return "200 OK"
rescue => e
p e
@pgconn.disconnect
2025-08-20 19:15:19 +09:00
return "200 OK"
2024-11-03 19:53:23 +09:00
end
end
#=====================================
# queues3
#=====================================
def s3Uploader data_dir, filepath, filename
bucket = s3_bucket().freeze
region = s3_region().freeze
access_key = s3_key().freeze
secret_key = s3_Skey().freeze
aws_storage = S3_StorageUtil.new( access_key,secret_key,region,bucket,data_dir )
aws_bucket = S3_FolderUtil.new( "offlineRecog/work",aws_storage )
originPath = filepath
destPath = data_dir
filename = filename
aws_bucket.uploadFile( originPath,destPath,filename )
aws_url = s3_domain() + '/' + data_dir + '/' + filename
return aws_url
end
#=====================================
# queuescoreboard
#=====================================
def makeScoreboard zekken_number, event_code, reprintF = false, budleF = false
p "makeScoreboard"
filepath = getScoreboardGeneral(zekken_number, event_code)
p "return filepath"
if filepath == "no_data" then
p "no data error"
return "no data error"
end
if reprintF then
date_memory = DateTime.now.to_s.gsub(':','-').gsub('+','_')
nextpath = set_commonbase() + "/#{event_code}" + "/scoreboard/#{zekken_number}_scoreboard_" + date_memory + ".xlsx"
else
nextpath = set_commonbase() + "/#{event_code}" + "/scoreboard/#{zekken_number}_scoreboard.xlsx"
end
p "nextpath set"
if( !Dir.exist?(set_commonbase() + "/#{event_code}" + "/scoreboard") )then
if( Dir.mkdir( set_commonbase() + "/#{event_code}" + "/scoreboard",0755 ) == 0 ) then
#p "mkdir #{commonbase}"
end
end
p "dir set"
puts "filepath=#{filepath},nextpath=#{nextpath}"
FileUtils.mv(filepath,nextpath)
p "file move"
docpath_user = set_commonbase() + "/#{event_code}" + "/scoreboard"
pdffile = "#{zekken_number}_scoreboard"
puts "PDF file will be #{pdffile}_#{date_memory} ..."
if reprintF then
pdffile = pdffile + '_' + date_memory
end
p "bofore PDF"
command ="/home/mobilousInstance/jodconverter-cli-4.4.5-SNAPSHOT/bin/jodconverter-cli -o #{docpath_user}/#{pdffile}.xlsx #{docpath_user}/#{pdffile}.pdf" #郡上のイベント後はこちらの仕様に置き換える
system( command )
puts command
#system("echo 'sumasen@123' |sudo -S /var/www/lib/generatePDF.sh #{docpath_user} #{pdffile}")
p "after PDF"
aws_url = s3Uploader("#{event_code}/scoreboard", docpath_user, pdffile + '.pdf')
p "s3 upload complete"
if getFinalReport(zekken_number, event_code) == "no report" then
inputFinalReport(zekken_number, event_code, aws_url)
else
changeFinalReport(zekken_number, event_code, aws_url)
end
p "report complete"
# File.delete(nextpath)
if budleF == false then
# File.delete(nextpath.gsub('.xlsx','.pdf'))
return nextpath.gsub('.xlsx','.pdf')
end
end
def getScoreboardGeneral zekken_number, event_code
p "getScoreboardGeneral"
#usernameエラーで引っかかる
#
#$bean.read_bean
#username = $bean.username
username = 'test'
record = {}
record["zekken_number"] = zekken_number
p "zekken_number : #{zekken_number}, event_code : #{event_code}"
result = getGpsInfo(zekken_number, event_code)
if result == [] then
p "getGPSInfo no_data"
return "no_data"
end
count = 0
result.each { |rec|
count += 1
}
result2 = getPhotoFromRR(zekken_number, event_code, count)
if result2 == {} || result2["result"] == "ERROR" then
p "getPhotoFromRP no_data"
return "no_data"
end
record.merge!(result2)
if count <= 60 then
document = "scoreboardGeneral"
else
document = "scoreboardGeneral2"
end
count = count * 2 + 1
record["num_image"] = count
#return record.to_s #昼休み後ここから
ExcelObject.resetClass
doc = AppExeExcelDoc.new
#doc = AppExeGeneralDocument.new
doc.init( username,0,document,"jp","/var/www/docbase","/home/mobilousInstance" ) # <== "/home/mobilousInstance" を出力先のベースフォルダーにしてください。
pgconn=UserPostgres.new
dbname = set_dbname()
pgconn.connectPg("localhost","mobilous",0,dbname)
rec = JSON.parse( JSON.generate(record) )
#return rec
#@sheetname = sheet
#filename = doc.makeReport( pgconn,rec,"outfile.xlsx",0 ) # ==> Use ini file defnition 2021-11-15
doc.makeReport( pgconn,rec )
# make a excel file under /var/www/docbase/(@username)/(@projectno)/
#file_path = filename.to_s.gsub(/wrote excel file on /,"")
#puts "=========> file_path = #{file_path}"
pgconn.disconnect
filename = doc.outfile
file_path = doc.outpath
puts "=========> file_path = #{file_path}, filename = #{filename}"
return file_path
end
#====================================
# キューイング処理本体
#====================================
$queue = Queue.new
Thread.new do
loop do
begin
item = JSON.parse($queue.pop)
p "queue pop : #{item}"
2025-08-20 19:15:19 +09:00
pdf_path = makeScoreboard(item["zekken_number"],item["event_code"],to_boolean(item["reprintF"]),false)
# 印刷確認処理
if pdf_path && File.exist?(pdf_path)
print_command = "lpr -P scoreboard_printer #{pdf_path}"
result = system(print_command)
puts "印刷結果: #{result ? '成功' : '失敗'}"
end
2024-11-03 19:53:23 +09:00
result = removeQueueMemory()
if result == "delete error" then
timestamp = Time.now.strftime("%Y-%m-%d %H:%M:%S")
item_value = defined?(item) ? item.to_s : ""
error_message = "#{timestamp}=> #{item_value} : queue memory delete fail\n"
File.open(queue_error_log_base(), "a") do |file|
file.write(error_message)
end
end
rescue => e
timestamp = Time.now.strftime("%Y-%m-%d %H:%M:%S")
item_value = defined?(item) ? item.to_s : ""
error_message = "#{timestamp}=> #{item_value} : #{e.message}\n"
File.open(queue_error_log_base(), "a") do |file|
file.write(error_message)
end
end
end
end
data = getPrintQueueMemory()
p "data : #{data}"
data.each { |rec|
json = JSON.parse(rec["queue_detail"])
jhash = {"zekken_number" => json["zekken_number"], "event_code" => json["event_code"], "reprintF" => json["reprintF"]}
new_json = JSON.generate(jhash)
p "queue add : #{new_json}"
$queue << new_json
}
#====================================
# sinatraここから
#====================================
module Sinatra
module MobServer_gifuroge
module Helpers
#====================================
# utils
#====================================
def crossdomain
headers 'Access-Control-Allow-Origin' => '*'
end
def headjson
headers 'Content-Type' => 'application/json; charset=utf-8'
end
#====================================
# config
#====================================
def client
# p "boot client method!"
@client ||= Line::Bot::Client.new { |config|
config.channel_id = "1657548864"
config.channel_secret = "01846a8d9d1832e55626098fca072e05"
config.channel_token = "MGv4aes9X9aTDBBv7ocR8jgine8ct7f4XpLreUt6qg8/WuEhTWhNJTa1vlbJIVOxvWTGR4SBpECM8SkccZCGF4rfrQxsATf20AK5/QNZlXZ6rh8J1R3Sth8yaX1mMNIa1ZJMvw2whdVSe90ZdywZsgdB04t89/1O/w1cDnyilFU="
}
end
def set_dbname
return "gifuroge"
end
def set_commonbase # 画像やスコアボードを保存している場所
return "/var/www/html/images/gifuRoge"
end
def set_commonbase2 # 画像やスコアボードを保存している場所をアドレスにしたもの
return "https://rogaining.sumasen.net/images/gifuRoge"
end
def set_originbase # 汎用的な画像を格納している場所。基本的に弄らなくていいはず
return "https://rogaining.sumasen.net/images/gifuRoge/asset"
end
def set_rogSimBase #ロゲイニングシミュレーターの位置
return "/home/mobilousInstance/rogaining/rogaining"
end
def location_threshold # 位置情報の閾値
return 30
end
def special_threshold
return 100
end
def latitude_1m # 1mあたりの緯度
return 0.000008983148616
end
def longitude_1m # 1mあたりの経度
return 0.000010966382364
end
def image_size_width
return 150
end
def image_size_height
return 105
end
def s3_key
return "AKIA6LVMTADSVEB5LZ2H"
end
def s3_Skey
return "KIbm47dqVBxSmeHygrh5ENV1uXzJMc7fLnJOvtUm"
end
def s3_bucket
return "sumasenrogaining"
end
def s3_region
return "us-west-2"
end
def s3_domain
return "https://sumasenrogaining.s3.us-west-2.amazonaws.com"
end
def latitude_threshols mode = nil
if mode == "special"
return special_threshold() * latitude_1m()
end
return location_threshold() * latitude_1m()
end
def longitude_threshols mode = nil
if mode == "special"
return special_threshold() * longitude_1m()
end
return location_threshold() * longitude_1m()
end
#====================================
# text
#====================================
def text_importantError errorCode
return "エラーコード:#{errorCode}\nゼッケン番号とエラーコードを添えて、運営に問い合わせて下さい。"
end
# エラーコード一覧
# STA-001 : パスワード入力のキャンセルに失敗した状態。応急対応運営側で当該ユーザーIDのchat_statusレコードを削除。
# STA-002 : 処理には成功したがchat_statusのレコードデリートに失敗した状態。応急対応処理には成功していることを伝えた上で、運営側で当該ユーザーIDのchat_statusレコードを削除。
# STA-003 : 写真受付のキャンセルに失敗した状態。応急対応運営側で当該ユーザーのchat_statusレコードを削除
# USR-001 : LINEのユーザー名を取得できていない状態。応急対応エラーを無視してゼッケン番号を登録してもらう。ゼッケン番号とユーザーIDの紐付けが出来たら、手動でユーザー名をuser_tableに追加する。
# USR-002 : ログインに成功したが、user_tableのレコードアップデートに失敗した状態。応急対応ログを確認し、実際にログインに成功しているか検証した上で、手動でゼッケン番号とチーム名をuser_tableに追加する。
# USR-003 : ログアウトの処理に失敗した。応急対応LINEのアカウント名を聞き取り、手動でuser_tableからteam_nameとzekken_nameの中身を消去する。
# DBS-001 : そのユーザーが何時間部門のユーザーなのかを認識できなくなった状態。データベースに何かしらの問題が生じていることが考えられるため、竜一に連絡
def text_zekkenRegister zekken_number
return "#{zekken_number}の代表登録を受け付けました。\n確認のためパスワードを入力し、送信して下さい。"
end
def text_teamRegister user_name, team_name
return "#{user_name}さんをチーム:#{team_name}の代表として登録しました。"
end
def text_noZekken1 user_name
return "#{user_name}さんは現在チームの代表として登録されていません。\nあなたがチームの代表であるなら、"
end
def text_noZekken2
return "ゼッケン番号:[ゼッケン番号]"
end
def text_noZekken3
return "の形でゼッケン番号を登録して下さい。"
end
def text_noZekkenNumber
return "入力されたゼッケン番号は存在しません。タイプミスがないか確認し、再度送信して下さい。"
end
def text_alreadyZekken
return "ログインに成功しましたが、入力されたゼッケン番号のチームは既に代表が登録されています。\nあなたが代表で他の方が代表登録してしまっている場合、その方に「ログアウト」と入力して貰ってから再度パスワードを入力して下さい。\n他の誰かが代表登録しているわけでもないのにこのエラーが出る場合、不正ログインが疑われますので、運営に問い合わせて下さい。"
end
def text_passwordError
return "パスワードが一致しません。もう一度入力して下さい。\nゼッケン番号の入力からやり直す場合は「キャンセル」と入力して下さい。"
end
def text_AuthorizationCancel
return "受付をキャンセルしました。"
end
def text_loguotSuccess
return "ログアウトの処理が完了しました。"
end
def text_errorCPnumber
return "CP番号は自然数で入力してください。"
end
def text_errorNoCP cp_number
return "CP番号#{cp_number}に該当するチェックポイントがありません。もう一度ご確認ください。"
end
def text_getCPnumber cp_number, cp_name
return "CP番号#{cp_number}#{cp_name}です。よろしいですか?\n宜しければ、続けて写真を送って下さい。\n間違っていれば「NO」と返信して下さい。"
end
def text_noLocation
return "位置情報の周辺15mにチェックポイントを発見できませんでした。"
end
def text_noLocationCSB cp_number, cp_name
return "位置情報の周辺15mに#{cp_number}:#{cp_name}を発見できませんでした。\nチェックポイントの指定をやり直す場合は「キャンセル」と返信して下さい。"
end
def text_registredCP cp_number, cp_name
return "#{cp_number}:#{cp_name}は既に登録されています。"
end
def text_registreCP cp_number, cp_name
return "#{cp_number}:#{cp_name}を登録しました。"
end
def text_standByBuyPoint cp_number, cp_name
return "#{cp_number}:#{cp_name}はサービスポイントのチェックポイントです。\nチェックポイントで撮影した写真をアップロードして下さい。特定の対象を写真に含めると加点対象になります。\n想定と異なるチェックポイントが認識されてしまった場合は「キャンセル」で写真受付をキャンセル出来ます。"
end
def text_BuyPointError cp_number, cp_name
return "#{cp_number}:#{cp_name}はサービスポイントのチェックポイントなので位置情報では認証できません。\n写真をアップロードして下さい。"
end
def text_getGPSlogger
return "GPSloggerのデータを受け取りました。結果発表をお待ち下さい。"
end
def text_approval_cp cp_name
return "チェックポイント:#{cp_name}の写真が承認されました。"
end
def text_not_approval_cp cp_name, reason
return "チェックポイント:#{cp_name}の写真が承認されませんでした。\n事由:#{reason}\nお手数ですが、CPの宣言からやり直して下さい。"
end
def text_goalCheck1
return "ゴールチェックポイントを確認しましたが、ゴールは"
end
def text_goalCheck2
return "ゴール:[ゴールした時刻]"
end
def text_goalCheck3
return "と入力して下さい。"
end
def text_getGoal goal_time
return "#{goal_time}でゴールタイムを記録しました。続けてタイマーの写真を送って下さい。\nゴールタイムの入力ミスなどがあった場合には「キャンセル」で、写真受付をキャンセルして、再度ゴールタイムを登録して下さい。"
end
def text_getGoalPhoto
return "ゴールの写真を記録しました。お疲れ様でした。\n印刷受付にレポートを受け取りに来て下さい。"
end
def text_alreadyGoal
return "既にゴールタイムの記録は完了しております。結果発表をお待ち下さい。"
end
def text_goalError
return "ゴールタイムの認識に失敗しました。「○○:○○」若しくは「○○時○○分」で入力して下さい。\n正しく入力しているのにこのエラーが出ている場合は運営に問い合わせて下さい。"
end
def text_notAgent
return "パスワードが一致する代理人が存在しません。"
end
def text_agentStart event_name
return "イベント:#{event_name}の代理人としてログインしました。"
end
def text_ask_for_receipt_image cp_number
return "写真を登録しました。cp: #{cp_number}は対象の商品を購入したレシートの画像を送っていただくとさらにポイントが追加されます。\nレシート写真を送ってください。\n「キャンセル」でレシート写真受付をキャンセル出来ます。"
end
def text_insertComplete cp_number, cp_name, insert_number
return "#{cp_number}:#{cp_name}#{insert_number}に挿入しました。"
end
def text_noCPregist cp_number
return "このチームの通過記録に#{cp_number}を通過したという記録はありません。"
end
def text_deleteCP sn
return "通し番号:#{sn}を削除しました。"
end
def text_moveCP sn, new_sn
return "通し番号:#{sn}の記録を通し番号:#{new_sn}に移動しました。"
end
def text_moveSameNum
return "移動元と移動先に同じ通し番号が入力されています。"
end
def text_moveOverNum
return "存在しない通し番号が指定されています。"
end
def text_goalUpdate goal_time
return "ゴール時間を#{goal_time}に更新し、遅刻点も再計算しました。"
end
def text_reprint
return "新しいレポートの生成を開始しました。"
end
def text_argumentError_Insert
return "INSERTの引数が正しくありません。\nINSERT [挿入したい通し番号] [挿入したいチェックポイント番号]\nの書式で入力して下さい。"
end
def text_notNaturakNumber
return "挿入する番号は自然数で入力して下さい。"
end
def text_startStand
return "「スタート」を実行するとチェックポイント通過情報が初期化されます。\n問題なければ「YES」、中断する場合は「NO」と入力して下さい。"
end
def text_startRun
return "チェックポイント通過情報を初期化し、ロゲイニングを開始する準備が整いました。"
end
def text_noEventName
return "該当するイベントコードが見つかりませんでした。"
end
def text_zekkenNotExist zekken_number
return "#{zekken_number}に該当するチームがありませんでした。"
end
def text_agentLogin team_name
return "#{team_name}に代理ログインしました。"
end
def text_agentLogout
return "代理ログアウトしました。"
end
#====================================
# DB:SELECT (get)
#====================================
def getUserName userId
@pgconn=UserPostgres.new
dbname = set_dbname()
@pgconn.connectPg("localhost","mobilous",0,dbname)
anytable=UserPostgresTable.new
anytable.useTable( @pgconn,'user_table' )
where = "userid = '" + userId.to_s + "'"
list = anytable.find2(where)
result = {}
if list == nil then
return getNewUserName(userId)
end
list.each { |rec|
result = rec
}
@pgconn.disconnect
if result != {} && result != nil then
return result
else
return getNewUserName(userId)
end
end
def getUserIdByZekkenNumber zekken_number, event_code
@pgconn=UserPostgres.new
dbname = set_dbname()
@pgconn.connectPg("localhost","mobilous",0,dbname)
anytable=UserPostgresTable.new
anytable.useTable( @pgconn,'user_table' )
where = "zekken_number = '#{zekken_number}' AND event_code = '#{event_code}'"
list = anytable.find2(where)
result = ""
if list == nil then
return "no zekken number"
end
list.each { |rec|
result = rec["userid"]
}
@pgconn.disconnect
if result != "" && result != nil then
return result
else
return "no zekken number"
end
end
def getZekkenNumberByUserId userId
@pgconn=UserPostgres.new
dbname = set_dbname()
@pgconn.connectPg("localhost","mobilous",0,dbname)
anytable=UserPostgresTable.new
anytable.useTable( @pgconn,'user_table' )
where = "userid = '#{userId}'"
list = anytable.find2(where)
result = ""
if list == nil then
return "no zekken number"
end
list.each { |rec|
result = rec["zekken_number"]
}
@pgconn.disconnect
if result != "" && result != nil then
return result
else
return "no zekken number"
end
end
def getCPname cp_number, event_code
@pgconn=UserPostgres.new
dbname = set_dbname()
@pgconn.connectPg("localhost","mobilous",0,dbname)
anytable=UserPostgresTable.new
anytable.useTable( @pgconn,'checkpoint_table' )
where = "cp_number = " + cp_number.to_s + " AND event_code = '#{event_code}'"
list = anytable.find2(where)
result = ""
if list == nil then
return "no cp error"
end
list.each { |rec|
result = rec["cp_name"]
}
@pgconn.disconnect
if result != "" && result != nil then
return result
else
return "no cp error"
end
end
def getMaxNumByGI zekken_number, event_code # GI => gps_information
@pgconn=UserPostgres.new
dbname = set_dbname()
@pgconn.connectPg("localhost","mobilous",0,dbname)
anytable=UserPostgresTable.new
anytable.useTable( @pgconn,'gps_information' )
where = "serial_number = (SELECT max(serial_number) FROM gps_information WHERE zekken_number = '#{zekken_number}' AND event_code = '#{event_code}' )"
list = anytable.find2(where)
result = ""
if list == nil then
return 0
end
list.each { |rec|
result = rec['serial_number']
}
@pgconn.disconnect
if result != "" && result != nil then
return result
else
return 0
end
end
def getZekkenListByUT #UT => user_table
@pgconn=UserPostgres.new
dbname = set_dbname()
@pgconn.connectPg("localhost","mobilous",0,dbname)
anytable=UserPostgresTable.new
anytable.useTable( @pgconn,'user_table' )
list = anytable.find2("zekken_number IS NOT NULL")
result = []
if list == nil then
return []
end
list.each { |rec|
result.push(rec['zekken_number'])
}
@pgconn.disconnect
if result != "" && result != nil then
return result
else
return []
end
end
def getZekkenListByTT event_code #TT => team_table
@pgconn=UserPostgres.new
dbname = set_dbname()
@pgconn.connectPg("localhost","mobilous",0,dbname)
anytable=UserPostgresTable.new
anytable.useTable( @pgconn,'team_table' )
list = anytable.find2("class_name != 'test' AND event_code = '#{event_code}'")
result = []
if list == nil then
return []
end
list.each { |rec|
result.push(rec['zekken_number'])
}
@pgconn.disconnect
if result != "" && result != nil then
return result
else
return []
end
end
def getPhotoList zekken, event_code
@pgconn=UserPostgres.new
dbname = set_dbname()
@pgconn.connectPg("localhost","mobilous",0,dbname)
anytable=UserPostgresTable.new
anytable.useTable( @pgconn,'gps_information' )
where = "zekken_number = '#{zekken}' AND event_code = '#{event_code}'"
list = anytable.find2(where)
result = []
if list == nil then
return []
end
list.each { |rec|
if rec['image_address'] != "#{set_originbase}/location_checked.png" && rec['image_address'] != "#{set_originbase}/location_checked.png" && rec['image_address'] != "#{set_originbase}/photo_none.png" && rec['image_address'] != "#{set_originbase}/asset/photo_none.png" && rec['image_address'] != "#{set_originbase}/start.png" && rec['image_address'] != "#{set_originbase}/asset/start.png" then
result.push(rec['image_address'])
end
}
@pgconn.disconnect
if result != "" && result != nil then
return result
else
return []
end
end
def getGpsInfo zekken_number, event_code
@pgconn=UserPostgres.new
dbname = set_dbname()
@pgconn.connectPg("localhost","mobilous",0,dbname)
anytable=UserPostgresTable.new
anytable.useTable( @pgconn,'gps_information' )
where = "zekken_number = '#{zekken_number}' AND event_code = '#{event_code}' ORDER BY serial_number"
list = anytable.find2(where)
result = []
if list == nil then
return []
end
count = 0
list.each { |rec|
result[count] = {"cp_number" => rec['cp_number']}
count += 1
}
@pgconn.disconnect
if result != "" && result != nil then
return result
else
return []
end
end
def getCPnameByThreshols latitude, longitude, event_code, cp_number = nil
@pgconn=UserPostgres.new
dbname = set_dbname()
@pgconn.connectPg("localhost","mobilous",0,dbname)
anytable=UserPostgresTable.new
anytable.useTable( @pgconn,'checkpoint_table' )
if cp_number.to_i == 999 then
where = "latitude BETWEEN #{latitude - latitude_threshols("special")} AND #{latitude + latitude_threshols("special")} AND longitude BETWEEN #{longitude - longitude_threshols("special")} AND #{longitude + longitude_threshols("special")} AND event_code = '#{event_code}'"
else
where = "latitude BETWEEN #{latitude - latitude_threshols()} AND #{latitude + latitude_threshols()} AND longitude BETWEEN #{longitude - longitude_threshols()} AND #{longitude + longitude_threshols()} AND event_code = '#{event_code}'"
end
if cp_number != nil
where = where + " AND cp_number = #{cp_number}"
end
p "where : #{where}"
list = anytable.find2(where)
result = {}
if list == nil then
result["result"] = "no cp error"
return result
end
list.each { |rec|
result["cp_number"] = rec["cp_number"]
result["cp_name"] = rec["cp_name"]
result["buy_point"] = rec["buy_point"]
}
@pgconn.disconnect
if result != {} && result != nil then
result["result"] = "OK"
return result
else
result["result"] = "no cp error"
return result
end
end
def getTeamDataByZekken_number zekken_number, event_code
@pgconn=UserPostgres.new
dbname = set_dbname()
@pgconn.connectPg("localhost","mobilous",0,dbname)
anytable=UserPostgresTable.new
anytable.useTable( @pgconn,'team_table' )
where = "zekken_number = '#{zekken_number}' AND event_code = '#{event_code}'"
list = anytable.find2(where)
result = {}
if list == nil then
result["result"] = "ERROR"
@pgconn.disconnect
return result
end
list.each { |rec|
result["zekken_number"] = rec["zekken_number"]
result["team_name"] = rec["team_name"]
result["class_name"] = rec["class_name"]
}
@pgconn.disconnect
if result != {} && result != nil then
result["result"] = "OK"
return result
else
result["result"] = "ERROR"
return result
end
end
def getPhotoFromRR zekken_number, event_code, num #RR => RouteResult
@pgconn=UserPostgres.new
dbname = set_dbname()
@pgconn.connectPg("localhost","mobilous",0,dbname)
if num <= 60
table = 'route_result'
else
table = 'route_result_2'
end
anytable=UserPostgresTable.new
anytable.useTable( @pgconn,table )
where = "zekken_number = '#{zekken_number}' AND event_code = '#{event_code}'"
list = anytable.find2(where)
result = {}
if list == nil then
@pgconn.disconnect
return {"result" => "ERROR"}
end
docpath = set_commonbase() + '/' + event_code + '/' + zekken_number
if( !Dir.exist?(docpath) )then
if( Dir.mkdir( docpath,0755 ) == 0 ) then
end
end
list.each { |rec|
for i in 1..num do
begin
if rec["cp#{i}_ph"].include?(s3_domain()) then
extension = result["cp#{i}_ph"].to_s.split('.').last
result["cp#{i}_ph"] = rec["cp#{i}_ph"].gsub(s3_domain(),set_commonbase()).gsub(".#{extension}","_th.#{extension}")
elsif rec["cp#{i}_ph"].include?(set_commonbase()) then
result["cp#{i}_ph"] = rec["cp#{i}_ph"].gsub(set_commonbase(),set_commonbase2())
else
result["cp#{i}_ph"] = "#{set_commonbase()}/asset/photo_none.png"
end
rescue => e
p "error : #{e}, result[cp#{i}_ph] :#{result["cp#{i}_ph"]}"
result["cp#{i}_ph"] = "#{set_commonbase()}/asset/photo_none.png"
end
if result["cp#{i}_ph"].include?("asset/asset") then
result["cp#{i}_ph"].gsub!('asset/asset', 'asset')
end
if File.exist?(result["cp#{i}_ph"]) == false then
begin
filename = rec["cp#{i}_ph"].split('/').last
fullpath = docpath + '/' + filename
fullpath2 = s3_domain + '/' + URI.encode_www_form_component(event_code, enc=nil) + '/' + zekken_number + '/' + filename
URI.open(fullpath2) do |image|
File.open(fullpath, 'w') do |file|
file.write(image.read)
end
end
extension = filename.split('.').last
filenameTh = filename.gsub(".#{extension}","_th.#{extension}")
imageOri = Magick::Image.read(fullpath).first
imageTh = imageOri.scale(image_size_width(), image_size_height())
imageTh.write("temp/#{filenameTh}")
nextpath = docpath + '/' + filenameTh
FileUtils.mv("/var/www/temp/#{filenameTh}",nextpath)
# File.delete(fullpath)
result["cp#{i}_ph"] = nextpath
rescue => e
p "error : #{e}, rec[cp#{i}_ph] :#{rec["cp#{i}_ph"]}"
result["cp#{i}_ph"] = "#{set_commonbase()}/asset/photo_none.png"
end
end
begin
result["cp#{i}_s"] = rec["cp#{i}_s"].gsub(set_commonbase2(),set_commonbase())
rescue => e
p "error : #{e}, result[cp#{i}_s] : #{result["cp#{i}_s"]}"
result["cp#{i}_s"] = "#{set_commonbase()}/asset/photo_none.png"
end
if result["cp#{i}_s"].include?("asset/asset") then
result["cp#{i}_s"].gsub!('asset/asset', 'asset')
end
if File.exist?(result["cp#{i}_s"]) == false then
result["cp#{i}_s"] = "#{set_commonbase()}/asset/photo_none.png"
end
end
}
@pgconn.disconnect
if result == [] || result == nil then
return {"result" => "ERROR"}
end
result["result"] = "OK"
return result
end
def getZekkenNumberByTeamName team_name, event_code
puts "team_name=#{team_name}, event_code=#{event_code}"
@pgconn=UserPostgres.new
dbname = set_dbname()
puts "dbname=#{dbname}"
@pgconn.connectPg("localhost","mobilous",0,dbname)
anytable=UserPostgresTable.new
anytable.useTable( @pgconn,'team_table' )
if team_name.include?("'") then
team_name.gsub!("'","''")
end
where = "team_name = '#{team_name}' AND event_code = '#{event_code}'"
puts "where = #{where}"
list = anytable.find2(where)
result = ""
puts "list = #{list}"
if list == nil then
@pgconn.disconnect
return "no zekken number"
end
list.each { |rec|
result = rec["zekken_number"]
}
@pgconn.disconnect
if result != "" && result != nil then
return result
else
return "no zekken number"
end
end
def get_lat_lng_bounds_for_event_code(event_code)
@pgconn = UserPostgres.new
dbname = set_dbname()
@pgconn.connectPg("localhost", "mobilous", 0, dbname)
anytable = UserPostgresTable.new
anytable.useTable(@pgconn, 'gps_detail')
where = "event_code = '#{event_code}' ORDER BY serial_number"
list = anytable.find2(where)
p "list: #{list}"
max_latitude = -Float::INFINITY
min_latitude = Float::INFINITY
max_longitude = -Float::INFINITY
min_longitude = Float::INFINITY
list.each do |rec|
latitude = rec['latitude'].to_f
longitude = rec['longitude'].to_f
max_latitude = latitude if latitude > max_latitude
min_latitude = latitude if latitude < min_latitude
max_longitude = longitude if longitude > max_longitude
min_longitude = longitude if longitude < min_longitude
end
@pgconn.disconnect
{
max_latitude: max_latitude,
min_latitude: min_latitude,
max_longitude: max_longitude,
min_longitude: min_longitude
}
end
def getGpsList zekken_number, event_code, sort = 'ASC'
@pgconn=UserPostgres.new
dbname = set_dbname()
@pgconn.connectPg("localhost","mobilous",0,dbname)
anytable=UserPostgresTable.new
anytable.useTable( @pgconn,'gps_detail' )
where = "zekken_number = '#{zekken_number}' AND event_code = '#{event_code}' ORDER BY serial_number #{sort}"
list = anytable.find2(where)
result_list = []
if list == nil then
return []
end
list.each { |rec|
result_list.push(rec)
}
@pgconn.disconnect
if result_list != [] && result_list != nil then
return result_list
else
return []
end
end
def getSerialNumberByCpNumber zekken_number, event_code, cp_number
@pgconn=UserPostgres.new
dbname = set_dbname()
@pgconn.connectPg("localhost","mobilous",0,dbname)
anytable=UserPostgresTable.new
anytable.useTable( @pgconn,'gps_information' )
where = "zekken_number = '#{zekken_number}' AND cp_number = #{cp_number}"
list = anytable.find2(where)
result = ""
if list == nil then
return "no sn"
end
list.each { |rec|
result = rec["serial_number"]
}
@pgconn.disconnect
if result != "" && result != nil then
return result
else
return "no sn"
end
end
def getTeamNameByZekkenNumber zekken_number, event_code
@pgconn=UserPostgres.new
dbname = set_dbname()
@pgconn.connectPg("localhost","mobilous",0,dbname)
anytable=UserPostgresTable.new
anytable.useTable( @pgconn,'team_table' )
where = "zekken_number = '#{zekken_number}' AND event_code = '#{event_code}'"
list = anytable.find2(where)
result = ""
list.each { |rec|
result = rec["team_name"]
}
@pgconn.disconnect
return result
end
def getFinalReport zekken_number, event_code
@pgconn=UserPostgres.new
dbname = set_dbname()
@pgconn.connectPg("localhost","mobilous",0,dbname)
anytable=UserPostgresTable.new
anytable.useTable( @pgconn,'report_list' )
where = "zekken_number = '#{zekken_number}' AND event_code = '#{event_code}'"
list = anytable.find2(where)
result = ""
list.each { |rec|
result = rec["report_address"]
}
@pgconn.disconnect
if result == "" || result == nil then
return "no report"
end
return result
end
def getTeamList event_code=nil
@pgconn=UserPostgres.new
dbname = set_dbname()
@pgconn.connectPg("localhost","mobilous",0,dbname)
anytable=UserPostgresTable.new
anytable.useTable( @pgconn,'team_table' )
if event_code == nil then
where = "0 = 0"
else
where = "event_code = '#{event_code}'"
end
list = anytable.find2(where)
result = []
list.each { |rec|
result.push(rec)
}
@pgconn.disconnect
if result == "" || result == nil then
return "no report"
end
return result
end
def getZekkenNumberByAgentId agent_id
@pgconn=UserPostgres.new
dbname = set_dbname()
@pgconn.connectPg("localhost","mobilous",0,dbname)
anytable=UserPostgresTable.new
anytable.useTable( @pgconn,'agent_login' )
where = "agent_id = '#{agent_id}'"
list = anytable.find2(where)
result = ""
agent_id = ""
list.each { |rec|
result = rec["zekken_number"]
agent_id = rec["agent_id"]
}
@pgconn.disconnect
if result == "" || result == nil then
if agent_id == "" || agent_id == nil then
return "no data"
else
return "no login"
end
end
return result
end
def getDataFromDatabase(zekken_number, event_code)
@pgconn = UserPostgres.new
dbname = set_dbname()
@pgconn.connectPg("localhost", "mobilous", 0, dbname)
anytable = UserPostgresTable.new
anytable.useTable(@pgconn, 'gps_detail')
where = "zekken_number = '#{zekken_number}' AND event_code = '#{event_code}' ORDER BY serial_number"
list = anytable.find2(where)
p "list: #{list}"
result = []
list.each { |rec|
result.push(rec)
}
@pgconn.disconnect
result # 返り値としてresultを返す
end
def getCPlatlngByCPnumber cp_number, event_code
@pgconn=UserPostgres.new
dbname = set_dbname()
@pgconn.connectPg("localhost","mobilous",0,dbname)
anytable=UserPostgresTable.new
anytable.useTable( @pgconn,'checkpoint_table' )
where = "cp_number = " + cp_number.to_s + " AND event_code = '#{event_code}'"
list = anytable.find2(where)
record = {}
if list == nil then
return {"status" => "no cp error"}
end
list.each { |rec|
record = rec
}
@pgconn.disconnect
result = {}
if result != "" && result != nil then
result["status"] = "OK"
result["record"] = record
return result
else
return {"status" => "no cp error"}
end
end
def getEventStartTime event_code
@pgconn=UserPostgres.new
dbname = set_dbname()
@pgconn.connectPg("localhost","mobilous",0,dbname)
anytable=UserPostgresTable.new
anytable.useTable( @pgconn,'event_table' )
where = "event_code = '#{event_code}'"
list = anytable.find2(where)
result = ""
if list == nil then
return ""
end
list.each { |rec|
result = rec["start_time"]
}
@pgconn.disconnect
if result != "" && result != nil then
return result
else
return ""
end
end
def getCPNumByPhotoPoint photo_point, event_code
@pgconn=UserPostgres.new
dbname = set_dbname()
@pgconn.connectPg("localhost","mobilous",0,dbname)
anytable=UserPostgresTable.new
anytable.useTable( @pgconn,'checkpoint_table' )
where = "photo_point = " + photo_point.to_s + " AND event_code = '#{event_code}'"
list = anytable.find2(where)
result = ""
if list == nil then
return "no cp error"
end
list.each { |rec|
result = rec["cp_number"]
}
@pgconn.disconnect
if result != "" && result != nil then
return result
else
return "no cp error"
end
end
def getPhotoPointByCPNum cp_number, event_code
@pgconn=UserPostgres.new
dbname = set_dbname()
@pgconn.connectPg("localhost","mobilous",0,dbname)
anytable=UserPostgresTable.new
anytable.useTable( @pgconn,'checkpoint_table' )
where = "cp_number = " + cp_number.to_s + " AND event_code = '#{event_code}'"
list = anytable.find2(where)
result = ""
if list == nil then
return "no cp error"
end
list.each { |rec|
result = rec["photo_point"]
}
@pgconn.disconnect
if result != "" && result != nil then
return result
else
return "no cp error"
end
end
def getCheckpointList event_code
@pgconn=UserPostgres.new
dbname = set_dbname()
@pgconn.connectPg("localhost","mobilous",0,dbname)
anytable=UserPostgresTable.new
anytable.useTable( @pgconn,'checkpoint_table' )
where = "event_code = '#{event_code}'"
list = anytable.find2(where)
result_list = []
if list == nil then
return []
end
list.each { |rec|
result_list.push(rec)
}
@pgconn.disconnect
if result_list != [] && result_list != nil then
return result_list
else
return []
end
end
def getMaxUserNumByRSR event_code # RS => rogeSimRecord
@pgconn=UserPostgres.new
dbname = set_dbname()
@pgconn.connectPg("localhost","mobilous",0,dbname)
anytable=UserPostgresTable.new
anytable.useTable( @pgconn,'rogSimRecord' )
where = "user_serial = (SELECT max(user_serial) FROM rogSimRecord WHERE event_code = '#{event_code}' )"
list = anytable.find2(where)
result = ""
if list == nil then
return 0
end
list.each { |rec|
result = rec['user_serial']
}
@pgconn.disconnect
if result != "" && result != nil then
return result
else
return 0
end
end
def getMaxNumByRSR userId, event_code # RS => rogeSimRecord
@pgconn=UserPostgres.new
dbname = set_dbname()
@pgconn.connectPg("localhost","mobilous",0,dbname)
anytable=UserPostgresTable.new
anytable.useTable( @pgconn,'rogSimRecord' )
where = "serial_number = (SELECT max(serial_number) FROM rogSimRecord WHERE event_code = '#{event_code}' AND user_serial = #{userId} )"
list = anytable.find2(where)
result = ""
if list == nil then
return 0
end
list.each { |rec|
result = rec['serial_number']
}
@pgconn.disconnect
if result != "" && result != nil then
return result
else
return 0
end
end
def getRogSimResult userId, event_code
@pgconn=UserPostgres.new
dbname = set_dbname()
@pgconn.connectPg("localhost","mobilous",0,dbname)
anytable=UserPostgresTable.new
anytable.useTable( @pgconn,'rogSimRecord' )
where = "user_serial = '#{userId}' AND event_code = '#{event_code}' ORDER BY serial_number"
list = anytable.find2(where)
result = []
if list == nil then
return []
end
count = 0
list.each { |rec|
result[count] = {"cp_number" => rec['cp_number']}
count += 1
}
@pgconn.disconnect
if result != "" && result != nil then
return result
else
return []
end
end
def getPhotoFromRSV userId, event_code, num #RSV => rogeSimView
@pgconn=UserPostgres.new
dbname = set_dbname()
@pgconn.connectPg("localhost","mobilous",0,dbname)
table = 'rogeSimView'
anytable=UserPostgresTable.new
anytable.useTable( @pgconn,table )
where = "user_serial = '#{userId}' AND event_code = '#{event_code}'"
list = anytable.find2(where)
result = {}
if list == nil then
return {"result" => "ERROR"}
end
list.each { |rec|
for i in 1..num do
begin
result["cp#{i}_s"] = rec["cp#{i}_s"].gsub(set_commonbase2(),set_commonbase())
rescue => e
p "error : #{e}, result[cp#{i}_s] : #{result["cp#{i}_s"]}"
result["cp#{i}_s"] = "#{set_commonbase()}/asset/photo_none.png"
end
if result["cp#{i}_s"].include?("asset/asset") then
result["cp#{i}_s"].gsub!('asset/asset', 'asset')
end
if File.exist?(result["cp#{i}_s"]) == false then
result["cp#{i}_s"] = "#{set_commonbase()}/asset/photo_none.png"
end
end
}
@pgconn.disconnect
if result == [] || result == nil then
return {"result" => "ERROR"}
end
result["result"] = "OK"
return result
end
def getEventData event_code
@pgconn=UserPostgres.new
dbname = set_dbname()
@pgconn.connectPg("localhost","mobilous",0,dbname)
anytable=UserPostgresTable.new
anytable.useTable( @pgconn,'event_table' )
where = "event_code = '#{event_code}'"
list = anytable.find2(where)
result = {}
if list == nil then
return ""
end
list.each { |rec|
result = rec
}
@pgconn.disconnect
if result != "" && result != nil then
return result
else
return ""
end
end
def getMaxNumByCLS # CLS => cp_listsheet
@pgconn=UserPostgres.new
dbname = set_dbname()
@pgconn.connectPg("localhost","mobilous",0,dbname)
anytable=UserPostgresTable.new
anytable.useTable( @pgconn,'cp_listsheet' )
where = "serial_number = (SELECT max(serial_number) FROM cp_listsheet)"
list = anytable.find2(where)
result = ""
if list == nil then
return 0
end
list.each { |rec|
result = rec['serial_number']
}
@pgconn.disconnect
if result != "" && result != nil then
return result
else
return 0
end
end
def getNewUserName userId
response = client.get_profile(userId)
case response
when Net::HTTPSuccess then
contact = JSON.parse(response.body)
username = contact['displayName']
@pgconn=UserPostgres.new
dbname = set_dbname()
@pgconn.connectPg("localhost","mobilous",0,dbname)
anytable=UserPostgresTable.new
anytable.useTable( @pgconn,'user_table' )
title = ["userid","user_name","create_at","update_at"]
record = {"userid" => userId, "user_name" => username, "create_at" => DateTime.now, "update_at" => DateTime.now}
sql = anytable.makeInsertKeySet(title,record)
begin
ret = anytable.exec(sql) # true or false
rescue => error
p error
end
@pgconn.disconnect
return {"user_name" => username, "zekken_number" => "no zekken number", "event_code" => ""}
else
p "#{
response.code
} #{
response.body
}"
return {"user_name" => "get name error"}
end
end
def haversine_distance(lat1, lon1, lat2, lon2)
r = 6371 # 地球の半径km
phi1 = lat1 * Math::PI / 180
phi2 = lat2 * Math::PI / 180
delta_phi = (lat2 - lat1) * Math::PI / 180
delta_lambda = (lon2 - lon1) * Math::PI / 180
a = Math.sin(delta_phi / 2) ** 2 + Math.cos(phi1) * Math.cos(phi2) * Math.sin(delta_lambda / 2) ** 2
c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a))
r * c
end
def calculate_speed_and_type(prev_point, current_point, next_point)
if prev_point && next_point
time_diff = (Time.parse(next_point['create_at']) - Time.parse(prev_point['create_at'])) / 3600.0 # 時間
distance = haversine_distance(prev_point['latitude'].to_f, prev_point['longitude'].to_f,
next_point['latitude'].to_f, next_point['longitude'].to_f)
speed = distance / time_diff
else
speed = 0
end
movement_type = speed < 18 ? "walking/jogging" : "public_transport"
[speed, movement_type]
end
def calculate_cumulative_distance(gps_data, index)
distance = 0
(1..index).each do |i|
distance += haversine_distance(gps_data[i-1]['latitude'].to_f, gps_data[i-1]['longitude'].to_f,
gps_data[i]['latitude'].to_f, gps_data[i]['longitude'].to_f)
end
distance
end
#====================================
# DB:SELECT (check)
#====================================
def checkBuypointSingleRecord zekken_number, event_code, cp_number
@pgconn=UserPostgres.new
dbname = set_dbname()
@pgconn.connectPg("localhost","mobilous",0,dbname)
anytable=UserPostgresTable.new
anytable.useTable( @pgconn,'gps_information' )
#buy_pointであり、レコード数が1以下なら重複なしとして扱う
where_relation = " JOIN checkpoint_table AS c ON g.event_code = c.event_code AND g.cp_number = c.cp_number WHERE g.zekken_number = '#{zekken_number}' AND g.event_code = '#{event_code}' AND g.cp_number = '#{cp_number}' AND c.buy_point > 0"
count = nil
list_relation = anytable.find_for_relation(where_relation)
list_relation.each do |row|
count = row["count"] if row.is_a?(Hash) # rowがハッシュであれば
end
if count.to_i == 1 then
return true
else
return false
end
end
def cpDoubleCheck(zekken_number, event_code, cp_number) # 重複してたらtrue
@pgconn = UserPostgres.new
dbname = set_dbname()
@pgconn.connectPg("localhost", "mobilous", 0, dbname)
anytable = UserPostgresTable.new
anytable.useTable(@pgconn, 'gps_information')
# 今日の日付のレコードのみをチェック
today = Date.today.to_s
# buy_pointであり、今日のレコード数が1以下なら重複なしとして扱う
where_relation = " JOIN checkpoint_table AS c ON g.event_code = c.event_code AND g.cp_number = c.cp_number WHERE g.zekken_number = '#{zekken_number}' AND g.event_code = '#{event_code}' AND g.cp_number = '#{cp_number}' AND c.buy_point > 0 AND DATE(g.create_at) = '#{today}'"
count = nil
list_relation = anytable.find_for_relation(where_relation)
list_relation.each do |row|
count = row["count"] if row.is_a?(Hash) # rowがハッシュであれば
end
if count.to_i == 1 then
@pgconn.disconnect
return false
end
# 今日の日付のレコードをチェック
where = "zekken_number = '#{zekken_number}' AND event_code = '#{event_code}' AND cp_number = '#{cp_number}' AND DATE(create_at) = '#{today}'"
list = anytable.find2(where)
result = ""
if list == nil then
@pgconn.disconnect
return false
end
list.each { |rec|
result = rec["serial_number"]
}
@pgconn.disconnect
if result != "" && result != nil then
return true
else
return false
end
end
# def cpDoubleCheck zekken_number, event_code, cp_number # 重複してたらtrue
# @pgconn=UserPostgres.new
# dbname = set_dbname()
# @pgconn.connectPg("localhost","mobilous",0,dbname)
# anytable=UserPostgresTable.new
# anytable.useTable( @pgconn,'gps_information' )
# #buy_pointであり、レコード数が1以下なら重複なしとして扱う
# where_relation = " JOIN checkpoint_table AS c ON g.event_code = c.event_code AND g.cp_number = c.cp_number WHERE g.zekken_number = '#{zekken_number}' AND g.event_code = '#{event_code}' AND g.cp_number = '#{cp_number}' AND c.buy_point > 0"
# count = nil
# list_relation = anytable.find_for_relation(where_relation)
# list_relation.each do |row|
# count = row["count"] if row.is_a?(Hash) # rowがハッシュであれば
# end
# if count.to_i == 1 then
# return false
# end
# where = "zekken_number = '#{zekken_number}' AND event_code = '#{event_code}' AND cp_number = '#{cp_number}'"
# list = anytable.find2(where)
# #return list
# #p list
# #return true
# result = ""
# if list == nil then
# return false
# end
# list.each { |rec|
# result = rec["serial_number"]
# }
# @pgconn.disconnect
# if result != "" && result != nil then
# return true
# else
# return false
# end
# end
def zekkenAuthorization zekken,password
@pgconn=UserPostgres.new
dbname = set_dbname()
@pgconn.connectPg("localhost","mobilous",0,dbname)
anytable=UserPostgresTable.new
anytable.useTable( @pgconn,'team_table' )
where = "zekken_number = '#{zekken}' AND password = '#{password}'"
list = anytable.find2(where)
result = {}
if list == nil then
return { "zekken_number" => "ERROR" }
end
list.each { |rec|
result["zekken_number"] = rec["zekken_number"]
result["team_name"] = rec["team_name"]
result["event_code"] = rec["event_code"]
}
@pgconn.disconnect
if result != {} && result != nil then
result["result"] = "OK"
return result
else
result["result"] = "ERROR"
return result
end
end
def agentAuthorization password
@pgconn=UserPostgres.new
dbname = set_dbname()
@pgconn.connectPg("localhost","mobilous",0,dbname)
anytable=UserPostgresTable.new
anytable.useTable( @pgconn,'agent_table' )
where = "password = '#{password}'"
p "where : #{where}"
list = anytable.find2(where)
result = ""
if list == nil then
return "ERROR"
end
list.each { |rec|
result = rec["agent_id"]
}
@pgconn.disconnect
if result != "" && result != nil then
return result
else
return "ERROR"
end
end
def checkStatus userId
@pgconn=UserPostgres.new
dbname = set_dbname()
@pgconn.connectPg("localhost","mobilous",0,dbname)
anytable=UserPostgresTable.new
anytable.useTable( @pgconn,'chat_status' )
where = "userid = '#{userId}'"
list = anytable.find2(where)
result = {}
if list == nil then
result['status'] = "nothing"
return result
end
list.each { |rec|
result['status'] = rec["status"]
result['memory'] = rec["memory"]
}
@pgconn.disconnect
if result != {} && result != nil then
return result
else
result['status'] = "nothing"
return result
end
end
def checkAgentFlag zekken_number,event_code
@pgconn=UserPostgres.new
dbname = set_dbname()
@pgconn.connectPg("localhost","mobilous",0,dbname)
anytable=UserPostgresTable.new
anytable.useTable( @pgconn,'agent_flag' )
where = "zekken_number = '#{zekken_number}' AND event_code = '#{event_code}'"
list = anytable.find2(where)
result = {}
if list == nil then
return false
end
list.each { |rec|
result = rec["agent_id"]
}
@pgconn.disconnect
if result != "" && result != nil then
return true
else
return false
end
end
def checkBonusPointFlag(zekken_number, event_code)
@pgconn=UserPostgres.new
dbname = set_dbname()
@pgconn.connectPg("localhost", "mobilous", 0, dbname)
anytable=UserPostgresTable.new
anytable.useTable(@pgconn, 'bonus_point_flag')
where = "zekken_number = '#{zekken_number}' AND event_code = '#{event_code}'"
list = anytable.find2(where)
@pgconn.disconnect # データベース接続を切断
# ntuplesメソッドを使用して結果セットに含まれる行の数をチェック
if list.ntuples.zero?
return false # レコードが存在しない場合はfalseを返す
else
return true # レコードが1つでも見つかった場合はtrueを返す
end
end
def checkEventCode event_code
@pgconn=UserPostgres.new
dbname = set_dbname()
@pgconn.connectPg("localhost","mobilous",0,dbname)
anytable=UserPostgresTable.new
anytable.useTable( @pgconn,'event_table' )
where = "event_code = '#{event_code}'"
list = anytable.find2(where)
result = ""
if list == nil then
return ""
end
list.each { |rec|
result = rec["event_name"]
}
@pgconn.disconnect
if result != "" && result != nil then
return result
else
return ""
end
end
def checkZekkenExist zekken_number
@pgconn=UserPostgres.new
dbname = set_dbname()
@pgconn.connectPg("localhost","mobilous",0,dbname)
anytable=UserPostgresTable.new
anytable.useTable( @pgconn,'team_table' )
where = "zekken_number = '#{zekken_number}'"
list = anytable.find2(where)
result = ""
if list == nil then
return false
end
list.each { |rec|
result = rec["team_name"]
}
@pgconn.disconnect
if result != "" && result != nil then
return true
else
return false
end
end
def process_route_data(gps_data, bounds)
width = 800
height = 600
# ルートポイントを正規化
normalized_points = gps_data.map do |point|
x = (point['longitude'].to_f - bounds[:min_longitude]) * width / (bounds[:max_longitude] - bounds[:min_longitude])
y = height - (point['latitude'].to_f - bounds[:min_latitude]) * height / (bounds[:max_latitude] - bounds[:min_latitude])
{
x: x,
y: y,
longitude: point['longitude'].to_f,
latitude: point['latitude'].to_f,
timestamp: point['timestamp']
}
end
{
points: normalized_points,
start: normalized_points.first,
end: normalized_points.last,
bounds: bounds
}
end
# ユーザーのルート情報を取得するメソッド
def get_user_route(pgconn, event_code, zekken_number)
anytable = UserPostgresTable.new
anytable.useTable(pgconn, 'gps_detail')
where = "zekken_number = '#{zekken_number}' AND event_code = '#{event_code}' ORDER BY create_at ASC"
route_data = anytable.find2(where)
route_data.map do |point|
{
latitude: point['latitude'].to_f,
longitude: point['longitude'].to_f,
timestamp: point['create_at']
}
end
end
#====================================
# DB:INSERT
#====================================
# def inputCPnumber zekken_number, event_code, cp_number, image_address, insert_number = 0
# if insert_number == 0 then
# next_num = getMaxNumByGI(zekken_number,event_code).to_i + 1
# else
# next_num = insert_number
# end
# @pgconn=UserPostgres.new
# dbname = set_dbname()
# @pgconn.connectPg("localhost","mobilous",0,dbname)
# anytable=UserPostgresTable.new
# anytable.useTable( @pgconn,'gps_information' )
# #buy_pointであり、すでに同じcpのレコードが存在しているなら
# where_relation = " JOIN checkpoint_table AS c ON g.event_code = c.event_code AND g.cp_number = c.cp_number WHERE g.zekken_number = '#{zekken_number}' AND g.event_code = '#{event_code}' AND g.cp_number = '#{cp_number}' AND c.buy_point > 0"
# count = nil
# list_relation = anytable.find_for_relation(where_relation)
# list_relation.each do |row|
# count = row["count"] if row.is_a?(Hash) # rowがハッシュであれば
# end
# if count.to_i == 1 then
# title = ["serial_number", "zekken_number","event_code","cp_number","image_address","create_at","update_at","minus_photo_flag"]
# record = {"serial_number" => next_num, "zekken_number" => zekken_number, "event_code" => event_code, "cp_number" => cp_number, "image_address" => image_address,"create_at" => DateTime.now, "update_at" => DateTime.now, "minus_photo_flag" => 'true', "photo_point" => 0}
# sql = anytable.makeInsertKeySet(title,record)
# begin
# #ret = anytable.exec(sql) # true or false
# anytable.insertExec(sql) # true or false
# rescue => error
# p error
# end
# @pgconn.disconnect
# return "200 OK"
# end
# title = ["serial_number", "zekken_number","event_code","cp_number","image_address","create_at","update_at"]
# record = {"serial_number" => next_num, "zekken_number" => zekken_number, "event_code" => event_code, "cp_number" => cp_number, "image_address" => image_address,"create_at" => DateTime.now, "update_at" => DateTime.now}
# sql = anytable.makeInsertKeySet(title,record)
# begin
# #ret = anytable.exec(sql) # true or false
# anytable.insertExec(sql) # true or false
# rescue => error
# p error
# end
# @pgconn.disconnect
# return "200 OK"
# end
def inputCPnumber(zekken_number, event_code, cp_number, image_address, insert_number = 0)
puts "inputCPnumber"
if insert_number == 0
next_num = getMaxNumByGI(zekken_number, event_code).to_i + 1
else
next_num = insert_number
end
@pgconn = UserPostgres.new
dbname = set_dbname()
@pgconn.connectPg("localhost", "mobilous", 0, dbname)
anytable = UserPostgresTable.new
anytable.useTable(@pgconn, 'gps_information')
# colabo_company_memoの初期化
colabo_company_memo = ''
# 日付チェックと値の設定
current_date = Date.today
if current_date >= Date.new(2024, 7, 8) && current_date <= Date.new(2024, 10, 31)
colabo_company_memo = "FC岐阜"
end
# 同じ日付でのチェックポイント数を確認
today = Date.today.to_s
where_relation = "zekken_number = '#{zekken_number}' AND event_code = '#{event_code}' AND DATE(create_at) = '#{today}'"
# buy_pointが0より大きいチェックポイントの数を確認
buy_point_count = anytable.count("#{where_relation} AND cp_number IN (SELECT cp_number FROM checkpoint_table WHERE event_code = '#{event_code}' AND buy_point > 0)")
# photo_pointのみのチェックポイントの数を確認
photo_point_count = anytable.count("#{where_relation} AND cp_number IN (SELECT cp_number FROM checkpoint_table WHERE event_code = '#{event_code}' AND buy_point = 0)")
# 現在のcp_numberのbuy_pointを確認
cp_buy_point_query = "JOIN checkpoint_table c ON g.event_code = c.event_code AND g.cp_number = c.cp_number WHERE g.event_code = '#{event_code}' AND g.cp_number = '#{cp_number}'"
cp_buy_point_result = anytable.find_for_relation(cp_buy_point_query, nil, "c.buy_point")
current_cp_buy_point = 0
if cp_buy_point_result && cp_buy_point_result.any?
current_cp_buy_point = cp_buy_point_result.first['buy_point'].to_i
end
if (current_cp_buy_point > 0 && buy_point_count.to_i >= 2) || (current_cp_buy_point == 0 && photo_point_count.to_i >= 1)
@pgconn.disconnect
return "409 Conflict" # 既に制限に達している場合
end
# 同じ日付で同じチェックポイントのレコードが存在するか確認
same_cp_count = anytable.count("#{where_relation} AND cp_number = '#{cp_number}'")
if same_cp_count.to_i > 0
@pgconn.disconnect
return "409 Conflict" # 既に同じ日付で同じチェックポイントのレコードが存在する場合
end
title = ["serial_number", "zekken_number", "event_code", "cp_number", "image_address", "create_at", "update_at", "colabo_company_memo"]
record = {
"serial_number" => next_num,
"zekken_number" => zekken_number,
"event_code" => event_code,
"cp_number" => cp_number,
"image_address" => image_address,
"create_at" => DateTime.now,
"update_at" => DateTime.now,
"colabo_company_memo" => colabo_company_memo
}
sql = anytable.makeInsertKeySet(title, record)
begin
anytable.insertExec(sql) # true or false
rescue => error
p error
@pgconn.disconnect
return "500 Internal Server Error"
end
@pgconn.disconnect
return "200 OK"
end
def test_inputCPnumber zekken_number, event_code, cp_number, image_address, insert_number = 0
if insert_number == 0 then
next_num = getMaxNumByGI(zekken_number,event_code).to_i + 1
else
next_num = insert_number
end
@pgconn=UserPostgres.new
dbname = set_dbname()
@pgconn.connectPg("localhost","mobilous",0,dbname)
anytable=UserPostgresTable.new
anytable.useTable( @pgconn,'gps_information' )
#buy_pointであり、すでに同じcpのレコードが存在しているなら
where_relation = " JOIN checkpoint_table AS c ON g.event_code = c.event_code AND g.cp_number = c.cp_number WHERE g.zekken_number = '#{zekken_number}' AND g.event_code = '#{event_code}' AND g.cp_number = '#{cp_number}' AND c.buy_point > 0"
count = nil
list_relation = anytable.find_for_relation(where_relation)
list_relation.each do |row|
count = row["count"] if row.is_a?(Hash) # rowがハッシュであれば
end
if count.to_i == 1 then
title = ["serial_number", "zekken_number","event_code","cp_number","image_address","create_at","update_at","minus_photo_flag"]
record = {"serial_number" => next_num, "zekken_number" => zekken_number, "event_code" => event_code, "cp_number" => cp_number, "image_address" => image_address,"create_at" => DateTime.now, "update_at" => DateTime.now, "minus_photo_flag" => 'true'}
sql = anytable.makeInsertKeySet(title,record)
return sql
begin
#ret = anytable.exec(sql) # true or false
anytable.insertExec(sql) # true or false
rescue => error
p error
end
@pgconn.disconnect
return "200 OK"
end
title = ["serial_number", "zekken_number","event_code","cp_number","image_address","create_at","update_at"]
record = {"serial_number" => next_num, "zekken_number" => zekken_number, "event_code" => event_code, "cp_number" => cp_number, "image_address" => image_address,"create_at" => DateTime.now, "update_at" => DateTime.now}
sql = anytable.makeInsertKeySet(title,record)
begin
#ret = anytable.exec(sql) # true or false
anytable.insertExec(sql) # true or false
rescue => error
p error
end
@pgconn.disconnect
return "200 OK"
end
def inputStatus userId, status, memory
@pgconn=UserPostgres.new
dbname = set_dbname()
@pgconn.connectPg("localhost","mobilous",0,dbname)
anytable=UserPostgresTable.new
anytable.useTable( @pgconn,'chat_status' )
title = ["userid", "status", "memory", "create_at", "update_at"]
record = {"userid" => userId, "status" => status, "memory" => memory, "create_at" => DateTime.now, "update_at" => DateTime.now }
sql = anytable.makeInsertKeySet(title,record)
begin
ret = anytable.exec(sql) # true or false
rescue => error
p error
end
@pgconn.disconnect
return "OK"
end
def inputGPSlog zekken_number, event_code, lat, lon
@pgconn=UserPostgres.new
dbname = set_dbname()
@pgconn.connectPg("localhost","mobilous",0,dbname)
anytable=UserPostgresTable.new
anytable.useTable( @pgconn,'gpslogger_data' )
title = ["zekken_number","event_code","latitude","longitude","point_category","create_at","update_at"]
record = {"zekken_number" => zekken_number, "event_code" => event_code, "latitude" => lat, "longitude" => lon, "point_category" => "route", "create_at" => DateTime.now, "update_at" => DateTime.now}
sql = anytable.makeInsertKeySet(title,record)
begin
ret = anytable.exec(sql) # true or false
rescue => error
p error
end
@pgconn.disconnect
return "200 OK"
end
def inputGoalTime zekken_number, event_code, goal_time, late_point,goal_photo
sn = getMaxNumByGI(zekken_number, event_code).to_i + 1
@pgconn=UserPostgres.new
dbname = set_dbname()
@pgconn.connectPg("localhost","mobilous",0,dbname)
anytable=UserPostgresTable.new
anytable.useTable( @pgconn,'gps_information' )
title = ["serial_number","zekken_number","event_code","cp_number","image_address","goal_time","late_point","create_at","update_at"]
record = {"serial_number" => sn, "zekken_number" => zekken_number, "event_code" => event_code, "cp_number" => -1,"image_address" => goal_photo, "goal_time" => goal_time, "late_point" => late_point, "create_at" => DateTime.now, "update_at" => DateTime.now}
sql = anytable.makeInsertKeySet(title,record)
begin
ret = anytable.exec(sql) # true or false
rescue => error
p error
end
@pgconn.disconnect
return "200 OK"
end
def inputAgentLogin agent_id, zekken_number, event_code
@pgconn=UserPostgres.new
dbname = set_dbname()
@pgconn.connectPg("localhost","mobilous",0,dbname)
anytable=UserPostgresTable.new
anytable.useTable( @pgconn,'agent_login' )
title = ["agent_id", "zekken_number","event_code","create_at","update_at"]
record = {"agent_id" => agent_id, "zekken_number" => zekken_number, "event_code" => event_code, "create_at" => DateTime.now, "update_at" => DateTime.now}
sql = anytable.makeInsertKeySet(title,record)
begin
ret = anytable.exec(sql) # true or false
rescue => error
p error
end
@pgconn.disconnect
end
def inputFinalReport zekken_number, event_code, pdf_address
@pgconn=UserPostgres.new
dbname = set_dbname()
@pgconn.connectPg("localhost","mobilous",0,dbname)
anytable=UserPostgresTable.new
anytable.useTable( @pgconn,'report_list' )
title = ["zekken_number", "event_code", "report_address"]
record = {"zekken_number" => zekken_number, "event_code" => event_code, "report_address" => pdf_address}
sql = anytable.makeInsertKeySet(title,record)
begin
ret = anytable.exec(sql) # true or false
rescue => error
p error
end
@pgconn.disconnect
return "200 OK"
end
def inputAgentFlag zekken_number, event_code, agent_id
@pgconn=UserPostgres.new
dbname = set_dbname()
@pgconn.connectPg("localhost","mobilous",0,dbname)
anytable=UserPostgresTable.new
anytable.useTable( @pgconn,'agent_flag' )
title = ["zekken_number", "agent_id", "event_code", "create_at", "update_at"]
record = {"zekken_number" => zekken_number, "agent_id" => agent_id, "event_code" => event_code, "create_at" => DateTime.now, "update_at" => DateTime.now }
sql = anytable.makeInsertKeySet(title,record)
begin
ret = anytable.exec(sql) # true or false
rescue => error
p error
end
@pgconn.disconnect
end
def inputTeamData event_code,class_name,zekken_number,team_name,pass
@pgconn=UserPostgres.new
dbname = set_dbname()
@pgconn.connectPg("localhost","mobilous",0,dbname)
anytable=UserPostgresTable.new
anytable.useTable( @pgconn,'team_table' )
title = ["zekken_number", "event_code", "team_name", "class_name", "password"]
record = {"zekken_number" => zekken_number, "event_code" => event_code, "team_name" => team_name, "class_name" => class_name, "password" => pass }
sql = anytable.makeInsertKeySet(title,record)
begin
ret = anytable.exec(sql) # true or false
rescue => error
p error
end
@pgconn.disconnect
end
def inputRogSimRecord userId, event_code, cp_number, insert_number = 0
if insert_number == 0 then
next_num = getMaxNumByRSR(userId,event_code).to_i + 1
else
next_num = insert_number
end
@pgconn=UserPostgres.new
dbname = set_dbname()
@pgconn.connectPg("localhost","mobilous",0,dbname)
anytable=UserPostgresTable.new
anytable.useTable( @pgconn,'rogSimRecord' )
title = ["serial_number", "user_serial","event_code","cp_number","create_at"]
record = {"serial_number" => next_num, "user_serial" => userId, "event_code" => event_code, "cp_number" => cp_number, "create_at" => DateTime.now}
sql = anytable.makeInsertKeySet(title,record)
begin
ret = anytable.exec(sql) # true or false
rescue => error
p error
end
@pgconn.disconnect
return "200 OK"
end
def inputCpListSheet header, record
@pgconn=UserPostgres.new
dbname = set_dbname()
@pgconn.connectPg("localhost","mobilous",0,dbname)
anytable=UserPostgresTable.new
anytable.useTable( @pgconn,'cp_listsheet' )
sql = anytable.makeInsertKeySet(header,record)
begin
ret = anytable.insertExec(sql) # true or false
rescue => error
p error
end
@pgconn.disconnect
return "200 OK"
end
def inputPrintQueueMemory queue
@pgconn=UserPostgres.new
dbname = set_dbname()
@pgconn.connectPg("localhost","mobilous",0,dbname)
anytable=UserPostgresTable.new
anytable.useTable( @pgconn,'print_queue_memory' )
title = ["queue_detail", "add_datetime"]
record = {"queue_detail" => queue, "add_datetime" => DateTime.now}
sql = anytable.makeInsertKeySet(title,record)
begin
ret = anytable.insertExec(sql) # true or false
rescue => error
p error
end
@pgconn.disconnect
return "200 OK"
end
#====================================
# DB:UPDATE (add)
#====================================
def addPhotoToGPS serial_number, photoURI
@pgconn=UserPostgres.new
dbname = set_dbname()
@pgconn.connectPg("localhost","mobilous",0,dbname)
rec = {"image_address" => photoURI, "update_at" => DateTime.now}
where = "serial_number = " + serial_number
begin
@pgconn.update("gps_information",rec,where)
rescue => e
p e
message = {
type: 'text',
text: "写真データの保存に失敗しました。大変申し訳ありませんが、もう一度やり直して下さい。"
}
client.reply_message(event['replyToken'], message)
@pgconn.disconnect
return "UPDATE ERROR"
end
@pgconn.disconnect
end
def addUserData userId, zekken_number, event_code
@pgconn=UserPostgres.new
dbname = set_dbname()
@pgconn.connectPg("localhost","mobilous",0,dbname)
rec = {"zekken_number" => zekken_number, "event_code" => event_code,"update_at" => DateTime.now}
where = "userid = '#{userId}'"
begin
@pgconn.update("user_table",rec,where)
rescue => e
p e
@pgconn.disconnect
return "UPDATE ERROR"
end
@pgconn.disconnect
return "200 OK"
end
def addBuyFlagTrue serial_number, zekken_number, event_code
@pgconn=UserPostgres.new
dbname = set_dbname()
@pgconn.connectPg("localhost","mobilous",0,dbname)
rec = {"buy_flag" => true, "update_at" => DateTime.now}
where = "event_code = '#{event_code}' AND zekken_number = '#{zekken_number}' AND serial_number = #{serial_number}"
begin
@pgconn.update("gps_information",rec,where)
rescue => e
p e
@pgconn.disconnect
return "UPDATE ERROR"
end
@pgconn.disconnect
return "OK"
end
def addBuyFlagFalse serial_number, zekken_number, event_code
@pgconn=UserPostgres.new
dbname = set_dbname()
@pgconn.connectPg("localhost","mobilous",0,dbname)
rec = {"buy_flag" => false, "update_at" => DateTime.now}
where = "event_code = '#{event_code}' AND zekken_number = '#{zekken_number}' AND serial_number = #{serial_number}"
begin
@pgconn.update("gps_information",rec,where)
rescue => e
p e
@pgconn.disconnect
return "UPDATE ERROR"
end
@pgconn.disconnect
return "OK"
end
#====================================
# DB:UPDATE (change)
#====================================
def changeSerialNumberInGPSInformation zekken_number, event_code, serial_number, new_serial_number
@pgconn=UserPostgres.new
dbname = set_dbname()
@pgconn.connectPg("localhost","mobilous",0,dbname)
rec = {"serial_number" => new_serial_number, "update_at" => DateTime.now}
where = "serial_number = #{serial_number} AND zekken_number = '#{zekken_number}' AND event_code = '#{event_code}'"
begin
@pgconn.update("gps_information",rec,where)
rescue => e
p e
@pgconn.disconnect
return "UPDATE ERROR"
end
@pgconn.disconnect
return "OK"
end
def changeGoalTimeAndLatePoint zekken_number, event_code, goal_time, late_point
@pgconn=UserPostgres.new
dbname = set_dbname()
@pgconn.connectPg("localhost","mobilous",0,dbname)
rec = {"goal_time" => goal_time, "late_point" => late_point, "update_at" => DateTime.now}
where = "zekken_number = '#{zekken_number}' AND cp_number = -1 AND event_code = '#{event_code}'"
begin
@pgconn.update("gps_information",rec,where)
rescue => e
p e
@pgconn.disconnect
return "UPDATE ERROR"
end
@pgconn.disconnect
return "OK"
end
def changeAgentLogin agent_id, zekken_number, event_code
@pgconn=UserPostgres.new
dbname = set_dbname()
@pgconn.connectPg("localhost","mobilous",0,dbname)
rec = {"zekken_number" => zekken_number, "event_code" => event_code, "update_at" => DateTime.now}
where = "agent_id = '#{agent_id}'"
begin
@pgconn.update("agent_login",rec,where)
rescue => e
p e
@pgconn.disconnect
return "UPDATE ERROR"
end
@pgconn.disconnect
return "OK"
end
def changeFinalReport zekken_number, event_code, pdf_address
@pgconn=UserPostgres.new
dbname = set_dbname()
@pgconn.connectPg("localhost","mobilous",0,dbname)
rec = {"report_address" => pdf_address}
where = "zekken_number = '#{zekken_number}' AND event_code = '#{event_code}'"
begin
@pgconn.update("report_list",rec,where)
rescue => e
p e
@pgconn.disconnect
return "UPDATE ERROR"
end
@pgconn.disconnect
return "OK"
end
def changeTeamClass zekken_number, event_code, new_class
@pgconn=UserPostgres.new
dbname = set_dbname()
@pgconn.connectPg("localhost","mobilous",0,dbname)
rec = {"class_name" => new_class}
where = "zekken_number = '#{zekken_number}' AND event_code = '#{event_code}'"
begin
@pgconn.update("team_table",rec,where)
rescue => e
p e
@pgconn.disconnect
return "ERROR"
end
@pgconn.disconnect
return "OK"
end
#====================================
# DB:DELETE
#====================================
def removeGI zekken_number, event_code, serial_number #GI => gps_information
@pgconn=UserPostgres.new
dbname = set_dbname()
@pgconn.connectPg("localhost","mobilous",0,dbname)
anytable=UserPostgresTable.new
anytable.useTable( @pgconn,'gps_information' )
where = "serial_number = #{serial_number} AND zekken_number = '#{zekken_number}' AND event_code = '#{event_code}'"
begin
p anytable.remove(where)
@pgconn.disconnect
return "200 OK"
rescue => e
p e
return "delete error"
end
end
def removeAllGI zekken_number, event_code #GI => gps_information
@pgconn=UserPostgres.new
dbname = set_dbname()
@pgconn.connectPg("localhost","mobilous",0,dbname)
anytable=UserPostgresTable.new
anytable.useTable( @pgconn,'gps_information' )
where = "zekken_number = '#{zekken_number}' AND event_code = '#{event_code}'"
begin
p anytable.remove(where)
anytable.remove(where)
@pgconn.disconnect
return "200 OK"
rescue => e
return "delete error"
end
end
def removeStatus userId #GI => gps_information
@pgconn=UserPostgres.new
dbname = set_dbname()
@pgconn.connectPg("localhost","mobilous",0,dbname)
anytable=UserPostgresTable.new
anytable.useTable( @pgconn,'chat_status' )
where = "userid = '#{userId}'"
begin
p anytable.remove(where)
@pgconn.disconnect
return "200 OK"
rescue => e
return "delete error"
end
end
#====================================
# RogSim
#====================================
def rogainingSimulator event_code, course_time, pause_time_free, pause_time_paid, spare_time, target_velocity, free_node_to_visit, paid_node_to_visit
p "target_velocity : #{target_velocity}"
input_hash = {
'course_time' => course_time,
'pause_time_free' => pause_time_free,
'pause_time_paid' => pause_time_paid,
'spare_time' => spare_time,
'target_velocity' => target_velocity,
'free_node_to_visit' => free_node_to_visit,
'paid_node_to_visit' => paid_node_to_visit
}
p "input_hash : #{input_hash}"
input_json = JSON.generate(input_hash)
file_origin = set_rogSimBase() + "/work"
file_name = DateTime.now.to_s.gsub(':','-').gsub('+','_') + '.json'
file_path = file_origin + "/input/" + file_name
File.open(file_path, "w") do |f|
f.write(input_json)
end
system("bash #{set_rogSimBase()}/rogeSim.sh #{event_code} #{file_name}")
begin
response = {"status" => "OK", "detail" => JSON.parse(File.read(file_origin + "/output/" + file_name))}
rescue Errno::ENOENT => e
response = {"status" => "ERROR", "detail" => "File not found."}
rescue => e
response = {"status" => "ERROR", "detail" => e}
end
return response
end
#====================================
# Register
#====================================
def cpNumberRegister userId, zekken_number, event_code, cp_number, slice_number, client, event
if slice_number != 0 then
cp_number.slice!(0,slice_number)
end
if (cp_number.to_s.start_with?('#')) then
cp_number.delete_prefix!('#')
end
cp_number = cp_number.to_i
if cp_number <= 0 then
message = {
type: 'text',
text: text_errorCPnumber()
}
client.reply_message(event['replyToken'], message)
chatLogger(userId, 'bot', 'text', text_errorCPnumber())
return "200 OK"
end
cp_number = cp_number.to_i
if cp_number <= 0 then
message = {
type: 'text',
text: text_errorNoCP(cp_number)
}
client.reply_message(event['replyToken'], message)
chatLogger(userId, 'bot', 'text', text_errorNoCP(cp_number))
return "200 OK"
end
cp_name = getCPname(cp_number, event_code)
if cp_name == "no cp error" then
message = {
type: 'text',
text: text_errorNoCP(cp_number)
}
client.reply_message(event['replyToken'], message)
chatLogger(userId, 'bot', 'text', text_errorNoCP(cp_number))
return "200 OK"
end
if cpDoubleCheck(zekken_number, event_code, cp_number) then
message = {
type: 'text',
text: text_registredCP(cp_number,cp_name)
}
client.reply_message(event['replyToken'], message)
chatLogger(userId, 'bot', 'text', text_registredCP(cp_number,cp_name))
return "200 OK"
end
inputStatus(userId,'cp_stanby',cp_number)
message = {
type: 'text',
text: text_getCPnumber(cp_number, cp_name)
}
client.reply_message(event['replyToken'], message)
chatLogger(userId, 'bot', 'text', text_getCPnumber(cp_number, cp_name))
return "200 OK"
end
def zekkenNumberRegister userId, zekken_number, event_code, slice_number, client, event
zekken_number.slice!(0,slice_number)
if zekken_number.start_with?('[') then
zekken_number.delete_prefix!("[")
end
if zekken_number.end_with?("]") then
zekken_number.delete_suffix!("]")
end
for i in 1 .. 5 do
if zekken_number.end_with?("-#{i}") then
zekken_number.chop!
zekken_number.chop!
end
end
if (checkZekkenExist(zekken_number) == false) then
message = {
type: 'text',
text: text_noZekkenNumber()
}
client.reply_message(event['replyToken'], message)
chatLogger(userId, 'bot', 'text', text_noZekkenNumber())
return "200 OK"
end
inputStatus(userId, "zekkenAuthorization", zekken_number)
message = {
type: 'text',
text: text_zekkenRegister(zekken_number)
}
client.reply_message(event['replyToken'], message)
chatLogger(userId, 'bot', 'text', text_zekkenRegister(zekken_number))
return "200 OK"
end
def goalRegister userId, zekken_number, event_code, goal_time, slice_number, client, event
if cpDoubleCheck(zekken_number, event_code, -1) then
message = {
type: 'text',
text: text_alreadyGoal()
}
client.reply_message(event['replyToken'], message)
chatLogger(userId, 'bot', 'text', text_alreadyGoal())
return "200 OK"
end
goal_time.slice!(0,slice_number)
if zekken_number.start_with?('[') then
zekken_number.delete_prefix!("[")
end
if zekken_number.end_with?("]") then
zekken_number.delete_suffix!("]")
end
if goal_time.include?('時') then
goal_time.gsub!(//, ':')
end
if goal_time.include?('秒') then
goal_time.delete_suffix!("")
goal_time.gsub!(//, ':')
end
if goal_time.include?('分') then
goal_time.delete_suffix!("")
end
if goal_time.end_with?(':') then
message = {
type: 'text',
text: text_goalError()
}
client.reply_message(event['replyToken'], message)
chatLogger(userId, 'bot', 'text', text_goalError())
return "200 OK"
end
begin
goaltime = Time.parse(goal_time)
rescue => error
p error
message = {
type: 'text',
text: text_goalError()
}
client.reply_message(event['replyToken'], message)
chatLogger(userId, 'bot', 'text', text_goalError())
return "200 OK"
end
result = getTeamDataByZekken_number(zekken_number, event_code)
starttime = Time.parse(getEventStartTime(event_code))
if result['class_name'].include?('3時間') then
limittime = starttime + (3 * 60 * 60)
elsif result['class_name'].include?('5時間') then
limittime = starttime + (5 * 60 * 60)
elsif result['class_name'].include?("テスト") || result['class_name'].include?("test") then
#elsif result['class_name'] == "test" || result['class_name'] == "test2" then
limittime = starttime + (5 * 60 * 60)
else
message = {
type: 'text',
text: 'エラーコードDBS-001\nチーム情報の取得に失敗しました。\nゼッケン番号とこのエラーコードを添えて運営に問い合わせて下さい。'
}
client.reply_message(event['replyToken'], message)
chatLogger(userId, 'bot', 'text', 'エラーコードDBS-001\nチーム情報の取得に失敗しました。\nゼッケン番号とこのエラーコードを添えて運営に問い合わせて下さい。')
return "200 OK"
end
if limittime < goaltime then
late_point = goaltime - limittime
if late_point < 60
late_point = 50
else
late_point = late_point/60 + 1
late_point = late_point.floor*50
end
else
late_point = 0
end
data = {"goal_time" => goal_time, "late_point" => late_point}
jdata = JSON.generate(data)
inputStatus(userId,'goal_stanby',jdata)
message = {
type: 'text',
text: text_getGoal(goal_time)
}
client.reply_message(event['replyToken'], message)
chatLogger(userId, 'bot', 'text', text_getGoal(goal_time))
return "200 OK"
end
def agentRegister userId, command, client, event
p "agentR command : #{command}"
commandAr = command.split(' ')
agent_id = agentAuthorization(commandAr[1])
if (agent_id == "ERROR") then
message = {
type: 'text',
text: text_notAgent()
}
client.reply_message(event['replyToken'], message)
chatLogger(userId, 'bot', 'text', text_notAgent())
return "200 OK"
else
end
event_code = commandAr[2]
event_name = checkEventCode(event_code)
if event_name == "" then
message = {
type: 'text',
text: text_noEventName()
}
client.reply_message(event['replyToken'], message)
chatLogger(userId, 'bot', 'text', text_noEventName())
return "200 OK"
end
result = addUserData(userId,agent_id,event_code)
if result == "UPDATE ERROR" then
message = {
type: 'text',
text: "エラーコードUSR-002\nログインには成功しましたが、チーム情報の紐付けに失敗しました。\n恐れ入りますが、時間をあけて再度パスワードを御入力頂けますでしょうか。\n※このエラーが何度も発生する場合、エラーコード、LINEのユーザー名を添えて、運営に問い合わせて下さい。"
}
client.reply_message(event['replyToken'], message)
chatLogger(userId, 'bot', 'text', "エラーコードUSR-002\nログインには成功しましたが、チーム情報の紐付けに失敗しました。\n恐れ入りますが、時間をあけて再度パスワードを御入力頂けますでしょうか。\n※このエラーが何度も発生する場合、エラーコード、LINEのユーザー名を添えて、運営に問い合わせて下さい。")
return "200 OK"
end
message = {
type: 'text',
text: text_agentStart(event_name)
}
client.reply_message(event['replyToken'], message)
chatLogger(userId, 'bot', 'text', text_agentStart(event_name))
return "200 OK"
end
def checkinRegister userId, command, agent_id, event_code, client, event
commandAr = command.split(' ')
zekken_number = commandAr[1]
teamData = getTeamDataByZekken_number(zekken_number, event_code)
if teamData['result'] == "ERROR" then
message = {
type: 'text',
text: text_zekkenNotExist(zekken_number)
}
client.reply_message(event['replyToken'], message)
chatLogger(userId, 'bot', 'text', text_agentStart(zekken_number))
return "200 OK"
end
result = getZekkenNumberByAgentId(agent_id)
if result == "no data" then
inputAgentLogin(agent_id,zekken_number,event_code)
else
changeAgentLogin(agent_id,zekken_number,event_code)
end
if (checkAgentFlag(zekken_number, event_code) == false) then
inputAgentFlag(zekken_number, event_code, agent_id)
end
message = {
type: 'text',
text: text_agentLogin(teamData["team_name"])
}
client.reply_message(event['replyToken'], message)
chatLogger(userId, 'bot', 'text', text_agentLogin(teamData["team_name"]))
return "200 OK"
end
def checkoutRegister userId, agent_id, event_code, client, event
result = getZekkenNumberByAgentId(agent_id)
if result == "no login" || result == "no data" then
return "200 OK"
end
changeAgentLogin(agent_id,"","")
message = {
type: 'text',
text: text_agentLogout()
}
client.reply_message(event['replyToken'], message)
chatLogger(userId, 'bot', 'text', text_agentLogout())
return "200 OK"
end
def insertTentativeRegister userId, zekken_number, event_code, command, client, event
commandAr = command.split(' ')
insert_number = commandAr[1].to_i
cp_number = commandAr[2].to_i
if insert_number == "" || cp_number == "" then
message = {
type: 'text',
text: text_argumentError_Insert()
}
client.reply_message(event['replyToken'], message)
chatLogger(userId, 'bot', 'text', text_argumentError_Insert())
return "200 OK"
end
if insert_number <= 0 then
message = {
type: 'text',
text: text_notNaturakNumber()
}
client.reply_message(event['replyToken'], message)
chatLogger(userId, 'bot', 'text', text_notNaturakNumber())
return "200 OK"
end
if cp_number <= 0 then
message = {
type: 'text',
text: text_errorCPnumber()
}
client.reply_message(event['replyToken'], message)
chatLogger(userId, 'bot', 'text', text_errorCPnumber())
return "200 OK"
end
photo_point = 0
if cp_number < 996 then
photo_point = getPhotoPointByCPNum(cp_number,event_code)
if cp_number == "no cp error" then
message = {
type: 'text',
text: text_errorNoCP(cp_number)
}
client.reply_message(event['replyToken'], message)
chatLogger(userId, 'bot', 'text', text_errorNoCP(cp_number))
end
end
if cp_number <= 0 then
message = {
type: 'text',
text: text_errorNoCP(cp_number)
}
client.reply_message(event['replyToken'], message)
chatLogger(userId, 'bot', 'text', text_errorNoCP(cp_number))
return "200 OK"
end
jdata = JSON.generate({"insert_number" => insert_number, "cp_number" => cp_number, "photo_point" => photo_point})
cp_name = getCPname(cp_number, event_code)
if cp_name == "no cp error" then
message = {
type: 'text',
text: text_errorNoCP(cp_number)
}
client.reply_message(event['replyToken'], message)
chatLogger(userId, 'bot', 'text', text_errorNoCP(cp_number))
return "200 OK"
end
if (cpDoubleCheck(zekken_number, event_code, cp_number)) then
message = {
type: 'text',
text: text_registredCP(cp_number,cp_name)
}
client.reply_message(event['replyToken'], message)
chatLogger(userId, 'bot', 'text', text_registredCP(cp_number,cp_name))
return "200 OK"
end
inputStatus(userId, "insert", jdata)
message = {
type: 'text',
text: text_getCPnumber(cp_number, cp_name)
}
client.reply_message(event['replyToken'], message)
chatLogger(userId, 'bot', 'text', text_getCPnumber(cp_number, cp_name))
return "200 OK"
end
def insertRegister userId, zekken_number, event_code, jdata, image, client, event
data = JSON.parse(jdata)
insert_number = data["insert_number"]
cp_number = data["cp_number"]
photo_point = data["photo_point"]
cp_name = getCPname(cp_number, event_code)
if (cpDoubleCheck(zekken_number, event_code, cp_number)) then
message = {
type: 'text',
text: text_registredCP(cp_number,cp_name)
}
client.reply_message(event['replyToken'], message)
chatLogger(userId, 'bot', 'text', text_registredCP(cp_number,cp_name))
return "200 OK"
end
gps_list = getGpsList(zekken_number, event_code, "DESC")
gps_list.each{ |rec|
sn = rec["serial_number"]
result = changeSerialNumberInGPSInformation(zekken_number, event_code, sn, sn.to_i + 1)
if sn.to_i == insert_number.to_i then
break
end
}
inputCPnumber(zekken_number, event_code, cp_number, image, insert_number)
result = removeStatus(userId)
if result == "delete error" then
for i in 1..10 do
result = removeStatus(userId)
if result == "200 OK" then
break
end
end
end
if result == "delete error"
message = {
type: 'text',
text: text_importantError("STA-002")
}
client.reply_message(event['replyToken'], message)
chatLogger(userId, 'bot', 'text', text_importantError("STA-002"))
return "200 OK"
end
message = {
type: 'text',
text: text_insertComplete(cp_number,cp_name,insert_number)
}
client.reply_message(event['replyToken'], message)
chatLogger(userId, 'bot', 'text', text_insertComplete(cp_number,cp_name,insert_number))
return "200 OK"
end
def deleteRegister userId, zekken_number, event_code, command, client, event, api_flag = false
commandAr = command.split(' ')
c_sn = commandAr[1]
removeGI(zekken_number, event_code, c_sn)
gps_list = getGpsList(zekken_number,event_code, "ASC")
gps_list.each{ |rec|
sn = rec["serial_number"]
if sn.to_i > c_sn.to_i then
result = changeSerialNumberInGPSInformation(zekken_number, event_code, sn, sn.to_i - 1)
end
}
if api_flag == true then
return "OK"
end
message = {
type: 'text',
text: text_deleteCP(c_sn)
}
client.reply_message(event['replyToken'], message)
chatLogger(userId, 'bot', 'text', text_deleteCP(c_sn))
return "200 OK"
end
def moveRegister userId, zekken_number, event_code,command, client, event, api_flag = false
commandAr = command.split(' ')
old_sn = commandAr[1]
new_sn = commandAr[2]
max_sn = getMaxNumByGI(zekken_number,event_code)
p "max_sn : #{max_sn}, old_sn : #{old_sn}, new_sn : #{new_sn}"
if new_sn.to_i > max_sn.to_i || old_sn.to_i > max_sn.to_i then
p "over num error"
if api_flag then
return "over num error"
end
message = {
type: 'text',
text: text_moveOverNum()
}
client.reply_message(event['replyToken'], message)
chatLogger(userId, 'bot', 'text', text_moveOverNum())
return "200 OK"
end
if old_sn.to_i == new_sn.to_i then
p "same num error"
if api_flag then
return "same num error"
end
message = {
type: 'text',
text: text_moveSameNum()
}
client.reply_message(event['replyToken'], message)
chatLogger(userId, 'bot', 'text', text_moveSameNum())
return "200 OK"
end
changeSerialNumberInGPSInformation(zekken_number, event_code, old_sn, -1)
gps_list = getGpsList(zekken_number, event_code, "ASC")
gps_list.each{ |rec|
sn = rec["serial_number"]
if sn.to_i > old_sn.to_i then
result = changeSerialNumberInGPSInformation(zekken_number, event_code, sn.to_i, sn.to_i - 1)
end
}
if new_sn.to_i == max_sn.to_i then
else
gps_list = getGpsList(zekken_number, event_code, "DESC")
gps_list.each{ |rec|
sn = rec["serial_number"]
result = changeSerialNumberInGPSInformation(zekken_number, event_code, sn.to_i, sn.to_i + 1)
if sn.to_i == new_sn.to_i then
break
end
}
end
changeSerialNumberInGPSInformation(zekken_number, event_code, -1, new_sn.to_i)
if api_flag then
return "OK"
end
message = {
type: 'text',
text: text_moveCP(old_sn, new_sn)
}
client.reply_message(event['replyToken'], message)
chatLogger(userId, 'bot', 'text', text_moveCP(old_sn, new_sn))
return "200 OK"
end
def timeChRegister userId, zekken_number, event_code, command, client, event
commandAr = command.split(' ')
goal_time = commandAr[1]
if zekken_number.start_with?('[') then
zekken_number.delete_prefix!("[")
end
if zekken_number.end_with?("]") then
zekken_number.delete_suffix!("]")
end
if goal_time.include?('時') then
goal_time.gsub!(//, ':')
end
if goal_time.include?('秒') then
goal_time.delete_suffix!("")
goal_time.gsub!(//, ':')
end
if goal_time.include?('分') then
goal_time.delete_suffix!("")
end
if goal_time.end_with?(':') then
message = {
type: 'text',
text: text_goalError()
}
client.reply_message(event['replyToken'], message)
chatLogger(userId, 'bot', 'text', text_goalError())
return "200 OK"
end
begin
goaltime = Time.parse(goal_time)
rescue => error
p error
message = {
type: 'text',
text: text_goalError()
}
client.reply_message(event['replyToken'], message)
chatLogger(userId, 'bot', 'text', text_goalError())
return "200 OK"
end
result = getTeamDataByZekken_number(zekken_number, event_code)
starttime = Time.parse(getEventStartTime(event_code))
if result['class_name'].include?('3時間') then
limittime = starttime + (3 * 60 * 60)
elsif result['class_name'].include?('5時間') then
limittime = starttime + (5 * 60 * 60)
elsif result['class_name'].include?("テスト") || result['class_name'].include?("test") then
#elsif result['class_name'] == "test" then
limittime = starttime + (5 * 60 * 60)
else
message = {
type: 'text',
text: 'エラーコードDBS-001\nチーム情報の取得に失敗しました。\nゼッケン番号とこのエラーコードを添えて運営に問い合わせて下さい。'
}
client.reply_message(event['replyToken'], message)
chatLogger(userId, 'bot', 'text', 'エラーコードDBS-001\nチーム情報の取得に失敗しました。\nゼッケン番号とこのエラーコードを添えて運営に問い合わせて下さい。')
return "200 OK"
end
if limittime < goaltime then
late_point = goaltime - limittime
if late_point < 60
late_point = 50
else
late_point = late_point/60 + 1
late_point = late_point.floor*50
end
else
late_point = 0
end
result = changeGoalTimeAndLatePoint(zekken_number, event_code, goal_time, late_point)
if result == "UPDATE ERROR" then
message = {
type: 'text',
text: "システム的なエラーにより時刻の更新に失敗しました。もう一度やり直すか、このエラーが連続する場合、システム管理者に連絡してください。"
}
client.reply_message(event['replyToken'], message)
chatLogger(userId, 'bot', 'text', "システム的なエラーにより時刻の更新に失敗しました。もう一度やり直すか、このエラーが連続する場合、システム管理者に連絡してください。")
return "200 OK"
end
message = {
type: 'text',
text: text_goalUpdate(goal_time)
}
client.reply_message(event['replyToken'], message)
chatLogger(userId, 'bot', 'text', text_goalUpdate(goal_time))
return "200 OK"
end
def reprinter userId, zekken_number, event_code, client, event
message = {
type: 'text',
text: text_reprint()
}
client.reply_message(event['replyToken'], message)
chatLogger(userId, 'bot', 'text', text_reprint())
Thread.new do
makeScoreboardThread(zekken_number, event_code, "true")
end
end
def listUpper userId, zekken_number, event_code, client, event
origin_list = getGpsList(zekken_number, event_code, "ASC")
message_text = "チェックポイント通過リスト\n"
origin_list.each { |rec|
if rec["cp_number"].to_i == -1 then
message_text += "#{rec["serial_number"]}】ゴールタイム:#{rec["goal_time"]} 減点:#{rec["late_point"]}"
break
else
if rec["buy_point"].to_i == 0 then
point = rec["photo_point"]
else
point = rec["buy_point"]
end
message_text += "#{rec["serial_number"]}#{rec["cp_number"]}:#{rec["cp_name"]} 得点:#{point}\n"
end
}
message = {
type: 'text',
text: message_text
}
client.reply_message(event['replyToken'], message)
chatLogger(userId, 'bot', 'text', message_text)
return "200 OK"
end
def startRegister userId, zekken_number, client, event
inputStatus(userId, "start", "nil")
message = {
type: 'text',
text: text_startStand()
}
client.reply_message(event['replyToken'], message)
chatLogger(userId, 'bot', 'text', text_startStand())
return "200 OK"
end
#====================================
# Scoreboard
#====================================
def makeScoreboardThread zekken_number, event_code, reprintF = false, budleF = false
item = {"zekken_number" => zekken_number, "event_code" => event_code, "reprintF" => reprintF}
itemJSON = JSON.generate(item)
p "queue add : #{itemJSON}"
inputPrintQueueMemory(itemJSON)
$queue << itemJSON
end
def makeScoreboard zekken_number, event_code, reprintF = false, budleF = false
filepath = getScoreboardGeneral(zekken_number, event_code)
if filepath == "no_data" then
return "no data error"
end
if reprintF then
date_memory = DateTime.now.to_s.gsub(':','-').gsub('+','_')
nextpath = set_commonbase() + "/#{event_code}" + "/scoreboard/#{zekken_number}_scoreboard_" + date_memory + ".xlsx"
else
nextpath = set_commonbase() + "/#{event_code}" + "/scoreboard/#{zekken_number}_scoreboard.xlsx"
end
if( !Dir.exist?(set_commonbase() + "/#{event_code}" + "/scoreboard") )then
if( Dir.mkdir( set_commonbase() + "/#{event_code}" + "/scoreboard",0755 ) == 0 ) then
#p "mkdir #{commonbase}"
end
end
FileUtils.mv(filepath,nextpath)
docpath_user = set_commonbase() + "/#{event_code}" + "/scoreboard"
pdffile = "#{zekken_number}_scoreboard"
if reprintF then
pdffile = pdffile + '_' + date_memory
end
command ="/home/mobilousInstance/jodconverter-cli-4.4.5-SNAPSHOT/bin/jodconverter-cli -o #{docpath_user}/#{pdffile}.xlsx #{docpath_user}/#{pdffile}.pdf" #郡上のイベント後はこちらの仕様に置き換える
system( command )
puts command
#system("echo 'sumasen@123' |sudo -S /var/www/lib/generatePDF.sh #{docpath_user} #{pdffile}")
aws_url = s3Uploader("#{event_code}/scoreboard", docpath_user, pdffile + '.pdf')
if getFinalReport(zekken_number, event_code) == "no report" then
inputFinalReport(zekken_number, event_code, aws_url)
else
changeFinalReport(zekken_number, event_code, aws_url)
end
# File.delete(nextpath)
if budleF == false then
# File.delete(nextpath.gsub('.xlsx','.pdf'))
return nextpath.gsub('.xlsx','.pdf')
end
end
def getScoreboardGeneral zekken_number, event_code
#usernameエラーで引っかかる
#
#$bean.read_bean
#username = $bean.username
username = 'test'
record = {}
record["zekken_number"] = zekken_number
result = getGpsInfo(zekken_number, event_code)
if result == [] then
return "no_data"
end
count = 0
result.each { |rec|
count += 1
}
result2 = getPhotoFromRR(zekken_number, event_code, count)
if result2 == {} || result2["result"] == "ERROR" then
return "no_data"
end
record.merge!(result2)
if count <= 60 then
document = "scoreboardGeneral"
else
document = "scoreboardGeneral2"
end
count = count * 2 + 1
record["num_image"] = count
ExcelObject.resetClass
doc = AppExeExcelDoc.new
#doc = AppExeGeneralDocument.new
doc.init( username,0,document,"jp","/var/www/docbase","/home/mobilousInstance" ) # <== "/home/mobilousInstance" を出力先のベースフォルダーにしてください。
pgconn=UserPostgres.new
dbname = set_dbname()
pgconn.connectPg("localhost","mobilous",0,dbname)
rec = JSON.parse( JSON.generate(record) )
#@sheetname = sheet
#filename = doc.makeReport( pgconn,rec,"outfile.xlsx",0 ) # ==> Use ini file defnition 2021-11-15
doc.makeReport( pgconn,rec )
# make a excel file under /var/www/docbase/(@username)/(@projectno)/
#file_path = filename.to_s.gsub(/wrote excel file on /,"")
#puts "=========> file_path = #{file_path}"
filename = doc.outfile
file_path = doc.outpath
puts "=========> file_path = #{file_path}, filename = #{filename}"
return file_path
end
#====================================
# rogSimResult
#====================================
def makeRogSimResultSheet userId, event_code
filepath = getRogSimResultSheet(userId, event_code)
if filepath == "no_data" then
return "no data error"
end
nextpath = set_commonbase() + "/#{event_code}" + "/rogeSimResult/#{userId}_rogeSimResult_#{DateTime.now.to_s.gsub(':','-').gsub('+','_')}.xlsx"
if( !Dir.exist?(set_commonbase() + "/#{event_code}" + "/rogeSimResult") )then
if( Dir.mkdir( set_commonbase() + "/#{event_code}" + "/rogeSimResult",0755 ) == 0 ) then
#p "mkdir #{commonbase}"
end
end
FileUtils.mv(filepath,nextpath)
docpath_user = set_commonbase() + "/#{event_code}" + "/rogeSimResult"
pdffile = "#{userId}_rogeSimResult_#{DateTime.now.to_s.gsub(':','-').gsub('+','_')}"
command ="/home/mobilousInstance/jodconverter-cli-4.4.5-SNAPSHOT/bin/jodconverter-cli -o #{docpath_user}/#{pdffile}.xlsx #{docpath_user}/#{pdffile}.pdf" #郡上のイベント後はこちらの仕様に置き換える
system( command )
puts command
#system("echo 'sumasen@123' |sudo -S /var/www/lib/generatePDF.sh #{docpath_user} #{pdffile}")
aws_url = s3Uploader("#{event_code}/rogeSimResult", docpath_user, pdffile + '.pdf')
return aws_url
end
def getRogSimResultSheet userId, event_code
#usernameで引っかかる
#$bean.read_bean
#username = $bean.username
username = 'test'
record = {}
record["user_serial"] = userId
record["event_code"] = event_code
result = getRogSimResult(userId, event_code)
if result == [] then
return "no_data"
end
count = 0
result.each { |rec|
count += 1
}
result2 = getPhotoFromRSV(userId, event_code, count)
if result2 == {} || result2["result"] == "ERROR" then
return "no_data"
end
record.merge!(result2)
document = "rogeSimResult"
count = count + 1
record["num_image"] = count
ExcelObject.resetClass
doc = AppExeExcelDoc.new
#doc = AppExeGeneralDocument.new
doc.init( username,0,document,"jp","/var/www/docbase","/home/mobilousInstance" ) # <== "/home/mobilousInstance" を出力先のベースフォルダーにしてください。
pgconn=UserPostgres.new
dbname = set_dbname()
pgconn.connectPg("localhost","mobilous",0,dbname)
rec = JSON.parse( JSON.generate(record) )
#@sheetname = sheet
#filename = doc.makeReport( pgconn,rec,"outfile.xlsx",0 ) # ==> Use ini file defnition 2021-11-15
doc.makeReport( pgconn,rec )
# make a excel file under /var/www/docbase/(@username)/(@projectno)/
#file_path = filename.to_s.gsub(/wrote excel file on /,"")
#puts "=========> file_path = #{file_path}"
pgconn.disconnect
filename = doc.outfile
file_path = doc.outpath
puts "=========> file_path = #{file_path}, filename = #{filename}"
return file_path
end
#====================================
# save / upload
#====================================
def s3Uploader data_dir, filepath, filename
bucket = s3_bucket().freeze
region = s3_region().freeze
access_key = s3_key().freeze
secret_key = s3_Skey().freeze
aws_storage = S3_StorageUtil.new( access_key,secret_key,region,bucket,data_dir )
aws_bucket = S3_FolderUtil.new( "offlineRecog/work",aws_storage )
originPath = filepath
destPath = data_dir
filename = filename
aws_bucket.uploadFile( originPath,destPath,filename )
aws_url = s3_domain() + '/' + data_dir + '/' + filename
return aws_url
end
def photoSaver zekken_number, event_code, response
commonbase = set_commonbase() + '/' + event_code
commonbase2 = set_commonbase2() + '/' + event_code
docpath = commonbase + '/' + zekken_number
docpath2 = commonbase2 + '/' + zekken_number
if( !Dir.exist?(docpath) )then
if( Dir.mkdir( docpath,0755 ) == 0 ) then
#p "mkdir #{commonbase}"
end
end
filename = DateTime.now.to_s.gsub(':','-').gsub('+','_') + '.png'
fullpath = docpath + '/' + filename
fullpath2 = docpath2 + '/' + filename
open(fullpath, 'w') do |pass|
pass.write(response.body)
end
fullpath2 = s3Uploader("#{event_code}/#{zekken_number}",docpath,filename)
filenameTh = filename.gsub(".png","_th.png")
imageOri = Magick::Image.read(fullpath).first
imageTh = imageOri.scale(image_size_width(), image_size_height())
imageTh.write("temp/#{filenameTh}")
nextpath = docpath + '/' + filenameTh
FileUtils.mv("/var/www/temp/#{filenameTh}",nextpath)
# File.delete(fullpath)
return fullpath2
end
def chatLogger userId, talker, type, detail
p "#{talker} : #{detail}"
@pgconn=UserPostgres.new
dbname = set_dbname()
@pgconn.connectPg("localhost","mobilous",0,dbname)
anytable=UserPostgresTable.new
anytable.useTable( @pgconn,'chat_log' )
title = ["userid","talker","message_type","message_detail","create_at"]
record = {"userid" => userId, "talker" => talker, "message_type" => type, "message_detail" => detail, "create_at" => DateTime.now}
sql = anytable.makeInsertKeySet(title,record)
begin
ret = anytable.exec(sql) # true or false
rescue => error
p error
end
@pgconn.disconnect
return "OK"
end
end
def self.registered( app )
app.helpers MobServer_gifuroge::Helpers
app.get "/test_gifuroge" do
crossdomain
headjson
result = "git push test from development to production3"
p result
end
def calculateMonthlyScore(zekken_number, event_code)
@pgconn = UserPostgres.new
dbname = set_dbname()
@pgconn.connectPg("localhost", "mobilous", 0, dbname)
anytable = UserPostgresTable.new
anytable.useTable(@pgconn, 'gps_information')
# 現在の月の開始日と終了日を取得
today = Date.today
start_date = today.beginning_of_month
end_date = today.end_of_month
# 一ヶ月分のデータを取得
where = "zekken_number = '#{zekken_number}' AND event_code = '#{event_code}' " \
"AND create_at >= '#{start_date}' AND create_at <= '#{end_date}' " \
"ORDER BY create_at ASC"
records = anytable.find2(where)
@pgconn.disconnect
# 日ごとにグループ化して得点を計算
daily_scores = {}
(start_date..end_date).each do |date|
daily_records = records.select { |r| Date.parse(r['create_at']) == date }
start_index = daily_records.index { |r| r['cp_number'] == -2 }
end_index = daily_records.index { |r| r['cp_number'] == -1 }
if start_index && end_index && start_index < end_index
valid_records = daily_records[start_index+1...end_index]
score = valid_records.sum { |r| r['photo_point'].to_i }
daily_scores[date] = score
else
daily_scores[date] = 0
end
end
# 月間の合計得点を計算
total_monthly_score = daily_scores.values.sum
return {
daily_scores: daily_scores,
total_monthly_score: total_monthly_score
}
end
#====================================
# LINEbot本体
#====================================
app.post '/callback_gifuroge' do
crossdomain
# p "call back!"
body = request.body.read
# p "body read!"
signature = request.env['HTTP_X_LINE_SIGNATURE']
# p "signature read!"
unless client.validate_signature(body, signature)
p "400 Bad Request"
error 400 do 'Bad Request' end
end
# p "not 400!"
events = client.parse_events_from(body)
# p "event read!"
events.each do |event|
userId = event['source']['userId']
userdata = getUserName(userId)
if userdata["user_name"] == "get name error" then
message = {
type: 'text',
text: "エラーコードUSR-001\nユーザー名の取得に失敗しました。\n※このエラーが何度も発生する場合、エラーコードとゼッケン番号を添えて、運営に問い合わせて下さい。"
}
client.reply_message(event['replyToken'], message)
chatLogger(userId, 'bot', 'text', "エラーコードUSR-001\nユーザー名の取得に失敗しました。\n※このエラーが何度も発生する場合、エラーコードとゼッケン番号を添えて、運営に問い合わせて下さい。")
return "200 OK"
end
zekken_number = userdata["zekken_number"]
event_code = userdata["event_code"]
p "username : #{userdata["user_name"]} ( #{zekken_number} ( #{event_code} ) )"
case event
when Line::Bot::Event::Message
notZekken = false
status = checkStatus(userId)
if zekken_number == "" then
status = checkStatus(userId)
if status['status'] != "zekkenAuthorization" then
notZekken = true
end
end
agentF = false
agent_id = ""
if zekken_number != nil then
if (zekken_number.start_with?('a')) then
agent_id = zekken_number
zekken_number = getZekkenNumberByAgentId(zekken_number)
agentF = true
if status['status'] == "Goal" then
result = removeStatus(userId)
if result == "delete error" then
for i in 1..10 do
result = removeStatus(userId)
if result == "200 OK" then
break
end
end
end
status['status'] = "nothing"
if result == "delete error"
message = {
type: 'text',
text: text_importantError("STA-002")
}
client.reply_message(event['replyToken'], message)
chatLogger(userId, 'bot', 'text', text_importantError("STA-002"))
return "200 OK"
end
end
end
end
case event.type
when Line::Bot::Event::MessageType::Text
chatLogger(userId, 'user', 'text', event.message['text'])
command = NKF.nkf('-w -Z4', NKF.nkf('--katakana -w', event.message['text'])).upcase # この一行により入力された内容は全て半角かつ、ひらがなはカタカナに、小文字アルファベットは大文字に、変換される
if status['status'] == "Goal" then
if command.to_s.start_with?('AGENT') then
commandAr = event.message['text'].split(' ')
agent_id = agentAuthorization(commandAr[1])
if (agent_id == "ERROR") then
message = {
type: 'text',
text: text_notAgent()
}
client.reply_message(event['replyToken'], message)
chatLogger(userId, 'bot', 'text', text_notAgent())
return "200 OK"
else
end
result = removeStatus(userId)
if result == "delete error" then
for i in 1..10 do
result = removeStatus(userId)
if result == "200 OK" then
break
end
end
end
if result == "delete error"
message = {
type: 'text',
text: text_importantError("STA-002")
}
client.reply_message(event['replyToken'], message)
chatLogger(userId, 'bot', 'text', text_importantError("STA-002"))
return "200 OK"
end
agentRegister(userId,event.message['text'].to_s,client,event)
elsif (command == 'ログアウト' || command == 'LOGOUT') then
result = addUserData(userId, "", "")
if result == "UPDATE ERROR" then
message = {
type: 'text',
text: "エラーコードUSR-003\nログアウトの処理に失敗しました。\n恐れ入りますが、時間をあけてもう一度やり直して下さい。\n※このエラーが何度も発生する場合、LINEのユーザー名とエラーコードを運営に問い合わせて下さい。"
}
client.reply_message(event['replyToken'], message)
chatLogger(userId, 'bot', 'text', "エラーコードUSR-003\nログアウトの処理に失敗しました。\n恐れ入りますが、時間をあけてもう一度やり直して下さい。\n※このエラーが何度も発生する場合、LINEのユーザー名とエラーコードを運営に問い合わせて下さい。")
return "200 OK"
end
result = removeStatus(userId)
if result == "delete error" then
for i in 1..10 do
result = removeStatus(userId)
if result == "200 OK" then
break
end
end
end
if result == "delete error"
message = {
type: 'text',
text: text_importantError("STA-002")
}
client.reply_message(event['replyToken'], message)
chatLogger(userId, 'bot', 'text', text_importantError("STA-002"))
return "200 OK"
end
message = {
type: 'text',
text: text_loguotSuccess()
}
client.reply_message(event['replyToken'], message)
chatLogger(userId, 'bot', 'text', text_loguotSuccess())
return "200 OK"
elsif (command.start_with?('ゼッケン番号:')) then
result = removeStatus(userId)
if result == "delete error" then
for i in 1..10 do
result = removeStatus(userId)
if result == "200 OK" then
break
end
end
end
if result == "delete error"
message = {
type: 'text',
text: text_importantError("STA-002")
}
client.reply_message(event['replyToken'], message)
chatLogger(userId, 'bot', 'text', text_importantError("STA-002"))
return "200 OK"
end
zekkenNumberRegister(userId, command.to_s, event_code, 8, client,event)
elsif (command.to_s.start_with?('ゼッケン:')) then
result = removeStatus(userId)
if result == "delete error" then
for i in 1..10 do
result = removeStatus(userId)
if result == "200 OK" then
break
end
end
end
if result == "delete error"
message = {
type: 'text',
text: text_importantError("STA-002")
}
client.reply_message(event['replyToken'], message)
chatLogger(userId, 'bot', 'text', text_importantError("STA-002"))
return "200 OK"
end
zekkenNumberRegister(userId, command.to_s, event_code, 6, client,event)
elsif (command.to_s.start_with?('TIMECH')) then
if (agentF) then
timeChRegister(userId, zekken_number, event_code, command, client, event)
end
elsif (command.to_s.start_with?('時間変更')) then
if (agentF) then
timeChRegister(userId, zekken_number, command, client, event)
end
elsif (command.to_s.start_with?('REPRINT')) then
if (agentF) then
reprinter(userId, zekken_number, event_code, client, event)
end
elsif (command.to_s.start_with?('再印刷')) then
if (agentF) then
reprinter(userId, zekken_number, event_code, client, event)
end
elsif (command.to_s.start_with?('LIST')) then
if (agentF) then
listUpper(userId, zekken_number, event_code, client, event)
end
elsif (command.to_s.start_with?('一覧')) then
if (agentF) then
listUpper(userId, zekken_number, event_code, client, event)
end
else
message = {
type: 'text',
text: text_alreadyGoal()
}
client.reply_message(event['replyToken'], message)
chatLogger(userId, 'bot', 'text', text_alreadyGoal())
return "200 OK"
end
end
if notZekken then
if (command.start_with?('ゼッケン番号:')) then
zekkenNumberRegister(userId, command.to_s, event_code, 8, client,event)
elsif (command.to_s.start_with?('ゼッケン:')) then
zekkenNumberRegister(userId, command.to_s, event_code, 6, client,event)
elsif (command.to_s.start_with?('AGENT')) then
agentRegister(userId,event.message['text'].to_s,client,event)
return "200 OK"
elsif (command.to_s.start_with?('代理人')) then
agentRegister(userId,event.message['text'].to_s,client,event)
return "200 OK"
elsif (command.to_s.start_with?('CHECKIN')) then
if (agentF) then
checkinRegister(userId,command.to_s,agent_id,event_code,client,event)
end
elsif (command.to_s.start_with?('代理ログイン')) then
if (agentF) then
checkinRegister(userId,command.to_s,agent_id,event_code,client,event)
end
elsif (command.to_s.start_with?('CHECKOUT')) then
if (agentF) then
checkoutRegister(userId,agent_id,event_code,client,event)
end
elsif (command.to_s.start_with?('代理ログアウト')) then
if (agentF) then
checkoutRegister(userId,agent_id,event_code,client,event)
end
else
message = {
type: 'text',
text: text_noZekken1(userdata["user_name"])
}
client.reply_message(event['replyToken'], message)
chatLogger(userId, 'bot', 'text', text_noZekken1(userdata["user_name"]))
message = {
type: 'text',
text: text_noZekken2()
}
client.push_message(userId, message)
chatLogger(userId, 'bot', 'text', text_noZekken2())
message = {
type: 'text',
text: text_noZekken3()
}
client.push_message(userId, message)
chatLogger(userId, 'bot', 'text', text_noZekken3())
return "200 OK"
end
end
case status['status']
when 'nothing'
if (command.start_with?('ゼッケン番号:')) then
zekkenNumberRegister(userId, command.to_s, event_code, 8, client,event)
elsif (command.to_s.start_with?('ゼッケン:')) then
zekkenNumberRegister(userId, command.to_s, event_code, 6, client,event)
elsif (command.to_s.start_with?('CP番号:')) then
cpNumberRegister(userId, zekken_number, event_code, command.to_s, 5, client,event)
elsif (command.to_s.start_with?('CP:')) then
cpNumberRegister(userId, zekken_number, event_code, command.to_s, 3, client,event)
elsif (command.to_s.start_with?('ADD')) then
cp_number = command.split(' ')[1]
cpNumberRegister(userId, zekken_number, event_code, cp_number.to_s, 0, client,event)
elsif (command.to_s.start_with?('追加')) then
cp_number = command.split(' ')[1]
cpNumberRegister(userId, zekken_number, event_code, cp_number.to_s, 0, client,event)
elsif (command.to_s.start_with?('ゴール:') || command.to_s.start_with?('GOAL:')) then
goalRegister(userId,zekken_number, event_code, command.to_s, 5, client,event)
elsif (command.to_s.start_with?('ゴール ') || command.to_s.start_with?('GOAL ')) then
command = command.split(' ')[1]
goalRegister(userId,zekken_number, event_code, command.to_s, 0, client,event)
elsif (command.to_s.start_with?('ゴ:')) then
goalRegister(userId,zekken_number, event_code, command.to_s, 3, client,event)
elsif (command.to_s.start_with?('G:')) then
goalRegister(userId,zekken_number, event_code, command.to_s, 2, client,event)
elsif (command.to_s.start_with?('スタート')) then
startRegister(userId,zekken_number,client,event)
elsif (command.to_s.start_with?('START')) then
startRegister(userId,zekken_number,client,event)
elsif (command.to_s.start_with?('AGENT')) then
agentRegister(userId,event.message['text'].to_s,client,event)
elsif (command.to_s.start_with?('代理人')) then
agentRegister(userId,event.message['text'].to_s,client,event)
elsif (command.to_s.start_with?('CHECKIN')) then
if (agentF) then
checkinRegister(userId,command.to_s,agent_id,event_code,client,event)
end
elsif (command.to_s.start_with?('代理ログイン')) then
if (agentF) then
checkinRegister(userId,command.to_s,agent_id,event_code,client,event)
end
elsif (command.to_s.start_with?('CHECKOUT')) then
if (agentF) then
checkoutRegister(userId,agent_id,event_code,client,event)
end
elsif (command.to_s.start_with?('代理ログアウト')) then
if (agentF) then
checkoutRegister(userId,agent_id,event_code,client,event)
end
elsif (command.to_s.start_with?('INSERT')) then
if (agentF) then
insertTentativeRegister(userId, zekken_number,event_code, command, client, event)
end
elsif (command.to_s.start_with?('挿入')) then
if (agentF) then
insertTentativeRegister(userId, zekken_number, event_code, command, client, event)
end
elsif (command.to_s.start_with?('DELETE')) then
if (agentF) then
deleteRegister(userId, zekken_number, event_code, command, client, event)
end
elsif (command.to_s.start_with?('削除')) then
if (agentF) then
deleteRegister(userId, zekken_number, event_code, command, client, event)
end
elsif (command.to_s.start_with?('TIMECH')) then
if (agentF) then
timeChRegister(userId, zekken_number, event_code, command, client, event)
end
elsif (command.to_s.start_with?('時間変更')) then
if (agentF) then
timeChRegister(userId, zekken_number, event_code, command, client, event)
end
elsif (command.to_s.start_with?('REPRINT')) then
if (agentF) then
reprinter(userId, zekken_number, event_code, client, event)
end
elsif (command.to_s.start_with?('再印刷')) then
if (agentF) then
reprinter(userId, zekken_number, event_code, client, event)
end
elsif (command.to_s.start_with?('LIST')) then
if (agentF) then
listUpper(userId, zekken_number, event_code, client, event)
end
elsif (command.to_s.start_with?('一覧')) then
if (agentF) then
listUpper(userId, zekken_number, event_code, client, event)
end
elsif (command.to_s.start_with?('MOVE')) then
if (agentF) then
moveRegister(userId, zekken_number, event_code, command, client, event)
end
elsif (command.to_s.start_with?('移動')) then
if (agentF) then
moveRegister(userId, zekken_number, event_code, command, client, event)
end
elsif (command == 'ログアウト' || command == 'LOGOUT') then
result = addUserData(userId, "", "")
if result == "UPDATE ERROR" then
message = {
type: 'text',
text: "エラーコードUSR-003\nログアウトの処理に失敗しました。\n恐れ入りますが、時間をあけてもう一度やり直して下さい。\n※このエラーが何度も発生する場合、LINEのユーザー名とエラーコードを運営に問い合わせて下さい。"
}
client.reply_message(event['replyToken'], message)
chatLogger(userId, 'bot', 'text', "エラーコードUSR-003\nログアウトの処理に失敗しました。\n恐れ入りますが、時間をあけてもう一度やり直して下さい。\n※このエラーが何度も発生する場合、LINEのユーザー名とエラーコードを運営に問い合わせて下さい。")
return "200 OK"
end
message = {
type: 'text',
text: text_loguotSuccess()
}
client.reply_message(event['replyToken'], message)
chatLogger(userId, 'bot', 'text', text_loguotSuccess())
return "200 OK"
else # CP登録と仮定する
if (command.to_s.start_with?('#')) then
command.delete_prefix!('#')
end
cp_number = command.to_i
if cp_number <= 0 then
return "200 OK"
end
cpNumberRegister(userId, zekken_number, event_code, cp_number, 0, client,event)
end
when "zekkenAuthorization"
if command.to_s.start_with?('PASSWORD:') then
password = event.message['text'].to_s.slice(0,9)
elsif command.to_s.start_with?('パスワード:') then
password = event.message['text'].to_s.slice(0,6)
elsif (command == 'NO' || command == "キャンセル" || command == "CANCEL" || command == "イイエ" || command == "ノー") then
result = removeStatus(userId)
if result == "delete error" then
message = {
type: 'text',
text: "エラーコードSTA-002\nパスワード受付のキャンセルに失敗しました。\n恐れ入りますが、時間をあけてもう一度やり直して下さい。\n※このエラーが何度も発生する場合、LINEのユーザー名とエラーコードを運営に問い合わせて下さい。"
}
client.reply_message(event['replyToken'], message)
chatLogger(userId, 'bot', 'text', "エラーコードSTA-002\nパスワード受付のキャンセルに失敗しました。\n恐れ入りますが、時間をあけてもう一度やり直して下さい。\n※このエラーが何度も発生する場合、LINEのユーザー名とエラーコードを運営に問い合わせて下さい。")
return "200 OK"
end
message = {
type: 'text',
text: text_AuthorizationCancel()
}
client.reply_message(event['replyToken'], message)
chatLogger(userId, 'bot', 'text', text_AuthorizationCancel())
return "200 OK"
else
password = event.message['text']
end
result = zekkenAuthorization(status['memory'], password)
if result["result"] == "OK"
if getUserIdByZekkenNumber(result['zekken_number'],result["event_code"]) != "no zekken number" then
message = {
type: 'text',
text: text_alreadyZekken()
}
client.reply_message(event['replyToken'], message)
chatLogger(userId, 'bot', 'text', text_alreadyZekken())
return "200 OK"
end
result2 = addUserData(userId,result['zekken_number'],result["event_code"])
if result2 == "UPDATE ERROR" then
message = {
type: 'text',
text: "エラーコードUSR-002\nログインには成功しましたが、チーム情報の紐付けに失敗しました。\n恐れ入りますが、時間をあけて再度パスワードを御入力頂けますでしょうか。\n※このエラーが何度も発生する場合、エラーコード、LINEのユーザー名を添えて、運営に問い合わせて下さい。"
}
client.reply_message(event['replyToken'], message)
chatLogger(userId, 'bot', 'text', "エラーコードUSR-002\nログインには成功しましたが、チーム情報の紐付けに失敗しました。\n恐れ入りますが、時間をあけて再度パスワードを御入力頂けますでしょうか。\n※このエラーが何度も発生する場合、エラーコード、LINEのユーザー名を添えて、運営に問い合わせて下さい。")
return "200 OK"
end
result3 = removeStatus(userId)
if result3 == "delete error" then
for i in 1..10 do
result3 = removeStatus(userId)
if result3 == "200 OK" then
break
end
end
end
if result3 == "delete error"
message = {
type: 'text',
text: text_importantError("STA-002")
}
client.reply_message(event['replyToken'], message)
chatLogger(userId, 'bot', 'text', text_importantError("STA-002"))
return "200 OK"
end
message = {
type: 'text',
text: text_teamRegister(userdata["user_name"], result['team_name'])
}
client.reply_message(event['replyToken'], message)
chatLogger(userId, 'bot', 'text', text_teamRegister(userdata["user_name"], result['team_name']))
elsif result["result"] == "ERROR"
message = {
type: 'text',
text: text_passwordError()
}
client.reply_message(event['replyToken'], message)
chatLogger(userId, 'bot', 'text', text_passwordError())
end
when "cp_stanby"
if (command == 'NO' || command == "キャンセル" || command == "イイエ" || command == "ノー") then
result = removeStatus(userId)
if result == "delete error" then
message = {
type: 'text',
text: "エラーコードSTA-003\n写真受付のキャンセルに失敗しました。\n恐れ入りますが、時間をあけてもう一度やり直して下さい。\n※このエラーが何度も発生する場合、ゼッケン番号とエラーコードを運営に問い合わせて下さい。"
}
client.reply_message(event['replyToken'], message)
chatLogger(userId, 'bot', 'text', "エラーコードSTA-003\n写真受付のキャンセルに失敗しました。\n恐れ入りますが、時間をあけてもう一度やり直して下さい。\n※このエラーが何度も発生する場合、ゼッケン番号とエラーコードを運営に問い合わせて下さい。")
return "200 OK"
end
message = {
type: 'text',
text: text_AuthorizationCancel()
}
client.reply_message(event['replyToken'], message)
chatLogger(userId, 'bot', 'text', text_AuthorizationCancel())
return "200 OK"
end
when "goal_stanby"
if (command == 'NO' || command == "キャンセル" || command == "イイエ" || command == "ノー") then
result = removeStatus(userId)
if result == "delete error" then
message = {
type: 'text',
text: "エラーコードSTA-003\n写真受付のキャンセルに失敗しました。\n恐れ入りますが、時間をあけてもう一度やり直して下さい。\n※このエラーが何度も発生する場合、ゼッケン番号とエラーコードを運営に問い合わせて下さい。"
}
client.reply_message(event['replyToken'], message)
chatLogger(userId, 'bot', 'text', "エラーコードSTA-003\n写真受付のキャンセルに失敗しました。\n恐れ入りますが、時間をあけてもう一度やり直して下さい。\n※このエラーが何度も発生する場合、ゼッケン番号とエラーコードを運営に問い合わせて下さい。")
return "200 OK"
end
message = {
type: 'text',
text: text_AuthorizationCancel()
}
client.reply_message(event['replyToken'], message)
chatLogger(userId, 'bot', 'text', text_AuthorizationCancel())
return "200 OK"
end
when "insert"
if (command == 'NO' || command == "キャンセル" || command == "イイエ" || command == "ノー") then
result = removeStatus(userId)
if result == "delete error" then
message = {
type: 'text',
text: "エラーコードSTA-003\n写真受付のキャンセルに失敗しました。\n恐れ入りますが、時間をあけてもう一度やり直して下さい。\n※このエラーが何度も発生する場合、ゼッケン番号とエラーコードを運営に問い合わせて下さい。"
}
client.reply_message(event['replyToken'], message)
chatLogger(userId, 'bot', 'text', "エラーコードSTA-003\n写真受付のキャンセルに失敗しました。\n恐れ入りますが、時間をあけてもう一度やり直して下さい。\n※このエラーが何度も発生する場合、ゼッケン番号とエラーコードを運営に問い合わせて下さい。")
return "200 OK"
end
message = {
type: 'text',
text: text_AuthorizationCancel()
}
client.reply_message(event['replyToken'], message)
chatLogger(userId, 'bot', 'text', text_AuthorizationCancel())
return "200 OK"
end
when "start"
if (command == 'NO' || command == "キャンセル" || command == "イイエ" || command == "ノー") then
result = removeStatus(userId)
if result == "delete error" then
message = {
type: 'text',
text: "エラーコードSTA-003\nスタートのキャンセルに失敗しました。\n恐れ入りますが、時間をあけてもう一度やり直して下さい。\n※このエラーが何度も発生する場合、ゼッケン番号とエラーコードを運営に問い合わせて下さい。"
}
client.reply_message(event['replyToken'], message)
chatLogger(userId, 'bot', 'text', "エラーコードSTA-003\nスタートのキャンセルに失敗しました。\n恐れ入りますが、時間をあけてもう一度やり直して下さい。\n※このエラーが何度も発生する場合、ゼッケン番号とエラーコードを運営に問い合わせて下さい。")
return "200 OK"
end
message = {
type: 'text',
text: text_AuthorizationCancel()
}
client.reply_message(event['replyToken'], message)
chatLogger(userId, 'bot', 'text', text_AuthorizationCancel())
return "200 OK"
elsif (command == 'YES' || command == 'ハイ' || command == 'イエス') then
removeAllGI(zekken_number, event_code)
inputCPnumber(zekken_number,event_code,-2,set_originbase() + '/start.png')
result = removeStatus(userId)
if result == "delete error" then
for i in 1..10 do
result = removeStatus(userId)
if result == "200 OK" then
break
end
end
end
if result == "delete error"
message = {
type: 'text',
text: text_importantError("STA-002")
}
client.reply_message(event['replyToken'], message)
chatLogger(userId, 'bot', 'text', text_importantError("STA-002"))
return "200 OK"
end
message = {
type: 'text',
text: text_startRun()
}
client.reply_message(event['replyToken'], message)
chatLogger(userId, 'bot', 'text', text_startRun())
return "200 OK"
end
end
when Line::Bot::Event::MessageType::Image
if notZekken then
chatLogger(userId, 'user', 'image', '[保存しなかった画像ファイル]')
message = {
type: 'text',
text: text_noZekken1(userdata["user_name"])
}
client.reply_message(event['replyToken'], message)
chatLogger(userId, 'bot', 'text', text_noZekken1(userdata["user_name"]))
message = {
type: 'text',
text: text_noZekken2()
}
client.push_message(userId, message)
chatLogger(userId, 'bot', 'text', text_noZekken2())
message = {
type: 'text',
text: text_noZekken3()
}
client.push_message(userId, message)
chatLogger(userId, 'bot', 'text', text_noZekken3())
return "200 OK"
end
case status['status']
when 'nothing'
chatLogger(userId, 'user', 'image', '[保存しなかった画像ファイル]')
# 何もなし
when 'cp_stanby'
response = client.get_message_content(event.message['id'])
fullpath = photoSaver(zekken_number, event_code, response)
chatLogger(userId, 'user', 'image', fullpath)
###
#早野修正分
#ユーザーのbuy_pointレコードが1なら追加の写真を要求する。
#validation(重複チェック)などはいるか?
inputCPnumber(zekken_number, event_code, status['memory'], fullpath)
if checkBuypointSingleRecord(zekken_number, event_code, status['memory'])
message = {
type: 'text',
text: text_ask_for_receipt_image(status['memory'])
}
client.reply_message(event['replyToken'], message)
chatLogger(userId, 'bot', 'text', text_ask_for_receipt_image(status['memory']))
return "200 OK"
end
###
result = removeStatus(userId)
if result == "delete error" then
for i in 1..10 do
result = removeStatus(userId)
if result == "200 OK" then
break
end
end
end
if result == "delete error"
message = {
type: 'text',
text: text_importantError("STA-002")
}
client.reply_message(event['replyToken'], message)
chatLogger(userId, 'bot', 'text', text_importantError("STA-002"))
return "200 OK"
end
cp_name = getCPname(status['memory'], event_code)
cp_number = status['memory'].to_i
message = {
type: 'text',
text: text_registreCP(cp_number,cp_name)
}
client.reply_message(event['replyToken'], message)
chatLogger(userId, 'bot', 'text', text_registreCP(cp_number,cp_name))
when 'goal_stanby'
response = client.get_message_content(event.message['id'])
fullpath = photoSaver(zekken_number, event_code, response)
chatLogger(userId, 'user', 'image', fullpath)
jdata = status['memory']
data = JSON.parse(jdata)
inputGoalTime(zekken_number,event_code,data['goal_time'],data['late_point'],fullpath)
result = removeStatus(userId)
if result == "delete error" then
for i in 1..10 do
result = removeStatus(userId)
if result == "200 OK" then
break
end
end
end
if result == "delete error"
message = {
type: 'text',
text: text_importantError("STA-002")
}
client.reply_message(event['replyToken'], message)
chatLogger(userId, 'bot', 'text', text_importantError("STA-002"))
return "200 OK"
end
message = {
type: 'text',
text: text_getGoalPhoto()
}
client.reply_message(event['replyToken'], message)
chatLogger(userId, 'bot', 'text', text_getGoalPhoto())
inputStatus(userId, "Goal", 'nil')
Thread.new do
makeScoreboardThread(zekken_number, event_code)
end
return "200 OK"
when "insert"
response = client.get_message_content(event.message['id'])
fullpath = photoSaver(zekken_number, event_code, response)
chatLogger(userId, 'user', 'image', fullpath)
insertRegister(userId, zekken_number, event_code, status['memory'], fullpath, client, event)
end
when Line::Bot::Event::MessageType::Location
latitude = event.message['latitude']
longitude = event.message['longitude']
chatLogger(userId, 'user', 'location', "latitude : #{latitude} , longitude : #{longitude}")
if notZekken then
message = {
type: 'text',
text: text_noZekken1(userdata["user_name"])
}
client.reply_message(event['replyToken'], message)
chatLogger(userId, 'bot', 'text', text_noZekken1(userdata["user_name"]))
message = {
type: 'text',
text: text_noZekken2()
}
client.push_message(userId, message)
chatLogger(userId, 'bot', 'text', text_noZekken2())
message = {
type: 'text',
text: text_noZekken3()
}
client.push_message(userId, message)
chatLogger(userId, 'bot', 'text', text_noZekken3())
return "200 OK"
end
case status['status']
when 'nothing'
p "latitude : #{latitude} , longitude : #{longitude}"
cp_data = getCPnameByThreshols(latitude,longitude, event_code)
if cp_data["result"] == "no cp error" then
message = {
type: 'text',
text: text_noLocation()
}
client.reply_message(event['replyToken'], message)
chatLogger(userId, 'bot', 'text', text_noLocation())
return "200 OK"
end
if (cp_data["cp_number"].to_i == -1) then
message = {
type: 'text',
text: text_goalCheck1()
}
client.reply_message(event['replyToken'], message)
chatLogger(userId, 'bot', 'text', text_goalCheck1())
message = {
type: 'text',
text: text_goalCheck2()
}
client.push_message(userId, message)
chatLogger(userId, 'bot', 'text', text_goalCheck2())
message = {
type: 'text',
text: text_goalCheck3()
}
client.push_message(userId, message)
chatLogger(userId, 'bot', 'text', text_goalCheck3())
return "200 OK"
end
if cpDoubleCheck(zekken_number, event_code, cp_data['cp_number']) then
message = {
type: 'text',
text: text_registredCP(cp_data["cp_number"],cp_data["cp_name"])
}
client.reply_message(event['replyToken'], message)
chatLogger(userId, 'bot', 'text', text_registredCP(cp_data["cp_number"],cp_data["cp_name"]))
return "200 OK"
end
if cp_data['buy_point'] != '0' then
inputStatus(userId,'cp_stanby',cp_data["cp_number"])
message = {
type: 'text',
text: text_standByBuyPoint(cp_data["cp_number"],cp_data["cp_name"])
}
client.reply_message(event['replyToken'], message)
chatLogger(userId, 'bot', 'text', text_standByBuyPoint(cp_data["cp_number"],cp_data["cp_name"]))
return "200 OK"
end
fullpath = set_originbase() + '/location_checked.png'
inputCPnumber(zekken_number,event_code,cp_data["cp_number"],fullpath)
cp_number = cp_data["cp_number"]
message = {
type: 'text',
text: text_registreCP(cp_number,cp_data["cp_name"])
}
client.reply_message(event['replyToken'], message)
chatLogger(userId, 'bot', 'text', text_registreCP(cp_number,cp_data["cp_name"]))
return "200 OK"
when 'cp_stanby'
p "latitude : #{latitude} , longitude : #{longitude}"
cp_data = {}
if status['memory'].to_i == 998 then
cp_data["cp_number"] = 998
cp_data["cp_name"] = "テストチェックポイント2"
cp_data["buy_point"] = '0'
else
cp_data = getCPnameByThreshols(latitude,longitude,event_code,status['memory'])
end
if cp_data["result"] == "no cp error" then
cp_name = getCPname(status["memory"],event_code)
if status["memory"].to_i < 996 then
cp_number = getPhotoPointByCPNum(status["memory"],event_code)
else
cp_number = status["memory"]
end
message = {
type: 'text',
text: text_noLocationCSB(cp_number,cp_name)
}
client.reply_message(event['replyToken'], message)
chatLogger(userId, 'bot', 'text', text_noLocationCSB(cp_number,cp_name))
return "200 OK"
end
if cp_data['buy_point'] != '0' then
message = {
type: 'text',
text: text_BuyPointError(cp_data["cp_number"],cp_data["cp_name"])
}
client.reply_message(event['replyToken'], message)
chatLogger(userId, 'bot', 'text', text_BuyPointError(cp_data["cp_number"],cp_data["cp_name"]))
return "200 OK"
end
fullpath = set_originbase() + '/location_checked.png'
inputCPnumber(zekken_number,event_code,cp_data["cp_number"],fullpath)
if status["memory"].to_i < 996 then
cp_number = getPhotoPointByCPNum(status["memory"],event_code)
else
cp_number = status["memory"]
end
message = {
type: 'text',
text: text_registreCP(cp_number,cp_data["cp_name"])
}
client.reply_message(event['replyToken'], message)
chatLogger(userId, 'bot', 'text', text_registreCP(cp_number,cp_data["cp_name"]))
result = removeStatus(userId)
if result == "delete error" then
for i in 1..10 do
result = removeStatus(userId)
if result == "200 OK" then
break
end
end
end
if result == "delete error"
message = {
type: 'text',
text: text_importantError("STA-002")
}
client.reply_message(event['replyToken'], message)
chatLogger(userId, 'bot', 'text', text_importantError("STA-002"))
return "200 OK"
end
return "200 OK"
end
when Line::Bot::Event::MessageType::File
if notZekken then
chatLogger(userId, 'user', 'file', "[保存しなかったファイル]")
message = {
type: 'text',
text: text_noZekken1(userdata["user_name"])
}
client.reply_message(event['replyToken'], message)
chatLogger(userId, 'bot', 'text', text_noZekken1(userdata["user_name"]))
message = {
type: 'text',
text: text_noZekken2()
}
client.push_message(userId, message)
chatLogger(userId, 'bot', 'text', text_noZekken2())
message = {
type: 'text',
text: text_noZekken3()
}
client.push_message(userId, message)
chatLogger(userId, 'bot', 'text', text_noZekken3())
return "200 OK"
end
chatLogger(userId, 'user', 'file', "[保存しなかったファイル]")
# commonbase = set_commonbase()
# docpath = commonbase + '/' + event_code + '/' + zekken_number
# filename = DateTime.now.to_s.gsub(':','-').gsub('+','_') + '.xml'
# fullpath = docpath + '/' + filename
#
# response = client.get_message_content(event.message['id'])
#
# open(fullpath, 'w') do |pass|
# pass.write(response.body)
# end
#
# chatLogger(userId, 'user', 'file', fullpath)
#
# doc = REXML::Document.new(File.open(fullpath))
#
# doc.elements.each('gpx/trk/trkseg/trkpt') do |elm|
#
# lat = elm.attribute('lat').value
# lon = elm.attribute('lon').value
#
# p "lat : #{lat}, lon : #{lon}"
#
# inputGPSlog(zekken_number,event_code,lat,lon)
#
# end
message = {
type: 'text',
text: text_getGPSlogger()
}
client.reply_message(event['replyToken'], message)
else
chatLogger(userId, 'user', 'other', "[テキスト、画像、位置情報、ファイル以外の保存しなかった何か]")
if notZekken then
message = {
type: 'text',
text: text_noZekken1(userdata["user_name"])
}
client.reply_message(event['replyToken'], message)
chatLogger(userId, 'bot', 'text', text_noZekken1(userdata["user_name"]))
message = {
type: 'text',
text: text_noZekken2()
}
client.push_message(userId, message)
chatLogger(userId, 'bot', 'text', text_noZekken2())
message = {
type: 'text',
text: text_noZekken3()
}
client.push_message(userId, message)
chatLogger(userId, 'bot', 'text', text_noZekken3())
return "200 OK"
end
end
end
end
p "200 OK"
end
# https://natnats.mobilous.com/get_zekken_list?event='ogaki'
app.get "/get_zekken_list" do
crossdomain
headjson
p "/get_zekken_list"
p "params : #{params}"
return JSON.generate(getZekkenListByTT(params['event']))
end
# https://natnats.mobilous.com/get_photo_list?zekken=[zekken_number]&pw=[password]
app.get "/get_photo_list" do
crossdomain
p "/get_photo_list"
zekken = params['zekken']
password = params['pw']
event_code = params['event']
result = zekkenAuthorization(zekken,password)
if result["zekken_number"] == "ERROR" || result["event_code"] != event_code then
headjson
return JSON.generate({"status" => "ERROR"})
end
# ゼッケン番号の変換。美濃加茂ロゲで、以下のゼッケン番号の登録を間違えていたので急造の変換
zekken_conversion = {
"MF3-160" => "MZ3-160",
"MF3-161" => "MZ3-161",
"MF3-162" => "MZ3-162",
"MF3-163" => "MZ3-163",
"MF5-170" => "MZ5-170",
"MF5-171" => "MZ5-171",
"MF5-172" => "MZ5-172",
"MF5-173" => "MZ5-173",
"MF5-174" => "MZ5-174",
"MF5-175" => "MZ5-175",
"MF5-176" => "MZ5-176",
"MF5-177" => "MZ5-177",
"MF5-178" => "MZ5-178",
"MF5-179" => "MZ5-179"
}
if zekken_conversion.key?(zekken)
zekken = zekken_conversion[zekken]
end
photo_list = []
routePath = "#{set_commonbase()}/route_photo/#{zekken}.png"
routePath2 = "#{set_commonbase2()}/route_photo/#{zekken}.png"
if File.exist?(routePath) then
photo_list.push(routePath2)
end
photo_list.concat(getPhotoList(zekken, event_code))
headjson
return JSON.generate({"status" => "OK", "photo_list" => photo_list, "report" => getFinalReport(zekken,event_code)})
end
# https://natnats.mobilous.com/getScoreboard?z_num=[zekken_number]
app.get "/getScoreboard" do
crossdomain
p "/getScoreboard"
p "params : #{params}"
zekken_number = params["z_num"]
event_code = params["event"]
file_path = getScoreboardOgaki(zekken_number,event_code)
content_type "application/xlsx"
attachment "#{file_path}"
send_file(file_path, :filename => "#{zekken_number}_scoreboardOgaki.xlsx",:type => "application/xlsx", :disposition => 'attachment')
end
# app.post "/xlsx_receive_ogaki" do
# crossdomain
#
# savepath = set_commonbase() + "/temp/#{params['input_file'][:filename]}"
#
# if (Dir.exist?(savepath) ) then
# File.delete(savepath)
# end
#
# File.open(savepath, 'wb') do |f|
# f.write params['input_file'][:tempfile].read
# end
#
# @pgconn=UserPostgres.new
# dbname = set_dbname()
# @pgconn.connectPg("localhost","mobilous",0,dbname)
#
# template = AppExeExcelWorkBook.new
# template.readWorkBook(savepath)
#
# dataSheet = AppExeExcelWorkSheet.new
# dataSheet.initLoad(template,"計算用")
#
# if dataSheet.getCell(1,2).value == nil then
# return "no zekken error"
# end
#
# zekken_number = dataSheet.getCell(1,2).value
#
# anytable=UserPostgresTable.new
# anytable.useTable( @pgconn,'user_table' )
# anytable2=UserPostgresTable.new
# anytable2.useTable( @pgconn,'gps_information' )
#
# userId = getUserIdByZekkenNumber(zekken_number)
#
# if userId == "no zekken number" then
#
# title = ["userid", "zekken_number", "create_at", "update_at"]
#
# record = {"userid" => zekken_number, "zekken_number" => zekken_number, "create_at" => DateTime.now, "update_at" => DateTime.now}
#
# sql = anytable.makeInsertKeySet(title,record)
# p sql
#
# begin
# ret = anytable.exec(sql) # true or false
# rescue => error
# p error
# end
#
# userId = zekken_number
#
# end
#
#
# title = ["user_name", "cp_number", "create_at", "update_at"]
#
# col = 1
# line = 6
#
# for i in 0 .. 99 do
# if dataSheet.getCell(line,col) == nil then
# break
# end
# if dataSheet.getCell(line,col).value == nil then
# break
# end
# rec = dataSheet.getCell(line,col).value
# if (cpDoubleCheck(zekken_number,rec)) then
# p "double! #{rec}"
# else
# record = {"user_name" => userId, "cp_number" => rec, "create_at" => DateTime.now, "update_at" => DateTime.now}
# sql = anytable2.makeInsertKeySet(title,record)
# p sql
#
# begin
# ret = anytable2.exec(sql) # true or false
# rescue => error
# p error
# end
# end
#
# col += 1
#
# if col == 11 then
# col = 1
# line += 5
# end
# if line == 56 then
# break
# end
# end
#
# goal_time = dataSheet.getCell(3,8).value
#
# late_point = dataSheet.getCell(56,3).value
#
# title = ["user_name", "goal_time", "late_point", "create_at", "update_at"]
#
# record = {"user_name" => userId, "goal_time" => goal_time, "late_point" => late_point, "create_at" => DateTime.now, "update_at" => DateTime.now}
# sql = anytable2.makeInsertKeySet(title,record)
# p sql
#
# begin
# ret = anytable2.exec(sql) # true or false
# rescue => error
# p error
# end
#
# @pgconn.disconnect
#
# p "200 OK"
#
# end
#====================================
# realtimemonitor API
#====================================
app.get "/realtimeMonitor" do
crossdomain
p "/realtimeMonitor"
p "params : #{params}"
event_code = params["event_code"]
class_name = params["class"]
@pgconn=UserPostgres.new
dbname = set_dbname()
@pgconn.connectPg("localhost","mobilous",0,dbname)
anytable=UserPostgresTable.new
anytable.useTable( @pgconn,'realtimemonitor' )
where = "event_code = '#{event_code}'"
if class_name == nil || class_name == "" then
else
where = where + "AND class_name = '#{class_name}'"
end
list = anytable.find2(where)
result = []
list.each { |rec|
result.push(rec)
}
@pgconn.disconnect
headjson
return JSON.generate(result)
end
app.get "/realtimeMonitor_zekken_narrow" do
crossdomain
p "/realtimeMonitor_zekken_narrow"
p "params : #{params}"
zekken_number = params["zekken"]
event_code = params["event_code"]
@pgconn=UserPostgres.new
dbname = set_dbname()
@pgconn.connectPg("localhost","mobilous",0,dbname)
anytable=UserPostgresTable.new
anytable.useTable( @pgconn,'realtimemonitor' )
where = "zekken_number = '#{zekken_number}' AND event_code = '#{event_code}'"
list = anytable.find2(where)
result = []
list.each { |rec|
result.push(rec)
}
@pgconn.disconnect
headjson
return JSON.generate(result)
end
app.get "/getRoute" do
crossdomain
p "/getRoute"
p "params : #{params}"
team_name = params["team"]
event_code = params["event_code"]
zekken_number = getZekkenNumberByTeamName(team_name,event_code)
p "zekken_number: #{zekken_number}"
if zekken_number == "no zekken number" then
headjson
return JSON.generate({"status" => "ERROR"})
end
input_file = "#{set_commonbase}/#{event_code}/#{zekken_number}/waypoints.csv"
bounds = get_lat_lng_bounds_for_event_code(event_code)
include_min_lat = bounds[:min_latitude]
include_max_lat = bounds[:max_latitude]
include_min_lng = bounds[:min_longitude]
include_max_lng = bounds[:max_longitude]
#ファイルがあって
#if File.exist?(input_file) && event_code != '大垣2'
if File.exist?(input_file)
data = CSV.read(input_file)
if data.empty?
result = getDataFromDatabase(zekken_number, event_code)
else
result = []
data.each do |line|
latitude = line[0].to_f
longitude = line[1].to_f
# 緯度経度が指定された範囲内にある場合のみ追加
if (include_min_lat..include_max_lat).include?(latitude) && (include_min_lng..include_max_lng).include?(longitude)
waypoint = {
"latitude" => latitude.to_s,
"longitude" => longitude.to_s,
"create_at" => line[2]
}
result.push(waypoint)
end
end
#csvそのまま表示する時の処理。
# else
# result = []
# data.each do |line|
# waypoint = {
# "latitude" => line[0],
# "longitude" => line[1],
# "create_at" => line[2]
# }
# result.push(waypoint)
# end
end
else
result = getDataFromDatabase(zekken_number, event_code)
end
# p "result: #{result}"
result2 = {"status" => "OK"}
result2["detail"] = result
headjson
return JSON.generate(result2)
end
app.get "/fetchUserLocations" do
crossdomain
p "/getRoute"
p "params : #{params}"
zekken_number = params["zekken_number"]
event_code = params["event_code"]
result = getDataFromDatabase(zekken_number, event_code)
headjson
return JSON.generate(result)
end
app.get "/generate_route_image" do
begin
crossdomain
headjson
p "/generate_route_image"
p "params : #{params}"
event_code = params["event_code"]
zekken_number = params["zekken_number"]
# データの取得
gps_data = getGpsList(zekken_number, event_code)
p "GPS data: #{gps_data}"
if gps_data.empty?
return JSON.generate({"status" => "ERROR", "detail" => "No GPS data found for this participant"})
end
# イベントの範囲を取得
bounds = get_lat_lng_bounds_for_event_code(event_code)
p "Bounds: #{bounds}"
# 画像生成
image = generate_route_image(gps_data, bounds)
# 画像の保存
filename = "route_#{event_code}_#{zekken_number}_#{Time.now.strftime("%Y%m%d%H%M%S")}.png"
save_path = "#{set_commonbase()}/#{event_code}/route_images/#{filename}"
# ディレクトリが存在しない場合は作成
FileUtils.mkdir_p(File.dirname(save_path))
image.write(save_path)
# S3にアップロード
s3_url = s3Uploader("#{event_code}/route_images", File.dirname(save_path), filename)
return JSON.generate({"status" => "OK", "image_url" => s3_url})
rescue => e
puts "Error: #{e.message}"
puts e.backtrace.join("\n")
return JSON.generate({"status" => "ERROR", "detail" => e.message, "backtrace" => e.backtrace})
end
end
app.get "/getAllRoutes" do
crossdomain
p "/getAllRoutes"
p "params : #{params}"
event_code = params["event_code"]
class_name_param = params["class_name"] # class_name パラメータの取得
class_name = class_name_param unless class_name_param.nil? || class_name_param.empty? || class_name_param == "全て"
@pgconn = UserPostgres.new
dbname = set_dbname()
@pgconn.connectPg("localhost", "mobilous", 0, dbname)
anytable = UserPostgresTable.new
anytable.useTable(@pgconn, 'gps_detail_for_animation')
# class_name が指定されている場合は、それをクエリの条件に含める
class_condition = class_name ? "AND class_name = '#{class_name}'" : ""
result = {}
zekken_list = anytable.find2("event_code = '#{event_code}' #{class_condition} ORDER BY zekken_number")
.map { |rec| rec["zekken_number"] }.uniq
zekken_list.each do |zekken_number|
team_name = get_team_name(zekken_number, event_code)
input_file = "#{set_commonbase}/#{event_code}/#{zekken_number}/waypoints.csv"
route_data = []
if File.exist?(input_file) && event_code != '大垣2'
CSV.foreach(input_file) do |line|
waypoint = {
"latitude" => line[0],
"longitude" => line[1],
"create_at" => line[2],
"team_name" => team_name
# class_name はここでは不要なので追加しない
}
route_data << waypoint
end
else
where = "zekken_number = '#{zekken_number}' AND event_code = '#{event_code}' #{class_condition} ORDER BY serial_number"
list = anytable.find2(where)
list.each do |rec|
waypoint = rec.merge("team_name" => team_name) # ここでもclass_nameは不要
route_data << waypoint
end
end
result[zekken_number] = route_data
end
@pgconn.disconnect
result2 = {"status" => "OK", "detail" => result}
headjson
return JSON.generate(result2)
end
app.get "/getStartPoint" do
crossdomain
headjson
p "getStartPoint"
p "params : #{params}"
event_code = params['event']
result = getCPlatlngByCPnumber(-2, event_code)
if result["status"] == "no cp error" then
return JSON.generate({"status" => "ERROR", "detail" => "no such cp"})
end
return JSON.generate(result)
end
app.get "/get_ranking" do
crossdomain
p "get_ranking"
p "params : #{params}"
class_name = params["class"]
event_code = params["event"]
@pgconn=UserPostgres.new
dbname = set_dbname()
@pgconn.connectPg("localhost","mobilous",0,dbname)
anytable=UserPostgresTable.new
anytable.useTable( @pgconn,'ranking_fix' )
where = "class_name = '#{class_name}' AND event_code ='#{event_code}' ORDER BY point DESC"
list = anytable.find2(where)
result = []
list.each { |rec|
result.push(rec)
}
@pgconn.disconnect
headjson
return JSON.generate(result)
end
app.get "/all_ranking_top3" do
crossdomain
headjson
p "/all_ranking_top3"
p "params : #{params}"
event_code = params["event"]
class_list = ['3時間一般','3時間ファミリー','3時間自転車','3時間ソロ男子','3時間ソロ女子','3時間パラロゲ','3時間無料','5時間一般','5時間ファミリー','5時間自転車','5時間ソロ男子','5時間ソロ女子']
class_map = {'3時間一般'=>'一般-3時間','3時間ファミリー'=>'ファミリー-3時間','3時間自転車'=>'自転車-3時間','3時間ソロ男子'=>'ソロ男子-3時間','3時間ソロ女子'=>'ソロ女子-3時間','3時間パラロゲ'=>'パラロゲ-3時間','3時間無料'=>'お試し-3時間','5時間一般'=>'一般-5時間','5時間ファミリー'=>'ファミリー-5時間','5時間自転車'=>'自転車-5時間','5時間ソロ男子'=>'ソロ男子-5時間','5時間ソロ女子'=>'ソロ女子-5時間'}
result_hash = {}
@pgconn=UserPostgres.new
dbname = set_dbname()
@pgconn.connectPg("localhost","admin",0,dbname)
anytable=UserPostgresTable.new
anytable.useTable( @pgconn,'ranking_fix' )
class_list.each{ |class_name|
alternative = class_map[class_name]
where = "(class_name = '#{class_name}' or class_name = '#{alternative}') AND event_code = '#{event_code}' ORDER BY point DESC"
list = anytable.find2(where)
result = []
count = 0
list.each { |rec|
count += 1
result.push(rec)
if count == 3 then
break
end
}
result_hash[class_name] = result
}
@pgconn.disconnect
return JSON.generate(result_hash)
end
app.get "/analyze_point" do
crossdomain
headjson
p "/analyze_point"
p "params : #{params}"
lat = params["lat"].to_f
lng = params["lng"].to_f
team_name = params["team_name"]
event_code = params["event_code"]
zekken_number = getZekkenNumberByTeamName(team_name, event_code)
if zekken_number == "no zekken number" then
return JSON.generate({"status" => "ERROR", "detail" => "該当するチーム名が存在しません。the team name is not exist."})
end
gps_data = getGpsList(zekken_number, event_code)
# 最も近い地点を見つける
closest_point = gps_data.min_by { |point| haversine_distance(lat, lng, point['latitude'].to_f, point['longitude'].to_f) }
# 前後の点を含めた分析を行う
index = gps_data.index(closest_point)
prev_point = index > 0 ? gps_data[index - 1] : nil
next_point = index < gps_data.length - 1 ? gps_data[index + 1] : nil
# 速度と移動タイプを計算
speed, movement_type = calculate_speed_and_type(prev_point, closest_point, next_point)
# 累積距離を計算
cumulative_distance = calculate_cumulative_distance(gps_data, index)
result = {
"status" => "OK",
"latitude" => closest_point['latitude'],
"longitude" => closest_point['longitude'],
"time" => closest_point['create_at'],
"speed" => speed,
"movement_type" => movement_type,
"cumulative_distance" => cumulative_distance
}
JSON.generate(result)
end
# app.get "/all_ranking_top3_for_fcgifu" do
# crossdomain
# headjson
# p "/all_ranking_top3_for_fcgifu"
# p "params : #{params}"
# result_hash = {}
# @pgconn = UserPostgres.new
# dbname = set_dbname()
# @pgconn.connectPg("localhost", "admin", 0, dbname)
# begin
# # Get all unique event_codes
# event_code
# s = get_unique_event_codes(@pgconn)
# event_codes.each do |event_code|
# # イベントコードごとに、クラス別の上位3チームを取得
# top_users_by_class = get_top_users_by_class(@pgconn, event_code)
# result_hash[event_code] = top_users_by_class
# end
# @pgconn.disconnect
# return JSON.generate(result_hash)
# rescue StandardError => e
# @pgconn.disconnect if @pgconn
# return JSON.generate({ error: e.message, backtrace: e.backtrace })
# end
# end
app.get "/all_ranking_for_fcgifu" do
crossdomain
headjson
p "/all_ranking_for_fcgifu"
p "params : #{params}"
result_hash = {}
@pgconn = UserPostgres.new
dbname = set_dbname()
@pgconn.connectPg("localhost", "admin", 0, dbname)
begin
# Get all unique event_codes
event_codes = get_unique_event_codes(@pgconn)
event_codes.each do |event_code|
# イベントコードごとに、全ユーザーを取得
all_users_by_class = get_all_users_by_class(@pgconn, event_code)
# 各クラスの全ユーザーのルート情報を取得
all_users_by_class.each do |class_name, users|
users.each do |user|
user["route"] = get_user_route(@pgconn, event_code, user["zekken_number"])
end
end
result_hash[event_code] = all_users_by_class
end
@pgconn.disconnect
return JSON.generate(result_hash)
rescue StandardError => e
@pgconn.disconnect if @pgconn
return JSON.generate({ error: e.message, backtrace: e.backtrace })
end
end
app.get "/all_ranking_top3_for_fcgifu" do
crossdomain
headjson
p "/all_ranking_top3_for_fcgifu"
p "params : #{params}"
result_hash = {}
@pgconn = UserPostgres.new
dbname = set_dbname()
@pgconn.connectPg("localhost", "admin", 0, dbname)
begin
# Get all unique event_codes
event_codes = get_unique_event_codes(@pgconn)
event_codes.each do |event_code|
# イベントコードごとに、クラス別の上位3チームを取得
top_users_by_class = get_top_users_by_class(@pgconn, event_code)
# 各クラスの上位ユーザーのルート情報を取得
top_users_by_class.each do |class_name, users|
users.each do |user|
user["route"] = get_user_route(@pgconn, event_code, user["zekken_number"])
end
end
result_hash[event_code] = top_users_by_class
end
@pgconn.disconnect
return JSON.generate(result_hash)
rescue StandardError => e
@pgconn.disconnect if @pgconn
return JSON.generate({ error: e.message, backtrace: e.backtrace })
end
end
##移動経路出力
app.get "/top_users_routes" do
crossdomain
headjson
event_code = params['event_code']
class_name = params['class_name']
@pgconn = UserPostgres.new
dbname = set_dbname()
@pgconn.connectPg("localhost", "mobilous", 0, dbname)
routes = get_top_users_routes(@pgconn, event_code, class_name)
bounds = get_lat_lng_bounds_for_event_code(event_code)
processed_routes = {}
routes.each do |zekken_number, route_data|
processed_routes[zekken_number] = process_route_data(route_data, bounds)
end
@pgconn.disconnect
JSON.generate({
status: "OK",
routes: processed_routes
})
end
#====================================
# rogaining simulator API
#====================================
app.get "/getCheckpointList" do
crossdomain
headjson
p "/getCheckpointList"
p "params : #{params}"
event_code = params['event']
return JSON.generate(getCheckpointList(event_code))
end
app.get "/rogainingSimulator" do
crossdomain
headjson
p "/rogainingSimulator"
p "params : #{params}"
begin
event_code = params["event_code"].to_s
course_time = params["course_time"].to_i
pause_time_free = params["pause_time_free"].to_i
pause_time_paid = params["pause_time_paid"].to_i
spare_time = params["spare_time"].to_i
target_velocity = params["target_velocity"].to_f
p "target_velocity : #{target_velocity}"
rescue => e
p e
return JSON.generate({"status" => "error", "detail" => "Invalid arguments provided."})
end
begin
free_node_to_visit = params["free_node_to_visit"].scan(/\d+/).map(&:to_i)
rescue => e
p e
free_node_to_visit = []
end
begin
paid_node_to_visit = params["paid_node_to_visit"].scan(/\d+/).map(&:to_i)
rescue => e
p e
paid_node_to_visit = []
end
simResult = rogainingSimulator(event_code, course_time, pause_time_free, pause_time_paid, spare_time, target_velocity, free_node_to_visit, paid_node_to_visit)
if (simResult["status"] == "ERROR") then
return JSON.generate({"status" => "ERROR", "detail" => simResult["detail"]})
end
# return JSON.generate(simResult) # まずは仮に
cp_list = simResult["detail"]["route"]
if cp_list[1].to_i == 0 then
return JSON.generate({"status" => "ERROR", "detail" => "Could not find the optimal route."})
end
userId = getMaxUserNumByRSR(event_code).to_i + 1
cp_list.shift #頭の0を除去
response_cp_list = []
inputRogSimRecord(userId,event_code,-2)
result = getCPlatlngByCPnumber(-2,event_code)
if result["status"] == "no cp error" then
return JSON.generate({"status" => "ERROR", "detail" => "no cp error"})
end
response_cp_list.push("latitude" => result["record"]["latitude"], "longitude" => result["record"]["longitude"])
cp_list.each do |n|
if n.to_i == 0 then
inputRogSimRecord(userId,event_code,-1)
result = getCPlatlngByCPnumber(-1,event_code)
if result["status"] == "no cp error" then
return JSON.generate({"status" => "ERROR", "detail" => "no cp error"})
end
response_cp_list.push("latitude" => result["record"]["latitude"], "longitude" => result["record"]["longitude"])
else
inputRogSimRecord(userId,event_code,n.to_i)
result = getCPlatlngByCPnumber(n.to_i,event_code)
if result["status"] == "no cp error" then
return JSON.generate({"status" => "ERROR", "detail" => "no cp error"})
end
response_cp_list.push("latitude" => result["record"]["latitude"], "longitude" => result["record"]["longitude"])
end
end
# return JSON.generate({"status" => "OK", "detail" => response_cp_list}) #仮2
begin
file_address = makeRogSimResultSheet(userId,event_code)
rescue => e
p e
return JSON.generate({"status" => "ERROR", "detail" => "Failed to generate the result data."})
end
if file_address == "no data error" then
return JSON.generate({"status" => "ERROR", "detail" => "Failed to generate the result data."})
end
return JSON.generate({"status" => "OK", "cp_list" => response_cp_list, "address" => file_address})
end
#====================================
# checkin admin API
#====================================
app.get "/getCheckinList" do
crossdomain
headjson
p "/getCheckinList"
p "params : #{params}"
zekken = params["zekken"]
event_code = params["event"]
@pgconn=UserPostgres.new
dbname = set_dbname()
@pgconn.connectPg("localhost","mobilous",0,dbname)
anytable=UserPostgresTable.new
anytable.useTable( @pgconn,'gps_detail_fix' )
where = "zekken_number = '#{zekken}' AND event_code = '#{event_code}' ORDER BY serial_number"
list = anytable.find2(where)
result = []
list.each { |rec|
result.push(rec)
}
@pgconn.disconnect
result2 = {}
result2 = {"status" => "OK"}
result2["detail"] = result
return JSON.generate(result2)
end
# app.delete "/deleteCheckin" do
app.get "/deleteCheckin" do # deleteではCORSpolisyのエラーが出るため
crossdomain
headjson
p "/deleteCheckin"
p "params : #{params}"
zekken = params["zekken"]
event_code = params["event"]
sn = params["sn"]
command = "DELETE #{sn}"
result = deleteRegister('API', zekken, event_code, command, nil, nil, true)
if result == "delete error" then
return JSON.generate({"status" => "error"})
end
return JSON.generate({"status" => "OK"})
end
app.get "/moveCheckin" do # patchではCORSpolisyのエラーが出るため
crossdomain
headjson
p "/moveCheckin"
p "params : #{params}"
zekken = params["zekken"]
event_code = params["event"]
old_sn = params["old_sn"]
new_sn = params["new_sn"]
command = "MOVE #{old_sn} #{new_sn}"
result = moveRegister('API', zekken, event_code, command, nil, nil, true)
if (checkAgentFlag(zekken, event_code) == false) then
inputAgentFlag(zekken, event_code, 'checkinAdmin')
end
if result == 'OK' then
return JSON.generate({"status" => "OK"})
end
return JSON.generate({"status" => "error", "detail" => result})
end
app.get "/startCheckin" do
crossdomain
headjson
p "/startCheckin"
p "params : #{params}"
event_code = params["event"]
zekken_number = params["zekken"]
#FC岐阜コラボの時に、スタート時にチェックイン情報が全削除されないようにする
# removeAllGI(zekken_number, event_code)
inputCPnumber(zekken_number,event_code,-2,set_originbase() + '/start.png')
#bonus_point_flagにデータがあったらポイント追加
# if (checkBonusPointFlag(zekken_number, event_code) == true) then
# inputCPnumber(zekken_number,event_code,102,set_originbase() + '/start.png')
# end
# if (checkAgentFlag(zekken_number, event_code) == false) then
# inputAgentFlag(zekken_number, event_code, agent_id)
# end
return JSON.generate({"status" => "OK"})
end
app.get "/addCheckin" do
crossdomain
headjson
p "/addCheckin"
p "params : #{params}"
event_code = params["event"]
zekken_number = params["zekken"]
checkin_list = params["list"]
errorAr = []
checkinArr = checkin_list.split(',')
checkinArr.each { |cp_number|
if cp_number != "" then
if cp_number == "no cp error" then
errorAr.push(cp_number)
elsif cpDoubleCheck(zekken_number, event_code, cp_number) then
errorAr.push(cp_number)
elsif getCPname(cp_number, event_code) == "no cp error" then
errorAr.push(cp_number)
else
inputCPnumber(zekken_number,event_code,cp_number,set_originbase() + '/photo_none.png')
end
end
}
if (checkAgentFlag(zekken_number, event_code) == false) then
inputAgentFlag(zekken_number, event_code, 'checkinAdmin')
end
if errorAr == [] then
return JSON.generate({"status" => "OK"})
else
return JSON.generate({"status" => "not best", "detail" => errorAr.join(',')})
end
end
app.get "/goalCheckin" do
crossdomain
headjson
p "/goalCheckin"
p "params : #{params}"
event_code = params["event"]
zekken_number = params["zekken"]
goal_time = params['goal_time']
begin
goaltime = Time.parse(goal_time)
rescue => error
p error
return JSON.generate({"status" => "ERROR", "detail" => "ゴール時間のパースに失敗しました。Goal time parsing failed."})
end
result = getTeamDataByZekken_number(zekken_number, event_code)
starttime = Time.parse(getEventStartTime(event_code))
if result['class_name'].include?('3時間') then
limittime = starttime + (3 * 60 * 60)
elsif result['class_name'].include?('5時間') then
limittime = starttime + (5 * 60 * 60)
#else
elsif result['class_name'].include?("テスト") || result['class_name'].include?("test") then
limittime = starttime + (5 * 60 * 60)
else
message = {
type: 'text',
text: 'エラーコードDBS-001\nチーム情報の取得に失敗しました。\nゼッケン番号とこのエラーコードを添えて運営に問い合わせて下さい。'
}
client.reply_message(event['replyToken'], message)
chatLogger(userId, 'bot', 'text', 'DBS-001\nチーム情報の取得に失敗しました\nゼッケン番号とこのエラーコードを添えて運営に問
')
return JSON.generate({"status" => "NG"})
end
if limittime < goaltime then
late_point = goaltime - limittime
if late_point < 60
late_point = 50
else
late_point = late_point/60 + 1
late_point = late_point.floor*50
end
else
late_point = 0
end
inputGoalTime(zekken_number,event_code,goal_time,late_point,set_originbase() + '/photo_none.png')
Thread.new do
makeScoreboardThread(zekken_number, event_code)
end
return JSON.generate({"status" => "OK"})
end
app.post "/goal_from_rogapp" do
crossdomain
headjson
p "goal_from_rogapp"
p "params : #{params}"
event_code = params["event_code"]
zekken_number = getZekkenNumberByTeamName(params["team_name"], event_code)
if zekken_number == "no zekken number" then
return JSON.generate({"status" => "ERROR", "detail" => "該当するチーム名が存在しません。the team name is not exist."})
end
# if cpDoubleCheck(zekken_number, event_code, -1) then
# return JSON.generate({"status" => "ERROR", "detail" => "このチェックポイントは既に登録されています。the check point is already registered."})
# end
docpath = set_commonbase() + '/' + event_code + '/' + zekken_number
docpath2 = set_commonbase2() + '/' + event_code + '/' + zekken_number
if( !Dir.exist?(docpath) )then
Dir.mkdir( docpath, 0755 )
end
filename = params['image'].split('/').last
if filename.to_s.empty?
return JSON.generate({"status" => "ERROR", "detail" => "画像アドレスが指定されていません。Image address is not specified."})
end
fullpath = docpath + '/' + filename
begin
url = params['image']
encoded_url = URI::DEFAULT_PARSER.escape(url)
puts "uri=#{encoded_url}"
URI.open(encoded_url) do |image|
File.open(fullpath, 'w') do |file|
file.write(image.read)
end
end
rescue => e
p e
return JSON.generate({"status" => "ERROR", "detail" => "写真の保存に失敗しました。Failed to save photo."})
end
fullpath2 = s3Uploader("#{event_code}/#{zekken_number}", docpath, filename)
extension = filename.split('.').last
filenameTh = filename.gsub(".#{extension}", "_th.#{extension}")
imageOri = Magick::Image.read(fullpath).first
imageTh = imageOri.scale(image_size_width(), image_size_height())
imageTh.write("temp/#{filenameTh}")
nextpath = docpath + '/' + filenameTh
FileUtils.mv("/var/www/temp/#{filenameTh}", nextpath)
goal_time = params['goal_time']
begin
goaltime = Time.parse(goal_time)
rescue => error
p error
return JSON.generate({"status" => "ERROR", "detail" => "ゴール時間のパースに失敗しました。Goal time parsing failed."})
end
result = getTeamDataByZekken_number(zekken_number, event_code)
starttime = Time.parse(getEventStartTime(event_code))
if result['class_name'].include?('3時間') || result['class_name'].include?('3時間')
limittime = starttime + (3 * 60 * 60)
elsif result['class_name'].include?('5時間') || result['class_name'].include?('5時間')
limittime = starttime + (5 * 60 * 60)
elsif result['class_name'].include?("テスト") || result['class_name'].include?("test")
limittime = starttime + (5 * 60 * 60)
else
return JSON.generate({
"status" => "ERROR",
"detail" => "不明なクラス名です: #{result['class_name']}。運営に問い合わせてください。"
})
end
puts "limittime=#{limittime} , goaltime=#{goaltime}"
if limittime < goaltime then
late_point = goaltime - limittime
if late_point < 60
late_point = 50
else
late_point = late_point/60 + 1
late_point = late_point.floor*50
end
else
late_point = 0
end
inputGoalTime(zekken_number, event_code, goal_time, late_point, fullpath2)
begin
scoreboard_result = makeScoreboard(zekken_number, event_code)
if scoreboard_result
# S3のURLを使用
s3_url = scoreboard_result
# ダウンロード用のURLを生成
download_url = "/gifuroge/download_scoreboard?event_code=#{event_code}&zekken_number=#{zekken_number}"
return JSON.generate({
"status" => "OK",
"scoreboard_url" => s3_url,
"download_url" => download_url
})
else
return JSON.generate({
"status" => "OK",
"detail" => "スコアボードの生成に失敗しました。Failed to generate scoreboard."
})
end
rescue => e
p e
return JSON.generate({
"status" => "ERROR",
"detail" => "スコアボード生成中にエラーが発生しました: #{e.message}"
})
end
end
# 新しいダウンロードエンドポイント(必要に応じて追加)
app.get "/download_scoreboard" do
event_code = params["event_code"]
zekken_number = params["zekken_number"]
file_path = "#{set_commonbase()}/#{event_code}/scoreboard/#{zekken_number}_scoreboard.pdf"
if File.exist?(file_path)
send_file(file_path, :filename => "scoreboard_#{zekken_number}.pdf", :type => 'application/pdf')
else
status 404
"File not found"
end
end
app.get "/changeGoalTimeCheckin" do
crossdomain
headjson
p "changeGoalTimeCheckin"
p "params : #{params}"
event_code = params["event"]
zekken_number = params["zekken"]
goal_time = params['goal_time']
begin
goaltime = Time.parse(goal_time)
rescue => error
p error
return JSON.generate({"status" => "ERROR", "detail" => "ゴール時間のパースに失敗しました。Goal time parsing failed."})
end
result = getTeamDataByZekken_number(zekken_number, event_code)
starttime = Time.parse(getEventStartTime(event_code))
if result['class_name'].include?('3時間') then
limittime = starttime + (3 * 60 * 60)
elsif result['class_name'].include?('5時間') then
limittime = starttime + (5 * 60 * 60)
elsif result['class_name'].include?("テスト") || result['class_name'].include?("test") then
#else
limittime = starttime + (5 * 60 * 60)
else
message = {
type: 'text',
text: 'エラーコードDBS-001\nチーム情報の取得に失敗しました。\nゼッケン番号とこのエラーコードを添えて運営に問い合わせて下さい。'
}
client.reply_message(event['replyToken'], message)
chatLogger(userId, 'bot', 'text', 'DBS-001\nチーム情報の取得に失敗しました\nゼッケン番号とこのエラーコードを添えて運営に問
')
return JSON.generate({"status" => "NG"})
end
if limittime < goaltime then
late_point = goaltime - limittime
if late_point < 60
late_point = 50
else
late_point = late_point/60 + 1
late_point = late_point.floor*50
end
else
late_point = 0
end
changeGoalTimeAndLatePoint(zekken_number, event_code, goal_time, late_point)
return JSON.generate({"status" => "OK"})
end
app.get "/reprint" do
crossdomain
headjson
p "reprint"
p "params : #{params}"
event_code = params["event"]
zekken_number = params["zekken"]
Thread.new do
makeScoreboardThread(zekken_number, event_code, "true")
end
return JSON.generate({"status" => "OK"})
end
app.get "/serviceCheckTrue" do
crossdomain
headjson
p "serviceCheckTrue"
p "params : #{params}"
event_code = params["event"]
zekken_number = params["zekken"]
serial_number = params["sn"]
result = addBuyFlagTrue(serial_number, zekken_number, event_code)
if result == "OK" then
return JSON.generate({"status" => "OK"})
else
return JSON.generate({"status" => "ERROR"})
end
end
app.get "/serviceCheckFalse" do
crossdomain
headjson
p "serviceCheckFalse"
p "params : #{params}"
event_code = params["event"]
zekken_number = params["zekken"]
serial_number = params["sn"]
result = addBuyFlagFalse(serial_number, zekken_number, event_code)
if result == "OK" then
return JSON.generate({"status" => "OK"})
else
return JSON.generate({"status" => "ERROR"})
end
end
app.get "/getYetCheckSeeviceList" do
crossdomain
headjson
p "getYetCheckSeeviceList"
p "params : #{params}"
event_code = params["event"]
@pgconn=UserPostgres.new
dbname = set_dbname()
@pgconn.connectPg("localhost","mobilous",0,dbname)
anytable=UserPostgresTable.new
anytable.useTable( @pgconn,'gps_detail_fix' )
where = "event_code = '#{event_code}' AND origin_buy_point != 0 ORDER BY create_at DESC"
#where = "event_code = '#{event_code}' AND buy_flag = false ORDER BY create_at DESC"
list = anytable.find2(where)
result = []
list.each { |rec|
result.push(rec)
}
@pgconn.disconnect
result2 = {}
result2 = {"status" => "OK"}
result2["detail"] = result
return JSON.generate(result2)
end
#====================================
# 登録周り API
#====================================
app.post "/register_team" do
crossdomain
headjson
p "/register_team"
p "params : #{params}"
zekken_number = params["zekken_number"]
event_code = params["event_code"]
team_name = params["team_name"]
class_name = params["class_name"]
password = params["password"]
# パラメータの値を表示
puts "Received parameters:"
puts "zekken_number: #{zekken_number.inspect}"
puts "event_code: #{event_code.inspect}"
puts "team_name: #{team_name.inspect}"
puts "class_name: #{class_name.inspect}"
puts "password: #{password.inspect}"
# 必須パラメータのチェック(修正)
missing_params = []
[
['zekken_number', zekken_number],
['event_code', event_code],
['team_name', team_name],
['class_name', class_name],
['password', password]
].each do |name, value|
missing_params << name if value.nil? || value.to_s.strip.empty?
end
if missing_params.any?
return JSON.generate({
"status" => "ERROR",
"detail" => "Missing or empty required parameters: #{missing_params.join(', ')}"
})
end
# データベース接続
@pgconn = UserPostgres.new
dbname = set_dbname()
@pgconn.connectPg("localhost", "mobilous", 0, dbname)
# team_tableの取得
team_table = UserPostgresTable.new
team_table.useTable(@pgconn, 'team_table')
# 既存のチームをチェック
existing_team = team_table.findOne("zekken_number = '#{zekken_number}' AND event_code = '#{event_code}'")
if existing_team
@pgconn.disconnect
return JSON.generate({
"status" => "ERROR",
"detail" => "Team with this zekken number and event code already exists"
})
end
# 新しいチームの登録
record = {
"zekken_number" => zekken_number,
"event_code" => event_code,
"team_name" => team_name,
"class_name" => class_name,
"password" => password
}
begin
sql = team_table.makeInsertKeySet(record.keys, record)
puts "Executing SQL: #{sql}" # SQLクエリをログ出力
result = team_table.insertExec(sql)
if result
@pgconn.disconnect
return JSON.generate({"status" => "OK", "detail" => "Team registered successfully"})
else
@pgconn.disconnect
return JSON.generate({"status" => "ERROR", "detail" => "Failed to register team"})
end
rescue PG::UniqueViolation
@pgconn.disconnect
return JSON.generate({
"status" => "ERROR",
"detail" => "Team with this zekken number and event code already exists"
})
rescue => error
p error
@pgconn.disconnect
return JSON.generate({"status" => "ERROR", "detail" => "Database error: #{error.message}"})
end
end
app.post "/update_team_name" do
crossdomain
headjson
p "/update_team_name"
p "params : #{params}"
zekken_number = params["zekken_number"]
new_team_name = params["new_team_name"]
event_code = params["event_code"]
# 必須パラメータのチェック
if [zekken_number, new_team_name, event_code].any?(&:nil?)
return JSON.generate({"status" => "ERROR", "detail" => "Missing required parameters"})
end
@pgconn = UserPostgres.new
dbname = set_dbname()
@pgconn.connectPg("localhost", "mobilous", 0, dbname)
rec = {"team_name" => new_team_name}
where = "zekken_number = '#{zekken_number}' AND event_code = '#{event_code}'"
begin
result = @pgconn.update("team_table", rec, where)
if result
@pgconn.disconnect
return JSON.generate({"status" => "OK", "detail" => "Team name updated successfully"})
else
@pgconn.disconnect
return JSON.generate({"status" => "ERROR", "detail" => "Failed to update team name or no matching record found"})
end
rescue => error
p error
@pgconn.disconnect
return JSON.generate({"status" => "ERROR", "detail" => "Database error: #{error.message}"})
end
end
app.post '/input_cp' do
content_type :json
request.body.rewind
data = JSON.parse(request.body.read)
zekken_number = data['zekken_number']
event_code = data['event_code']
cp_number = data['cp_number']
image_address = data['image_address']
result = inputCPnumber(zekken_number, event_code, cp_number, image_address)
status 200
{ result: result }.to_json
end
#====================================
# chatLogViewer API
#====================================
app.get "/get_chatlog" do
crossdomain
headjson
p "get_chatlog"
p "params : #{params}"
event_code = params["event"]
zekken_number = params["zekken"]
userid = getUserIdByZekkenNumber(zekken_number, event_code)
if userid == "no zekken number" then
return JSON.generate({"status" => "ERROR", "detail" => "該当するユーザーを発見出来ませんでした"})
end
user_name = getUserName(userid)["user_name"]
@pgconn=UserPostgres.new
dbname = set_dbname()
@pgconn.connectPg("localhost","mobilous",0,dbname)
anytable=UserPostgresTable.new
anytable.useTable( @pgconn,'chat_log' )
where = "userid = '#{userid}' ORDER BY serial_number DESC"
list = anytable.find2(where)
result = []
list.each { |rec|
result.push(rec)
}
@pgconn.disconnect
result2 = {}
result2 = {"status" => "OK"}
result2["detail"] = result
result2["name"] = user_name
return JSON.generate(result2)
end
#====================================
# user admin API
#====================================
app.get "/teamRegister" do
crossdomain
headjson
p "/teamRegister"
p "params : #{params}"
event = params["event"]
class_name = params["class"]
zekken = params["zekken"]
team = params["team"]
pass = params["pass"]
inputTeamData(event,class_name,zekken,team,pass)
return JSON.generate({"status" => "OK"})
end
app.get "/zekkenMaxNum" do
crossdomain
headjson
p "/zekkenMaxNum"
p "params : #{params}"
event = params["event"]
list = getZekkenListByTT(event)
numList = []
list.each do |rec|
numList.push(rec.split('-')[1].to_i)
end
result = numList.max
if result == nil then
result = 0
end
return JSON.generate({"status" => "OK", "result" => result})
end
app.get "/zekkenDoubleCheck" do
crossdomain
headjson
p "/zekkenDoubleCheck"
p "params : #{params}"
zekken = params['zekken']
event = params['event']
list = getZekkenListByTT(event)
result = false
list.each do |rec|
if rec == zekken then
result = true
break
end
end
return JSON.generate({"status" => "OK", "result" => result})
end
app.get "/teamClassChanger" do
crossdomain
headjson
p "/teamClassChanger"
p "params : #{params}"
zekken = params['zekken']
event = params['event']
new_class = params['new_class']
result = changeTeamClass(zekken, event, new_class)
return JSON.generate({"status" => result})
end
#====================================
# CP一覧シート作成用API
#====================================
app.post "/makeCpListSheet" do
crossdomain
p "/makeCpListSheet"
p "params : #{params}"
event_code = params["event"]
cp_csv = params["cp_csv"]
sponsor_csv = params["sponsor_csv"]
insert_record = {}
insert_header = []
event_data = getEventData(event_code)
insert_header.push("event_name")
insert_record["event_name"] = event_data["event_name"]
insert_header.push("event_day")
insert_record["event_day"] = event_data["event_day"]
i = 1
CSV.foreach(cp_csv[:tempfile], headers: true) do |row|
#puts "row=#{row}"
if row["sub_loc_id"].to_s.start_with?('#-1') then
next
end
insert_header.push("sub_loc_id_#{i}")
insert_record["sub_loc_id_#{i}"] = row["sub_loc_id"]
insert_header.push("loc_name_#{i}")
insert_record["loc_name_#{i}"] = row["loc_name"]
insert_header.push("photo_#{i}")
insert_record["photo_#{i}"] = "#{set_commonbase()}/#{event_code}/cps/#{row["photos"]}"
insert_header.push("remark_#{i}")
insert_record["remark_#{i}"] = row["remark"]
insert_header.push("tags_#{i}")
insert_record["tags_#{i}"] = row["tags"]
i = i + 1
end
CSV.foreach(sponsor_csv[:tempfile], headers: true) do |row|
for ii in 1..30 do
if row["sponsor_#{ii}"] != nil && row["sponsor_#{ii}"] != "" then
insert_header.push("sponsor_#{ii}")
insert_record["sponsor_#{ii}"] = row["sponsor_#{ii}"]
end
end
end
sn = getMaxNumByCLS().to_i + 1
insert_header.push("serial_number")
insert_record["serial_number"] = sn
#p "insert_header : #{insert_header}"
#p "insert_record : #{insert_record}"
inputCpListSheet(insert_header, insert_record)
#ここから用紙生成プロセス
#$bean.read_bean
#username = $bean.username
username = "natnats"
record = insert_record
record["num_image"] = i + 1
document = "cpListSheet"
ExcelObject.resetClass
doc = AppExeExcelDoc.new
#doc = AppExeGeneralDocument.new
#doc.init( username,0,document,"jp","/var/www/docbase","/home/mobilousInstance" ) # <== "/home/mobilousInstance" を出力先のベースフォルダーにしてください。
doc.init( username,0,document,"jp","/var/www/docbase","/home/ubuntu" ) # <== "/home/mobilousInstance" を出力先のベースフォルダーにしてください。
pgconn=UserPostgres.new
dbname = set_dbname()
pgconn.connectPg("localhost","mobilous",0,dbname)
rec = JSON.parse( JSON.generate(record) )
#@sheetname = sheet
#filename = doc.makeReport( pgconn,rec,"outfile.xlsx",0 ) # ==> Use ini file defnition 2021-11-15
doc.makeReport( pgconn,rec )
# make a excel file under /var/www/docbase/(@username)/(@projectno)/
#file_path = filename.to_s.gsub(/wrote excel file on /,"")
#puts "=========> file_path = #{file_path}"
filename = doc.outfile
file_path = doc.outpath
puts "=========> file_path = #{file_path}, filename = #{filename}"
content_type "application/xlsx"
attachment "#{file_path}"
send_file(file_path, :filename => "cpListSheet_#{event_code}.xlsx",:type => "application/xlsx", :disposition => 'attachment')
end
#====================================
# 手動呼び出し用API
#====================================
app.get "/makeAllScoreboard" do
crossdomain
headjson
p "/makeAllScoreboard"
p "params : #{params}"
event_code = params["event"]
zekken_list = getZekkenListByTT(event_code)
if zekken_list == nil || zekken_list == [] then
return JSON.generate({"status" => "ERROR", "detail" => "no zekkens"})
end
complete_list = {}
fail_list = []
error_list = {}
zekken_list.each do |zekken|
begin
p "zekken : #{zekken}"
result = makeScoreboardThread(zekken, event_code, false, true)
if result == "no data erropr" then
fail_list.push(zekken)
else
complete_list[zekken] = result
end
rescue => e
p e
error_list[zekken] = e
end
end
return JSON.generate({"complete" => complete_list, "fail" => fail_list, "error" => error_list})
end
#====================================
# rog app API
#====================================
app.post "/start_from_rogapp" do
p "/start_from_rogapp"
crossdomain
headjson
p "start_from_rogapp"
p "params : #{params}"
event_code = params["event_code"]
zekken_number = getZekkenNumberByTeamName(params["team_name"], event_code)
if zekken_number == "no zekken number" then
return JSON.generate({"status" => "ERROR", "detail" => "該当するチーム名が存在しません。the team name is not exist."})
end
#FC岐阜コラボの時はスタートでチェックポイントを削除しないように(同じルートを別日に回ることがあるため)
# removeAllGI(zekken_number, event_code)
inputCPnumber(zekken_number,event_code,-2,set_originbase() + '/start.png')
# # bonus_point_flagにデータがあったらポイント追加
# if checkBonusPointFlag(zekken_number, event_code)
# inputCPnumber(zekken_number, event_code, 102, set_originbase() + '/start.png')
# end
return JSON.generate({"status" => "OK"})
end
app.get "/practice" do
crossdomain
headjson
practice_text = "practice"
return practice_text
end
app.post "/checkin_from_rogapp" do
crossdomain
headjson
p "checkin_from_rogapp"
p "params : #{params}"
event_code = params["event_code"]
zekken_number = getZekkenNumberByTeamName(params["team_name"], event_code)
# ディレクトリパスの構築
base_path = "/var/www/html/images/gifuRoge"
full_path = File.join(base_path, event_code, zekken_number.to_s)
# ディレクトリの作成(既に存在する場合は何もしない)
begin
FileUtils.mkdir_p(full_path) unless File.directory?(full_path)
rescue Errno::EACCES => e
puts "エラー: ディレクトリ作成の権限がありません。 #{e.message}"
return JSON.generate({"status" => "ERROR", "detail" => "サーバー内部エラー:ディレクトリ作成の権限がありません。"})
rescue => e
puts "エラー: ディレクトリ作成中に問題が発生しました。 #{e.message}"
return JSON.generate({"status" => "ERROR", "detail" => "サーバー内部エラー:ディレクトリ作成中に問題が発生しました。"})
end
if zekken_number == "no zekken number" then
return JSON.generate({"status" => "ERROR", "detail" => "該当するチーム名が存在しません。the team name is not exist."})
end
cp_number = params["cp_number"]
if cp_number.to_i == -1 || cp_number.to_i == -2 then
return JSON.generate({"status" => "ERROR", "detail" => "スタートやゴールをチェックインする時はそれぞれ専用のAPIを使ってチェックインしてください。When checking in for the start or finish, please use the respective dedicated API to check in."})
end
if cpDoubleCheck(zekken_number, event_code, cp_number) then
return JSON.generate({"status" => "ERROR", "detail" => "このチェックポイントは既に登録されています。the check point is already registered."})
end
docpath = set_commonbase() + '/' + event_code + '/' + zekken_number
docpath2 = set_commonbase2() + '/' + event_code + '/' + zekken_number
if( !Dir.exist?(docpath) )then
if( Dir.mkdir( docpath,0755 ) == 0 ) then
end
end
filename = params['image'].split('/').last
if filename == '' || filename == nil then
return JSON.generate({"status" => "ERROR", "detail" => "画像アドレスが指定されていません。Image address is not specified."})
end
fullpath = docpath + '/' + filename
begin
url = params['image']
encoded_url = URI::DEFAULT_PARSER.escape(url)
puts "uri=#{encoded_url}"
URI.open(encoded_url) do |image|
File.open(fullpath, 'w') do |file|
file.write(image.read)
end
end
rescue => e
p e
return JSON.generate({"status" => "ERROR", "detail" => "写真の保存に失敗しました。Failed to save photo."})
end
fullpath2 = s3Uploader("#{event_code}/#{zekken_number}",docpath,filename)
extension = filename.split('.').last
filenameTh = filename.gsub(".#{extension}","_th.#{extension}")
imageOri = Magick::Image.read(fullpath).first
imageTh = imageOri.scale(image_size_width(), image_size_height())
imageTh.write("temp/#{filenameTh}")
nextpath = docpath + '/' + filenameTh
FileUtils.mv("/var/www/temp/#{filenameTh}",nextpath)
# File.delete(fullpath)
fullpath = fullpath2
inputCPnumber(zekken_number, event_code, cp_number, fullpath)
return JSON.generate({"status" => "OK"})
end
app.post "/remove_checkin_from_rogapp" do
crossdomain
headjson
p "remove_checkin_from_rogapp"
p "params : #{params}"
begin
event_code = params["event_code"]
zekken_number = getZekkenNumberByTeamName(params["team_name"], event_code)
if zekken_number == "no zekken number" then
return JSON.generate({"status" => "ERROR", "detail" => "該当するチーム名が存在しません。the team name is not exist."})
end
cp_number = params["cp_number"]
sn = getSerialNumberByCpNumber(zekken_number, event_code, cp_number)
if sn == 'no sn' then
return JSON.generate({"status" => "ERROR", "detail" => "該当するチェックインが見つかりません。No corresponding checkin found."})
end
command = "DELETE #{sn}"
result = deleteRegister('API', zekken_number, event_code, command, nil, nil, true)
# チェックポイントが2回登録されている場合があるための処理 ここから
sn = getSerialNumberByCpNumber(zekken_number, event_code, cp_number)
if sn != 'no sn' then
command = "DELETE #{sn}"
result = deleteRegister('API', zekken_number, event_code, command, nil, nil, true)
end
# チェックポイントが2回登録されている場合があるための処理 ここまで
return JSON.generate({"status" => "OK"})
rescue => e
return JSON.generate({"status" => "ERROR", "detail" => "予期せぬエラー undefined error #{e}"})
end
end
app.get "/get_team_list" do
crossdomain
headjson
p "get_team_list"
p "params : #{params}"
event_code = params["event_code"]
if event_code == '' then
event_code = nil
end
return JSON.generate(getTeamList(event_code))
end
#元のゴール処理。fc岐阜用に同じ名前で修正したものを別のとこに作ってます
# app.post "/goal_from_rogapp" do
# crossdomain
# headjson
# p "goal_from_rogapp"
# p "params : #{params}"
# event_code = params["event_code"]
# zekken_number = getZekkenNumberByTeamName(params["team_name"], event_code)
# if zekken_number == "no zekken number" then
# return JSON.generate({"status" => "ERROR", "detail" => "該当するチーム名が存在しません。the team name is not exist."})
# end
# # if cpDoubleCheck(zekken_number, event_code, -1) then
# # return JSON.generate({"status" => "ERROR", "detail" => "このチェックポイントは既に登録されています。the check point is already registered."})
# # end
# docpath = set_commonbase() + '/' + event_code + '/' + zekken_number
# docpath2 = set_commonbase2() + '/' + event_code + '/' + zekken_number
# if( !Dir.exist?(docpath) )then
# Dir.mkdir( docpath, 0755 )
# end
# filename = params['image'].split('/').last
# if filename.to_s.empty?
# return JSON.generate({"status" => "ERROR", "detail" => "画像アドレスが指定されていません。Image address is not specified."})
# end
# fullpath = docpath + '/' + filename
# begin
# url = params['image']
# encoded_url = URI::DEFAULT_PARSER.escape(url)
# puts "uri=#{encoded_url}"
# URI.open(encoded_url) do |image|
# File.open(fullpath, 'w') do |file|
# file.write(image.read)
# end
# end
# rescue => e
# p e
# return JSON.generate({"status" => "ERROR", "detail" => "写真の保存に失敗しました。Failed to save photo."})
# end
# fullpath2 = s3Uploader("#{event_code}/#{zekken_number}", docpath, filename)
# extension = filename.split('.').last
# filenameTh = filename.gsub(".#{extension}", "_th.#{extension}")
# imageOri = Magick::Image.read(fullpath).first
# imageTh = imageOri.scale(image_size_width(), image_size_height())
# imageTh.write("temp/#{filenameTh}")
# nextpath = docpath + '/' + filenameTh
# FileUtils.mv("/var/www/temp/#{filenameTh}", nextpath)
# goal_time = params['goal_time']
# begin
# goaltime = Time.parse(goal_time)
# rescue => error
# p error
# return JSON.generate({"status" => "ERROR", "detail" => "ゴール時間のパースに失敗しました。Goal time parsing failed."})
# end
# result = getTeamDataByZekken_number(zekken_number, event_code)
# starttime = Time.parse(getEventStartTime(event_code))
# if result['class_name'].include?('3時間') || result['class_name'].include?('3時間')
# limittime = starttime + (3 * 60 * 60)
# elsif result['class_name'].include?('5時間') || result['class_name'].include?('5時間')
# limittime = starttime + (5 * 60 * 60)
# elsif result['class_name'].include?("テスト") || result['class_name'].include?("test")
# limittime = starttime + (5 * 60 * 60)
# else
# return JSON.generate({
# "status" => "ERROR",
# "detail" => "不明なクラス名です: #{result['class_name']}。運営に問い合わせてください。"
# })
# end
# puts "limittime=#{limittime} , goaltime=#{goaltime}"
# if limittime < goaltime then
# late_point = goaltime - limittime
# if late_point < 60
# late_point = 50
# else
# late_point = late_point/60 + 1
# late_point = late_point.floor*50
# end
# else
# late_point = 0
# end
# inputGoalTime(zekken_number, event_code, goal_time, late_point, fullpath2)
# Thread.new do
# makeScoreboardThread(zekken_number, event_code)
# end
# return JSON.generate({"status" => "OK"})
# end
app.post "/get_waypoint_datas_from_rogapp" do
crossdomain
headjson
begin
p "/get_waypoint_datas_from_rogapp"
p "params : #{params}"
team_name = params["team_name"]
event_code = params["event_code"]
list = params["waypoints"]
zekken_number = getZekkenNumberByTeamName(params["team_name"],event_code)
if zekken_number == "no zekken number" then
return JSON.generate({"status" => "ERROR", "detail" => "該当するチーム名が存在しません。the team name is not exist."})
end
data = []
list.each do |rec|
line = []
line.push(rec['latitude'])
line.push(rec['longitude'])
line.push(rec['time'])
data.push(line)
end
filebase = "#{set_commonbase}/#{event_code}/#{zekken_number}"
output_file = "#{filebase}/waypoints.csv"
if (File.exist?(output_file)) then
input_data = CSV.read(output_file)
data = input_data + data
end
if (!File.exist?(filebase)) then
if( Dir.mkdir( filebase,0755 ) == 0 ) then
end
end
CSV.open(output_file, 'w') do |csv|
data.each do |row|
csv << row
end
end
return JSON.generate({"status" => "OK"})
rescue => e
p e
return JSON.generate({"status" => "ERROR", "detail" => "予期せぬエラーが発生しました。undefined error : #{e}"})
end
end
app.get "/check_event_code" do
crossdomain
headjson
p "check_event_code"
p "params : #{params}"
zekken_number = params['zekken_number']
password = params['pw']
result = zekkenAuthorization(zekken_number, password)
if result["result"] == "ERROR" then
return JSON.generate({"status" => "ERROR"})
else
return JSON.generate({"status" => "OK", "event_code" => result["event_code"]})
end
end
end
end
end