asia_database/lib/tasks/asia_database_tasks.rake

274 lines
11 KiB
Ruby
Raw Normal View History

2023-05-26 14:17:05 +00:00
require 'net/http'
require "base64"
module AsiaDatabasePlugin
InUseLocales = Site.first.in_use_locales rescue [:en,:zh_tw]
class SafeHash < Hash
attr_accessor :duplicate_check_off
def []=(key, value)
if !duplicate_check_off && has_key?(key)
super(key,Array(self[key])+[value])
else
super
end
end
end
IV = [0x12, 0x34, 0x56, 0x84, 0x9b, 0xab, 0xcd, 0xef].pack('C*')
KEY = "Tch#^837".bytes.pack('C*')
def self.localize_data(data, locales=InUseLocales)
return locales.map{|locale| [locale, data.dup] }.to_h
end
# 研究計畫 Research Grants
def self.sync_projects(query_result, asia_teacher)
email_id = asia_teacher.email_id
return if email_id.blank?
puts "Projects(Research Grants) for user: #{email_id}"
projects = query_result["research"].to_a
if !query_result['emp'].blank?
AsiaProject.where(asia_teacher: asia_teacher,:rss2_id.ne=>nil).where(:rss2_id.nin=>projects.map{|v| v["ukey"]}).destroy
end
return if projects.count == 0
projects.each do |project|
pj = AsiaProject.where(:rss2_id=> project["ukey"]).first
pj = AsiaProject.new if pj.nil?
pj.rss2_id = project["ukey"]
pj.project_name_translations = localize_data(project["name"]) #計畫名稱
# pj.sponsor =
if project["period"].present?
period = project["period"].split('~').map{|date| DateTime.parse(date) rescue nil}
pj.start_date = period[0]
pj.end_date = period[1]
else
pj.start_date = nil
pj.end_date = nil
end
pj.asia_teacher = asia_teacher
puts "Project(Research Grants) #{pj.id} saved" if pj.save
end
end
def self.sync_papers(query_result, asia_teacher) # journal and conference papers
email_id = asia_teacher.email_id
return if email_id.blank?
puts "Paper for user: #{email_id}"
journal_papers = query_result["journal"].to_a
conference_papers = query_result["conference"].to_a
papers = journal_papers + conference_papers
if !query_result['emp'].blank?
AsiaPaper.where(asia_teacher: asia_teacher,:rss2_id.ne=>nil).where(:rss2_id.nin=>papers.map{|v| v["ukey"]}).destroy
end
return if papers.count == 0
journal_papers.each do |journal_paper|
jp = AsiaPaper.where(:rss2_id=> journal_paper["ukey"]).first
jp = AsiaPaper.new if jp.nil?
jp.rss2_id = journal_paper["ukey"]
jp.paper_name_translations = localize_data(journal_paper["Thesis_name"])
jp.journal_name_translations = localize_data(journal_paper["Journal_name"])
jp.issue_year = journal_paper["Thesis_year"]
jp.asia_teacher = asia_teacher
puts "Journal Paper #{jp.id} saved" if jp.save
end
conference_papers.each do |conference_paper|
wc = AsiaPaper.where(:rss2_id=> conference_paper["ukey"]).first
wc = AsiaPaper.new if wc.nil?
wc.rss2_id = conference_paper["ukey"]
titles = conference_paper["name"].split("-")
wc.paper_name_translations = localize_data(titles[0])
wc.journal_name_translations = localize_data(titles[1..-1].join("-"))
wc.issue_year = conference_paper["Thesis_year"]
wc.asia_teacher = asia_teacher
puts "conference paper #{wc.id} saved" if wc.save
end
end
def self.sync_patents(query_result, asia_teacher) # patents
email_id = asia_teacher.email_id
return if email_id.blank?
puts "Patent for user: #{email_id}"
patents = query_result["patent"].to_a
if !query_result['emp'].blank?
AsiaPatent.where(asia_teacher: asia_teacher,:rss2_id.ne=>nil).where(:rss2_id.nin=>patents.map{|v| v["ukey"]}).destroy
end
return if patents.count == 0
patents.each do |patent|
pt = AsiaPatent.where(:rss2_id=> patent["ukey"]).first
pt = AsiaPatent.new if pt.nil?
pt.rss2_id = patent["ukey"]
pt.patent_name_translations = localize_data(patent["Patent_name"])
pt.patent_country, pt.patent_no = patent["Patent_id"].split(":") #專利國家:專利編號, ex: 中華民國設計專利:D170464
if patent["sDate"].present?
period = patent["sDate"].split('~').map{|date| DateTime.parse(date) rescue nil}
pt.certification_date = period[0]
pt.end_date = period[1]
else
pt.certification_date = nil
pt.end_date = nil
end
pt.asia_teacher = asia_teacher
puts "Patent #{pt.id} saved" if pt.save
end
end
#技術轉移 Technology transfer
def self.sync_tec_transfers(query_result, asia_teacher)
email_id = asia_teacher.email_id
return if email_id.blank?
puts "Technology transfer for user: #{email_id}"
tec_transfers = query_result["tec_transfer"].to_a
if !query_result['emp'].blank?
AsiaTecTransfer.where(asia_teacher: asia_teacher,:rss2_id.ne=>nil).where(:rss2_id.nin=>tec_transfers.map{|v| v["ukey"]}).destroy
end
return if tec_transfers.count == 0
tec_transfers.each do |tec_transfer|
tt = AsiaTecTransfer.where(:rss2_id=> tec_transfer["ukey"]).first
tt = AsiaTecTransfer.new if tt.nil?
tt.rss2_id = tec_transfer["ukey"]
tt.tech_transfer_name_translations = localize_data(tec_transfer["Trans_Data_NAME"]) #技轉名稱
tt.receiving_unit_translations = localize_data(tec_transfer["Trans_Unit"]) #技轉對象
if tec_transfer["period"].present? #技轉期間
period = tec_transfer["period"].split('~').map{|date| Date.parse(date) rescue nil}
tt.start_date = period[0]
tt.end_date = period[1]
else
tt.start_date = nil
tt.end_date = nil
end
tt.asia_teacher = asia_teacher
puts "Technology transfer #{tt.id} saved" if tt.save
end
end
def self.sync_exhibitions(query_result, asia_teacher) # exhibitions
email_id = asia_teacher.email_id
return if email_id.blank?
puts "Exhibition(show) for user: #{email_id}"
exhibitions = query_result["show"].to_a
if !query_result['emp'].blank?
AsiaExhibition.where(asia_teacher: asia_teacher,:rss2_id.ne=>nil).where(:rss2_id.nin=>exhibitions.map{|v| v["ukey"]}).destroy
end
return if exhibitions.count == 0
exhibitions.each do |exhibition|
et = AsiaExhibition.where(:rss2_id=> exhibition["ukey"]).first
et = AsiaExhibition.new if et.nil?
et.rss2_id = exhibition["ukey"]
et.exhibition_name_translations = localize_data(exhibition["show_name"])
et.host_translations = localize_data(exhibition["show_author_local"])
if exhibition["period"].present? #展演期間
period = exhibition["period"].split('~').map{|date| DateTime.parse(date) rescue nil}
et.exhibition_start_date = period[0]
et.exhibition_end_date = period[1]
else
et.exhibition_start_date = nil
et.exhibition_end_date = nil
end
et.asia_teacher = asia_teacher
puts "Exhibition(show) #{et.id} saved" if et.save
end
end
2023-06-14 14:33:10 +00:00
def self.hashify(data_list, grouping_keys)
data_list.each_with_object({}) do |data, result|
val = result
grouping_keys[0...-1].each_with_index do |key, i|
kk = data[key]
val[kk] ||= {}
val = val[kk]
end
kk = data[grouping_keys[-1]]
val[kk] ||= []
val[kk] << data
end
end
2023-05-26 14:17:05 +00:00
end
namespace :asia_database do
desc "Sync asia database"
task :sync,[:user_names, :only_sync_data] => [:environment] do |task,args|
2023-06-14 14:33:10 +00:00
I18n.locale = "zh_tw"
2023-05-26 14:17:05 +00:00
if args.user_names.present?
asia_teachers = AsiaTeacher.where(:email_id.in=>args.user_names).to_a
else
if args.only_sync_data.blank? || (args.only_sync_data != 'true' && args.only_sync_data != true)
2023-06-14 14:33:10 +00:00
#{"ukey"=>"107100033", "ad"=>"slliu", "emp_nm"=>"劉淑玲",
#"emp_enm"=>"LIU, SHU-LING", "emp_typeNm"=>"專任", "dept_id"=>"NS00",
#"dept_college"=>"護理學院", "dept_nm"=>"護理學系", "dept_Fullnm"=>"護理學院護理學系",
#"dept_Fullenm"=>"Department of Nursing"}
asia_depart_teachers = AsiaDatabasePlugin.hashify(get_all_teacher_data, ['emp_typeNm', 'dept_college', 'dept_nm'])['專任']
AsiaAcademy.where(:academy_name.nin => asia_depart_teachers.keys).delete_all
puts asia_depart_teachers.keys.inspect
email_ids = []
2023-05-26 14:17:05 +00:00
asia_depart_teachers.each do |academy_name, departs_info|
academy = AsiaAcademy.where("academy_name.zh_tw"=>academy_name).first
if academy.nil?
academy = AsiaAcademy.create({:academy_name_translations=>AsiaDatabasePlugin.localize_data(academy_name)})
end
2023-06-14 14:33:10 +00:00
puts departs_info.keys.inspect
departs_info.each do |depart_name, data_list|
2023-05-26 14:17:05 +00:00
depart = AsiaDepartment.where("department_name.zh_tw"=>depart_name, "asia_academy"=>academy).first
if depart.nil?
depart = AsiaDepartment.create({:department_name_translations=>AsiaDatabasePlugin.localize_data(depart_name), :asia_academy=>academy})
end
2023-06-14 14:33:10 +00:00
data_list.each do |teacher_data|
email_id = teacher_data['ad']
email_ids << email_id
2023-05-26 14:17:05 +00:00
asia_teacher = AsiaTeacher.where(:email_id=>email_id).first
if asia_teacher.nil?
asia_teacher = AsiaTeacher.new(:email_id=>email_id, :asia_academy=>academy, :asia_department=>depart)
else
asia_teacher.asia_academy = academy
asia_teacher.asia_department = depart
end
2023-06-14 14:33:10 +00:00
asia_teacher.ukey = teacher_data["ukey"]
asia_teacher.teacher_translations = {"zh_tw"=>teacher_data["emp_nm"], "en"=>teacher_data["emp_enm"]}
2023-05-26 14:17:05 +00:00
asia_teacher.save
end
end
end
2023-06-14 14:33:10 +00:00
AsiaTeacher.where(:email_id.nin => email_ids).delete_all
2023-05-26 14:17:05 +00:00
end
asia_teachers = AsiaTeacher.all.to_a
end
asia_teachers.each do |asia_teacher|
query_result = get_sync_data(asia_teacher.email_id)
discipline_expertise_translations = AsiaDatabasePlugin.localize_data([], ['zh_tw', 'en'])
query_result['RshSkill'].to_a.each do |h|
tmp = h["RSkill"].to_s.strip
tmp2 = h["eRSkill"].to_s.strip
discipline_expertise_translations['zh_tw'] << [tmp, tmp2].select{|s| s.present?}.join('/')
discipline_expertise_translations['en'] << (tmp2.present? ? tmp2 : tmp)
end
asia_teacher.discipline_expertise_translations = discipline_expertise_translations
asia_teacher.save
AsiaDatabasePlugin.sync_projects(query_result, asia_teacher)
AsiaDatabasePlugin.sync_papers(query_result, asia_teacher)
AsiaDatabasePlugin.sync_patents(query_result, asia_teacher)
AsiaDatabasePlugin.sync_tec_transfers(query_result, asia_teacher)
AsiaDatabasePlugin.sync_exhibitions(query_result, asia_teacher)
end
end
def net_http_get_response(uri,headers={})
http = Net::HTTP.new(uri.host, uri.port)
if uri.scheme == "https"
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
http.use_ssl = true
end
http.read_timeout = (@read_timeout.nil? ? 60 : @read_timeout)
res = http.get((uri.path.blank? ? "/" : uri.path)+(uri.query.blank? ? '' : "?#{uri.query}"))
res.uri = uri
res
end
def get_sync_data(email_id)
uri = URI.parse("https://webap.asia.edu.tw/TchEportfolio/API/Research/Load")
@read_timeout = 300
data = "id=#{email_id}"
cipher = OpenSSL::Cipher::Cipher.new("des-cbc").encrypt.tap do |obj|
obj.iv = AsiaDatabasePlugin::IV
obj.key = AsiaDatabasePlugin::KEY
end
encrypt = cipher.update(data) + cipher.final()
encrypt_base64 = Base64.encode64(encrypt).strip
res = net_http_get_response(uri + "?#{encrypt_base64}")
return JSON.parse(res.body,{object_class: AsiaDatabasePlugin::SafeHash})
end
2023-06-14 14:33:10 +00:00
def get_all_teacher_data
res = net_http_get_response(URI.parse("https://webap.asia.edu.tw/TchEportfolio/API/ResearchTID/Load"))
data = JSON.parse(res.body,{object_class: AsiaDatabasePlugin::SafeHash})
if data['emp']
return data['emp']
end
return []
end
2023-05-26 14:17:05 +00:00
end