Skip to content

Commit

Permalink
Merge branch 'main' into fb_headless
Browse files Browse the repository at this point in the history
  • Loading branch information
drfho authored Jun 29, 2023
2 parents 504f167 + c3f3c2d commit 605a671
Show file tree
Hide file tree
Showing 7 changed files with 349 additions and 11 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
class manage_zmsindex_reindex_paged:
"""
python-representation of manage_zmsindex_reindex_paged
"""

# Acquired
acquired = 0

# Action
action = "%smanage_executeMetacmd?id=manage_zmsindex_reindex_paged"

# Description
description = ""

# Execution
execution = False

# Icon_clazz
icon_clazz = "fas fa-cogs"

# Id
id = "manage_zmsindex_reindex_paged"

# Meta_types
meta_types = ["ZMS"]

# Name
name = "ZMSIndex: Reindex paged"

# Nodes
nodes = "{$}"

# Package
package = "com.zms.index"

# Revision
revision = "0.0.2"

# Roles
roles = ["ZMSAdministrator"]

# Stereotype
stereotype = ""

# Title
title = "ZMSIndex: Reindex paged"

# Impl
class Impl:
manage_zmsindex_reindex_paged = {"id":"manage_zmsindex_reindex_paged"
,"type":"External Method"}
Original file line number Diff line number Diff line change
@@ -0,0 +1,273 @@
from Products.zms import standard
from abc import abstractmethod

# Abstract Interface for Handler
class IHandler:
@abstractmethod
def handle(self): raise NotImplementedError

# Implementation of ZMSIndexReindex Handler
class ZMSIndexReindexHandler(IHandler):
def __init__(self, zmsindex, catalog):
self.zmsindex = zmsindex
self.catalog = catalog
def handle(self, node):
return '\n'.join(self.zmsindex.reindex_node(node, self.catalog))

# Traverse and handle nodes of this page.
def traverse(data, root_node, node, handler, page_size=100):
count = 0
root_path = '/'.join(root_node.getPhysicalPath())
while node and count < page_size:
path = '/'.join(node.getPhysicalPath())
log = {'index':count,'path':path,'meta_id':node.meta_id}
log['action'] = handler.handle(node);
data['log'].append(log)
node = node.get_next_node()
if node and not '/'.join(node.getPhysicalPath()).startswith(root_path): node = None
data['next_node'] = None
if node:
root_element = node.getRootElement()
root = '/'.join(root_element.getHome().getPhysicalPath())
path = path[len(root):]
i = path.find('/content')
data['next_node'] = '{$%s@%s}'%(path[:i],path[i+len('/content')+1:])
count += 1

def manage_zmsindex_reindex_paged( self):
request = self.REQUEST
zmsindex = self.getZMSIndex()
catalog = zmsindex.get_catalog()

# REST Endpoints
if request.get('json'):
import json
request.RESPONSE.setHeader("Content-Type","text/json")
root_node = self.getLinkObj(request['root_node'])
data = {'pid':self.Control_Panel.process_id(),'root_node':request['root_node']}
# REST Endpoint: ajaxCount
if request.get('count'):
path = '/'.join(root_node.getPhysicalPath())
data['count'] = {}
r = catalog(path={'query':path})
data['total'] = len(r)
# REST Endpoint: ajaxTraverse
if request.get('traverse'):
node = self.getLinkObj(request['uid'])
page_size = int(request['page_size'])
data['log'] = []
data['next_node'] = None
handler = ZMSIndexReindexHandler(zmsindex,catalog)
traverse(data,root_node,node,handler,page_size)
return json.dumps(data)

home_id = self.getHome().id
prt = []
prt.append('<!DOCTYPE html>')
prt.append('<html lang="en">')
prt.append(self.zmi_html_head(self,request))
prt.append('<body class="%s">'%self.zmi_body_class(id='manage_zmsindex_reindex_paged'))
prt.append(self.zmi_body_header(self,request))
prt.append('<div id="zmi-tab">')
prt.append(self.zmi_breadcrumbs(self,request))
prt.append('<form class="form-horizontal card" name="form0" method="post" enctype="multipart/form-data">')
prt.append('<input type="hidden" name="lang" value="%s"/>'%request['lang'])
prt.append('<legend>ZMSIndex: Paged reindex</legend>')
prt.append('<div class="card-body">')
prt.append('<div class="form-group row">')
prt.append('<label class="col-sm-2 control-label">Page-Size</label>')
prt.append('<div class="col-sm-5">')
prt.append('<input class="form-control" id="page_size" name="page_size:int" type="number" value="100">')
prt.append('</div>')
prt.append('</div><!-- .form-group -->')
prt.append('<div class="form-group row">')
prt.append('<label class="col-sm-2 control-label">Root</label>')
prt.append('<div class="col-sm-5">')
prt.append('<input class="form-control url-input" id="root_node" name="root_node" type="text" value="{$}">')
prt.append('</div>')
prt.append('</div><!-- .form-group -->')
prt.append('<div class="form-group row d-none">')
prt.append('<label class="col-sm-2 control-label">Node</label>')
prt.append('<div class="col-sm-5">')
prt.append('<input class="form-control url-input" id="uid" name="uid" type="text" readonly="readonly">')
prt.append('</div>')
prt.append('</div><!-- .form-group -->')
prt.append('<div class="form-group row">')
prt.append('<label class="col-sm-2 control-label"></label>')
prt.append('<div class="col-sm-5">')
prt.append('<button id="start-button" class="btn btn-secondary mr-2">')
prt.append('<i class="fas fa-play text-success"></i>')
prt.append('</button>')
prt.append('<button id="stop-button" class="btn btn-secondary" disabled="disabled">')
prt.append('<i class="fas fa-stop"></i>')
prt.append('</button>')
prt.append('</div>')
prt.append('</div><!-- .form-group -->')
prt.append('<div class="form-group row">')
prt.append('<label class="col-sm-2 control-label"></label>')
prt.append('<div class="col-sm-5">')
prt.append('<div id="count">')
prt.append('</div>')
prt.append('</div>')
prt.append('</div><!-- .form-group -->')
prt.append('<div class="d-none progress mx-3">')
prt.append('<div class="progress-bar progress-bar-striped progress-bar-animated" role="progressbar" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100"></div>')
prt.append('</div>')
prt.append('<div class="d-none alert alert-info" role="alert">')
prt.append('</div>')
prt.append('</div><!-- .card-body -->')
prt.append('</form><!-- .form-horizontal -->')
prt.append('</div><!-- #zmi-tab -->')
prt.append(self.zmi_body_footer(self,request))
prt.append('''
<style>
@media (prefers-reduced-motion: reduce) {
.progress-bar-animated {
-webkit-animation: 1s linear infinite progress-bar-stripes;
animation: 1s linear infinite width;
}
.progress-bar {
transition: width .6s ease;
}
}
</style>
<script>
var map = undefined;
var started = false;
var paused = false;
var stopped = false;
function start() {
stopped = false;
$(".progress .progress-bar").removeClass("bg-danger bg-warning bg-success");
$("#stop-button").prop("disabled","");
$(".progress.d-none").removeClass("d-none");
$(".alert.alert-info").removeClass("d-none");
$(".alert.alert-info").html('<div class="spinner-border text-primary mx-auto" role="status"><span class="sr-only">Loading...</span></div>');
if (!started) {
// prepare counters
map = {};
$("#count_table tr td.id").each(function() {
map[$(this).text()] = 0;
});
started = true;
paused = false;
$("#start-button i").removeClass("fa-play text-success").addClass("fa-pause text-info");
ajaxCount(ajaxTraverse);
}
else if (!paused) {
paused = true;
$("#start-button i").removeClass("fa-pause text-info").addClass("fa-play text-success");
$(".progress .progress-bar").addClass("bg-warning");
}
else {
paused = false;
$("#start-button i").removeClass("fa-play text-success").addClass("fa-pause text-info");
ajaxTraverse();
}
return false;
}
function stop() {
started = false;
stopped = true;
$(".progress .progress-bar").removeClass("bg-success bg-warning bg-success");
$("#start-button i").removeClass("fa-pause").addClass("fa-play");
$("#stop-button").prop("disabled","disabled");
$(".progress .progress-bar").addClass("bg-warning");
return false;
}
function progress() {
const count = parseInt($("#count_table tr.Total .count").text());
const total = parseInt($("#count_table tr.Total .total").text());
const perc = Math.round(Math.floor(10.0*count*100/total)/10.0);
$(".progress .progress-bar").css("width",perc+"%").attr({"aria-valuenow":perc,"title":count+"/"+total}).html(perc+"%");
}
function ajaxCount(cb) {
const root_node = $('#root_node').val();
const params = {'json':true,'count':true,'root_node':root_node};
$.get('manage_zmsindex_reindex_paged',params,function(data) {
$('#uid').val(root_node);
var html = '';
html += '<table id="count_table" class="table table-bordered">';
Object.entries(data['count']).forEach((k,v) => {
html += '<tr class="' + k[0] + '">';
html += '<td class="id">' + k[0] + '</td>';
html += '<td class="total">' + k[1] + '</td>';
html += '<td class="count">' + 0 + '</td>';
html += '</tr>';
});
html += '<tr class="Total">';
html += '<td class="id"><strong>Total</strong></td>';
html += '<td class="total">' + data['total'] + '</td>';
html += '<td class="count">' + 0 + '</td>';
html += '</tr>';
html += '</table>';
$("#count").html(html);
// show progress
progress();
// execute callback
cb(uid);
});
}
function ajaxTraverse() {
const root_node = $('#root_node').val();
const uid = $('#uid').val();
const page_size = $("input#page_size").val();
const params = {'json':true,'traverse':true,'root_node':root_node,'uid':uid,'page_size':page_size};
$.get('manage_zmsindex_reindex_paged',params,function(data) {
$(".alert.alert-info").html($('<pre/>',{text:JSON.stringify(data,null,2)}))
if (!stopped && !paused) {
const log = data['log'];
if (log) {
log.filter(x => x['action']).forEach(x => {
// increase counter
const meta_id = x['meta_id'];
map[meta_id] = map[meta_id] + 1;
$("#count_table tr." + meta_id + " .count").html(map[meta_id]);
});
// absolute total
map['Total'] = map['Total'] + log.length;
$("#count_table tr." + 'Total' + " .count").html(map['Total']);
// show progress
progress();
}
const next_node = data['next_node'];
if (next_node) {
$('#uid').val(next_node);
ajaxTraverse();
}
else {
stop();
$(".progress .progress-bar").removeClass("bg-warning").addClass("bg-success")
}
}
})
.fail(function(e) {
stop();
alert(JSON.stringify(e));
});
}
$(function() {
$('#start-button').click(start);
$('#stop-button').click(stop);
$('#root_node').change( function() {
// Hide progress/log infos
$('.progress').addClass('d-none');
$('.progress .progress-bar').css("width",0);
$('.alert.alert-info').addClass('d-none').empty();
$("#count").html('<div class="spinner-border text-primary mx-auto" role="status"><span class="sr-only">Loading...</span></div>');
// Show object classes table
ajaxCount(stop);
}).change();
});
</script>
''')
prt.append('</body>')
prt.append('</html>')

return '\n'.join(prt)
24 changes: 16 additions & 8 deletions Products/zms/zmsindex.py
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,21 @@ def uncatalog_object(self, catalog, node):
# return printed
return printed

# --------------------------------------------------------------------------
# ZMSIndex.reindex_node:
# --------------------------------------------------------------------------
def reindex_node(self, node, catalog, regenerate_duplicates=False):
log = []
if node.meta_id == 'ZMS':
# Clear catalog
for i in catalog({'path':'/'.join(node.getPhysicalPath())}):
path = i['getPath']
log.append('INFO %s'%standard.writeBlock(self,'[ZMSIndex] uncatalog_object %s'%path))
catalog.uncatalog_object(path)
log.append('INFO %s'%standard.writeBlock(self,'[ZMSIndex] catalog_object %s %s'%(node.getPath(),str(node.get_uid()))))
self.catalog_object(catalog,node,regenerate_duplicates)
return log

##############################################################################
# Reindex
##############################################################################
Expand All @@ -238,14 +253,7 @@ def manage_reindex(self, regenerate_duplicates=False):
def visit(node):
l = []
l.append(1)
if node.meta_id == 'ZMS':
# Clear catalog
for i in catalog({'path':'/'.join(node.getPhysicalPath())}):
path = i['getPath']
log.append('INFO %s'%standard.writeBlock(self,'[ZMSIndex] uncatalog_object %s'%path))
catalog.uncatalog_object(path)
log.append('INFO %s'%standard.writeBlock(self,'[ZMSIndex] catalog_object %s %s'%(node.getPath(),str(node.get_uid()))))
self.catalog_object(catalog,node,regenerate_duplicates)
log.extend(self.reindex_node(node,catalog,regenerate_duplicates))
for childNode in node.getChildNodes():
l.extend(visit(childNode))
return l
Expand Down
4 changes: 2 additions & 2 deletions Products/zms/zmsobject.py
Original file line number Diff line number Diff line change
Expand Up @@ -598,12 +598,12 @@ def display_icon(self, REQUEST={}, meta_type=None, key='icon', zpt=True):
name = 'fas fa-exclamation-triangle'
title = self.display_type(meta_type=id)
extra = ''
if id in self.getMetaobjIds( sort=0):
if id in self.getMetaobjIds( sort=0) + ['ZMSTrashcan']:
name = self.evalMetaobjAttr( '%s.%s'%(id, 'icon_clazz'))
if not name:
metaObj = self.getMetaobj(id)
names = {'ZMSResource':'fas fa-asterisk icon-asterisk','ZMSLibrary':'fas fa-flask icon-beaker','ZMSPackage':'fas fa-suitcase icon-suitcase','ZMSRecordSet':'far fa-list-alt icon-list','ZMSReference':'fas fa-link icon-link','ZMSTrashcan':'fas fa-trash'}
name = names.get(metaObj.get('type'), 'fas fa-file-alt icon-file-alt')
name = names.get(id, 'fas fa-file-alt icon-file-alt')
if meta_type is None:
constraints = self.attr('check_constraints')
if isinstance(constraints, dict):
Expand Down
2 changes: 1 addition & 1 deletion Products/zms/zpt/ZMSZCatalogAdapter/manage_main.zpt
Original file line number Diff line number Diff line change
Expand Up @@ -269,7 +269,7 @@ function zmiExecuteCatalog(url) {
var uid = $input.val();
var data = {uid:uid};
var $a = $input.next("a");
$a.after(`<span class="response alert zmi-code text-truncate"><i class="fas fa-spinner fa-spin"></i></span>`);
$a.after(`<span ondblclick="$(this).toggleClass('full')" class="response alert zmi-code text-truncate"><i class="fas fa-spinner fa-spin"></i></span>`);
$.ajax({
url:url,
data:data,
Expand Down
Loading

0 comments on commit 605a671

Please sign in to comment.