Move export to multithread.
This commit is contained in:
parent
2178bafe2a
commit
a3f6657dfc
|
@ -169,14 +169,54 @@ class Admin::AnnouncementsController < OrbitAdminController
|
|||
end
|
||||
|
||||
def export_excel
|
||||
@announcements = Bulletin.all.desc(:created_at)
|
||||
respond_to do |format|
|
||||
format.xlsx {
|
||||
response.headers['Content-Disposition'] = 'attachment; filename="announcement_export.xlsx"'
|
||||
}
|
||||
@thread = Multithread.where(:key=>'export_announcements').first
|
||||
update_flag = true
|
||||
if @thread.nil?
|
||||
@thread = Multithread.create(:key=>'export_announcements',:status=>{:status=>'Processing'})
|
||||
else
|
||||
update_flag = false if @thread.status[:status] == 'Processing' && @thread.respond_to?(:updated_at) && (@thread.updated_at > DateTime.now - 1.minute rescue false)
|
||||
if update_flag
|
||||
@thread.update(:status=>{:status=>'Processing'})
|
||||
end
|
||||
end
|
||||
if update_flag
|
||||
Thread.new do
|
||||
begin
|
||||
@announcements = Bulletin.all.desc(:created_at)
|
||||
last_updated = Bulletin.max(:updated_at).to_i
|
||||
filename = "public/announcement_export_#{last_updated}.xlsx"
|
||||
if File.exist?(filename)
|
||||
@thread.update(:status=>{:status=>'finish','finish_percent'=>100,'info'=>I18n.t('announcement.read_from_cache')})
|
||||
else
|
||||
excel_contents = render_to_string( handlers: [:axlsx], formats: [:xlsx] ,partial: 'export_excel.xlsx',locals: {:@announcements=>@announcements,:@thread=>@thread} )
|
||||
File.open(filename, 'w') do |f|
|
||||
f.write excel_contents
|
||||
end
|
||||
end
|
||||
@thread.status[:file] = filename
|
||||
@thread.status[:filename] = "announcement_export_#{DateTime.now.in_time_zone(Time.zone.utc_offset / 3600).strftime('%Y_%m_%d_%H%M')}.xlsx"
|
||||
@thread.save
|
||||
rescue => e
|
||||
@thread.status[:status] = 'error'
|
||||
# @thread.status[:info] = [e.to_s, e.backtrace]
|
||||
puts [e.to_s, e.backtrace]
|
||||
@thread.save
|
||||
end
|
||||
end
|
||||
end
|
||||
redirect_to admin_announcement_import_path(:thread_id=>@thread.id.to_s)
|
||||
end
|
||||
def render_404
|
||||
render :file => "#{Rails.root}/app/views/errors/404.html", :layout => false, :status => 404, :formats => [:html]
|
||||
end
|
||||
def download_file_from_thread
|
||||
@thread = Multithread.where(:id=>params[:id]).first if params[:id].present?
|
||||
if @thread && @thread.status[:file]
|
||||
send_file(@thread.status[:file],:filename=>@thread.status[:filename])
|
||||
else
|
||||
render_404
|
||||
end
|
||||
end
|
||||
|
||||
def import_from_xml
|
||||
download_tmp_xml params["import_xml"]
|
||||
import_from_tmp_xml File.read(File.join(Rails.root, "tmp", "ann_cc_ntu.xml"))
|
||||
|
@ -184,6 +224,7 @@ class Admin::AnnouncementsController < OrbitAdminController
|
|||
end
|
||||
|
||||
def import
|
||||
@thread = Multithread.where(:id=>params[:thread_id]).first if params[:thread_id].present?
|
||||
end
|
||||
|
||||
|
||||
|
|
|
@ -123,7 +123,13 @@ wb.add_worksheet(name: "Annoucement") do |sheet|
|
|||
sheet.add_row row, :style => heading
|
||||
sheet.add_row row1
|
||||
sheet.add_row row2, :style => example
|
||||
|
||||
if @thread
|
||||
all_count = @announcements.count
|
||||
puts_every_count = [all_count * 3 / 100, 1].max
|
||||
current_count = 0
|
||||
finish_percent = 0
|
||||
@thread.update(:status=>{:status=>'Processing','all_count'=>all_count,'current_count'=>current_count,'finish_percent'=>finish_percent})
|
||||
end
|
||||
@announcements.each do |anns|
|
||||
row = []
|
||||
row << categories.to_a.index(anns.category)
|
||||
|
@ -168,10 +174,20 @@ wb.add_worksheet(name: "Annoucement") do |sheet|
|
|||
t = files.collect{|l|l.title_translations["zh_tw"]}
|
||||
row << t.join(";")
|
||||
sheet.add_row row
|
||||
if @thread
|
||||
current_count += 1
|
||||
if current_count % puts_every_count == 0
|
||||
finish_percent = (current_count * 100.0 / all_count).round(1)
|
||||
@thread.update(:status=>{:status=>'Processing','all_count'=>all_count,'current_count'=>current_count,'finish_percent'=>finish_percent})
|
||||
end
|
||||
end
|
||||
end
|
||||
if @thread
|
||||
finish_percent = 100
|
||||
@thread.update(:status=>{:status=>'finish','all_count'=>all_count,'current_count'=>current_count,'finish_percent'=>finish_percent})
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
end
|
|
@ -1,12 +1,41 @@
|
|||
<% content_for :page_specific_javascript do %>
|
||||
<script type="text/javascript" src="/assets/validator.js"></script>
|
||||
<% end %>
|
||||
<% if @thread %>
|
||||
<div id="threadModal" class="modal hide fade in" tabindex="-1" role="dialog" aria-labelledby="threadModal" aria-hidden="false">
|
||||
<div class="modal-dialog" role="document">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h3 id="threadModal"><%=t("e_paper.#{@thread.key}")%></h3>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<div class="thread-status"><%= @thread.status[:status] %></div>
|
||||
<div class="thread-count-zone <%= 'hide' unless @thread.status[:current_count]%>">
|
||||
<span class="thread-current-count"><%= @thread.status[:current_count].to_i %></span>/<span class="thread-all-count"><%= @thread.status[:all_count].to_i %></span>
|
||||
</div>
|
||||
<span class="thread-finish_percent"><%= @thread.status[:finish_percent].to_i %></span> % finished
|
||||
<br>
|
||||
<span class="thread-info"><%= @thread.status[:info].to_s.html_safe %></span>
|
||||
<br>
|
||||
<span class="thread-file">
|
||||
<% if @thread.status[:filename] %>
|
||||
<a href="<%=admin_announcement_download_file_from_thread_path(:id=>@thread.id.to_s) %>" title="<%= @thread.status[:filename] %>"><%= @thread.status[:filename] %></a>
|
||||
<% end %>
|
||||
</span>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button class="btn" id="modal-close-btn" style="width: 4em;" data-dismiss="modal" aria-hidden="true"><%=t('close')%></button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<% end %>
|
||||
<form action="<%= admin_announcement_importanns_path %>" method="post" class="form-horizontal main-forms" id="import-anns-xls" enctype="multipart/form-data">
|
||||
<h3 style="padding-left: 30px;"><%= t("announcement.export_to_excel") %></h3>
|
||||
<div class="control-group">
|
||||
<div class="controls">
|
||||
<a href="<%= admin_announcement_export_excel_path(:format => "xlsx") %>"><%= t("announcement.export_all_anns") %></a>
|
||||
</div>
|
||||
<a href="<%= admin_announcement_export_excel_path %>"><%= t("announcement.export_all_anns") %></a>
|
||||
</div>
|
||||
</div>
|
||||
<h3 style="padding-left: 30px;"><%= t("announcement.import_from_excel") %></h3>
|
||||
<%= hidden_field_tag :authenticity_token, form_authenticity_token %>
|
||||
|
@ -84,4 +113,58 @@
|
|||
ext = t[t.length - 1];
|
||||
return (ext == "xml")
|
||||
}
|
||||
$(document).ready(function(){
|
||||
function update_thread(){
|
||||
$.post("<%=admin_threads_get_status_path%>",{"id": "<%=params[:thread_id]%>"}).done(function(data){
|
||||
var finish_percent = data["finish_percent"];
|
||||
var current_count = data["current_count"];
|
||||
var all_count = data["all_count"];
|
||||
var is_finish = (data["status"] == "finish" || data["status"] == "error");
|
||||
var info = data["info"]
|
||||
if(finish_percent){
|
||||
$("#threadModal .modal-body .thread-status").text(data["status"]);
|
||||
if(data["current_count"]){
|
||||
$("#threadModal .modal-body .thread-count-zone").removeClass('hide');
|
||||
$("#threadModal .modal-body .thread-current-count").text(current_count);
|
||||
$("#threadModal .modal-body .thread-all-count").text(all_count);
|
||||
}else{
|
||||
$("#threadModal .modal-body .thread-count-zone").addClass('hide');
|
||||
}
|
||||
$("#threadModal .modal-body .thread-finish_percent").text(finish_percent);
|
||||
if(info){
|
||||
$("#threadModal .modal-body .thread-info").text(info);
|
||||
}
|
||||
}
|
||||
if(!is_finish){
|
||||
window.time_out_id = window.setTimeout(update_thread, 1000);
|
||||
}else{
|
||||
var id = "<%=@thread.id if @thread%>";
|
||||
var filename = data["filename"];
|
||||
if(filename){
|
||||
$("#threadModal .modal-body .thread-file").html(`<a href="<%=admin_announcement_download_file_from_thread_path%>?id=${id}" title="${filename}">${filename}</a>`);
|
||||
}
|
||||
if(window.time_out_id)
|
||||
window.clearTimeout(window.time_out_id);
|
||||
// window.setTimeout(function(){
|
||||
// $("#threadModal").modal("hide");
|
||||
// alert(data["status"]);
|
||||
// }, 3000);
|
||||
return;
|
||||
}
|
||||
});
|
||||
}
|
||||
if($("#threadModal").length != 0){
|
||||
$("#threadModal").on('hidden.bs.modal',function(){
|
||||
window.clearTimeout(window.time_out_id);
|
||||
window.history.replaceState(null,$('title').text(),window.location.pathname);
|
||||
})
|
||||
$("#threadModal").on('shown.bs.modal',function(){
|
||||
window.time_out_id = window.setTimeout(update_thread, 1000);
|
||||
})
|
||||
$("#threadModal").modal("show");
|
||||
$(".show_progress").click(function(){
|
||||
$("#threadModal").modal("show");
|
||||
})
|
||||
}
|
||||
})
|
||||
</script>
|
|
@ -3,6 +3,7 @@ en:
|
|||
feed: Feed
|
||||
import: Import
|
||||
announcement:
|
||||
read_from_cache: "Read from cache!"
|
||||
delete_selected: "Delete Selected"
|
||||
expired: This announcement has been expired.
|
||||
go_back: Go back to the list of announcements.
|
||||
|
|
|
@ -4,6 +4,7 @@ zh_tw:
|
|||
import: 匯入
|
||||
get_all_anncs_without_subannc: "選擇相關公告"
|
||||
announcement:
|
||||
read_from_cache: "從暫存中讀取!"
|
||||
delete_selected: "刪除所選"
|
||||
expired: 此則公告已過期
|
||||
go_back: 回到公告列表
|
||||
|
|
|
@ -28,6 +28,7 @@ Rails.application.routes.draw do
|
|||
get 'announcements/feedform', to: 'announcements#feedform'
|
||||
get 'announcement/settings', to: 'announcements#settings'
|
||||
get 'announcement/import', to: 'announcements#import'
|
||||
get 'announcement/download_file_from_thread', to: 'announcements#download_file_from_thread'
|
||||
post 'announcement/createsettings', to: 'announcements#createsettings'
|
||||
patch 'announcement/updatesettings', to: 'announcements#updatesettings'
|
||||
post 'announcement/import_from_wp', to: 'announcements#import_from_wp'
|
||||
|
|
Loading…
Reference in New Issue