Commit a395d6ce authored by Rafael Monnerat's avatar Rafael Monnerat

Update from upstream/master

parents 75b31033 8b7e104d
......@@ -26,9 +26,9 @@ informations = { 'processing': processing,
if informations['processing'] in ['converted', 'conversion_failed','empty']:
informations['permanent_url'] = document.Document_getPermanentUrl()
print dumps(informations) #print info before del object
print(dumps(informations)) #print info before del object
portal.portal_sessions.manage_delObjects(reference)
else:
print dumps(informations)
print(dumps(informations))
return printed
......@@ -35,7 +35,7 @@ search_params = dict(
for brain in portal.portal_simulation.getInventoryList(**search_params):
if round(brain.total_price, precision) == 0:
print '%s has a 0 balance but some not grouped transactions.' % brain.mirror_section_relative_url
print('%s has a 0 balance but some not grouped transactions.' % brain.mirror_section_relative_url)
if fixit:
tr = brain.getObject().getParentValue()
grouped_line_list = tr.AccountingTransaction_guessGroupedLines()
......@@ -51,9 +51,9 @@ for brain in portal.portal_simulation.getInventoryList(**search_params):
portal_type=portal.getPortalAccountingMovementTypeList(),
grouping_reference=None,) if not line.getObject().getGroupingReference()])
if grouped_line_list:
print 'FIXED', grouped_line_list
print('FIXED %s' % grouped_line_list)
else:
print 'NOT FIXED'
print('NOT FIXED')
active_result = ActiveResult(
summary=context.getTitle(),
......
......@@ -78,7 +78,7 @@ for property_dict in object_list:
gap = str(gap)
if gap:
gap = gap.replace('CLASSE ', '')
print '+ %s - %s - %s' % (gap or '', title or '', description or '')
print('+ %s - %s - %s' % (gap or '', title or '', description or ''))
path = root
b = ''
for a in gap:
......@@ -96,7 +96,7 @@ for path in existing_path_list:
description = document.getDescription() or ''
gap = document.getId() or ''
title = document.getTitle() or ''
print '- %s - %s - %s' % (gap or '', title or '', description or '')
print('- %s - %s - %s' % (gap or '', title or '', description or ''))
document.getParentValue().deleteContent(document.getId())
return printed
......@@ -7,7 +7,7 @@ for cat in category_list:
cat.getObject().setId(newid)
except:
pass
print newid
print(newid)
print 'Categories Renamed'
print('Categories Renamed')
return printed
......@@ -7,7 +7,7 @@ for cat in category_list:
cat.getObject().setId(newid)
except:
pass
print newid
print(newid)
print 'Categories Renamed'
print('Categories Renamed')
return printed
......@@ -48,7 +48,7 @@ dane.p59=dane.p55-dane.p56
if debug:
for f in range(20,60):
n='p'+str(f)
print n,getattr(dane,n)
print(n,getattr(dane,n))
return printed
return container[report].index_html(REQUEST=context.REQUEST, RESPONSE=context.REQUEST.RESPONSE,dane=dane)
......@@ -5,7 +5,7 @@ Warning: Before using this script as zope, edit account_workflow and give Manage
#This script will REMOVE any existing accounts!!!
#comment following if you are sure
print 'Nothing done!'
print('Nothing done!')
return printed
......@@ -22,7 +22,7 @@ for category in gap_root.getCategoryMemberValueList():
acc = account_module.newContent(title='%s %s' % (category.getId(),category.getTitle()),\
gap_value = category)
acc.validate()
print 'acc created'
print('acc created')
return printed
......@@ -251,7 +251,7 @@ for line in gap_text.splitlines():
cpath += n
path.append(cpath)
parent = gap.restrictedTraverse('/'.join(path))
print 'Added to ',parent
print('Added to ',parent)
parent.newContent(id=num, title=descr)
......
container.REQUEST.RESPONSE.setHeader('content-type', 'text/html')
print '<html><head><meta http-equiv="refresh" content="%s"></head><body>' % refresh_interval
print('<html><head><meta http-equiv="refresh" content="%s"></head><body>' % refresh_interval)
for table in 'message', 'message_queue':
q = """SELECT count(*) AS %(table)s, method_id, processing_node AS node, min(priority) AS min_pri, max(priority) AS max_pri
FROM %(table)s GROUP BY method_id, processing_node ORDER BY node""" % dict(table=table)
print "<table border=\"\" style=\"font-size:XX-small;\"><tbody> <tr><th>%s</th> <th>method_id</th> <th>node</th> <th>min_pri</th> <th>max_pri</th> </tr>" % table
print("<table border=\"\" style=\"font-size:XX-small;\"><tbody> <tr><th>%s</th> <th>method_id</th> <th>node</th> <th>min_pri</th> <th>max_pri</th> </tr>" % table)
for row in context.cmf_activity_sql_connection.manage_test(q):
print '<tr><td>%s</td><td>%s</td><td>%s</td><td>%s</td><td>%s</td</tr>' % (row[table], row['method_id'], row['node'], row['min_pri'], row['max_pri'])
print '</tbody> </table> <br/>'
print('<tr><td>%s</td><td>%s</td><td>%s</td><td>%s</td><td>%s</td</tr>' % (row[table], row['method_id'], row['node'], row['min_pri'], row['max_pri']))
print('</tbody> </table> <br/>')
return printed
......@@ -10,14 +10,14 @@ for security_uid_field in security_uid_field_list:
print(">> useless uids in roles_and_users table <<\n")
if len(referenced_uid_set) > 0:
for row in req("select * from roles_and_users where uid not in %s" + tuple(referenced_uid_set)):
print row.uid, row.local_roles_group_id, row.allowedRolesAndUsers
print(row.uid, row.local_roles_group_id, row.allowedRolesAndUsers)
print("\n>> uids that should be in roles_and_users table <<\n")
all_uid_set = {row.uid for row in req("select uid from roles_and_users")}
for security_uid_field in security_uid_field_list:
for row in req("select %s, relative_url from catalog where %s not in %s" % (security_uid_field, security_uid_field, tuple(all_uid_set))):
print security_uid_field, getattr(row, security_uid_field, None), row.relative_url
print(security_uid_field, getattr(row, security_uid_field, None), row.relative_url)
print("\n>> END <<")
return printed
......@@ -6,18 +6,18 @@ u = getSecurityManager().getUser()
user_value = u.getUserValue()
if user_value is None:
print 'User ID:', u.getId()
print('User ID:', u.getId())
else:
print 'User ID:', u.getId(), user_value.getPath()
print('User ID:', u.getId(), user_value.getPath())
login_value = u.getLoginValue()
if login_value is None:
print 'Login:', u.getUserName()
print('Login:', u.getUserName())
else:
print 'Login:', u.getUserName(), login_value.getPath()
print 'Is owner:', u.allowed(context,('Owner',))
print 'User roles:', u.getRoles()
print 'User roles in context:', u.getRolesInContext(context)
print 'Permissions:'
print('Login:', u.getUserName(), login_value.getPath())
print('Is owner:', u.allowed(context,('Owner',)))
print('User roles:', u.getRoles())
print('User roles in context:', u.getRolesInContext(context))
print('Permissions:')
for permission in [
'Access contents information',
'Add portal content',
......@@ -26,25 +26,25 @@ for permission in [
'View',
'Manage portal',
]:
print " ", permission, u.has_permission(permission, context)
print(" ", permission, u.has_permission(permission, context))
print
print()
try:
print "User groups:\n", pformat(sorted(u.getGroups()))
print("User groups:\n", pformat(sorted(u.getGroups())))
except AttributeError:
print 'no getGroups'
print('no getGroups')
print
print 'Local roles on document:\n', pformat(context.get_local_roles())
print()
print('Local roles on document:\n', pformat(context.get_local_roles()))
print '''
print('''
----------------
Security mapping
----------------'''
----------------''')
if u.getId() is not None:
try:
print context.Base_viewSecurityMappingAsUser(u.getId())
print(context.Base_viewSecurityMappingAsUser(u.getId()))
except Unauthorized:
print "user doesn't have permission to security mapping in this context"
print("user doesn't have permission to security mapping in this context")
return printed
......@@ -16,12 +16,12 @@ for method_id, base_category_list in getSecurityCategoryMapping():
security_category_dict.setdefault(tuple(base_category_list), []).extend(
getattr(context, method_id)(base_category_list, login, context, ''))
except Exception: # XXX: it is not possible to log message with traceback from python script
print 'It was not possible to invoke method %s with base_category_list %s'%(method_id, base_category_list)
print('It was not possible to invoke method %s with base_category_list %s'%(method_id, base_category_list))
for base_category_list, category_value_list in security_category_dict.items():
print 'base_category_list:', base_category_list
print('base_category_list: %s' % (base_category_list,))
for category_dict in category_value_list:
print '-> category_dict:', category_dict
print '-->', group_id_list_generator(category_order=base_category_list,
**category_dict)
print('-> category_dict: %s' % category_dict)
print('--> %s' % group_id_list_generator(category_order=base_category_list,
**category_dict))
return printed
......@@ -20,7 +20,7 @@ if context.getPortalType() == 'Alarm':
else:
active_process = context.portal_activities.newActiveProcess().getPath()
ERP5Site_checkDataWithScript = context.portal_activities.ERP5Site_checkDataWithScript
print 'Results will be saved to %s' % active_process
print('Results will be saved to %s' % active_process)
checkTopLevel()
ERP5Site_checkDataWithScript(
......
for builder in sorted(context.getPortalObject().portal_deliveries.contentValues(),
key=lambda x:x.getTitle()):
print builder.getId()
print " Title: %s" % (builder.getTitle())
print " Simulation Select Method: %s" % (builder.getSimulationSelectMethodId())
print " Delivery Select Method: %s" % (builder.getDeliverySelectMethodId())
print " After Generation Script: %s" % (builder.getDeliveryAfterGenerationScriptId())
print
print(builder.getId())
print(" Title: %s" % (builder.getTitle()))
print(" Simulation Select Method: %s" % (builder.getSimulationSelectMethodId()))
print(" Delivery Select Method: %s" % (builder.getDeliverySelectMethodId()))
print(" After Generation Script: %s" % (builder.getDeliveryAfterGenerationScriptId()))
print()
for mg in sorted(builder.contentValues(), key=lambda x:x.getTitle()):
print builder.getId()
print " ", "\n ".join([x for x in (
print(builder.getId())
print(" ", "\n ".join([x for x in (
"Id: %s" % mg.getId(),
"Title: %s" % mg.getTitle(),
"Type: %s" % mg.getPortalType(),
......@@ -17,7 +17,7 @@ for builder in sorted(context.getPortalObject().portal_deliveries.contentValues(
"Tested Properties: %r" % mg.getTestedPropertyList(),
"Update Always: %r" % mg.isUpdateAlways(),
)])
print
)]))
print()
return printed
......@@ -4,6 +4,6 @@ for business_template in sorted(context.getPortalObject().portal_templates.conte
key=lambda x:x.getTitle()):
if business_template.getInstallationState() == 'installed' and \
business_template.getTitle() not in ignore_business_template_list:
print business_template.getTitle()
print(business_template.getTitle())
return printed
for builder in sorted(context.getPortalObject().portal_orders.contentValues(),
key=lambda x:x.getTitle()):
print builder.getId()
print " Title: %s" % (builder.getTitle())
print " Simulation Select Method: %s" % (builder.getSimulationSelectMethodId())
print " Delivery Select Method: %s" % (builder.getDeliverySelectMethodId())
print " After Generation Script: %s" % (builder.getDeliveryAfterGenerationScriptId())
print " Delivery Module Before Building Script: %s" % (builder.getDeliveryModuleBeforeBuildingScriptId())
print
print(builder.getId())
print(" Title: %s" % (builder.getTitle()))
print(" Simulation Select Method: %s" % (builder.getSimulationSelectMethodId()))
print(" Delivery Select Method: %s" % (builder.getDeliverySelectMethodId()))
print(" After Generation Script: %s" % (builder.getDeliveryAfterGenerationScriptId()))
print(" Delivery Module Before Building Script: %s" % (builder.getDeliveryModuleBeforeBuildingScriptId()))
print()
for mg in sorted(builder.contentValues(), key=lambda x:x.getTitle()):
print builder.getId()
print " ", "\n ".join([x for x in (
print(builder.getId())
print(" ", "\n ".join([x for x in (
"Id: %s" % mg.getId(),
"Title: %s" % mg.getTitle(),
"Type: %s" % mg.getPortalType(),
......@@ -18,7 +18,7 @@ for builder in sorted(context.getPortalObject().portal_orders.contentValues(),
"Tested Properties: %r" % mg.getTestedPropertyList(),
"Update Always: %r" % mg.isUpdateAlways(),
)])
print
)]))
print()
return printed
......@@ -37,12 +37,12 @@ for skin_folder in portal.portal_skins.objectValues('Folder'):
for skin in skin_folder.objectValues():
if skin.getId() in ignore_skin_list:
continue
print getSkinHash(skin, skin_folder)
print(getSkinHash(skin, skin_folder))
if include_workflow_scripts:
for workflow in portal.portal_workflow.objectValues():
for skin in workflow.scripts.objectValues():
print getSkinHash(skin, workflow)
print(getSkinHash(skin, workflow))
container.REQUEST.RESPONSE.setHeader('content-type', 'text/plain')
return '\n'.join(sorted(printed.splitlines()))
for ti in sorted(context.getPortalObject().portal_types.contentValues(), key=lambda x:x.getId()):
for ai in sorted(ti.contentValues(portal_type='Action Information'), key=lambda x:x.getReference()):
print ti.getId()
print " ", "\n ".join([x for x in (
print(ti.getId())
print(" ", "\n ".join([x for x in (
"Reference: %s" % ai.getReference(),
"Title: %s" % ai.getTitle(),
"Action: %s" % ai.getActionText(),
......@@ -9,7 +9,7 @@ for ti in sorted(context.getPortalObject().portal_types.contentValues(), key=lam
"Permission: %s" % ai.getActionPermission(),
"Action Type: %s" % ai.getActionType(),
"Visible: %s" % ai.getVisible(),
"Index: %s" % ai.getFloatIndex())])
print
"Index: %s" % ai.getFloatIndex())]))
print()
return printed
for ti in sorted(context.getPortalObject().portal_types.contentValues(), key=lambda x:x.getId()):
print ti.getId()
print " ", "\n ".join([x for x in (
print(ti.getId())
print(" ", "\n ".join([x for x in (
"Short Title: %s" % ti.getShortTitle(),
"Class: %s" % ti.getTypeClass(),
"Init Script: %s" % ti.getTypeInitScriptId(),
......@@ -12,7 +12,7 @@ for ti in sorted(context.getPortalObject().portal_types.contentValues(), key=lam
"Hidden Content Types: %r" % sorted(ti.getTypeHiddenContentTypeList()),
"Searchable Property: %r" % sorted(ti.getSearchableTextPropertyIdList()),
"Searchable Method: %r" % sorted(ti.getSearchableTextMethodIdList()),
)])
print
)]))
print()
return printed
for ti in sorted(context.getPortalObject().portal_types.contentValues(), key=lambda x:x.getId()):
for ri in sorted(ti.contentValues(portal_type='Role Information'), key=lambda x:(x.getTitle(), x.getLocalRoleGroupId(), x.getRoleBaseCategoryScriptId(), x.getRoleBaseCategoryList())):
print ti.getId()
print " ", "\n ".join([x for x in (
print(ti.getId())
print(" ", "\n ".join([x for x in (
"Title: %s" % ri.getTitle(),
"Roles: %r" % ri.getRoleNameList(),
"Condition: %s" % ri.getConditionText(),
"Local Roles Group Id: %s" % ri.getLocalRoleGroupId(),
"Base Categories: %r" % ri.getRoleBaseCategoryList(),
"Base Category Script: %s" % ri.getRoleBaseCategoryScriptId(),
"Categories: %r" % ri.getRoleCategoryList() )])
print
"Categories: %r" % ri.getRoleCategoryList() )]))
print()
return printed
......@@ -6,7 +6,7 @@ for ps in sorted(context.getPortalObject().portal_property_sheets.contentValues(
ps_id = ps.getId()
if ps_id in ignore_property_sheet_list:
continue
print ps.getId()
print(ps.getId())
info_list = ['id', 'portal_type', 'reference']
std_prop_list = ['elementary_type', 'property_default', 'storage_id', 'multivaluated', 'range', 'preference', 'read_permission', 'write_permission', 'translatable', 'translation_domain']
if pd.getPortalType() == 'Standard Property':
......@@ -29,10 +29,10 @@ for ps in sorted(context.getPortalObject().portal_property_sheets.contentValues(
elif pd.getPortalType().endswith('Constraint'):
info_list += [] + [p for p in pd.propertyIds() if p.startswith('message')]
else:
print "(not supported)",pd.getRelativeUrl(), pd.getPortalType()
print("(not supported)",pd.getRelativeUrl(), pd.getPortalType())
print " ", "\n ".join(['%s: %s' % (prop, pd.getProperty(prop)) for prop in sorted(info_list)])
print
print(" ", "\n ".join(['%s: %s' % (prop, pd.getProperty(prop)) for prop in sorted(info_list)]))
print()
return printed
......@@ -2,17 +2,17 @@ for rule in sorted(context.getPortalObject().portal_rules.contentValues(),
key=lambda x:x.getTitle()):
if rule.getValidationState() != 'validated':
continue
print rule.getId()
print " Title: %s" % (rule.getTitle())
print " Trade Phases: %r" % (rule.getTradePhaseList())
print " Test Method Id: %s" % (rule.getTestMethodId())
print " Membership Criteria: %r" % (rule.getMembershipCriterionBaseCategoryList())
print " Membership Criterion Category: %r" % (rule.getMembershipCriterionCategoryList())
print
print(rule.getId())
print(" Title: %s" % (rule.getTitle()))
print(" Trade Phases: %r" % (rule.getTradePhaseList()))
print(" Test Method Id: %s" % (rule.getTestMethodId()))
print(" Membership Criteria: %r" % (rule.getMembershipCriterionBaseCategoryList()))
print(" Membership Criterion Category: %r" % (rule.getMembershipCriterionCategoryList()))
print()
for tester in sorted(rule.contentValues(), key=lambda x:x.getTitle()):
print rule.getId()
print " ", "\n ".join([x for x in (
print(rule.getId())
print(" ", "\n ".join([x for x in (
"Id: %s" % tester.getId(),
"Title: %s" % tester.getTitle(),
"Type: %s" % tester.getPortalType(),
......@@ -25,7 +25,7 @@ for rule in sorted(context.getPortalObject().portal_rules.contentValues(),
(tester.getMembershipCriterionBaseCategoryList()),
"Membership Criterion Category: %r" %
(tester.getMembershipCriterionCategoryList()),
)])
print
)]))
print()
return printed
......@@ -13,5 +13,5 @@ for name, layers in skin_tool.getSkinPaths():
if ignore_skin_folder_list is not None and\
layer in ignore_skin_folder_list:
continue
print '%s,%s' % (name, layer)
print('%s,%s' % (name, layer))
return printed
......@@ -13,6 +13,6 @@ for field_path, field in context.ZopeFind(
relation_setter_id = field.get_value('relation_setter_id')
if relation_setter_id:
print field_path, relation_setter_id
print(field_path, relation_setter_id)
return printed
......@@ -16,6 +16,6 @@ for bt in bt_list:
delete_list.append(bt_id)
break
print 'Deleted id list:%r' % delete_list
print('Deleted id list:%r' % delete_list)
portal_templates.manage_delObjects(delete_list)
return printed
......@@ -35,7 +35,7 @@
</item>
<item>
<key> <string>acquisition_portal_type</string> </key>
<value> <string>python: list(portal.getPortalAcquisitionMovementTypeList() + portal.getPortalItemTypeList())</string> </value>
<value> <string>python: list(portal.getPortalAcquisitionMovementTypeList() + portal.getPortalSupplyPathTypeList() + portal.getPortalItemTypeList())</string> </value>
</item>
<item>
<key> <string>categories</string> </key>
......
......@@ -33,10 +33,6 @@ class SplitMovementGroup(MovementGroup):
This movement group is used to split all the movements that are aggregated
by the Simulation Select Method.
XXX-Tatuya: However this test() method returns True, so the aggregated
movements can be inserted into existing Delivery/Line/Cell that are aggregated
by the Delivery Select Method. What use case this is applied for?
* Reference:
http://www.erp5.org/HowToConfigureMovementGroup
......
......@@ -8,5 +8,5 @@ context.ERP5Site_checkDataWithScript("Base_migrateToEmbeddedFile",
active_process=active_process.getPath(),
method_kw=dict(force=1))
print "Migration started with process id: %s" %active_process.getPath()
print("Migration started with process id: %s" %active_process.getPath())
return printed
......@@ -5,6 +5,7 @@ notification_message_list = portal.portal_catalog.getDocumentValueList(
reference=reference,
language=language,
strict_language=strict_language,
limit=limit,
**kw
)
if notification_message_list:
......
......@@ -50,7 +50,7 @@
</item>
<item>
<key> <string>_params</string> </key>
<value> <string>reference, language=None, strict_language=False, validation_state=None, **kw</string> </value>
<value> <string>reference, language=None, strict_language=False, validation_state=None, limit=1, **kw</string> </value>
</item>
<item>
<key> <string>id</string> </key>
......
from __future__ import print_function
from BTrees.LOBTree import LOBTree
from persistent import Persistent
import itertools
......@@ -314,7 +315,7 @@ class BTreeData(Persistent):
if __name__ == '__main__':
def check(tree, length, read_offset, read_length, data_, keys=None):
print list(tree._tree.items())
print(list(tree._tree.items()))
tree_length = len(tree)
tree_data = tree.read(read_offset, read_length)
tree_iterator_data = ''.join(tree.iterate(read_offset, read_length))
......
......@@ -68,11 +68,11 @@ for business_application_category_id, module_ids in module_business_application_
if module is not None:
module.edit(business_application = business_application_category_id)
print "Indexing translations"
print("Indexing translations")
portal.ERP5Site_updateTranslationTable()
# clear cache so user security is recalculated
portal.portal_caches.clearAllCache()
print "Clear cache."
print("Clear cache.")
log("%s" % printed)
......@@ -12,7 +12,7 @@ if business_template is not None:
filter=dict(portal_type=portal_type))
for module in module_list:
module.updateLocalRolesOnSecurityGroups()
print "Updated Role Mappings for: %s(%s) " % (module.getTitle(), module.getPortalType())
print("Updated Role Mappings for: %s(%s) " % (module.getTitle(), module.getPortalType()))
# validate and open all objects
for path in business_template.getTemplatePathList():
......@@ -22,16 +22,16 @@ if business_template is not None:
if obj.getPortalType() not in ('Category', 'Base Category',):
obj.updateLocalRolesOnSecurityGroups()
print "Updated Role Mappings for: ", path, obj.getPortalType()
print("Updated Role Mappings for: ", path, obj.getPortalType())
if obj.getPortalType() in ('Person', 'Organisation'):
for period in obj.contentValues(filter={'portal_type':'Accounting Period'}):
period.updateLocalRolesOnSecurityGroups()
print "\tOpen (Accounting Period): ", period.getRelativeUrl()
print("\tOpen (Accounting Period): ", period.getRelativeUrl())
for assignment in obj.contentValues(filter={'portal_type':'Assignment'}):
assignment.updateLocalRolesOnSecurityGroups()
print "\tOpen (assignment): ", assignment.getRelativeUrl()
print("\tOpen (assignment): ", assignment.getRelativeUrl())
for solver_type in context.portal_solvers.objectValues():
solver_type.updateLocalRolesOnSecurityGroups()
......@@ -96,11 +96,11 @@ if osoe_runner_website is not None:
available_language_list = list(portal.Localizer.get_supported_languages())
osoe_runner_website.edit(available_language_set = available_language_list)
print "Indexing translations"
print("Indexing translations")
portal.ERP5Site_updateTranslationTable()
# clear cache so user security is recalculated
portal.portal_caches.clearAllCache()
print "Clear cache."
print("Clear cache.")
log("%s" % printed)
......@@ -141,7 +141,7 @@ for message in message_list:
comment_list = message_dict[message]
comment_list.sort()
comment = '\n'.join([('#: %s' % i) for i in comment_list])
print MESSAGE_TEMPLATE % (comment, formatText(message))
print(MESSAGE_TEMPLATE % (comment, formatText(message)))
context.REQUEST.RESPONSE.setHeader('Content-Type', 'text/plain')
......
......@@ -8,10 +8,10 @@ message_list = ["Configuration is over. Enjoy your new ERP5 system!",
portal.REQUEST.RESPONSE.setHeader('content-type', 'text/plain')
for message in message_list:
if not message in html_status_report:
print "Error: {message} not found in status report".format(message=message)
print("Error: {message} not found in status report".format(message=message))
for log in portal.error_log.getLogEntries():
print "Error: {type} {value} {tb_text}".format(**log)
print("Error: {type} {value} {tb_text}".format(**log))
if str(printed):
return printed
......
......@@ -201,7 +201,7 @@ for serie in series_list:
# the last element must be saved
data_groups.append(new_group)
print data_groups
print(data_groups)
# [
......@@ -236,24 +236,24 @@ def aggregate(big_list, item_to_add):
if big_list == []:
return []
if getListLevel(big_list) == getListLevel(item_to_add):
print "big_list " + big_list
print "item_to_add " + item_to_add
print("big_list " + big_list)
print("item_to_add " + item_to_add)
big_list.append(item_to_add)
return big_list
else:
new_big_list_sub_level = aggregate(getLastSubList(big_list), item_to_add)
print "new_big_list_sub_level " + new_big_list_sub_level
print "big_list " + big_list
print("new_big_list_sub_level " + new_big_list_sub_level)
print("big_list " + big_list)
return None #setLastSubList(big_list, new_big_list_sub_level)
for group in data_groups:
collapsed_group = group[0]
for serie_group in group[1:]:
print serie_group
print(serie_group)
collapsed_group = aggregate(collapsed_group, serie_group)
print collapsed_group
print(collapsed_group)
# if
......
......@@ -50,7 +50,7 @@ from OFS.Image import Pdata
WORKFLOW_TYPE = 'erp5_workflow'
from Products.MimetypesRegistry.common import MimeTypeException
from Products.MimetypesRegistry.interfaces import MimeTypeException
from Products.PortalTransforms.Transform import Transform
Transform_tr_init = Transform._tr_init
Transform_manage_beforeDelete = Transform.manage_beforeDelete
......
......@@ -27,6 +27,7 @@
#
##############################################################################
from __future__ import print_function
import random
import time
......@@ -69,7 +70,7 @@ class TestRamCache(ERP5TypeTestCase):
for cache_plugin in filtered_cache_plugins:
if not self.quiet:
print "TESTING (scope): ", cache_plugin
print("TESTING (scope): ", cache_plugin)
## clear cache for this plugin
cache_plugin.clearCache()
......@@ -85,7 +86,7 @@ class TestRamCache(ERP5TypeTestCase):
## we set ONLY one value per scope -> check if we get the same cache_id
self.assertEqual([cache_id], cache_plugin.getScopeKeyList(scope))
if not self.quiet:
print "\t", cache_id, scope, "\t\tOK"
print("\t", cache_id, scope, "\t\tOK")
## get list of scopes which must be the same as test_scopes since we clear cache initially
scopes_from_cache = cache_plugin.getScopeList()
......@@ -118,7 +119,7 @@ class TestRamCache(ERP5TypeTestCase):
def generalExpire(self, cache_plugin, iterations):
if not self.quiet:
print "TESTING (expire): ", cache_plugin
print("TESTING (expire): ", cache_plugin)
base_timeout = 1
values = self.prepareValues(iterations)
scope = "peter"
......@@ -128,7 +129,7 @@ class TestRamCache(ERP5TypeTestCase):
cache_timeout = base_timeout + random.random()*2
cache_id = "mycache_id_to_expire_%s" %(count)
if not self.quiet:
print "\t", cache_id, " ==> timeout (s) = ", cache_timeout,
print("\t", cache_id, " ==> timeout (s) = ", cache_timeout, end=' ')
## set to cache
cache_plugin.set(cache_id, scope, value, cache_timeout)
......@@ -142,11 +143,11 @@ class TestRamCache(ERP5TypeTestCase):
## check it, we MUST NOT have this key any more in cache
self.assertEqual(False, cache_plugin.has_key(cache_id, scope))
if not self.quiet:
print "\t\tOK"
print("\t\tOK")
def generaltestSetGet(self, cache_plugin, iterations):
if not self.quiet:
print "TESTING (set/get/has/del): ", cache_plugin
print("TESTING (set/get/has/del): ", cache_plugin)
values = self.prepareValues(iterations)
cache_duration = 30
scope = "peter"
......@@ -158,7 +159,7 @@ class TestRamCache(ERP5TypeTestCase):
## set to cache
cache_plugin.set(cache_id, scope, value, cache_duration)
if not self.quiet:
print "\t", cache_id,
print("\t", cache_id, end=' ')
## check has_key()
self.assertEqual(True, cache_plugin.has_key(cache_id, scope))
......@@ -184,7 +185,7 @@ class TestRamCache(ERP5TypeTestCase):
self.assertEqual(False, cache_plugin.has_key(cache_id, scope))
if not self.quiet:
print "\t\tOK"
print("\t\tOK")
def prepareValues(self, iterations):
""" generate a big list of values """
......
......@@ -27,6 +27,7 @@
#
##############################################################################
from __future__ import print_function
import time
import unittest
......@@ -227,9 +228,9 @@ return result
def _cacheFactoryInstanceTest(self, my_cache, cf_name, clear_allowed):
portal = self.portal
print
print "="*40
print "TESTING:", cf_name
print()
print("="*40)
print("TESTING:", cf_name)
result = 'a short value'
#portal.portal_caches.clearCacheFactory(cf_name)
......@@ -249,12 +250,12 @@ return result
result=result)
## 1st call
calculation_time = callCache(real_calculation=True)
print "\n\tCalculation time (1st call)", calculation_time
print("\n\tCalculation time (1st call)", calculation_time)
self.commit()
## 2nd call - should be cached now
calculation_time = callCache(real_calculation=False)
print "\n\tCalculation time (2nd call)", calculation_time
print("\n\tCalculation time (2nd call)", calculation_time)
self.commit()
## OK so far let's clear cache
......@@ -263,10 +264,10 @@ return result
## 1st call
calculation_time = callCache(real_calculation=True)
print "\n\tCalculation time (after cache clear)", calculation_time
print("\n\tCalculation time (after cache clear)", calculation_time)
# Test delete method on CachingMethod
print "\n\tCalculation time (3rd call)", calculation_time
print("\n\tCalculation time (3rd call)", calculation_time)
# make sure cache id filled
calculation_time = callCache(real_calculation=False)
......@@ -275,7 +276,7 @@ return result
# Check that result is computed
calculation_time = callCache(real_calculation=True)
print "\n\tCalculation time (4th call)", calculation_time
print("\n\tCalculation time (4th call)", calculation_time)
self.commit()
def test_03_cachePersistentObjects(self):
......@@ -296,9 +297,9 @@ return result
def test_04_CheckConcurrentRamCacheDict(self):
"""Check that all RamCache doesn't clear the same cache_dict
"""
print
print "="*40
print "TESTING: Concurrent RamCache"
print()
print("="*40)
print("TESTING: Concurrent RamCache")
portal = self.portal
result = 'Something short'
......@@ -317,7 +318,7 @@ return result
result=result)
end = time.time()
calculation_time = end-start
print "\n\tCalculation time (1st call)", calculation_time
print("\n\tCalculation time (1st call)", calculation_time)
self.assertEqual(cached, result)
self.commit()
......@@ -328,7 +329,7 @@ return result
result=result)
end = time.time()
calculation_time = end-start
print "\n\tCalculation time (2nd call)", calculation_time
print("\n\tCalculation time (2nd call)", calculation_time)
self.assertTrue(1.0 > calculation_time, "1.0 <= %s" % calculation_time)
self.assertEqual(cached, result)
self.commit()
......@@ -342,7 +343,7 @@ return result
result=result)
end = time.time()
calculation_time = end-start
print "\n\tCalculation time (3rd call)", calculation_time
print("\n\tCalculation time (3rd call)", calculation_time)
self.assertTrue(1.0 > calculation_time, "1.0 <= %s" % calculation_time)
self.assertEqual(cached, result)
self.commit()
......@@ -351,9 +352,9 @@ return result
"""Check that persistent distributed Cache Plugin can handle keys
more than 250 bytes and values more than 1024 bytes.
"""
print
print '=' * 40
print 'TESTING: Long Keys and Large values'
print()
print('=' * 40)
print('TESTING: Long Keys and Large values')
portal = self.portal
# import the local and clear it
from Products.ERP5Type.CachePlugins.DistributedRamCache import\
......@@ -410,7 +411,7 @@ return 'a' * 1024 * 1024 * 25
long_parameter=long_parameter)
end = time.time()
calculation_time = end-start
print "\n\tCalculation time (1st call)", calculation_time
print("\n\tCalculation time (1st call)", calculation_time)
self.assertEqual(cached, result)
self.commit()
......@@ -423,7 +424,7 @@ return 'a' * 1024 * 1024 * 25
long_parameter=long_parameter)
end = time.time()
calculation_time = end-start
print "\n\tCalculation time (2nd call)", calculation_time
print("\n\tCalculation time (2nd call)", calculation_time)
self.assertTrue(1.0 > calculation_time, "1.0 <= %s" % calculation_time)
self.assertEqual(cached, result)
self.commit()
......@@ -431,37 +432,37 @@ return 'a' * 1024 * 1024 * 25
def test_06_CheckCacheExpiration(self):
"""Check that expiracy is well handle by Cache Plugins
"""
print
print "="*40
print "TESTING: Cache Expiration Time"
print()
print("="*40)
print("TESTING: Cache Expiration Time")
py_script_obj = getattr(self.portal, self.python_script_id)
cache_factory_list = ('ram_cache_factory', 'distributed_ram_cache_factory',
'distributed_persistent_cache_factory')
for cache_factory in cache_factory_list:
print '\n\t==> %s' % cache_factory
print('\n\t==> %s' % cache_factory)
my_cache = CachingMethod(py_script_obj,
'py_script_obj',
cache_factory=cache_factory)
# First call, fill the cache
calculation_time = self._callCache(my_cache, real_calculation=True)
print "\n\tCalculation time (1st call)", calculation_time
print("\n\tCalculation time (1st call)", calculation_time)
## 2nd call - should be cached now
calculation_time = self._callCache(my_cache, real_calculation=False)
print "\n\tCalculation time (2nd call)", calculation_time
print("\n\tCalculation time (2nd call)", calculation_time)
# Wait expiration period then check that value is computed
# .1 is an additional epsilon delay to work around time precision issues
time_left_to_wait = .1 + self.cache_duration
print "\n\tSleep %.2f seconds to wait expiration time" % time_left_to_wait
print("\n\tSleep %.2f seconds to wait expiration time" % time_left_to_wait)
time.sleep(time_left_to_wait)
# Call conversion for ram_cache_factory
calculation_time = self._callCache(my_cache, real_calculation=True)
print "\n\tCalculation time (3rd call)", calculation_time
print("\n\tCalculation time (3rd call)", calculation_time)
def test_06_CheckCacheBag(self):
"""
......
......@@ -576,7 +576,7 @@ class TestERP5Core(ERP5TypeTestCase, ZopeTestCase.Functional):
0 != i.getUid() != i.getProperty('uid')])
def test_04_site_manager_and_translation_migration(self):
from zope.site.hooks import setSite
from zope.component.hooks import setSite
from zope.component import queryUtility
# check translation is working normaly
erp5_ui_catalog = self.portal.Localizer.erp5_ui
......
......@@ -33,7 +33,8 @@ import six
from Products.ERP5Type.tests.ERP5TypeTestCase import ERP5TypeTestCase
from Products.ERP5Type.tests.utils import createZODBPythonScript
from Persistence import PersistentMapping
from zope.site.hooks import setSite
from zope.component.hooks import setSite
class TestLocalizer(ERP5TypeTestCase):
def afterSetUp(self):
......
......@@ -289,7 +289,7 @@ class TestProxyField(ERP5TypeTestCase):
python_script_id = "ERP5Site_testAccessProxyFieldProperty"
python_script_parameter = "proxy_field"
python_script_body = """
print proxy_field.getRecursiveTemplateField().meta_type
print (proxy_field.getRecursiveTemplateField().meta_type)
return printed
"""
skin_folder.manage_addProduct['PythonScripts'].manage_addPythonScript(
......
......@@ -6,5 +6,5 @@ portal.event_module.recurseCallMethod(
group_method_cost=1),
min_depth=1,
max_depth=1)
print "Migration started with process id: %s" %active_process.getPath()
print("Migration started with process id: %s" %active_process.getPath())
return printed
......@@ -6,6 +6,6 @@ object_list = list(context.portal_catalog(parent_uid=uids, portal_type = "Email
for o in object_list:
o_value = o.getObject()
if o is not None:
print o_value.getUrlString()
print(o_value.getUrlString())
return printed
......@@ -29,6 +29,7 @@
#
##############################################################################
from __future__ import print_function
import unittest
from AccessControl.SecurityManagement import newSecurityManager
......@@ -131,12 +132,12 @@ class TestEditorField(ERP5TypeTestCase, ZopeTestCase.Functional):
match_string1 = 'data-gadget-editable="field_%s"' % field_id
match_string2 = 'data-gadget-value="%s"' % html_quote(text_content)
if html_text.find(match_string1) == -1:
print html_text
print match_string1
print(html_text)
print(match_string1)
return False
if html_text.find(match_string2) == -1:
print html_text
print match_string2
print(html_text)
print(match_string2)
return False
return True
......@@ -156,13 +157,13 @@ class TestEditorField(ERP5TypeTestCase, ZopeTestCase.Functional):
match_string1 = 'data-gadget-editable="field_%s"' % field_id
match_string2 = 'data-gadget-value="%s"' % html_quote(text_content)
if html_text.find(match_string1) == -1:
print html_text
print match_string1
print(html_text)
print(match_string1)
import pdb; pdb.set_trace()
return False
if html_text.find(match_string2) == -1:
print html_text
print match_string2
print(html_text)
print(match_string2)
import pdb; pdb.set_trace()
return False
return True
......@@ -182,12 +183,12 @@ class TestEditorField(ERP5TypeTestCase, ZopeTestCase.Functional):
match_string1 = "data-gadget-editable="
match_string2 = 'data-gadget-value="%s"' % html_quote(text_content)
if html_text.find(match_string1) != -1:
print html_text
print match_string1
print(html_text)
print(match_string1)
return False
if html_text.find(match_string2) == -1:
print html_text
print match_string2
print(html_text)
print(match_string2)
return False
return True
......
......@@ -872,12 +872,10 @@ class TestDocument(TestDocumentMixin):
self.tic()
test_document_set = {document_1, document_2, document_3, person, web_page, organisation}
def getAdvancedSearchTextResultList(searchable_text, portal_type=None,src__=0):
def getAdvancedSearchTextResultList(searchable_text, portal_type=None):
kw = {'full_text': searchable_text}
if portal_type is not None:
kw['portal_type'] = portal_type
if src__==1:
print portal.portal_catalog(src__=src__,**kw)
result_list = [x.getObject() for x in portal.portal_catalog(**kw)]
return [x for x in result_list if x in test_document_set]
......
......@@ -8,5 +8,5 @@ context.ERP5Site_checkDataWithScript("Base_callPreConvert",
tag="pre_convert",
packet=2,
id_list=["document_module", "image_module", "web_page_module"])
print "OK"
print("OK")
return printed
......@@ -42,5 +42,5 @@ tiolive_logo_image = context.portal_catalog.getResultValue(
if tiolive_logo_image is not None and tiolive_logo_image.getValidationState() == 'published':
tiolive_logo_image.reject()
print "Done"
print("Done")
return printed
......@@ -2,5 +2,9 @@
#portal_preferences = context.portal_preferences
#portal_preferences.manage_delObjects(['dms_system_preference_ui_tests', 'dms_preference_ui_tests'])
#context.portal_caches.clearAllCache()
print "Done"
# Delete System Preference
#portal_preferences = context.portal_preferences
#portal_preferences.manage_delObjects(['dms_system_preference_ui_tests', 'dms_preference_ui_tests'])
#context.portal_caches.clearAllCache()
print("Done")
return printed
......@@ -2,10 +2,10 @@ result = context.GlossaryModule_getTermDictListFromPortalType(portal_type_list)
if export_tsv:
for i in result:
print '\t'.join(['"%s"' % x for x in (i['reference'], i['language'],
print('\t'.join(['"%s"' % x for x in (i['reference'], i['language'],
i['business_field'],
i['title'], i['description'],
i['field_path'])])
i['field_path'])]))
return printed
else:
portal_catalog = context.portal_catalog
......
......@@ -2,10 +2,10 @@ result = context.GlossaryModule_getTermDictListFromPropertySheet(property_sheet_
if export_tsv:
for i in result:
print '\t'.join(['"%s"' % x for x in (i['reference'], i['language'],
print('\t'.join(['"%s"' % x for x in (i['reference'], i['language'],
i['business_field'],
i['title'], i['description'],
i['field_path'])])
i['field_path'])]))
return printed
else:
portal_catalog = context.portal_catalog
......
......@@ -3,10 +3,10 @@ result = context.GlossaryModule_getTermDictListFromWorkflow(template_list)
if export_tsv:
for i in result:
print '\t'.join(['"%s"' % x for x in (i['reference'], i['language'],
print('\t'.join(['"%s"' % x for x in (i['reference'], i['language'],
i['business_field'],
i['title'], i['description'],
i['workflow_id'])])
i['workflow_id'])]))
return printed
else:
portal_catalog = context.portal_catalog
......
......@@ -24,7 +24,7 @@ def formatString(string):
# po header
now = DateTime().toZone('UTC').strftime("%Y-%m-%d %H:%M+0000")
print MESSAGE_TEMPLATE % (dict(english='""',
print(MESSAGE_TEMPLATE % (dict(english='""',
translation=
r'''"Project-Id-Version: ERP5 Localized Interface\n"
"POT-Creation-Date: %s\n"
......@@ -34,7 +34,7 @@ r'''"Project-Id-Version: ERP5 Localized Interface\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
''' % (now, now, language)))
''' % (now, now, language))))
catalog = context.portal_catalog
for i in catalog(portal_type='Glossary Term',
......@@ -63,18 +63,18 @@ for i in catalog(portal_type='Glossary Term',
if not english_title:
raise ValueError('Title of corresponding English term(%s) to "%s" is empty.' % (english_relative_url, translated_title))
if translated_title!=english_title:
print formatMessage(english=formatString(english_title),
print(formatMessage(english=formatString(english_title),
translation=formatString(translated_title),
term=term)
term=term))
if translated_description:
if not english_description:
raise ValueError('Description of corresponding English term(%s) to "%s" is empty.' % (english_relative_url, translated_description))
if translated_description!=english_description:
print formatMessage(english=formatString(english_description),
print(formatMessage(english=formatString(english_description),
translation=formatString(translated_description),
term=term)
term=term))
RESPONSE = context.REQUEST.RESPONSE
RESPONSE.setHeader('Content-disposition', 'attachment;filename=translation.po')
......
......@@ -5,6 +5,6 @@ for i in context.getPortalObject().glossary_module.objectValues():
lang = lang_list[0]
i.setLanguage(lang)
i.setCategoryList([x for x in i.categories if not x.startswith('language/')])
print i.getPath(), lang
print 'Migration finished.'
print(i.getPath(), lang)
print('Migration finished.')
return printed
......@@ -22,28 +22,28 @@ for diff_object in sortDiffObjectList(diff_object_list):
if getattr(diff_object, "error", None) is not None:
print("<p>")
print("Error")
print("(%s) -" % html_quote(diff_object.object_class))
print(("(%s) -" % html_quote(diff_object.object_class)))
if diff_object.object_class in link_configuration:
print(link_configuration[diff_object.object_class] % {"object_id": html_quote(diff_object.object_id)})
print((link_configuration[diff_object.object_class] % {"object_id": html_quote(diff_object.object_id)}))
else:
print(html_quote(diff_object.object_id))
print((html_quote(diff_object.object_id)))
print("</p>")
if detailed:
print("<p>")
print(html_quote(diff_object.error))
print((html_quote(diff_object.error)))
print("</p>")
else:
print("<p>")
print(html_quote(diff_object.object_state))
print("(%s) -" % html_quote(diff_object.object_class))
print((html_quote(diff_object.object_state)))
print(("(%s) -" % html_quote(diff_object.object_class)))
if diff_object.object_class in link_configuration:
print(link_configuration[diff_object.object_class] % {"object_id": html_quote(diff_object.object_id)})
print((link_configuration[diff_object.object_class] % {"object_id": html_quote(diff_object.object_id)}))
else:
print(html_quote(diff_object.object_id))
print((html_quote(diff_object.object_id)))
print("</p>")
if detailed and getattr(diff_object, "data", None) is not None:
print("<div>")
print(DiffFile(diff_object.data).toHTML())
print((DiffFile(diff_object.data).toHTML()))
print("</div>")
print("</div>")
return printed
......@@ -2,14 +2,14 @@ def sortDiffObjectList(diff_object_list):
return sorted(diff_object_list, key=lambda x: (x.object_state, x.object_class, x.object_id))
for diff_object in sortDiffObjectList(diff_object_list):
print("%s (%s) - %s" % (diff_object.object_state, diff_object.object_class, diff_object.object_id))
print(("%s (%s) - %s" % (diff_object.object_state, diff_object.object_class, diff_object.object_id)))
if getattr(diff_object, "error", None) is not None:
if detailed:
print(" %s" % diff_object.error)
print((" %s" % diff_object.error))
print("")
else:
if detailed and getattr(diff_object, "data", None) is not None:
print("%s" % diff_object.data.lstrip())
print(("%s" % diff_object.data.lstrip()))
print("")
return printed
# License: GPL
# Author: Lukasz Nowak <lukasz.nowak@ventis.com.pl>
# Copyright 2007 Ventis s. c.
simulations_found = context.Base_getSimulationTree(start_path=start_path)
if len(simulations_found) == 0:
print 'No simulations related'
print('No simulations related')
else:
for simulation_root in simulations_found.iterkeys():
print simulation_root
for simulation_root in simulations_found:
print(simulation_root)
for simulation in simulations_found[simulation_root]:
print '\t',simulation.getPath(),simulation.getPortalType(),
print('\t',simulation.getPath(),simulation.getPortalType(), end=' ')
if simulation.getPortalType() == 'Simulation Movement':
print simulation.getCausalityState(),
print(simulation.getCausalityState(), end=' ')
else:
print 'nostate',
print simulation.getCategoriesList()
print('nostate', end=' ')
print(simulation.getCategoriesList())
return printed
......@@ -172,10 +172,10 @@ def formatString(string):
else:
return '\n'.join(['""']+[formatString(i) for i in line_list])
print '''msgid ""
print('''msgid ""
msgstr "Content-Type: text/plain; charset=UTF-8"
'''
''')
MESSAGE_TEMPLATE = '''\
%s
......@@ -188,7 +188,7 @@ for message in message_list:
comment_list = message_dict[message]
comment_list.sort()
comment = '\n'.join([('#: %s' % i) for i in comment_list])
print MESSAGE_TEMPLATE % (comment, formatString(message))
print(MESSAGE_TEMPLATE % (comment, formatString(message)))
RESPONSE = context.REQUEST.RESPONSE
RESPONSE.setHeader('Content-disposition', 'attachment;filename=translation.pot')
......
......@@ -48,7 +48,7 @@ recurse(o, callback, seldict)
for selection_name in seldict.keys():
if len(seldict[selection_name]) != 1 or all_selections:
print "'%s' [%s]"%(selection_name,len(seldict[selection_name]))
print("'%s' [%s]"%(selection_name,len(seldict[selection_name])))
for form_name in seldict[selection_name]:
print "\t%s"%(form_name,)
print("\t%s"%(form_name,))
return printed
......@@ -3,12 +3,12 @@
from erp5.component.module.Log import log
log("Obsolete script, please use BaseType_copyRoleList instead")
print 'cloning role information from'
print from_type
print('cloning role information from')
print(from_type)
if to_type_list == ():
to_type_list = (to_type,)
print "to", to_type_list
print("to", to_type_list)
context.portal_types[from_type].BaseType_copyRoleList(remove_existing_roles=True,
portal_type_list=to_type_list)
......
......@@ -2,11 +2,11 @@
"""
portal_skin = context.REQUEST.get('portal_skin', 'View')
print "<html>"
print("<html>")
for field_path, field in context.ZopeFind(
context.portal_skins, obj_metatypes=['ProxyField'], search_sub=1):
if field.getTemplateField() is None:
print '<a href="%s/%s/manage_main?portal_skin=%s">%s</a><br />' % (context.absolute_url(), field_path, portal_skin, field_path)
print('<a href="%s/%s/manage_main?portal_skin=%s">%s</a><br />' % (context.absolute_url(), field_path, portal_skin, field_path))
print "</html>"
print("</html>")
return printed
......@@ -7,9 +7,9 @@ for form_path, form in context.ZopeFind(
try:
groups = form.get_groups()
except AttributeError as e:
print "%s is broken: %s" % (form_path, e)
print("%s is broken: %s" % (form_path, e))
if 'not_assigned' in groups:
print 'Not assigned fields in %s: %s' % (form_path,
[f.getId() for f in form.get_fields_in_group('not_assigned')])
print('Not assigned fields in %s: %s' % (form_path,
[f.getId() for f in form.get_fields_in_group('not_assigned')]))
return printed
......@@ -14,14 +14,14 @@ for field_path, field in context.ZopeFind(
continue
if not (field.get_value('proxy_listbox_ids') or field.get_value('columns')):
print field_path
print(field_path)
continue
for path, name in field.get_value('proxy_listbox_ids'):
if context.restrictedTraverse(path, None) is None:
print ' PROBLEM: field %s uses an invalid form for %s: %s' % (field_path, name, path)
print(' PROBLEM: field %s uses an invalid form for %s: %s' % (field_path, name, path))
else:
proxy_listbox = context.restrictedTraverse(path)
if proxy_listbox.meta_type not in ('ProxyField', 'ListBox'):
print ' PROBLEM: field %s uses an invalid proxy with %s meta_type' % (field_path, proxy_listbox.meta_type)
print(' PROBLEM: field %s uses an invalid proxy with %s meta_type' % (field_path, proxy_listbox.meta_type))
return printed
......@@ -6,7 +6,7 @@ container.REQUEST.RESPONSE.setHeader('content-type', 'text/html')
# make sure context is the skins tool
stool = context.portal_skins
print '<html><body>'
print('<html><body>')
skins_by_name = {}
for skin_key, skin_path_list in stool.getSkinPaths():
......@@ -24,9 +24,9 @@ for skin_key, skin_path_list in stool.getSkinPaths():
for skin_name, location_list in skins_by_name.items():
if len(location_list) > 1:
print skin_name, '<br/>'
print(skin_name, '<br/>')
for location in location_list:
print "&nbsp;" * 3, '<a href="%s/%s/%s/manage_main">%s</a><br/>' % (stool.absolute_url(), location, skin_name, location)
print("&nbsp;" * 3, '<a href="%s/%s/%s/manage_main">%s</a><br/>' % (stool.absolute_url(), location, skin_name, location))
print '</body></html>'
print('</body></html>')
return printed
......@@ -5,7 +5,7 @@ if template_tool.getDiffFilterScriptList():
else:
from erp5.component.module.DiffUtils import DiffFile
print '<div style="color: black">'
print('<div style="color: black">')
# XXX: ERP5VCS_doCreateJavaScriptStatus should send lists
if isinstance(added, basestring):
......@@ -19,20 +19,20 @@ for f in modified:
diff = DiffFile(vcs_tool.diff(f))
if not diff:
continue
print '<input name="modified" value="%s" type="checkbox" checked="checked" />'% f
print vcs_tool.getHeader(f)
print diff.toHTML()
print "<hr/><br/>"
print('<input name="modified" value="%s" type="checkbox" checked="checked" />'% f)
print(vcs_tool.getHeader(f))
print(diff.toHTML())
print("<hr/><br/>")
for f in added:
print '<input name="added" value="%s" type="checkbox" checked="checked" />'% f
print vcs_tool.getHeader(f)
print "<br/><span style='color: green;'>File Added</span><br/><br/><hr/><br/>"
print('<input name="added" value="%s" type="checkbox" checked="checked" />'% f)
print(vcs_tool.getHeader(f))
print("<br/><span style='color: green;'>File Added</span><br/><br/><hr/><br/>")
for f in removed:
print '<input name="removed" value="%s" type="checkbox" checked="checked" />'% f
print vcs_tool.getHeader(f)
print "<br/><span style='color: red;'>File Removed</span><br/><br/><hr/><br/>"
print('<input name="removed" value="%s" type="checkbox" checked="checked" />'% f)
print(vcs_tool.getHeader(f))
print("<br/><span style='color: red;'>File Removed</span><br/><br/><hr/><br/>")
print '</div>'
print('</div>')
return printed
......@@ -9,10 +9,10 @@ from string import capitalize
def addAction(portal_type, portal_type_type, country, amortisation_method):
print 'Adding UI tab "Amortisation Details" for method %s on portal_type %s... ' % (amortisation_method,portal_type),
print('Adding UI tab "Amortisation Details" for method %s on portal_type %s... ' % (amortisation_method,portal_type), end=' ')
id = "%s_%s_amortisation_details_view" % (country, amortisation_method)
if id in [x.id for x in portal_type.listActions()]:
print "Already exists"
print("Already exists")
else:
if portal_type_type == "Immobilisation":
action = "%s_Immobilisation_viewDetails" % amortisation_method
......@@ -27,7 +27,7 @@ def addAction(portal_type, portal_type_type, country, amortisation_method):
permission = ('View',),
category = "object_view",
visible = 1)
print "OK"
print("OK")
return printed
......@@ -44,10 +44,10 @@ amortisation_method = "".join(tokens[1:])
for portal_type in context.portal_types.objectValues():
# Check if the portal_type is Immobilisation
if portal_type.id == "Immobilisation":
print addAction(portal_type, "Immobilisation", country, amortisation_method),
print(addAction(portal_type, "Immobilisation", country, amortisation_method), end=' ')
else:
# Check if the portal_type is amortisable
if "immobilise" in [x.id for x in portal_type.listActions()]:
print addAction(portal_type, "Item", country, amortisation_method),
print(addAction(portal_type, "Item", country, amortisation_method), end=' ')
return printed
......@@ -10,18 +10,18 @@ actions_to_add = [
]
print 'Adding Immobilisation Item Actions to Portal Type %s :' % context.getId()
print('Adding Immobilisation Item Actions to Portal Type %s :' % context.getId())
action_list = context.listActions()
for action_to_add in actions_to_add:
print "- Adding Action '%s (%s)'... " % (action_to_add['id'],action_to_add['name']),
print("- Adding Action '%s (%s)'... " % (action_to_add['id'],action_to_add['name']), end=' ')
found = 0
for action in action_list:
if getattr(action, 'id', None) == action_to_add['id']:
print 'already exists'
print('already exists')
found = 1
if not found:
context.addAction(**action_to_add)
print "OK"
print("OK")
print
print()
return printed
......@@ -8,7 +8,7 @@ amortisation_method_view = 'amortisation_method_view'
action_list = context.listActions()
print "Making portal type '%s' an Immobilisation Movement :" % context.getId()
print("Making portal type '%s' an Immobilisation Movement :" % context.getId())
# Add a view for each amortisation method
amortisation_method_list = context.Immobilisation_getAmortisationMethodList()
for method in amortisation_method_list:
......@@ -17,13 +17,13 @@ for method in amortisation_method_list:
title = method[1].title or id
action_id = view_id_basis % (region, id)
print "- Adding View for method '%s'... " % title,
print("- Adding View for method '%s'... " % title, end=' ')
# Check if the action already exists
exists = 0
for action in action_list:
if getattr(action, "id", None) == action_id:
print "already exists"
print("already exists")
exists = 1
if not exists:
......@@ -37,8 +37,8 @@ for method in amortisation_method_list:
permission = view_permissions_basis,
category = "object_view",
visible=1)
print "OK"
print("OK")
print
print()
return printed
......@@ -18,18 +18,18 @@ actions_to_add = [
]
print 'Adding Immobilisation Item Actions to Portal Type %s :' % context.getId()
print('Adding Immobilisation Item Actions to Portal Type %s :' % context.getId())
action_list = context.listActions()
for action_to_add in actions_to_add:
print "- Adding Action '%s (%s)'... " % (action_to_add['id'],action_to_add['name']),
print("- Adding Action '%s (%s)'... " % (action_to_add['id'],action_to_add['name']), end=' ')
found = 0
for action in action_list:
if getattr(action, 'id', None) == action_to_add['id']:
print 'already exists'
print('already exists')
found = 1
if not found:
context.addAction(**action_to_add)
print "OK"
print("OK")
print
print()
return printed
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="Workflow Variable" module="erp5.portal_type"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_local_properties</string> </key>
<value>
<tuple>
<dictionary>
<item>
<key> <string>id</string> </key>
<value> <string>permission_list</string> </value>
</item>
<item>
<key> <string>type</string> </key>
<value> <string>lines</string> </value>
</item>
</dictionary>
<dictionary>
<item>
<key> <string>id</string> </key>
<value> <string>role_list</string> </value>
</item>
<item>
<key> <string>type</string> </key>
<value> <string>lines</string> </value>
</item>
</dictionary>
<dictionary>
<item>
<key> <string>id</string> </key>
<value> <string>group_list</string> </value>
</item>
<item>
<key> <string>type</string> </key>
<value> <string>lines</string> </value>
</item>
</dictionary>
</tuple>
</value>
</item>
<item>
<key> <string>automatic_update</string> </key>
<value> <int>0</int> </value>
</item>
<item>
<key> <string>comment</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>description</string> </key>
<value> <string>Provides access to workflow history</string> </value>
</item>
<item>
<key> <string>for_catalog</string> </key>
<value> <int>0</int> </value>
</item>
<item>
<key> <string>group_list</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>variable_error_message</string> </value>
</item>
<item>
<key> <string>language</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>permission_list</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>portal_type</string> </key>
<value> <string>Workflow Variable</string> </value>
</item>
<item>
<key> <string>role_list</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>status_included</string> </key>
<value> <int>0</int> </value>
</item>
<item>
<key> <string>title</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>variable_default_expression</string> </key>
<value> <string>state_change/getHistory</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="Workflow Variable" module="erp5.portal_type"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_local_properties</string> </key>
<value>
<tuple>
<dictionary>
<item>
<key> <string>id</string> </key>
<value> <string>permission_list</string> </value>
</item>
<item>
<key> <string>type</string> </key>
<value> <string>lines</string> </value>
</item>
</dictionary>
<dictionary>
<item>
<key> <string>id</string> </key>
<value> <string>role_list</string> </value>
</item>
<item>
<key> <string>type</string> </key>
<value> <string>lines</string> </value>
</item>
</dictionary>
<dictionary>
<item>
<key> <string>id</string> </key>
<value> <string>group_list</string> </value>
</item>
<item>
<key> <string>type</string> </key>
<value> <string>lines</string> </value>
</item>
</dictionary>
</tuple>
</value>
</item>
<item>
<key> <string>automatic_update</string> </key>
<value> <int>0</int> </value>
</item>
<item>
<key> <string>comment</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>description</string> </key>
<value> <string>Provides access to workflow history</string> </value>
</item>
<item>
<key> <string>for_catalog</string> </key>
<value> <int>0</int> </value>
</item>
<item>
<key> <string>group_list</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>variable_error_message</string> </value>
</item>
<item>
<key> <string>language</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>permission_list</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>portal_type</string> </key>
<value> <string>Workflow Variable</string> </value>
</item>
<item>
<key> <string>role_list</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>status_included</string> </key>
<value> <int>0</int> </value>
</item>
<item>
<key> <string>title</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>variable_default_expression</string> </key>
<value> <string>state_change/getHistory</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
user_preferences = context.KnowledgeBox_getDefaultPreferencesDict()
print user_preferences
print(user_preferences)
return printed
......@@ -17,5 +17,5 @@ if remove_existing_pads:
user_knowledge_pad_list = context.ERP5Site_getKnowledgePadListForUser(mode = mode)
context.knowledge_pad_module.manage_delObjects([x.getId() for x in user_knowledge_pad_list])
print "Done"
print("Done")
return printed
......@@ -37,16 +37,16 @@ document_list = portal.portal_catalog(
path_list = [software_product_rurl]
print " Processing File List \r===============================\r"
print(" Processing File List \r===============================\r")
for document_brain in document_list:
document = document_brain.getObject()
if document.getFollowUp():
continue
print document.getId()
print(document.getId())
new_document = document.Base_createCloneDocument(batch_mode=True)
new_id = base_id + new_document.getReference().replace('.', '_')
if new_id in new_document.getParentValue():
print " deleting %s" % new_id
print(" deleting %s" % new_id)
new_document.getParentValue().manage_delObjects([new_id])
new_document.setId(new_id)
path_list.append(new_document.getRelativeUrl())
......@@ -54,8 +54,8 @@ for document_brain in document_list:
# new_document.setVersion(base_id + "dev")
new_document.setFollowUp(software_product_rurl)
print "\r\r Here is your path list\r===============================\r\r"
print '\r'.join(path_list)
print "\r\r===============================\r\r"
print " Done"
print("\r\r Here is your path list\r===============================\r\r")
print('\r'.join(path_list))
print("\r\r===============================\r\r")
print(" Done")
return printed
......@@ -23,6 +23,8 @@ var EnemyDroneAPI = /** @class */ (function () {
this._drone_dict_list = [];
this._acceleration = DEFAULT_ACCELERATION;
this._collision_sector = COLLISION_SECTOR;
this._is_landing = false;
this._is_ready_to_fly = true;
}
/*
** Function called on start phase of the drone, just before onStart AI script
......@@ -49,7 +51,6 @@ var EnemyDroneAPI = /** @class */ (function () {
if (drone._maxSinkRate > drone._maxSpeed) {
throw new Error('max sink rate cannot be superior to max speed');
}
drone._maxOrientation = this.getMaxOrientation();
return;
};
/*
......@@ -57,10 +58,12 @@ var EnemyDroneAPI = /** @class */ (function () {
*/
EnemyDroneAPI.prototype.internal_update = function (context, delta_time) {
context._speed += context._acceleration * delta_time / 1000;
if (context._speed > context._maxSpeed)
if (context._speed > context._maxSpeed) {
context._speed = context._maxSpeed;
if (context._speed < -context._maxSpeed)
}
if (context._speed < -context._maxSpeed) {
context._speed = -context._maxSpeed;
}
var updateSpeed = context._speed * delta_time / 1000;
if (context._direction.x !== 0 ||
context._direction.y !== 0 ||
......@@ -68,13 +71,9 @@ var EnemyDroneAPI = /** @class */ (function () {
context._controlMesh.position.addInPlace(
new BABYLON.Vector3(context._direction.x * updateSpeed,
context._direction.y * updateSpeed,
context._direction.z * updateSpeed));
context._direction.z * updateSpeed)
);
}
var orientationValue = context._maxOrientation *
(context._speed / context._maxSpeed);
context._mesh.rotation = new BABYLON.Vector3(
orientationValue * context._direction.z, 0,
-orientationValue * context._direction.x);
context._controlMesh.computeWorldMatrix(true);
context._mesh.computeWorldMatrix(true);
return;
......@@ -119,7 +118,9 @@ var EnemyDroneAPI = /** @class */ (function () {
EnemyDroneAPI.prototype.internal_setTargetCoordinates =
function (drone, coordinates) {
if (!drone._canPlay) return;
if (!drone._canPlay) {
return;
}
var x = coordinates.x, y = coordinates.y, z = coordinates.z;
if (isNaN(x) || isNaN(y) || isNaN(z)) {
throw new Error('Target coordinates must be numbers');
......@@ -240,7 +241,7 @@ var EnemyDroneAPI = /** @class */ (function () {
' return Math.sqrt((a.x - b.x) ** 2 + (a.y - b.y) ** 2 + (a.z - b.z) ** 2);\n' +
'}\n' +
'\n' +
'me.onStart = function () {\n' +
'me.onStart = function (timestamp) {\n' +
' me.setDirection(0,0,0);\n' +
' return;\n' +
'\n' +
......@@ -279,20 +280,20 @@ var EnemyDroneAPI = /** @class */ (function () {
EnemyDroneAPI.prototype.getMaxAcceleration = function () {
return this._flight_parameters.drone.maxAcceleration;
};
EnemyDroneAPI.prototype.getMaxOrientation = function () {
//TODO should be a game parameter (but how to force value to PI quarters?)
return Math.PI / 4;
EnemyDroneAPI.prototype.getMaxCommandFrequency = function () {
return Infinity;
};
EnemyDroneAPI.prototype.triggerParachute = function (drone) {
EnemyDroneAPI.prototype.land = function (drone) {
var drone_pos = drone.getCurrentPosition();
drone.setTargetCoordinates(drone_pos.latitude, drone_pos.longitude, 5);
drone.setTargetCoordinates(drone_pos.latitude, drone_pos.longitude, 0);
this._is_ready_to_fly = false;
this._is_landing = true;
};
EnemyDroneAPI.prototype.landed = function (drone) {
var drone_pos = drone.getCurrentPosition();
return Math.floor(drone_pos.altitude) < 10;
EnemyDroneAPI.prototype.isReadyToFly = function () {
return this._is_ready_to_fly;
};
EnemyDroneAPI.prototype.exit = function () {
return;
EnemyDroneAPI.prototype.isLanding = function () {
return this._is_landing;
};
EnemyDroneAPI.prototype.getInitialAltitude = function () {
return 0;
......
......@@ -246,7 +246,7 @@
</item>
<item>
<key> <string>serial</string> </key>
<value> <string>1011.46035.33513.61849</string> </value>
<value> <string>1014.60631.26636.59528</string> </value>
</item>
<item>
<key> <string>state</string> </key>
......@@ -266,7 +266,7 @@
</tuple>
<state>
<tuple>
<float>1697031010.99</float>
<float>1709288499.16</float>
<string>UTC</string>
</tuple>
</state>
......
......@@ -31,6 +31,8 @@ var FixedWingDroneAPI = /** @class */ (function () {
this._loiter_radius = 100;
//this._start_altitude = 0;
this._loiter_mode = false;
this._is_landing = false;
this._is_ready_to_fly = true;
this._drone_dict_list = [];
}
/*
......@@ -86,45 +88,19 @@ var FixedWingDroneAPI = /** @class */ (function () {
if (drone._maxClimbRate > drone._maxSpeed) {
throw new Error('max climb rate cannot be superior to max speed');
}
drone._maxOrientation = this.getMaxOrientation();
drone._maxCommandFrequency = this.getMaxCommandFrequency();
if (drone._maxCommandFrequency <= 0) {
throw new Error('max command frequence must be superior to 0');
}
return;
};
/*
** Function called on every drone update, right before onUpdate AI script
*/
FixedWingDroneAPI.prototype.internal_update = function (context, delta_time) {
var diff, newrot, orientationValue, rotStep;
//TODO rotation
if (context._rotationTarget) {
rotStep = BABYLON.Vector3.Zero();
diff = context._rotationTarget.subtract(context._controlMesh.rotation);
rotStep.x = (diff.x >= 1) ? 1 : diff.x;
rotStep.y = (diff.y >= 1) ? 1 : diff.y;
rotStep.z = (diff.z >= 1) ? 1 : diff.z;
if (rotStep === BABYLON.Vector3.Zero()) {
context._rotationTarget = null;
return;
}
newrot = new BABYLON.Vector3(context._controlMesh.rotation.x +
(rotStep.x * context._rotationSpeed),
context._controlMesh.rotation.y +
(rotStep.y * context._rotationSpeed),
context._controlMesh.rotation.z +
(rotStep.z * context._rotationSpeed)
);
context._controlMesh.rotation = newrot;
}
this._updateSpeed(context, delta_time);
this._updatePosition(context, delta_time);
//TODO rotation
orientationValue = context._maxOrientation *
(context._speed / context._maxSpeed);
context._mesh.rotation =
new BABYLON.Vector3(orientationValue * context._direction.z, 0,
-orientationValue * context._direction.x);
context._controlMesh.computeWorldMatrix(true);
context._mesh.computeWorldMatrix(true);
};
......@@ -144,7 +120,7 @@ var FixedWingDroneAPI = /** @class */ (function () {
'latitude' : drone_position.latitude,
'longitude' : drone_position.longitude,
'yaw': drone.getYaw(),
'speed': drone.getAirSpeed(),
'speed': drone.getSpeed(),
'climbRate': drone.getClimbRate()
};
_this._drone_dict_list[_this._id] = drone_info;
......@@ -158,7 +134,7 @@ var FixedWingDroneAPI = /** @class */ (function () {
};
FixedWingDroneAPI.prototype._updateSpeed = function (drone, delta_time) {
var speed = drone.getAirSpeed(), speedDiff, speedUpdate;
var speed = drone.get3DSpeed(), speedDiff, speedUpdate;
if (speed !== this._targetSpeed) {
speedDiff = this._targetSpeed - speed;
speedUpdate = drone._acceleration * delta_time / 1000;
......@@ -231,7 +207,7 @@ var FixedWingDroneAPI = /** @class */ (function () {
verticalSpeed = this._getVerticalSpeed(drone);
groundSpeed = Math.sqrt(
Math.pow(drone.getAirSpeed(), 2) - Math.pow(verticalSpeed, 2)
Math.pow(drone.get3DSpeed(), 2) - Math.pow(verticalSpeed, 2)
);
distance = (groundSpeed * delta_time / 1000) / R;
......@@ -293,39 +269,27 @@ var FixedWingDroneAPI = /** @class */ (function () {
verticalSpeed = this._computeVerticalSpeed(
altitudeDiff,
this.getMaxClimbRate(),
drone.getAirSpeed(),
drone.get3DSpeed(),
this.getMaxPitchAngle()
);
} else {
verticalSpeed = -this._computeVerticalSpeed(
Math.abs(altitudeDiff),
this.getMaxSinkRate(),
drone.getAirSpeed(),
drone.get3DSpeed(),
-this.getMinPitchAngle()
);
}
return verticalSpeed;
};
FixedWingDroneAPI.prototype.setRotation = function (drone, x, y, z) {
//TODO rotation
drone._rotationTarget = new BABYLON.Vector3(x, z, y);
};
FixedWingDroneAPI.prototype.setRotationBy = function (drone, x, y, z) {
//TODO rotation
drone._rotationTarget = new BABYLON.Vector3(drone.rotation.x + x,
drone.rotation.y + z,
drone.rotation.z + y);
};
FixedWingDroneAPI.prototype.setSpeed = function (drone, speed) {
this._targetSpeed = Math.max(
Math.min(speed, this.getMaxSpeed()),
this.getMinSpeed()
);
drone._acceleration = (this._targetSpeed > drone.getAirSpeed()) ?
drone._acceleration = (this._targetSpeed > drone.get3DSpeed()) ?
this.getMaxAcceleration() : -this.getMaxDeceleration();
};
......@@ -345,7 +309,7 @@ var FixedWingDroneAPI = /** @class */ (function () {
};
FixedWingDroneAPI.prototype.internal_setTargetCoordinates =
function (drone, coordinates, radius) {
function (drone, coordinates, speed, radius) {
if (radius) {
this._loiter_mode = true;
if (radius >= LOITER_LIMIT) {
......@@ -354,6 +318,7 @@ var FixedWingDroneAPI = /** @class */ (function () {
} else {
this._loiter_mode = false;
}
this.setSpeed(drone, speed);
};
FixedWingDroneAPI.prototype.sendMsg = function (msg, to) {
......@@ -489,14 +454,13 @@ var FixedWingDroneAPI = /** @class */ (function () {
FixedWingDroneAPI.prototype.getMaxClimbRate = function () {
return this._flight_parameters.drone.maxClimbRate;
};
FixedWingDroneAPI.prototype.getMaxOrientation = function () {
//TODO should be a game parameter (but how to force value to PI quarters?)
return Math.PI / 4;
FixedWingDroneAPI.prototype.getMaxCommandFrequency = function () {
return this._flight_parameters.drone.maxCommandFrequency;
};
FixedWingDroneAPI.prototype.getYawVelocity = function (drone) {
return 360 * EARTH_GRAVITY *
Math.tan(this._toRad(this.getMaxRollAngle())) /
(2 * Math.PI * drone.getAirSpeed());
(2 * Math.PI * drone.get3DSpeed());
};
FixedWingDroneAPI.prototype.getYaw = function (drone) {
var direction = drone.worldDirection;
......@@ -532,25 +496,34 @@ var FixedWingDroneAPI = /** @class */ (function () {
return angle * 180 / Math.PI;
};
FixedWingDroneAPI.prototype.getClimbRate = function (drone) {
return drone.worldDirection.y * drone.getAirSpeed();
return drone.worldDirection.y * drone.get3DSpeed();
};
FixedWingDroneAPI.prototype.getGroundSpeed = function (drone) {
FixedWingDroneAPI.prototype.getSpeed = function (drone) {
var direction = drone.worldDirection;
return Math.sqrt(
Math.pow(direction.x * drone.getAirSpeed(), 2) +
Math.pow(direction.z * drone.getAirSpeed(), 2)
Math.pow(direction.x * drone.get3DSpeed(), 2) +
Math.pow(direction.z * drone.get3DSpeed(), 2)
);
};
FixedWingDroneAPI.prototype.triggerParachute = function (drone) {
var drone_pos = drone.getCurrentPosition();
drone.setTargetCoordinates(drone_pos.latitude, drone_pos.longitude, 5);
FixedWingDroneAPI.prototype.takeOff = function () {
return console.log("Fixed-wing drones can only be taken off manually.");
};
FixedWingDroneAPI.prototype.landed = function (drone) {
FixedWingDroneAPI.prototype.land = function (drone) {
var drone_pos = drone.getCurrentPosition();
return Math.floor(drone_pos.altitude) < 10;
drone.setTargetCoordinates(
drone_pos.latitude,
drone_pos.longitude,
0,
drone.get3DSpeed()
);
this._is_ready_to_fly = false;
this._is_landing = true;
};
FixedWingDroneAPI.prototype.exit = function () {
return;
FixedWingDroneAPI.prototype.isReadyToFly = function () {
return this._is_ready_to_fly;
};
FixedWingDroneAPI.prototype.isLanding = function () {
return this._is_landing;
};
FixedWingDroneAPI.prototype.getInitialAltitude = function () {
return this._map_dict.start_AMSL;
......
......@@ -246,7 +246,7 @@
</item>
<item>
<key> <string>serial</string> </key>
<value> <string>1011.46032.14056.1553</string> </value>
<value> <string>1014.60714.57448.36454</string> </value>
</item>
<item>
<key> <string>state</string> </key>
......@@ -266,7 +266,7 @@
</tuple>
<state>
<tuple>
<float>1696870145.24</float>
<float>1709288420.35</float>
<string>UTC</string>
</tuple>
</state>
......
......@@ -246,7 +246,7 @@
</item>
<item>
<key> <string>serial</string> </key>
<value> <string>1011.57487.9176.36369</string> </value>
<value> <string>1014.60733.7318.44953</string> </value>
</item>
<item>
<key> <string>state</string> </key>
......@@ -266,7 +266,7 @@
</tuple>
<state>
<tuple>
<float>1697558075.38</float>
<float>1709546292.39</float>
<string>UTC</string>
</tuple>
</state>
......
......@@ -153,14 +153,24 @@
<h3>Functions called by game on event</h3>
<!-- Start -->
<h4 class="item-name" id="start"><span>onStart</span><span>: void</span></h4>
<h4 class="item-name" id="start"><span>onStart</span><span>: timestamp</span></h4>
<p class="item-descr">Function called on game start.</p>
<div>
<h5 class="item-param-1">Param</h5>
<h5 class="item-param-2">Description</h5>
</div>
<div>
<p class="item-param-1">timestamp: Integer</p>
<p class="item-param-2">Timestamp in milliseconds from UNIX epoch</p>
</div>
<div>
<h5 class="item-param-1">Example</h5>
</div>
<p class="item-param-1">me.onStart = function() {<br>
<p class="item-param-1">me.onStart = function(timestamp) {<br>
&nbsp;&nbsp;//one time execution code<br>
}
</p>
......@@ -168,7 +178,7 @@
<div class="line"></div>
<!-- Update -->
<h4 class="item-name" id="update"><span>onUpdate</span><span>: void</span></h4>
<h4 class="item-name" id="update"><span>onUpdate</span><span>: timestamp</span></h4>
<p class="item-descr">Function called on game update, 60 times / second. <br></p>
<div>
......@@ -183,7 +193,7 @@
<h5 class="item-param-1">Example</h5>
<p class="item-example">me.onUpdate = function() {<br>
<p class="item-example">me.onUpdate = function(timestamp) {<br>
&nbsp;&nbsp;//code executed 60 times per second<br>
}
</p>
......@@ -340,6 +350,24 @@
<div class="line"></div>
<!-- takeOff -->
<h4 class="item-name" id="takeOff"><span>takeOff</span><span>: void</span></h4>
<p class="item-descr">Trigger drone's takeoff (has only effect on multicopters as fixed wings drones need to take off manually).</p>
<div>
<h5 class="item-param-1">Param</h5>
<h5 class="item-param-2">Description</h5>
</div>
<div>
<h5 class="item-param-1">Example</h5>
</div>
<p class="item-param-1">me.takeOff();<br>
</p>
<div class="line"></div>
<!-- setTargetCoordinates -->
<h4 class="item-name" id="setTargetCoordinates"><span>setTargetCoordinates</span><span>: void</span></h4>
<p class="item-descr">
......@@ -363,39 +391,20 @@
<p class="item-param-1">altitude: Float</p>
<p class="item-param-2">altitude value (in meters).</p>
</div>
<div>
<h5 class="item-param-1">Example</h5>
</div>
<div>
<p class="item-example">
me.setTargetCoordinates(lat, lon, altitude);<br>
</p>
</div>
<div class="line"></div>
<!-- setAirSpeed -->
<h4 class="item-name" id="setAirSpeed"><span>setAirSpeed</span><span>: void</span></h4>
<p class="item-descr">Set the drone speed in meters/second. The drone will move at the given value.</p>
<div>
<h5 class="item-param-1">Param</h5>
<h5 class="item-param-2">Description</h5>
</div>
<div>
<p class="item-param-1">speed: Float</p>
<p class="item-param-2">Speed value</p>
<p class="item-param-2">speed value (in meters per second).</p>
</div>
<div>
<h5 class="item-param-1">Example</h5>
</div>
<p class="item-param-1">me.setAirSpeed(16);<br>
<div>
<p class="item-example">
me.setTargetCoordinates(lat, lon, altitude, speed);<br>
</p>
</div>
<div class="line"></div>
......@@ -458,9 +467,9 @@
<div class="line"></div>
<!-- triggerParachute -->
<h4 class="item-name" id="triggerParachute"><span>triggerParachute</span><span>: void</span></h4>
<p class="item-descr">Indicates the drone to deploy the parachute to finish the landing.</p>
<!-- land -->
<h4 class="item-name" id="land"><span>land</span><span>: void</span></h4>
<p class="item-descr">Indicates the drone to trigger landing.</p>
<div>
<h5 class="item-param-1">Param</h5>
......@@ -471,23 +480,33 @@
<h5 class="item-param-1">Example</h5>
</div>
<p class="item-param-1">me.triggerParachute();<br>
<p class="item-param-1">me.land();<br>
</p>
<div class="line"></div>
<!-- landed -->
<h4 class="item-name" id="landed"><span>landed</span><span>: boolean</span></h4>
<p class="item-descr">Indicates if the drone has landed (reached the floor altitude).</p>
<!-- isReadyToFly -->
<h4 class="item-name" id="isReadyToFly"><span>isReadyToFly</span><span>: void</span></h4>
<p class="item-descr">Check if drone takeoff is finished.</p>
<div>
<h5 class="item-param-1">Example</h5>
</div>
<p class="item-example">
if (me.landed()) {<br>
&nbsp;&nbsp;//do something<br>
}<br>
<p class="item-param-1">me.isReadyToFly();<br>
</p>
<div class="line"></div>
<!-- isLanding -->
<h4 class="item-name" id="isLanding"><span>isLanding</span><span>: void</span></h4>
<p class="item-descr">Check if drone landing has been triggered.</p>
<div>
<h5 class="item-param-1">Example</h5>
</div>
<p class="item-param-1">me.isLanding();<br>
</p>
<div class="line"></div>
......@@ -520,15 +539,15 @@
<div class="line"></div>
<!-- getAirSpeed -->
<h4 class="item-name" id="getAirSpeed"><span>getAirSpeed</span><span>: Float</span></h4>
<p class="item-descr">Get drone air speed in meters/second.</p>
<!-- getSpeed -->
<h4 class="item-name" id="getSpeed"><span>getSpeed</span><span>: Float</span></h4>
<p class="item-descr">Get drone ground speed in meters/second as wind is neglected in simulation. In real flights with fixed wings drones the returned value is the airspeed.</p>
<div>
<h5 class="item-param-1">Example</h5>
</div>
<p class="item-param-1">me.getAirSpeed();<br>
<p class="item-param-1">me.getSpeed();<br>
</p>
<div class="line"></div>
......@@ -572,19 +591,6 @@
<div class="line"></div>
<!-- getSinkRate -->
<h4 class="item-name" id="getSinkRate"><span>getSinkRate</span><span>: Float</span></h4>
<p class="item-descr">Get drone sink rate in meters/second.</p>
<div>
<h5 class="item-param-1">Example</h5>
</div>
<p class="item-param-1">me.getSinkRate();<br>
</p>
<div class="line"></div>
<h3>Drone properties</h3>
<div class="line"></div>
......
......@@ -244,7 +244,7 @@
</item>
<item>
<key> <string>serial</string> </key>
<value> <string>1013.8667.7605.21589</string> </value>
<value> <string>1014.48209.18178.31351</string> </value>
</item>
<item>
<key> <string>state</string> </key>
......@@ -264,7 +264,7 @@
</tuple>
<state>
<tuple>
<float>1702410728.19</float>
<float>1708710825.64</float>
<string>UTC</string>
</tuple>
</state>
......
......@@ -77,6 +77,7 @@ var OperatorAPI = /** @class */ (function () {
MAX_PITCH = 25,
MAX_CLIMB_RATE = 8,
MAX_SINK_RATE = 3,
MAX_COMMAND_FREQUENCY = 2,
NUMBER_OF_DRONES = 5,
// Non-inputs parameters
EPSILON = "15",
......@@ -104,7 +105,7 @@ var OperatorAPI = /** @class */ (function () {
' );\n' +
'}\n' +
'\n' +
'me.onStart = function () {\n' +
'me.onStart = function (timestamp) {\n' +
' me.direction_set = false;\n' +
' me.dodging = false;\n' +
' me.ongoing_detection = false;\n' +
......@@ -136,7 +137,8 @@ var OperatorAPI = /** @class */ (function () {
' me.setTargetCoordinates(\n' +
' me.flag_positions[me.next_checkpoint].position.latitude,\n' +
' me.flag_positions[me.next_checkpoint].position.longitude,\n' +
' me.flag_positions[me.next_checkpoint].position.altitude + me.id\n' +
' me.flag_positions[me.next_checkpoint].position.altitude + me.id,\n' +
' ' + DEFAULT_SPEED + '\n' +
' );\n' +
//' console.log("[DEMO] Going to Checkpoint %d", me.next_checkpoint);\n' +
' }\n' +
......@@ -162,12 +164,6 @@ var OperatorAPI = /** @class */ (function () {
' }\n' +
' return;\n' +
' }\n' +
' if (me.next_checkpoint == me.flag_positions.length) {\n' +
' me.triggerParachute();\n' +
' }\n' +
' if (me.landed()) {\n' +
' me.exit();\n' +
' }\n' +
'};\n' +
'\n' +
'me.onDroneViewInfo = function (drone_view) {\n' +
......@@ -182,7 +178,7 @@ var OperatorAPI = /** @class */ (function () {
' } else {\n' +
' dodge_point.longitude = dodge_point.longitude * -1;\n' +
' }\n' +
' me.setTargetCoordinates(dodge_point.latitude, dodge_point.longitude, me.getCurrentPosition().altitude);\n' +
' me.setTargetCoordinates(dodge_point.latitude, dodge_point.longitude, me.getCurrentPosition().altitude, ' + DEFAULT_SPEED + ');\n' +
' return;\n' +
' }\n' +
'};',
......@@ -680,6 +676,17 @@ var OperatorAPI = /** @class */ (function () {
"hidden": 0,
"type": "FloatField"
},
"my_drone_max_command_frequency": {
"description": "",
"title": "Drone max command frequency",
"default": gadget.state.drone_max_command_frequency,
"css_class": "",
"required": 1,
"editable": 1,
"key": "drone_max_command_frequency",
"hidden": 0,
"type": "FloatField"
},
"my_number_of_drones": {
"description": "",
"title": "Number of drones",
......@@ -708,7 +715,8 @@ var OperatorAPI = /** @class */ (function () {
[["my_drone_min_speed"], ["my_drone_speed"], ["my_drone_max_speed"],
["my_drone_max_acceleration"], ["my_drone_max_deceleration"],
["my_drone_max_roll"], ["my_drone_min_pitch"], ["my_drone_max_pitch"],
["my_drone_max_sink_rate"], ["my_drone_max_climb_rate"]]
["my_drone_max_sink_rate"], ["my_drone_max_climb_rate"],
["my_drone_max_command_frequency"]]
]]
}
});
......@@ -836,6 +844,7 @@ var OperatorAPI = /** @class */ (function () {
"maxPitchAngle": parseFloat(gadget.state.drone_max_pitch),
"maxSinkRate": parseFloat(gadget.state.drone_max_sink_rate),
"maxClimbRate": parseFloat(gadget.state.drone_max_climb_rate),
"maxCommandFrequency": parseFloat(gadget.state.drone_max_command_frequency),
"list": drone_list
},
"gameTime": parseInt(gadget.state.simulation_time, 10),
......@@ -950,6 +959,7 @@ var OperatorAPI = /** @class */ (function () {
operator_script: DEFAULT_OPERATOR_SCRIPT,
drone_script: DEFAULT_SCRIPT_CONTENT,
number_of_drones: NUMBER_OF_DRONES,
drone_max_command_frequency: MAX_COMMAND_FREQUENCY,
drone_max_climb_rate: MAX_CLIMB_RATE,
drone_max_sink_rate: MAX_SINK_RATE,
drone_max_pitch: MAX_PITCH,
......
......@@ -246,7 +246,7 @@
</item>
<item>
<key> <string>serial</string> </key>
<value> <string>1011.57494.145.60023</string> </value>
<value> <string>1014.48194.32365.65399</string> </value>
</item>
<item>
<key> <string>state</string> </key>
......@@ -266,7 +266,7 @@
</tuple>
<state>
<tuple>
<float>1697558059.95</float>
<float>1708709921.07</float>
<string>UTC</string>
</tuple>
</state>
......
......@@ -4,7 +4,7 @@
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Test Drone Capture Flag OJS app (expected failure)</title>
<!-- This test is expected to fail as the drone simulator runs on a web worker canvas, which relies on a very new feature: offscreen canvas
---- This feature is not supported yet by the latest Firefox ESR used in the test nodes -->
---- This feature is not supported yet by the latest Firefox ESR used in the test nodes (error: webgl not supported) -->
</head>
<body>
<table cellpadding="1" cellspacing="1" border="1">
......@@ -30,36 +30,16 @@
<td>//div[contains(@data-gadget-url, 'gadget_erp5_page_drone_capture_flag_script_page.html')]</td>
<td></td>
<tr>
<!-- Check game -->
<tr>
<td>waitForElementPresent</td>
<td>//label[text()='Simulation Speed']</td>
<td></td>
<tr>
<tr>
<td>waitForElementPresent</td>
<td>//div[contains(@data-gadget-url, 'codemirror.gadget.html')]</td>
<td>//span[@id="loading"]</td>
<td></td>
<tr>
<!-- Check panel -->
<tr>
<td>assertElementPresent</td>
<td>//div[contains(@data-gadget-url, 'gadget_erp5_panel_drone_capture_flag.html')]//a[contains(@class, 'ui-icon-puzzle-piece') and text()='Run Game']</td>
<td></td>
<tr>
<!-- Run game -->
<tr>
<td>pause</td>
<td>3000</td>
<td></td>
</tr>
<tr>
<td>click</td>
<td>//div[contains(@data-gadget-url, 'gadget_erp5_page_drone_capture_flag_script_page.html')]//input[@type="submit" and @name="action_run"]</td>
<td></td>
<tr>
<tr>
<td>waitForElementPresent</td>
<td>//span[@id="loading"]</td>
<td>//div[contains(@data-gadget-url, 'gadget_erp5_panel_drone_capture_flag.html')]//a[contains(@class, 'ui-icon-puzzle-piece') and text()='Run Game']</td>
<td></td>
<tr>
<!-- Check simulator gadget and babylon lib -->
......
......@@ -5,13 +5,15 @@
var SIMULATION_SPEED = 10,
SIMULATION_TIME = 270,
MAP_SIZE = 1905,
min_lat = 45.6364,
max_lat = 45.65,
min_lon = 14.2521,
max_lon = 14.2766,
MIN_LAT = 45.6364,
MAX_LAT = 45.65,
MIN_LON = 14.2521,
MAX_LON = 14.2766,
map_height = 700,
start_AMSL = 595,
INIT_LON = 14.2658,
INIT_LAT = 45.6412,
INIT_ALT = 15,
DEFAULT_SPEED = 16,
MAX_ACCELERATION = 6,
MAX_DECELERATION = 1,
......@@ -31,6 +33,7 @@
' else\n' +
' console.log(msg + ": FAIL");\n' +
'}\n' +
'\n' +
'function distance(lat1, lon1, lat2, lon2) {\n' +
' var R = 6371e3, // meters\n' +
' la1 = lat1 * Math.PI / 180, // lat, lon in radians\n' +
......@@ -42,39 +45,46 @@
' h = haversine_phi + Math.cos(la1) * Math.cos(la2) * sin_lon * sin_lon;\n' +
' return 2 * R * Math.asin(Math.sqrt(h));\n' +
'}\n' +
'\n' +
'function compare(coord1, coord2) {\n' +
' assert(coord1.x, coord2.x, "Latitude")\n' +
' assert(coord1.y, coord2.y, "Longitude")\n' +
' assert(coord1.z, coord2.z, "Altitude")\n' +
' assert(coord1.latitude, coord2.latitude, "Latitude")\n' +
' assert(coord1.longitude, coord2.longitude, "Longitude")\n' +
' assert(coord1.altitude, coord2.altitude, "Altitude")\n' +
'}\n' +
'me.onStart = function () {\n' +
' assert(me.getAirSpeed(), 16, "Initial speed");\n' +
'\n' +
'me.onStart = function (timestamp) {\n' +
' assert(me.getSpeed(), ' + DEFAULT_SPEED + ', "Initial speed");\n' +
' assert(me.getYaw(), 0, "Yaw angle")\n' +
' me.initialPosition = me.getCurrentPosition();\n' +
' me.start_time = timestamp;\n' +
' me.setTargetCoordinates(\n' +
' me.initialPosition.x + 0.01,\n' +
' me.initialPosition.y,\n' +
' me.initialPosition.z\n' +
' me.initialPosition.latitude + 0.01,\n' +
' me.initialPosition.longitude,\n' +
' me.getAltitudeAbs(),\n' +
' ' + DEFAULT_SPEED + '\n' +
' );\n' +
'};\n' +
'\n' +
'me.onUpdate = function (timestamp) {\n' +
' var current_position = me.getCurrentPosition(),\n' +
' realDistance = distance(\n' +
' me.initialPosition.x,\n' +
' me.initialPosition.y,\n' +
' me.getCurrentPosition().x,\n' +
' me.getCurrentPosition().y\n' +
').toFixed(8),\n' +
' expectedDistance = (me.getAirSpeed() * timestamp / 1000).toFixed(8);\n' +
' assert(timestamp, 1000 / 60, "Timestamp");\n' +
' me.initialPosition.latitude,\n' +
' me.initialPosition.longitude,\n' +
' me.getCurrentPosition().latitude,\n' +
' me.getCurrentPosition().longitude\n' +
' ).toFixed(8),\n' +
' time_interval = timestamp - me.start_time,\n' +
' expected_interval = 1000 / 60,\n' +
' expectedDistance = (me.getSpeed() * expected_interval / 1000).toFixed(8);\n' +
' assert(time_interval, Math.floor(expected_interval), "Timestamp");\n' +
' assert(realDistance, expectedDistance, "Distance");\n' +
' current_position.x = current_position.x.toFixed(7);\n' +
' current_position.latitude = current_position.latitude.toFixed(7);\n' +
' compare(current_position, {\n' +
' x: (me.initialPosition.x + 2.3992831666911723e-06).toFixed(7),\n' +
' y: me.initialPosition.y,\n' +
' z: me.initialPosition.z\n' +
'});\n' +
'me.exit(me.triggerParachute());\n' +
' latitude: (me.initialPosition.latitude + 2.3992831666911723e-06).toFixed(7),\n' +
' longitude: me.initialPosition.longitude,\n' +
' altitude: me.initialPosition.altitude\n' +
' });\n' +
' me.exit(me.land());\n' +
'};',
DRAW = true,
LOG = true,
......@@ -82,6 +92,7 @@
DRONE_LIST = [],
LOGIC_FILE_LIST = [
'gadget_erp5_page_drone_capture_flag_logic.js',
'gadget_erp5_page_drone_capture_map_utils.js',
'gadget_erp5_page_drone_capture_flag_fixedwingdrone.js',
'gadget_erp5_page_drone_capture_flag_enemydrone.js'
];
......@@ -100,7 +111,7 @@
.declareJob('runGame', function runGame() {
var gadget = this, i,
fragment = gadget.element.querySelector('.simulator_div'),
game_parameters_json, map_json;
game_parameters_json, map_json, operator_init_msg;
DRONE_LIST = [];
fragment = domsugar(gadget.element.querySelector('.simulator_div'),
[domsugar('div')]).firstElementChild;
......@@ -109,26 +120,25 @@
"script_content": DEFAULT_SCRIPT_CONTENT};
}
map_json = {
"map_size": parseFloat(MAP_SIZE),
"height": parseInt(map_height, 10),
"start_AMSL": parseFloat(start_AMSL),
"min_lat": parseFloat(min_lat),
"max_lat": parseFloat(max_lat),
"min_lon": parseFloat(min_lon),
"max_lon": parseFloat(max_lon),
"flag_list": [{
"position": {
"x": -27,
"y": 72,
"z": 10
}
}],
"min_lat": parseFloat(MIN_LAT),
"max_lat": parseFloat(MAX_LAT),
"min_lon": parseFloat(MIN_LON),
"max_lon": parseFloat(MAX_LON),
"flag_list": [],
"obstacle_list" : [],
"drones": {
"user": DRONE_LIST,
"enemy": []
"enemy_list" : [],
"initial_position": {
"longitude": parseFloat(INIT_LON),
"latitude": parseFloat(INIT_LAT),
"altitude": parseFloat(INIT_ALT)
}
};
operator_init_msg = {
"flag_positions": []
};
/*jslint evil: false*/
game_parameters_json = {
"debug_test_mode": true,
"drone": {
......@@ -141,7 +151,8 @@
"minPitchAngle": parseFloat(MIN_PITCH),
"maxPitchAngle": parseFloat(MAX_PITCH),
"maxSinkRate": parseFloat(MAX_SINK_RATE),
"maxClimbRate": parseFloat(MAX_CLIMB_RATE)
"maxClimbRate": parseFloat(MAX_CLIMB_RATE),
"list": DRONE_LIST
},
"gameTime": parseInt(SIMULATION_TIME, 10),
"simulation_speed": parseInt(SIMULATION_SPEED, 10),
......@@ -150,6 +161,7 @@
"communication": 0
},
"map": map_json,
"operator_init_msg": operator_init_msg,
"draw_flight_path": DRAW,
"temp_flight_path": true,
"log_drone_flight": LOG,
......
......@@ -246,7 +246,7 @@
</item>
<item>
<key> <string>serial</string> </key>
<value> <string>1010.33861.49321.40789</string> </value>
<value> <string>1014.60680.20078.34286</string> </value>
</item>
<item>
<key> <string>state</string> </key>
......@@ -266,7 +266,7 @@
</tuple>
<state>
<tuple>
<float>1692294109.04</float>
<float>1709286290.59</float>
<string>UTC</string>
</tuple>
</state>
......
......@@ -207,11 +207,11 @@ var DroneLogAPI = /** @class */ (function () {
DroneLogAPI.prototype.getFlightParameters = function () {
return this._flight_parameters;
};
DroneLogAPI.prototype.exit = function (drone) {
return;
DroneLogAPI.prototype.isReadyToFly = function () {
return true;
};
DroneLogAPI.prototype.set_loiter_mode = function (loiter) {
return;
DroneLogAPI.prototype.getMaxCommandFrequency = function () {
return Infinity;
};
return DroneLogAPI;
......
......@@ -246,7 +246,7 @@
</item>
<item>
<key> <string>serial</string> </key>
<value> <string>1011.48679.53693.47701</string> </value>
<value> <string>1014.60631.26636.59528</string> </value>
</item>
<item>
<key> <string>state</string> </key>
......@@ -266,7 +266,7 @@
</tuple>
<state>
<tuple>
<float>1697030760.48</float>
<float>1709288518.39</float>
<string>UTC</string>
</tuple>
</state>
......
......@@ -30,6 +30,8 @@ var FixedWingDroneAPI = /** @class */ (function () {
this._loiter_radius = 100;
//this._start_altitude = 0;
this._loiter_mode = false;
this._is_landing = false;
this._is_ready_to_fly = true;
this._drone_dict_list = [];
}
Object.defineProperty(FixedWingDroneAPI.prototype, "isCollidable", {
......@@ -90,45 +92,19 @@ var FixedWingDroneAPI = /** @class */ (function () {
if (drone._maxClimbRate > drone._maxSpeed) {
throw new Error('max climb rate cannot be superior to max speed');
}
drone._maxOrientation = this.getMaxOrientation();
drone._maxCommandFrequency = this.getMaxCommandFrequency();
if (drone._maxCommandFrequency <= 0) {
throw new Error('max command frequence must be superior to 0');
}
return;
};
/*
** Function called on every drone update, right before onUpdate AI script
*/
FixedWingDroneAPI.prototype.internal_update = function (context, delta_time) {
var diff, newrot, orientationValue, rotStep;
//TODO rotation
if (context._rotationTarget) {
rotStep = BABYLON.Vector3.Zero();
diff = context._rotationTarget.subtract(context._controlMesh.rotation);
rotStep.x = (diff.x >= 1) ? 1 : diff.x;
rotStep.y = (diff.y >= 1) ? 1 : diff.y;
rotStep.z = (diff.z >= 1) ? 1 : diff.z;
if (rotStep === BABYLON.Vector3.Zero()) {
context._rotationTarget = null;
return;
}
newrot = new BABYLON.Vector3(context._controlMesh.rotation.x +
(rotStep.x * context._rotationSpeed),
context._controlMesh.rotation.y +
(rotStep.y * context._rotationSpeed),
context._controlMesh.rotation.z +
(rotStep.z * context._rotationSpeed)
);
context._controlMesh.rotation = newrot;
}
this._updateSpeed(context, delta_time);
this._updatePosition(context, delta_time);
//TODO rotation
orientationValue = context._maxOrientation *
(context._speed / context._maxSpeed);
context._mesh.rotation =
new BABYLON.Vector3(orientationValue * context._direction.z, 0,
-orientationValue * context._direction.x);
context._controlMesh.computeWorldMatrix(true);
context._mesh.computeWorldMatrix(true);
};
......@@ -148,7 +124,7 @@ var FixedWingDroneAPI = /** @class */ (function () {
'latitude' : drone_position.latitude,
'longitude' : drone_position.longitude,
'yaw': drone.getYaw(),
'speed': drone.getAirSpeed(),
'speed': drone.getSpeed(),
'climbRate': drone.getClimbRate()
};
_this._drone_dict_list[_this._id] = drone_info;
......@@ -162,7 +138,7 @@ var FixedWingDroneAPI = /** @class */ (function () {
};
FixedWingDroneAPI.prototype._updateSpeed = function (drone, delta_time) {
var speed = drone.getAirSpeed(), speedDiff, speedUpdate;
var speed = drone.get3DSpeed(), speedDiff, speedUpdate;
if (speed !== this._targetSpeed) {
speedDiff = this._targetSpeed - speed;
speedUpdate = drone._acceleration * delta_time / 1000;
......@@ -235,7 +211,7 @@ var FixedWingDroneAPI = /** @class */ (function () {
verticalSpeed = this._getVerticalSpeed(drone);
groundSpeed = Math.sqrt(
Math.pow(drone.getAirSpeed(), 2) - Math.pow(verticalSpeed, 2)
Math.pow(drone.get3DSpeed(), 2) - Math.pow(verticalSpeed, 2)
);
distance = (groundSpeed * delta_time / 1000) / R;
......@@ -297,39 +273,27 @@ var FixedWingDroneAPI = /** @class */ (function () {
verticalSpeed = this._computeVerticalSpeed(
altitudeDiff,
this.getMaxClimbRate(),
drone.getAirSpeed(),
drone.get3DSpeed(),
this.getMaxPitchAngle()
);
} else {
verticalSpeed = -this._computeVerticalSpeed(
Math.abs(altitudeDiff),
this.getMaxSinkRate(),
drone.getAirSpeed(),
drone.get3DSpeed(),
-this.getMinPitchAngle()
);
}
return verticalSpeed;
};
FixedWingDroneAPI.prototype.setRotation = function (drone, x, y, z) {
//TODO rotation
drone._rotationTarget = new BABYLON.Vector3(x, z, y);
};
FixedWingDroneAPI.prototype.setRotationBy = function (drone, x, y, z) {
//TODO rotation
drone._rotationTarget = new BABYLON.Vector3(drone.rotation.x + x,
drone.rotation.y + z,
drone.rotation.z + y);
};
FixedWingDroneAPI.prototype.setSpeed = function (drone, speed) {
this._targetSpeed = Math.max(
Math.min(speed, this.getMaxSpeed()),
this.getMinSpeed()
);
drone._acceleration = (this._targetSpeed > drone.getAirSpeed())
drone._acceleration = (this._targetSpeed > drone.get3DSpeed())
? this.getMaxAcceleration() : -this.getMaxDeceleration();
};
......@@ -349,7 +313,7 @@ var FixedWingDroneAPI = /** @class */ (function () {
};
FixedWingDroneAPI.prototype.internal_setTargetCoordinates =
function (drone, coordinates, radius) {
function (drone, coordinates, speed, radius) {
if (radius) {
this._loiter_mode = true;
if (radius >= LOITER_LIMIT) {
......@@ -358,6 +322,7 @@ var FixedWingDroneAPI = /** @class */ (function () {
} else {
this._loiter_mode = false;
}
this.setSpeed(drone, speed);
};
FixedWingDroneAPI.prototype.sendMsg = function (msg, to) {
......@@ -447,14 +412,13 @@ var FixedWingDroneAPI = /** @class */ (function () {
FixedWingDroneAPI.prototype.getMaxClimbRate = function () {
return this._flight_parameters.drone.maxClimbRate;
};
FixedWingDroneAPI.prototype.getMaxOrientation = function () {
//TODO should be a game parameter (but how to force value to PI quarters?)
return Math.PI / 4;
FixedWingDroneAPI.prototype.getMaxCommandFrequency = function () {
return this._flight_parameters.drone.maxCommandFrequency;
};
FixedWingDroneAPI.prototype.getYawVelocity = function (drone) {
return 360 * EARTH_GRAVITY
* Math.tan(this._toRad(this.getMaxRollAngle()))
/ (2 * Math.PI * drone.getAirSpeed());
/ (2 * Math.PI * drone.get3DSpeed());
};
FixedWingDroneAPI.prototype.getYaw = function (drone) {
var direction = drone.worldDirection;
......@@ -491,25 +455,34 @@ var FixedWingDroneAPI = /** @class */ (function () {
return angle * 180 / Math.PI;
};
FixedWingDroneAPI.prototype.getClimbRate = function (drone) {
return drone.worldDirection.y * drone.getAirSpeed();
return drone.worldDirection.y * drone.get3DSpeed();
};
FixedWingDroneAPI.prototype.getGroundSpeed = function (drone) {
FixedWingDroneAPI.prototype.getSpeed = function (drone) {
var direction = drone.worldDirection;
return Math.sqrt(
Math.pow(direction.x * drone.getAirSpeed(), 2)
+ Math.pow(direction.z * drone.getAirSpeed(), 2)
Math.pow(direction.x * drone.get3DSpeed(), 2)
+ Math.pow(direction.z * drone.get3DSpeed(), 2)
);
};
FixedWingDroneAPI.prototype.triggerParachute = function (drone) {
var drone_pos = drone.getCurrentPosition();
drone.setTargetCoordinates(drone_pos.latitude, drone_pos.longitude, 5);
FixedWingDroneAPI.prototype.takeOff = function () {
return console.log("Fixed-wing drones can only be taken off manually.");
};
FixedWingDroneAPI.prototype.landed = function (drone) {
FixedWingDroneAPI.prototype.land = function (drone) {
var drone_pos = drone.getCurrentPosition();
return Math.floor(drone_pos.altitude) < 10;
drone.setTargetCoordinates(
drone_pos.latitude,
drone_pos.longitude,
0,
drone.get3DSpeed()
);
this._is_ready_to_fly = false;
this._is_landing = true;
};
FixedWingDroneAPI.prototype.exit = function () {
return;
FixedWingDroneAPI.prototype.isReadyToFly = function () {
return this._is_ready_to_fly;
};
FixedWingDroneAPI.prototype.isLanding = function () {
return this._is_landing;
};
FixedWingDroneAPI.prototype.getInitialAltitude = function () {
return this._map_dict.start_AMSL;
......
......@@ -240,7 +240,7 @@
</item>
<item>
<key> <string>serial</string> </key>
<value> <string>1011.48679.53693.47701</string> </value>
<value> <string>1014.60724.24572.64853</string> </value>
</item>
<item>
<key> <string>state</string> </key>
......@@ -260,7 +260,7 @@
</tuple>
<state>
<tuple>
<float>1697030763.04</float>
<float>1709289024.77</float>
<string>UTC</string>
</tuple>
</state>
......
......@@ -25,11 +25,11 @@ var DroneManager = /** @class */ (function () {
this._maxRollAngle = 0;
this._maxSinkRate = 0;
this._maxClimbRate = 0;
this._maxOrientation = 0;
this._maxCommandFrequency = 0;
this._last_command_timestamp = 0;
this._speed = 0;
this._acceleration = 0;
this._direction = new BABYLON.Vector3(0, 0, 1); // North
this._rotationSpeed = 0.4;
this._scene = scene;
this._canUpdate = true;
this._id = id;
......@@ -126,7 +126,7 @@ var DroneManager = /** @class */ (function () {
this._canCommunicate = true;
this._targetCoordinates = initial_position;
try {
return this.onStart();
return this.onStart(this._API._gameManager._game_duration);
} catch (error) {
console.warn('Drone crashed on start due to error:', error);
this._internal_crash(error);
......@@ -136,22 +136,29 @@ var DroneManager = /** @class */ (function () {
* Set a target point to move
*/
DroneManager.prototype.setTargetCoordinates =
function (latitude, longitude, altitude) {
this._internal_setTargetCoordinates(latitude, longitude, altitude);
function (latitude, longitude, altitude, speed) {
this._internal_setTargetCoordinates(latitude, longitude, altitude, speed);
};
DroneManager.prototype._internal_setTargetCoordinates =
function (latitude, longitude, altitude, radius) {
if (!this._canPlay) {
function (latitude, longitude, altitude, speed, radius) {
if (!this._canPlay || !this.isReadyToFly()) {
return;
}
if (this._API._gameManager._game_duration - this._last_command_timestamp
< 1000 / this._API.getMaxCommandFrequency()) {
this._internal_crash(new Error('Minimum interval between commands is ' +
1000 / this._API.getMaxCommandFrequency() + ' milliseconds'));
}
//convert real geo-coordinates to virtual x-y coordinates
this._targetCoordinates =
this._API.processCoordinates(latitude, longitude, altitude);
return this._API.internal_setTargetCoordinates(
this._API.internal_setTargetCoordinates(
this,
this._targetCoordinates,
speed,
radius
);
this._last_command_timestamp = this._API._gameManager._game_duration;
};
DroneManager.prototype.internal_update = function (delta_time) {
var context = this;
......@@ -197,15 +204,6 @@ var DroneManager = /** @class */ (function () {
}
return this._API.setStartingPosition(this, x, y, z);
};
DroneManager.prototype.setAirSpeed = function (speed) {
if (!this._canPlay) {
return;
}
if (isNaN(speed)) {
throw new Error('Speed must be a number');
}
return this._API.setSpeed(this, speed);
};
DroneManager.prototype.setDirection = function (x, y, z) {
if (!this._canPlay) {
return;
......@@ -217,20 +215,6 @@ var DroneManager = /** @class */ (function () {
this._direction = new BABYLON.Vector3(x, z, y).normalize();
};
//TODO rotation
DroneManager.prototype.setRotation = function (x, y, z) {
if (!this._canPlay) {
return;
}
return this._API.setRotation(this, x, y, z);
};
DroneManager.prototype.setRotationBy = function (x, y, z) {
if (!this._canPlay) {
return;
}
return this._API.setRotation(this, x, y, z);
};
/**
* Send a message to drones
* @param msg The message to send
......@@ -299,11 +283,12 @@ var DroneManager = /** @class */ (function () {
* Make the drone loiter (circle with a set radius)
*/
DroneManager.prototype.loiter =
function (latitude, longitude, altitude, radius) {
function (latitude, longitude, altitude, radius, speed) {
this._internal_setTargetCoordinates(
latitude,
longitude,
altitude,
speed,
radius
);
};
......@@ -316,27 +301,29 @@ var DroneManager = /** @class */ (function () {
DroneManager.prototype.getYaw = function () {
return this._API.getYaw(this);
};
DroneManager.prototype.getAirSpeed = function () {
DroneManager.prototype.get3DSpeed = function () {
return this._speed;
};
DroneManager.prototype.getGroundSpeed = function () {
return this._API.getGroundSpeed(this);
DroneManager.prototype.getSpeed = function () {
return this._API.getSpeed(this);
};
DroneManager.prototype.getClimbRate = function () {
return this._API.getClimbRate(this);
};
DroneManager.prototype.getSinkRate = function () {
return this._API.getSinkRate();
DroneManager.prototype.takeOff = function () {
return this._API.takeOff();
};
DroneManager.prototype.triggerParachute = function () {
return this._API.triggerParachute(this);
DroneManager.prototype.land = function () {
return this._API.land(this);
};
DroneManager.prototype.exit = function () {
this._internal_crash();
return this._API.exit();
return this._internal_crash();
};
DroneManager.prototype.isReadyToFly = function () {
return this._API.isReadyToFly();
};
DroneManager.prototype.landed = function () {
return this._API.landed(this);
DroneManager.prototype.isLanding = function () {
return this._API.isLanding();
};
/**
* Set the drone last checkpoint reached
......@@ -349,12 +336,12 @@ var DroneManager = /** @class */ (function () {
/**
* Function called on game start
*/
DroneManager.prototype.onStart = function () { return; };
DroneManager.prototype.onStart = function (timestamp) { return; };
/**
* Function called on game update
* @param timestamp The tic value
*/
DroneManager.prototype.onUpdate = function () { return; };
DroneManager.prototype.onUpdate = function (timestamp) { return; };
/**
* Function called when drone crashes
*/
......@@ -675,8 +662,12 @@ var GameManager = /** @class */ (function () {
drone._tick += 1;
if (drone._API.isCollidable && drone.can_play) {
if (drone.getCurrentPosition().altitude <= 0) {
if (!drone.isLanding()) {
drone._internal_crash(new Error('Drone ' + drone.id +
' touched the floor.'));
} else {
drone._internal_crash();
}
} else {
_this._droneList.forEach(function (other) {
if (other.can_play && drone.id !== other.id) {
......@@ -729,7 +720,7 @@ var GameManager = /** @class */ (function () {
game_manager._game_duration, geo_coordinates.latitude,
geo_coordinates.longitude,
map_info.start_AMSL + drone_position.z,
drone_position.z, drone.getYaw(), drone.getGroundSpeed(),
drone_position.z, drone.getYaw(), drone.getSpeed(),
drone.getClimbRate()
]);
}
......@@ -912,8 +903,8 @@ var GameManager = /** @class */ (function () {
_this.ongoing_update_promise = null;
_this.finish_deferred = RSVP.defer();
console.log("Simulation started.");
this._game_duration = 0;
this._totalTime = GAMEPARAMETERS.gameTime;
this._game_duration = Date.now();
this._totalTime = GAMEPARAMETERS.gameTime + this._game_duration;
return new RSVP.Queue()
.push(function () {
......
......@@ -240,7 +240,7 @@
</item>
<item>
<key> <string>serial</string> </key>
<value> <string>1011.48744.22696.33177</string> </value>
<value> <string>1014.60716.53618.32563</string> </value>
</item>
<item>
<key> <string>state</string> </key>
......@@ -260,7 +260,7 @@
</tuple>
<state>
<tuple>
<float>1697032866.09</float>
<float>1709288704.17</float>
<string>UTC</string>
</tuple>
</state>
......
......@@ -22,6 +22,7 @@
MAX_PITCH = 25,
MAX_CLIMB_RATE = 8,
MAX_SINK_RATE = 3,
MAX_COMMAND_FREQUENCY = 2,
INITIAL_POSITION = {
"latitude": 45.6412,
"longitude": 14.2658,
......@@ -87,18 +88,19 @@
' return 2 * R * Math.asin(Math.sqrt(h));\n' +
'}\n' +
'\n' +
'me.onStart = function () {\n' +
'me.onStart = function (timestamp) {\n' +
' me.direction_set = false;\n' +
' me.next_checkpoint = 0;\n' +
'};\n' +
'\n' +
'me.onUpdate = function (timestamp) {' +
'me.onUpdate = function (timestamp) {\n' +
' if (!me.direction_set) {\n' +
' if (me.next_checkpoint < CHECKPOINT_LIST.length) {\n' +
' me.setTargetCoordinates(\n' +
' CHECKPOINT_LIST[me.next_checkpoint].latitude,\n' +
' CHECKPOINT_LIST[me.next_checkpoint].longitude,\n' +
' CHECKPOINT_LIST[me.next_checkpoint].altitude + ALTITUDE + ALTITUDE * me.id\n' +
' CHECKPOINT_LIST[me.next_checkpoint].altitude + ALTITUDE + ALTITUDE * me.id,\n' +
' ' + DEFAULT_SPEED + '\n' +
' );\n' +
' console.log("[DEMO] Going to Checkpoint %d", me.next_checkpoint);\n' +
' }\n' +
......@@ -299,6 +301,17 @@
"hidden": 0,
"type": "FloatField"
},
"my_drone_max_command_frequency": {
"description": "",
"title": "Drone max command frequency",
"default": MAX_COMMAND_FREQUENCY,
"css_class": "",
"required": 1,
"editable": 1,
"key": "drone_max_command_frequency",
"hidden": 0,
"type": "FloatField"
},
"my_minimum_latitud": {
"description": "",
"title": "Minimum latitude",
......@@ -441,7 +454,8 @@
[["my_start_AMSL"], ["my_drone_min_speed"], ["my_drone_speed"],
["my_drone_max_speed"], ["my_drone_max_acceleration"],
["my_drone_max_deceleration"], ["my_drone_max_roll"], ["my_drone_min_pitch"],
["my_drone_max_pitch"], ["my_drone_max_sink_rate"], ["my_drone_max_climb_rate"]]
["my_drone_max_pitch"], ["my_drone_max_sink_rate"], ["my_drone_max_climb_rate"],
["my_drone_max_command_frequency"]]
], [
"bottom",
[["my_script"]]
......@@ -479,7 +493,8 @@
"minPitchAngle": parseFloat(options.drone_min_pitch),
"maxPitchAngle": parseFloat(options.drone_max_pitch),
"maxSinkRate": parseFloat(options.drone_max_sink_rate),
"maxClimbRate": parseFloat(options.drone_max_climb_rate)
"maxClimbRate": parseFloat(options.drone_max_climb_rate),
"maxCommandFrequency": parseFloat(options.drone_max_command_frequency)
},
"gameTime": parseInt(options.simulation_time, 10),
"simulation_speed": parseInt(options.simulation_speed, 10),
......
......@@ -246,7 +246,7 @@
</item>
<item>
<key> <string>serial</string> </key>
<value> <string>1011.48716.48246.13943</string> </value>
<value> <string>1014.60725.60577.24917</string> </value>
</item>
<item>
<key> <string>state</string> </key>
......@@ -266,7 +266,7 @@
</tuple>
<state>
<tuple>
<float>1697031250.03</float>
<float>1709289017.41</float>
<string>UTC</string>
</tuple>
</state>
......
......@@ -56,14 +56,16 @@
' assert(coord1.altitude, coord2.altitude, "Altitude")\n' +
'}\n' +
'\n' +
'me.onStart = function () {\n' +
' assert(me.getAirSpeed(), 16, "Initial speed");\n' +
'me.onStart = function (timestamp) {\n' +
' assert(me.getSpeed(), ' + DEFAULT_SPEED + ', "Initial speed");\n' +
' assert(me.getYaw(), 0, "Yaw angle")\n' +
' me.initialPosition = me.getCurrentPosition();\n' +
' me.start_time = timestamp;\n' +
' me.setTargetCoordinates(\n' +
' me.initialPosition.latitude + 0.01,\n' +
' me.initialPosition.longitude,\n' +
' me.getAltitudeAbs()\n' +
' me.getAltitudeAbs(),\n' +
' ' + DEFAULT_SPEED + '\n' +
' );\n' +
'};\n' +
'\n' +
......@@ -75,8 +77,10 @@
' me.getCurrentPosition().latitude,\n' +
' me.getCurrentPosition().longitude\n' +
' ).toFixed(8),\n' +
' expectedDistance = (me.getAirSpeed() * timestamp / 1000).toFixed(8);\n' +
' assert(timestamp, 1000 / 60, "Timestamp");\n' +
' time_interval = timestamp - me.start_time,\n' +
' expected_interval = 1000 / 60,\n' +
' expectedDistance = (me.getSpeed() * expected_interval / 1000).toFixed(8);\n' +
' assert(time_interval.toFixed(4), expected_interval.toFixed(4), "Timestamp");\n' +
' assert(realDistance, expectedDistance, "Distance");\n' +
' current_position.latitude = current_position.latitude.toFixed(7);\n' +
' compare(current_position, {\n' +
......@@ -84,7 +88,7 @@
' longitude: me.initialPosition.longitude,\n' +
' altitude: me.initialPosition.altitude\n' +
' });\n' +
' me.exit(me.triggerParachute());\n' +
' me.exit(me.land());\n' +
'};',
DRAW = true,
LOG = true,
......
......@@ -246,7 +246,7 @@
</item>
<item>
<key> <string>serial</string> </key>
<value> <string>1012.50925.12802.42871</string> </value>
<value> <string>1014.60681.20667.37171</string> </value>
</item>
<item>
<key> <string>state</string> </key>
......@@ -266,7 +266,7 @@
</tuple>
<state>
<tuple>
<float>1701095838.64</float>
<float>1709286436.53</float>
<string>UTC</string>
</tuple>
</state>
......
container.REQUEST.RESPONSE.setHeader('Content-Type', 'text/html')
print "<html><body><h1 class='test-script-title'>Title is : " + parameter + "</h1></body></html>"
print("<html><body><h1 class='test-script-title'>Title is : " + parameter + "</h1></body></html>")
return printed
......@@ -8,8 +8,8 @@ line_dict_list = context.PaySheetTransaction_getLineListAsDict()
title_list = ['Designation\t\t', 'Base', 'Employer Rate', 'Employer Share',
'Employee Rate', 'Employee Share']
print '\t\t'.join(title_list)
print ''
print('\t\t'.join(title_list))
print('')
def rightPad(string, length):
string=str(string)
......@@ -36,6 +36,6 @@ for line in line_dict_list:
string_to_display.append(rightPad(' ', 24))
string_to_display.append(rightPad(' ', 24))
print ''.join(string_to_display)
print(''.join(string_to_display))
return printed
......@@ -60,7 +60,7 @@
</item>
<item>
<key> <string>title</string> </key>
<value> <string>Print DSN report</string> </value>
<value> <string>Print DSN</string> </value>
</item>
<item>
<key> <string>visible</string> </key>
......@@ -77,7 +77,7 @@
<dictionary>
<item>
<key> <string>text</string> </key>
<value> <string>string:${object_url}/DSNReport_printAsFile</string> </value>
<value> <string>string:${object_url}/DSNMonthlyReport_viewFilePrintDialog</string> </value>
</item>
</dictionary>
</pickle>
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment