diff --git a/.classpath b/.classpath
index 56f0fa7..6c32ed5 100644
--- a/.classpath
+++ b/.classpath
@@ -1,36 +1,20 @@
-
-
-
+
-
-
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
diff --git a/.gitignore b/.gitignore
index 9a75992..7f1aabf 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,4 +1,2 @@
-/bin
-/build
-/dist
+/build/
*~
diff --git a/.project b/.project
index 610e8d9..ba6a56a 100644
--- a/.project
+++ b/.project
@@ -1,17 +1,19 @@
- StatoolInfos
+ StatoolInfosWeb
+ kiss4web
+ StatoolInfos
- org.eclipse.wst.common.project.facet.core.builder
+ org.eclipse.jdt.core.javabuilder
- org.eclipse.jdt.core.javabuilder
+ org.eclipse.wst.common.project.facet.core.builder
@@ -24,7 +26,8 @@
org.eclipse.jem.workbench.JavaEMFNature
org.eclipse.wst.common.modulecore.ModuleCoreNature
- org.eclipse.jdt.core.javanature
org.eclipse.wst.common.project.facet.core.nature
+ org.eclipse.jdt.core.javanature
+ org.eclipse.wst.jsdt.core.jsNature
diff --git a/.settings/.jsdtscope b/.settings/.jsdtscope
new file mode 100644
index 0000000..365979b
--- /dev/null
+++ b/.settings/.jsdtscope
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/.settings/com.wdev91.eclipse.copyright.xml b/.settings/com.wdev91.eclipse.copyright.xml
deleted file mode 100644
index 7683676..0000000
--- a/.settings/com.wdev91.eclipse.copyright.xml
+++ /dev/null
@@ -1,59 +0,0 @@
-
-
-
- .]]>
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/.settings/org.eclipse.core.resources.prefs b/.settings/org.eclipse.core.resources.prefs
new file mode 100644
index 0000000..99f26c0
--- /dev/null
+++ b/.settings/org.eclipse.core.resources.prefs
@@ -0,0 +1,2 @@
+eclipse.preferences.version=1
+encoding/=UTF-8
diff --git a/.settings/org.eclipse.jdt.core.prefs b/.settings/org.eclipse.jdt.core.prefs
index fbce724..2c0ff1c 100644
--- a/.settings/org.eclipse.jdt.core.prefs
+++ b/.settings/org.eclipse.jdt.core.prefs
@@ -11,9 +11,9 @@ org.eclipse.jdt.core.codeComplete.staticFinalFieldPrefixes=
org.eclipse.jdt.core.codeComplete.staticFinalFieldSuffixes=
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
org.eclipse.jdt.core.compiler.codegen.methodParameters=do not generate
-org.eclipse.jdt.core.compiler.codegen.targetPlatform=11
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=17
org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
-org.eclipse.jdt.core.compiler.compliance=11
+org.eclipse.jdt.core.compiler.compliance=17
org.eclipse.jdt.core.compiler.debug.lineNumber=generate
org.eclipse.jdt.core.compiler.debug.localVariable=generate
org.eclipse.jdt.core.compiler.debug.sourceFile=generate
@@ -22,19 +22,28 @@ org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning
org.eclipse.jdt.core.compiler.release=enabled
-org.eclipse.jdt.core.compiler.source=11
+org.eclipse.jdt.core.compiler.source=17
org.eclipse.jdt.core.formatter.align_assignment_statements_on_columns=false
org.eclipse.jdt.core.formatter.align_fields_grouping_blank_lines=2147483647
+org.eclipse.jdt.core.formatter.align_selector_in_method_invocation_on_expression_first_line=false
org.eclipse.jdt.core.formatter.align_type_members_on_columns=false
org.eclipse.jdt.core.formatter.align_variable_declarations_on_columns=false
org.eclipse.jdt.core.formatter.align_with_spaces=false
org.eclipse.jdt.core.formatter.alignment_for_additive_operator=16
+org.eclipse.jdt.core.formatter.alignment_for_annotations_on_enum_constant=49
+org.eclipse.jdt.core.formatter.alignment_for_annotations_on_field=49
+org.eclipse.jdt.core.formatter.alignment_for_annotations_on_local_variable=49
+org.eclipse.jdt.core.formatter.alignment_for_annotations_on_method=49
+org.eclipse.jdt.core.formatter.alignment_for_annotations_on_package=49
+org.eclipse.jdt.core.formatter.alignment_for_annotations_on_parameter=0
+org.eclipse.jdt.core.formatter.alignment_for_annotations_on_type=49
org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression=16
org.eclipse.jdt.core.formatter.alignment_for_arguments_in_annotation=0
org.eclipse.jdt.core.formatter.alignment_for_arguments_in_enum_constant=16
org.eclipse.jdt.core.formatter.alignment_for_arguments_in_explicit_constructor_call=16
org.eclipse.jdt.core.formatter.alignment_for_arguments_in_method_invocation=16
org.eclipse.jdt.core.formatter.alignment_for_arguments_in_qualified_allocation_expression=16
+org.eclipse.jdt.core.formatter.alignment_for_assertion_message=0
org.eclipse.jdt.core.formatter.alignment_for_assignment=0
org.eclipse.jdt.core.formatter.alignment_for_bitwise_operator=16
org.eclipse.jdt.core.formatter.alignment_for_compact_if=16
@@ -44,6 +53,8 @@ org.eclipse.jdt.core.formatter.alignment_for_conditional_expression_chain=0
org.eclipse.jdt.core.formatter.alignment_for_enum_constants=49
org.eclipse.jdt.core.formatter.alignment_for_expressions_in_array_initializer=16
org.eclipse.jdt.core.formatter.alignment_for_expressions_in_for_loop_header=0
+org.eclipse.jdt.core.formatter.alignment_for_expressions_in_switch_case_with_arrow=0
+org.eclipse.jdt.core.formatter.alignment_for_expressions_in_switch_case_with_colon=0
org.eclipse.jdt.core.formatter.alignment_for_logical_operator=16
org.eclipse.jdt.core.formatter.alignment_for_method_declaration=0
org.eclipse.jdt.core.formatter.alignment_for_module_statements=16
@@ -52,6 +63,7 @@ org.eclipse.jdt.core.formatter.alignment_for_multiplicative_operator=16
org.eclipse.jdt.core.formatter.alignment_for_parameterized_type_references=0
org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration=16
org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_permitted_types_in_type_declaration=16
org.eclipse.jdt.core.formatter.alignment_for_record_components=16
org.eclipse.jdt.core.formatter.alignment_for_relational_operator=0
org.eclipse.jdt.core.formatter.alignment_for_resources_in_try=80
@@ -62,8 +74,10 @@ org.eclipse.jdt.core.formatter.alignment_for_superclass_in_type_declaration=16
org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_enum_declaration=16
org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_record_declaration=16
org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_type_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_switch_case_with_arrow=0
org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_constructor_declaration=16
org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_method_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_type_annotations=0
org.eclipse.jdt.core.formatter.alignment_for_type_arguments=0
org.eclipse.jdt.core.formatter.alignment_for_type_parameters=0
org.eclipse.jdt.core.formatter.alignment_for_union_type_in_multicatch=16
@@ -112,6 +126,7 @@ org.eclipse.jdt.core.formatter.comment.indent_tag_description=false
org.eclipse.jdt.core.formatter.comment.insert_new_line_before_root_tags=insert
org.eclipse.jdt.core.formatter.comment.insert_new_line_between_different_tags=do not insert
org.eclipse.jdt.core.formatter.comment.insert_new_line_for_parameter=insert
+org.eclipse.jdt.core.formatter.comment.javadoc_do_not_separate_block_tags=false
org.eclipse.jdt.core.formatter.comment.line_length=80
org.eclipse.jdt.core.formatter.comment.new_lines_at_block_boundaries=true
org.eclipse.jdt.core.formatter.comment.new_lines_at_javadoc_boundaries=true
@@ -151,13 +166,6 @@ org.eclipse.jdt.core.formatter.insert_new_line_before_closing_brace_in_array_ini
org.eclipse.jdt.core.formatter.insert_new_line_before_else_in_if_statement=insert
org.eclipse.jdt.core.formatter.insert_new_line_before_finally_in_try_statement=insert
org.eclipse.jdt.core.formatter.insert_new_line_before_while_in_do_statement=do not insert
-org.eclipse.jdt.core.formatter.insert_new_line_in_empty_annotation_declaration=insert
-org.eclipse.jdt.core.formatter.insert_new_line_in_empty_anonymous_type_declaration=insert
-org.eclipse.jdt.core.formatter.insert_new_line_in_empty_block=insert
-org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_constant=insert
-org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_declaration=insert
-org.eclipse.jdt.core.formatter.insert_new_line_in_empty_method_body=insert
-org.eclipse.jdt.core.formatter.insert_new_line_in_empty_type_declaration=insert
org.eclipse.jdt.core.formatter.insert_space_after_additive_operator=insert
org.eclipse.jdt.core.formatter.insert_space_after_and_in_type_parameter=insert
org.eclipse.jdt.core.formatter.insert_space_after_arrow_in_switch_case=insert
@@ -191,6 +199,7 @@ org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_invocation_arg
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_field_declarations=insert
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_local_declarations=insert
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_parameterized_type_reference=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_permitted_types=insert
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_record_components=insert
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_superinterfaces=insert
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_switch_case_expressions=insert
@@ -282,6 +291,7 @@ org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_invocation_ar
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_field_declarations=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_local_declarations=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_parameterized_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_permitted_types=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_record_components=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_superinterfaces=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_switch_case_expressions=do not insert
@@ -365,6 +375,8 @@ org.eclipse.jdt.core.formatter.keep_simple_do_while_body_on_same_line=false
org.eclipse.jdt.core.formatter.keep_simple_for_body_on_same_line=false
org.eclipse.jdt.core.formatter.keep_simple_getter_setter_on_one_line=false
org.eclipse.jdt.core.formatter.keep_simple_while_body_on_same_line=false
+org.eclipse.jdt.core.formatter.keep_switch_body_block_on_one_line=one_line_never
+org.eclipse.jdt.core.formatter.keep_switch_case_with_arrow_on_one_line=one_line_never
org.eclipse.jdt.core.formatter.keep_then_statement_on_same_line=false
org.eclipse.jdt.core.formatter.keep_type_declaration_on_one_line=one_line_never
org.eclipse.jdt.core.formatter.lineSplit=200
@@ -395,6 +407,7 @@ org.eclipse.jdt.core.formatter.text_block_indentation=0
org.eclipse.jdt.core.formatter.use_on_off_tags=false
org.eclipse.jdt.core.formatter.use_tabs_only_for_leading_indentations=false
org.eclipse.jdt.core.formatter.wrap_before_additive_operator=true
+org.eclipse.jdt.core.formatter.wrap_before_assertion_message_operator=true
org.eclipse.jdt.core.formatter.wrap_before_assignment_operator=false
org.eclipse.jdt.core.formatter.wrap_before_bitwise_operator=true
org.eclipse.jdt.core.formatter.wrap_before_conditional_operator=true
@@ -404,5 +417,6 @@ org.eclipse.jdt.core.formatter.wrap_before_or_operator_multicatch=true
org.eclipse.jdt.core.formatter.wrap_before_relational_operator=true
org.eclipse.jdt.core.formatter.wrap_before_shift_operator=true
org.eclipse.jdt.core.formatter.wrap_before_string_concatenation=true
+org.eclipse.jdt.core.formatter.wrap_before_switch_case_arrow_operator=false
org.eclipse.jdt.core.formatter.wrap_outer_expressions_when_nested=true
org.eclipse.jdt.core.javaFormatter=org.eclipse.jdt.core.defaultJavaFormatter
diff --git a/.settings/org.eclipse.jdt.ui.prefs b/.settings/org.eclipse.jdt.ui.prefs
index 6cce11f..7c333a7 100644
--- a/.settings/org.eclipse.jdt.ui.prefs
+++ b/.settings/org.eclipse.jdt.ui.prefs
@@ -1,3 +1,4 @@
+cleanup.add_all=false
cleanup.add_default_serial_version_id=false
cleanup.add_generated_serial_version_id=true
cleanup.add_missing_annotations=true
@@ -7,34 +8,78 @@ cleanup.add_missing_nls_tags=false
cleanup.add_missing_override_annotations=true
cleanup.add_missing_override_annotations_interface_methods=true
cleanup.add_serial_version_id=true
+cleanup.also_simplify_lambda=true
cleanup.always_use_blocks=true
cleanup.always_use_parentheses_in_expressions=false
cleanup.always_use_this_for_non_static_field_access=true
cleanup.always_use_this_for_non_static_method_access=false
+cleanup.array_with_curly=false
+cleanup.arrays_fill=false
+cleanup.bitwise_conditional_expression=false
+cleanup.boolean_literal=false
+cleanup.boolean_value_rather_than_comparison=true
+cleanup.break_loop=false
+cleanup.collection_cloning=false
+cleanup.comparing_on_criteria=false
+cleanup.comparison_statement=false
+cleanup.controlflow_merge=false
cleanup.convert_functional_interfaces=false
cleanup.convert_to_enhanced_for_loop=false
cleanup.convert_to_enhanced_for_loop_if_loop_var_used=false
+cleanup.convert_to_switch_expressions=false
cleanup.correct_indentation=true
+cleanup.do_while_rather_than_while=true
+cleanup.double_negation=false
+cleanup.else_if=false
+cleanup.embedded_if=false
+cleanup.evaluate_nullable=false
+cleanup.extract_increment=false
cleanup.format_source_code=true
cleanup.format_source_code_changes_only=false
+cleanup.hash=false
+cleanup.if_condition=false
cleanup.insert_inferred_type_arguments=false
+cleanup.instanceof=false
+cleanup.instanceof_keyword=false
+cleanup.invert_equals=false
+cleanup.join=false
cleanup.lazy_logical_operator=false
cleanup.make_local_variable_final=false
cleanup.make_parameters_final=true
cleanup.make_private_fields_final=false
cleanup.make_type_abstract_if_missing_method=false
cleanup.make_variable_declarations_final=true
+cleanup.map_cloning=false
cleanup.merge_conditional_blocks=false
+cleanup.multi_catch=false
cleanup.never_use_blocks=false
cleanup.never_use_parentheses_in_expressions=true
+cleanup.no_string_creation=false
+cleanup.no_super=false
cleanup.number_suffix=false
+cleanup.objects_equals=false
+cleanup.one_if_rather_than_duplicate_blocks_that_fall_through=true
+cleanup.operand_factorization=false
cleanup.organize_imports=false
+cleanup.overridden_assignment=false
+cleanup.overridden_assignment_move_decl=true
+cleanup.plain_replacement=false
+cleanup.precompile_regex=false
+cleanup.primitive_comparison=false
+cleanup.primitive_parsing=false
+cleanup.primitive_rather_than_wrapper=true
+cleanup.primitive_serialization=false
+cleanup.pull_out_if_from_if_else=false
+cleanup.pull_up_assignment=false
cleanup.push_down_negation=false
cleanup.qualify_static_field_accesses_with_declaring_class=false
cleanup.qualify_static_member_accesses_through_instances_with_declaring_class=true
cleanup.qualify_static_member_accesses_through_subtypes_with_declaring_class=true
cleanup.qualify_static_member_accesses_with_declaring_class=true
cleanup.qualify_static_method_accesses_with_declaring_class=false
+cleanup.reduce_indentation=false
+cleanup.redundant_comparator=false
+cleanup.redundant_falling_through_block_end=false
cleanup.remove_private_constructors=true
cleanup.remove_redundant_modifiers=false
cleanup.remove_redundant_semicolons=false
@@ -47,13 +92,36 @@ cleanup.remove_unnecessary_casts=true
cleanup.remove_unnecessary_nls_tags=true
cleanup.remove_unused_imports=true
cleanup.remove_unused_local_variables=false
+cleanup.remove_unused_method_parameters=false
cleanup.remove_unused_private_fields=true
cleanup.remove_unused_private_members=false
cleanup.remove_unused_private_methods=true
cleanup.remove_unused_private_types=true
+cleanup.return_expression=false
cleanup.simplify_lambda_expression_and_method_ref=false
+cleanup.single_used_field=false
cleanup.sort_members=true
cleanup.sort_members_all=false
+cleanup.standard_comparison=false
+cleanup.static_inner_class=false
+cleanup.strictly_equal_or_different=false
+cleanup.stringbuffer_to_stringbuilder=false
+cleanup.stringbuilder=false
+cleanup.stringbuilder_for_local_vars=true
+cleanup.stringconcat_stringbuffer_stringbuilder=false
+cleanup.stringconcat_to_textblock=false
+cleanup.substring=false
+cleanup.switch=false
+cleanup.system_property=false
+cleanup.system_property_boolean=false
+cleanup.system_property_file_encoding=false
+cleanup.system_property_file_separator=false
+cleanup.system_property_line_separator=false
+cleanup.system_property_path_separator=false
+cleanup.ternary_operator=false
+cleanup.try_with_resource=false
+cleanup.unlooped_while=false
+cleanup.unreachable_block=false
cleanup.use_anonymous_class_creation=false
cleanup.use_autoboxing=false
cleanup.use_blocks=true
@@ -61,18 +129,22 @@ cleanup.use_blocks_only_for_return_and_throw=false
cleanup.use_directly_map_method=false
cleanup.use_lambda=true
cleanup.use_parentheses_in_expressions=false
+cleanup.use_string_is_blank=false
cleanup.use_this_for_non_static_field_access=true
cleanup.use_this_for_non_static_field_access_only_if_necessary=false
cleanup.use_this_for_non_static_method_access=false
cleanup.use_this_for_non_static_method_access_only_if_necessary=true
cleanup.use_unboxing=false
cleanup.use_var=false
-cleanup_profile=_StatoolInfos
+cleanup.useless_continue=false
+cleanup.useless_return=false
+cleanup.valueof_rather_than_instantiation=false
+cleanup_profile=_StaoolInfos
cleanup_settings_version=2
eclipse.preferences.version=1
editor_save_participant_org.eclipse.jdt.ui.postsavelistener.cleanup=true
formatter_profile=_StatoolInfos
-formatter_settings_version=19
+formatter_settings_version=23
jautodoc.cleanup.add_header=false
jautodoc.cleanup.javadoc=false
jautodoc.cleanup.replace_header=false
@@ -80,6 +152,8 @@ org.eclipse.jdt.ui.exception.name=exception
org.eclipse.jdt.ui.gettersetter.use.is=true
org.eclipse.jdt.ui.keywordthis=false
org.eclipse.jdt.ui.overrideannotation=true
+org.eclipse.jdt.ui.text.custom_code_templates=
+sp_cleanup.add_all=false
sp_cleanup.add_default_serial_version_id=true
sp_cleanup.add_generated_serial_version_id=false
sp_cleanup.add_missing_annotations=true
@@ -89,35 +163,79 @@ sp_cleanup.add_missing_nls_tags=false
sp_cleanup.add_missing_override_annotations=true
sp_cleanup.add_missing_override_annotations_interface_methods=true
sp_cleanup.add_serial_version_id=false
+sp_cleanup.also_simplify_lambda=true
sp_cleanup.always_use_blocks=true
sp_cleanup.always_use_parentheses_in_expressions=false
-sp_cleanup.always_use_this_for_non_static_field_access=true
+sp_cleanup.always_use_this_for_non_static_field_access=false
sp_cleanup.always_use_this_for_non_static_method_access=false
+sp_cleanup.array_with_curly=false
+sp_cleanup.arrays_fill=false
+sp_cleanup.bitwise_conditional_expression=false
+sp_cleanup.boolean_literal=false
+sp_cleanup.boolean_value_rather_than_comparison=false
+sp_cleanup.break_loop=false
+sp_cleanup.collection_cloning=false
+sp_cleanup.comparing_on_criteria=false
+sp_cleanup.comparison_statement=false
+sp_cleanup.controlflow_merge=false
sp_cleanup.convert_functional_interfaces=false
sp_cleanup.convert_to_enhanced_for_loop=false
sp_cleanup.convert_to_enhanced_for_loop_if_loop_var_used=false
-sp_cleanup.correct_indentation=true
+sp_cleanup.convert_to_switch_expressions=false
+sp_cleanup.correct_indentation=false
+sp_cleanup.do_while_rather_than_while=false
+sp_cleanup.double_negation=false
+sp_cleanup.else_if=false
+sp_cleanup.embedded_if=false
+sp_cleanup.evaluate_nullable=false
+sp_cleanup.extract_increment=false
sp_cleanup.format_source_code=true
sp_cleanup.format_source_code_changes_only=false
+sp_cleanup.hash=false
+sp_cleanup.if_condition=false
sp_cleanup.insert_inferred_type_arguments=false
+sp_cleanup.instanceof=false
+sp_cleanup.instanceof_keyword=false
+sp_cleanup.invert_equals=false
+sp_cleanup.join=false
sp_cleanup.lazy_logical_operator=false
-sp_cleanup.make_local_variable_final=false
-sp_cleanup.make_parameters_final=true
-sp_cleanup.make_private_fields_final=false
+sp_cleanup.make_local_variable_final=true
+sp_cleanup.make_parameters_final=false
+sp_cleanup.make_private_fields_final=true
sp_cleanup.make_type_abstract_if_missing_method=false
-sp_cleanup.make_variable_declarations_final=true
+sp_cleanup.make_variable_declarations_final=false
+sp_cleanup.map_cloning=false
sp_cleanup.merge_conditional_blocks=false
+sp_cleanup.multi_catch=false
sp_cleanup.never_use_blocks=false
sp_cleanup.never_use_parentheses_in_expressions=true
+sp_cleanup.no_string_creation=false
+sp_cleanup.no_super=false
sp_cleanup.number_suffix=false
-sp_cleanup.on_save_use_additional_actions=true
+sp_cleanup.objects_equals=false
+sp_cleanup.on_save_use_additional_actions=false
+sp_cleanup.one_if_rather_than_duplicate_blocks_that_fall_through=false
+sp_cleanup.operand_factorization=false
sp_cleanup.organize_imports=true
+sp_cleanup.overridden_assignment=false
+sp_cleanup.overridden_assignment_move_decl=true
+sp_cleanup.plain_replacement=false
+sp_cleanup.precompile_regex=false
+sp_cleanup.primitive_comparison=false
+sp_cleanup.primitive_parsing=false
+sp_cleanup.primitive_rather_than_wrapper=false
+sp_cleanup.primitive_serialization=false
+sp_cleanup.pull_out_if_from_if_else=false
+sp_cleanup.pull_up_assignment=false
sp_cleanup.push_down_negation=false
sp_cleanup.qualify_static_field_accesses_with_declaring_class=false
sp_cleanup.qualify_static_member_accesses_through_instances_with_declaring_class=true
sp_cleanup.qualify_static_member_accesses_through_subtypes_with_declaring_class=true
sp_cleanup.qualify_static_member_accesses_with_declaring_class=false
sp_cleanup.qualify_static_method_accesses_with_declaring_class=false
+sp_cleanup.reduce_indentation=false
+sp_cleanup.redundant_comparator=false
+sp_cleanup.redundant_falling_through_block_end=false
sp_cleanup.remove_private_constructors=true
sp_cleanup.remove_redundant_modifiers=false
sp_cleanup.remove_redundant_semicolons=false
@@ -127,29 +245,56 @@ sp_cleanup.remove_trailing_whitespaces_all=true
sp_cleanup.remove_trailing_whitespaces_ignore_empty=false
sp_cleanup.remove_unnecessary_array_creation=false
sp_cleanup.remove_unnecessary_casts=true
-sp_cleanup.remove_unnecessary_nls_tags=true
-sp_cleanup.remove_unused_imports=true
+sp_cleanup.remove_unnecessary_nls_tags=false
+sp_cleanup.remove_unused_imports=false
sp_cleanup.remove_unused_local_variables=false
+sp_cleanup.remove_unused_method_parameters=false
sp_cleanup.remove_unused_private_fields=true
sp_cleanup.remove_unused_private_members=false
sp_cleanup.remove_unused_private_methods=true
sp_cleanup.remove_unused_private_types=true
+sp_cleanup.return_expression=false
sp_cleanup.simplify_lambda_expression_and_method_ref=false
-sp_cleanup.sort_members=true
+sp_cleanup.single_used_field=false
+sp_cleanup.sort_members=false
sp_cleanup.sort_members_all=false
+sp_cleanup.standard_comparison=false
+sp_cleanup.static_inner_class=false
+sp_cleanup.strictly_equal_or_different=false
+sp_cleanup.stringbuffer_to_stringbuilder=false
+sp_cleanup.stringbuilder=false
+sp_cleanup.stringbuilder_for_local_vars=true
+sp_cleanup.stringconcat_stringbuffer_stringbuilder=false
+sp_cleanup.stringconcat_to_textblock=false
+sp_cleanup.substring=false
+sp_cleanup.switch=false
+sp_cleanup.system_property=false
+sp_cleanup.system_property_boolean=false
+sp_cleanup.system_property_file_encoding=false
+sp_cleanup.system_property_file_separator=false
+sp_cleanup.system_property_line_separator=false
+sp_cleanup.system_property_path_separator=false
+sp_cleanup.ternary_operator=false
+sp_cleanup.try_with_resource=false
+sp_cleanup.unlooped_while=false
+sp_cleanup.unreachable_block=false
sp_cleanup.use_anonymous_class_creation=false
sp_cleanup.use_autoboxing=false
-sp_cleanup.use_blocks=true
+sp_cleanup.use_blocks=false
sp_cleanup.use_blocks_only_for_return_and_throw=false
sp_cleanup.use_directly_map_method=false
-sp_cleanup.use_lambda=false
+sp_cleanup.use_lambda=true
sp_cleanup.use_parentheses_in_expressions=false
-sp_cleanup.use_this_for_non_static_field_access=true
-sp_cleanup.use_this_for_non_static_field_access_only_if_necessary=false
+sp_cleanup.use_string_is_blank=false
+sp_cleanup.use_this_for_non_static_field_access=false
+sp_cleanup.use_this_for_non_static_field_access_only_if_necessary=true
sp_cleanup.use_this_for_non_static_method_access=false
sp_cleanup.use_this_for_non_static_method_access_only_if_necessary=true
sp_cleanup.use_unboxing=false
sp_cleanup.use_var=false
+sp_cleanup.useless_continue=false
+sp_cleanup.useless_return=false
+sp_cleanup.valueof_rather_than_instantiation=false
sp_jautodoc.cleanup.add_header=false
sp_jautodoc.cleanup.javadoc=false
sp_jautodoc.cleanup.replace_header=false
diff --git a/.settings/org.eclipse.jst.j2ee.ejb.annotations.xdoclet.prefs b/.settings/org.eclipse.jst.j2ee.ejb.annotations.xdoclet.prefs
deleted file mode 100644
index 9bb48a9..0000000
--- a/.settings/org.eclipse.jst.j2ee.ejb.annotations.xdoclet.prefs
+++ /dev/null
@@ -1,5 +0,0 @@
-XDOCLETBUILDERACTIVE=false
-XDOCLETHOME=
-XDOCLETUSEGLOBAL=true
-XDOCLETVERSION=1.2.1
-eclipse.preferences.version=1
diff --git a/.settings/org.eclipse.wst.common.component b/.settings/org.eclipse.wst.common.component
index 8557b74..18e52a2 100644
--- a/.settings/org.eclipse.wst.common.component
+++ b/.settings/org.eclipse.wst.common.component
@@ -1,6 +1,23 @@
-
-
-
+
+
+
+
+
+
+
+
+
+ uses
+
+
+ uses
+
+
+
+
+
+
+
diff --git a/.settings/org.eclipse.wst.common.project.facet.core.xml b/.settings/org.eclipse.wst.common.project.facet.core.xml
index 138bbd1..fac5a37 100644
--- a/.settings/org.eclipse.wst.common.project.facet.core.xml
+++ b/.settings/org.eclipse.wst.common.project.facet.core.xml
@@ -1,7 +1,10 @@
+
+
+
-
-
-
+
+
+
diff --git a/.settings/org.eclipse.wst.jsdt.ui.superType.container b/.settings/org.eclipse.wst.jsdt.ui.superType.container
new file mode 100644
index 0000000..3bd5d0a
--- /dev/null
+++ b/.settings/org.eclipse.wst.jsdt.ui.superType.container
@@ -0,0 +1 @@
+org.eclipse.wst.jsdt.launching.baseBrowserLibrary
\ No newline at end of file
diff --git a/.settings/org.eclipse.wst.jsdt.ui.superType.name b/.settings/org.eclipse.wst.jsdt.ui.superType.name
new file mode 100644
index 0000000..05bd71b
--- /dev/null
+++ b/.settings/org.eclipse.wst.jsdt.ui.superType.name
@@ -0,0 +1 @@
+Window
\ No newline at end of file
diff --git a/CHANGELOG.md b/CHANGELOG.md
deleted file mode 100644
index 20e2542..0000000
--- a/CHANGELOG.md
+++ /dev/null
@@ -1,125 +0,0 @@
-# StatoolInfos Changelog
-
-All notable changes of StatoolInfos will be documented in this file.
-
-The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
-
-## [Unreleased]
-
-Changes for metrics:
-- …
-
-Changes for web building:
-- …
-
-## [0.5.1] – 2023-05-09
-
-Changes for metrics:
-- Added multi sources for Http log file search.
-- Added wrong password metrics for Minetest.
-- Fixed property label in Privatebin patch probe.
-- Added CLI commands to test HttpAccessLog files and lines.
-- Moved HttpErrorLog analyzer in dedicated package.
-- Refactored prober call from CLI.
-- Added new metrics analyzers.
-- Added pathFilter parameter in httpAccessLog read.
-- Fixed HTTP access log pattern.
-- Fixed HTTP pattern management from metric conf file.
-- Added Kuma in Bot detection file.
-- Added not authorized HTTP status code.
-- Added chat metrics for Minetest.
-- Set 401 uptime case as OK.
-- Improved bot pattern list with TinyStatus.
-- Added metrics for GSL.
-- Improved documentation (README)
-
-Changes for web building:
-- Improved property stats page with only active organizations.
-- Improved PropertyStats page with only active services.
-- Fixed hosting properties file management.
-- Added Z support in DATETIME property check.
-- Added optional parameter IPV6ONLY in statoolinfos.sh.
-- Changed metrics menu entry from 2020 to 2022.
-- Fixed bad category list building.
-- Removed debug trace.
-- Fixed categories compare.
-- Fixed wording.
-- Fixed separate case characters in property stats.
-- Improved federation service count.
-- Improved date management.
-- Improved startDate and endDate management for services.
-- Improved startDate and endDate management for organizations.
-- Improved Federation getStartDate management.
-- Added provider hypervisor charts for service stats.
-- Added type chart and provider hypervisor charts for organization stats.
-- Added federation organization type chart. Improved federation charts.
-- Refactored federation stats. Added provider hypervisor chart.
-- Added organization.type check entry.
-- Added host.provider.hypervisor check entry.
-- Changed color of ServiceCountYearChart.
-- Fixed bad display of htmlizeHostNamePieChart.
-- Swap columns in htmlizeOrganizationInOutChart.
-- Fixed colors.
-
-
-## [0.5.0] – 2022-01-23
-
-This release contains many improvments:
-- Extended http access log regex.
-- Restricted federation stats to active organizations only.
-- Improved status management in organizations and services display.
-- Added Let's encrypt detection for bot filtering.
-- Added date tips in header column with monthly label.
-- Replaced 0 value with emoji in organizations view and services view.
-- Added visits.ipv4 and visits.ipv6 management.
-- Added metrics configuration templates in README.
-- Changed visit and visitor definition.
-- Fixed bug in error nginx time parsing.
-- Fixed label display in 2 data graph.
-- Added bot pattern for mod_jk dummy connection in http logs.
-- Added asterisk month in organization list view.
-- Added asterisk month in service list view.
-- Fixed DataTables paths.
-- Fixed former member display.
-- Improved userAgent analyze.
-- Fixed empty http log file bug.
-- Added first veresion of Mumble probing (see README.md).
-- Fixed bug in TimeMark code.
-- Added first version of PrivateBin probing (see README.md).
-- Migrated to Log4j2 (with Log4shell fix).
-- Made code improvments.
-
-Warning: visit and visitors definition has changed. Now it is more restricted: humans + method GET + page + status SUCCESS.
-
-So some metrics have to be generate again (with -full) and some properties have to deleted:
-- Added
- - metrics.http.requesters : nombre de requêteurs.
- - metrics.http.requesters.ipv4 : nombre de requêteurs IPv4.
- - metrics.http.requesters.ipv6 : nombre de requêteurs IPv6.
- - metrics.http.requesters.humans : nombre de requêteurs humains.
- - metrics.http.requesters.bots : nombre de requêteurs bots.
- - metrics.http.requesters.bots.walks : nombre de passages de requêteurs bots.
- - metrics.http.metrics.methods.XXX : nombre de requête avec la méthode XXX.
- - metrics.http.visits.ipv4 : nombre de visites en IPv4.
- - metrics.http.visits.ipv6 : nombre de visites en IPv6.
-- Changed
- - metrics.http.visits : définition plus restrictive (humains + GET + page + SUCCESS).
- - metrics.http.visitors : définition de visiteur plus restrictive.
- - metrics.http.visitors.ipv4 : définition de visiteur plus restrictive.
- - metrics.http.visitors.ipv6 : définition de visiteur plus restrictive.
-- Removed
- - metrics.http.visitors.humans : remplacé par metrics.http.visitors (nouvelle définition d'une visite).
- - metrics.http.visitors.bots : supprimé (nouvelle définition d'une visite).
- - metrics.https.visits.bots : supprimé (nouvelle définition d'une visite).
-
-## [0.4.1] – 2021-12-23
-
-This release contains small improvments:
-- Fixed DataTables (CVE-2021-23445).
-- Improved wildcard feature in probe command (#1 thx Kepon).
-- Improved sample config file.
-- Added beta Minetest specific probing feature.
-
-## [0.4.0] – 2021-12-15
-
-This release contains probe feature to generate metrics files.
diff --git a/CONCEPT.md b/CONCEPT.md
deleted file mode 100644
index d09add5..0000000
--- a/CONCEPT.md
+++ /dev/null
@@ -1,85 +0,0 @@
-# Concepts de StatoolInfos
-
-## Principe générale
-
-StatoolInfos s'appuie sur StatoolInfos qui utilise des fichiers publics disponibles via des liens web :
-
-- 1 fichier web public pour décrire la fédération ;
-- 1 fichier web public par organisation membre de la fédération ;
-- 1 fichier web public par service des organisations.
-
-Chaque fichier web public étant acessible via un lien web, chaque fichier public peut se trouver sur un site web différent.
-
-Chaque fichier web public contient des informations descriptives et potentiellement des métriques d'activité.
-
-Il suffit de récupérer tous les fichiers web publics afin de pouvoir générer des pages web, des statistiques, des graphiques…
-
-
-## Format des fichiers web publics
-
-Dans StatoolInfos, ce sont des fichiers **properties**, c'est à dire ne contenant que des lignes de texte au format `chemin=valeur`.
-
-Un **chemin** consiste en une suite de mots séparés par des points : `organization.name=Chapril`.
-
-Les lignes vides et les lignes commençant par un `#` sont ignorées.
-
-Exemple :
-
-```
-# [Organisation]
-organization.name=Chapril
-organization.description=Chapril est le chaton de l\'April.
-organization.website=https://www.chapril.org/
-organization.logo=
-organization.owner.name=April
-organization.owner.website=https://www.april.org/
-organization.owner.logo=
-organization.geography=
-organization.contact.url=https://www.chapril.org/contact.xhtml
-organization.contact.email=contact@chapril.org
-organization.legal.url=
-organization.technical.url=
-organization.startDate=
-organization.endDate=
-```
-
-## Notion de section
-
-Le premier mot d'un chemin est appelé la **section**. Donc chaque fichier web public est une liste de sections.
-
-Suivant qu'il décrive la fédération, une organisation ou un service, le fichier web public ne contient pas les mêmes sections :
-
-- Fédération = file + federation + subs + metrics
-- Organisation = file + organization + subs + metrics
-- Service = file + service + host + software + metrics
-
-La liste des chemins de chaque section est normalisée dans une ontologie.
-
-
-## Des données simples
-
-Dans lignes de **properties**, les valeurs doivent être le plus simple possible.
-
-Voici une liste de types simples :
-
-
-| Type | Description | Modèle | Exemple |
-| ------ | ------ | ------ | ------ |
-| DATE | Une date au format ISO | ISO_8601 | 2020-07-06 |
-| DATETIME | Une date horaire au format ISO | ISO_8601 | 2020-07-06T14:23:20 |
-| DAYS | Une liste de 366 valeurs numériques avec séparateurs | STU | 1;2;3;4;5;…;365 |
-| EMAIL | Un courriel. | ^.+@.+$ | christian@momon.org |
-| MONTHS | Une liste de 12 valeurs numériques avec séparateurs | STU | 1;2;3;4;5;6;7;9;10;11;12 |
-| NUMERIC | Une valeur numérique | STU | -1234.567 |
-| NUMERICS | Une liste de valeurs numériques avec séparateurs | STU | 12.34;56.78;9 |
-| SEPARATOR | Un caractère séparateur | `;` ou `,` | Foo;foo;;foo |
-| STATUS | Un statut. | ON/MAINTENANCE/DOWN/OFF/DRAFT | ON |
-| STRING | Une chaîne de caractères quelconques. Peut contenir des `
` et des `\n`. | ^.*$ | Foo is foo. |
-| URL | Un lien web | ^https?://.+\..+/+$ | https://foo.foo/ |
-| VALUE | Une chaîne de caractère sans séparateur | Foo |
-| VALUES | Liste de valeurs de type VALUE avec séparateurs | STU | foo1;foo2;foo3 |
-| WEEKS | Liste de 52 valeurs numériques avec séparateurs | STU | 1;2;3;4;5;…;51;52 |
-
-Note for list:
-* une valeur vide ou null est autorisée ;
-* si une liste de valeurs contient moins de valeurs qu'attendu alors les valeurs manquantes sont considérées comme vides ou nulles.
diff --git a/GENERAL.md b/GENERAL.md
deleted file mode 100644
index 424cf90..0000000
--- a/GENERAL.md
+++ /dev/null
@@ -1,203 +0,0 @@
-# StatoolInfos
-
-StatoolInfos is…
-
-Data are stored in property files. Each entry line uses key defined by convention.
-
-## Primitive Types
-
-| Type | Description | Pattern | Example |
-| ------ | ------ | ------ | ------ |
-| DATE | A date in ISO format | ISO_DATE | 2020-07-06 |
-| DATETIME | A date and time in ISO format | ISO_DATETIME | 2020-07-06T14:23:20 |
-| DAYS | List of 366 NUMERIC separated by SEPARATOR | STU | 1;2;3;4;5;…;365 |
-| DECIMAL_DEGREE | Longitude or latitidue value | ^[+-]?\\d+[,\\.]\\d{1,8}$ | -12,3456 |
-| EMAIL | An electronic address. | ^.+@.+$ | christian@momon.org |
-| MONTHS | List of 12 NUMERIC separated by SEPARATOR | STU | 1;2;3;4;5;6;7;9;10;11;12 |
-| NUMERIC | A numeric value | STU | -1234.567 |
-| NUMERICS | List of NUMERIC separated by SEPARATOR | STU | 12.34;56.78;9 |
-| SEPARATOR | The default separator character | `;` | Foo;foo;;foo |
-| STATUS | A status. | ON/MAINTENANCE/DOWN/OFF/DRAFT | ON |
-| STRING | Foo string. With `
` or `\n`. | ^.*$ | Foo is foo. |
-| URL | A web link | ^https?://.+\..+/+$ | https://foo.foo/ |
-| VALUE | String not containg SEPARATOR character | Foo |
-| VALUES | List of VALUE separated by SEPARATOR | STU | foo1;foo2;foo3 |
-| WEEKS | List of 52 NUMERIC separated by SEPARATOR | STU | 1;2;3;4;5;…;51;52 |
-
-Note for list:
-* empty value or null value are available;
-* shorter list designs empty values.
-
-
-
-## Sections
-
-### Federation section
-
-| Field | Type | Mandatory | Description | Example |
-| ------ | ------ | ------| ------ | ------ |
-| federation.name | STRING | Yes | Name of federation | CHATONS |
-| federation.description | STRING | Yes | Desciption of the federation | Collectif CHATONS |
-| federation.website | URL | Yes | Official website URL of the federation | https://www.chatons.org/ |
-| federation.logo | URL | Wished | URL of the organization logo | https://chatons.org/logo_chatons_v2.png |
-| federation.favicon | URL | Wished | URL of the organization favicon | https://chatons.org/sites/default/files/chatons_logo_tiny.png |
-| federation.contact.url | URL | No | Contact webpage of the federation | https://www.chatons.org/contact |
-| federation.contact.email | EMAIL | Yes | Contact email of the federation | contact@chatons.org |
-| federation.legal.url | URL | No | Legal webpage of the federation | https://www.chatons.org/page/mentions-l%C3%A9gales |
-| federation.documentation.url | URL | No | Documentation webpage of the federation | https://wiki.chatons.org/ |
-| federation.documentation.technical.url | URL | No | Technical documentation webpage of the federation | |
-| federation.documentation.tutorial.url | URL | No | Tutorial documentation webpage of the federation | |
-| federation.birthdate | DATE | No | Date of birth of the federation | 09/02/2016 |
-
-
-### File section
-
-| Field | Type | Mandatory | Description | Example |
-| ------ | ------ | ------ | ------ | ------ |
-| file.class | Federation/Organization/Service/Device | Yes | Class of the content | Service |
-| file.protocol | STRING | Yes | Version of the StatoolInfos schema | StatoolInfos-0.1 |
-| file.datetime | DATETIME | Yes | Date and time of the file build. | 2020-07-06T14:23:20 |
-| file.generator | STRING | Yes | Generator of the file. | Cpm hands |
-| file.url | URL | Yes | Origin URL of the file. | Cpm hands |
-
-
-### Host section (dratf)
-
-| Field | Type | Mandatory | Description | Example |
-| ------ | ------ | ------ | ------ | ------ |
-| host.name | STRING | Yes | Name of the host | foo |
-| host.provider | STRING | Yes | Provider of the host | foo |
-| host.description | STRING | Wished | Description of the host | The virtual machine called foo |
-| host.type | VPS / CLOUD / LOCATEDSERVER / HOSTSERVER / HOMESERVER / RASPERRY | Wished | Type of the host | HOMESERVER |
-| host.country.name | STRING | Wished | Country name of the host | France |
-| host.country.code | STRING | Wished | ISO country code of the host | FR |
-
-
-### Metrics section
-
-| Field | Type | Mandatory | Description | Example |
-| ------ | ------ | ------ | ------ | ------ |
-| metrics.foo1.foo2.name | STRING | Wished | Name of metric | visitor Ip |
-| metrics.foo1.foo2.description | STRING | Wished | Description of metric | Nombre d'ip ayant visitées |
-| metrics.foo1.foo2.2020 | NUMERIC | No | Count of foo1.foo2 | 123 |
-| metrics.foo1.foo2.2020.months | MONTHS | No | Month count of foo1.foo2 for year 2020 | 100;200;300;;;; |
-| metrics.foo1.foo2.2020.weeks | WEEKS | No | Week count of foo1.foo2 for year 2020 | 100;200;300;;;; |
-| metrics.foo1.foo2.2020.days | DAYS | No | Day count of foo1.foo2 for year 2020 | 100;200;300;;;; |
-
-Examples:
-```
-metrics.visitors.ipv4.2020=123
-metrics.visitors.ipv6.2020=123
-metrics.visitors.total.2020=246
-
-metrics.visitors.ipv4.2020.months=12;34;56;
-metrics.visitors.ipv6.2020.months=12;34;56;
-metrics.visitors.total.2020.months=24;68;112;
-
-metrics.visitors.ipv4.2020.weeks=123;456;
-metrics.visitors.ipv6.2020.weeks=123;456;
-metrics.visitors.total.2020.weeks=246;912;
-
-metrics.visitors.ipv4.2020.days=123;456;
-metrics.visitors.ipv6.2020.days=123;456;
-metrics.visitors.total.2020.days=246;912;
-```
-
-
-### Organization section
-
-| Field | Type | Mandatory | Description | Example |
-| ------ | ------ | ------ | ------ | ------ |
-| organization.name | STRING | Yes | Name of the organization | Chapril |
-| organization.description | STRING | Wished | Description of the organization | Chapril est le chaton de l'April |
-| organization.website | URL | Y | Official website of the organization | httsp://www.chapril.org/ |
-| organization.logo | URL | Wished | Logo URL of the organization | https://date.chapril.org/Chapril-banner/v1/chapril-logo-small.png |
-| organization.favicon | URL | Wished | Favicon URL of the organization | https://date.chapril.org/favicon.png |
-| organization.owner.name | STRING | No | Name of the organization owner | April |
-| organization.owner.website | URL | No | Official website of the organization owner | https://www.april.org/ |
-| organization.owner.logo | URL | No | Logo URL of the organization owner | https://www.april.org/sites/default/themes/zen_april/logo.png |
-| organization.owner.favicon | URL | No | Favicon URL of the organization owner | https://www.april.org/sites/default/themes/zen_april/favicon.ico |
-| organization.contact.url | URL | Wished | Contact webpage of the organization | https://www.chapril.org/contact.html |
-| organization.contact.email | EMAIL | Contact email of the organization | contact@chapril.org |
-| organization.legal.url | URL | Wished | Legal webpage of the organization | https://www.chapril.org/cgu.html |
-| organization.documentation.technical.url | URL | Wished | Technical documentation webpage of the organization | https://admin.chapril.org/ |
-| organization.birthdate | DATE | Wished | Birth date of the organization | 08/11/2018 |
-
-
-### Service section
-
-| Field | Type | Mandatory | Description | Example |
-| ------ | ------ | ------ | ------ | ------ |
-| service.name | STRING | Yes | Service name. | MumbleChaprilOrg |
-| service.description | STRING | Yes | Service description. | Service libre de conférence audio |
-| service.organization.name | STRING | Yes | Organization name. | Chapril |
-| service.website.url | URL | Wished | Website of the service | https://mumble.chapril.org/ |
-| service.legal.url | URL | Wished | URL | Legal webpage of the organization | https://www.chapril.org/cgu.html |
-| service.documentation.technical.url | URL | No | Technical documentation webpage of the service | https://admin.chapril.org/doku.php?id=admin:services:mumble.chapril.org |
-| service.documentation.tutorial.url | URL | No | Tutorial documentation webpage of the service | https://www.chapril.org/Mumble.html |
-| service.contact.url | URL | Wished | Contact webpage of the service | contact@chapril.org |
-| service.contact.email | EMAIL | Wished | Contact email of the service | mumble-support@chapril.org |
-| service.birthdate | DATETIME | Wished | Birth date of the service | 20/03/2020 |
-| service.deathdate | DATETIME | No | Death date of the service | |
-| service.status | STATUS | Yes | Service status. | ON |
-| service.registration | None;Free;Member;Client | Yes | Registration requirement | Free; Member|
-
-### Subs section
-
-| Field | Type | Mandatory | Description | Example |
-| ------ | ------ | ------ | ------ | ------ |
-| subs.foo | URL | No | URL of a sub node. | Firefox Send |
-
-Example:
-```
-subs.datechaprilorg=https://date.chapril.org/.well-known/datechaprilorg.properties
-subs.pastechaprilorg=https://paste.chapril.org/.well-known/pastechaprilorg.properties
-subs.dropchaprilorg=https://drop.chapril.org/.well-known/dropchaprilorg.properties
-```
-
-
-
-### Software section
-
-| Field | Type | Mandatory | Description | Example |
-| ------ | ------ | ------ | ------ | ------ |
-| software.name | STRING | Yes | Name of the software | Firefox Send |
-| software.website | URL | Yes | Offical website of the software | https://send.firefox.com/ |
-| software.license.url | URL | Yes | Webpage of the software license | https://forge.april.org/Chapril/drop.chapril.org-firefoxsend/src/branch/chapril-v3.0.21/LICENSE |
-| software.license.name | STRING | Yes | Name of the license | Mozilla Public License Version 2.0 |
-| software.version | STRING | Yes | Version of the software | Chapril-3.0.21 |
-| software.source.url | URL | Yes | URL of the software source | https://forge.april.org/Chapril/drop.chapril.org-firefoxsend/ |
-
-
-
-
-
-## Classes
-
-### Federation class
-
-Federation = file + federation + subs + metrics
-
-### Organization class
-
-Organization = file + organization + subs + metrics
-
-### Service class
-
-Service = file + service + host + software + metrics + extras
-
-### Device class
-
-Device = file + device + system
-
-
-
-# Draft
-
-| Field | Type | Mandatory | Description |
-| ------ | ------ | ------ | ------ |
-| services.* | URL | Y | URL of the Statool file of the service |
-
-| Field | Type | Mandatory | Description |
-| ------ | ------ | ------ | ------ |
-| services.urls.* | URL | Y | URL of services |
diff --git a/LICENSE b/LICENSE
deleted file mode 100644
index dba13ed..0000000
--- a/LICENSE
+++ /dev/null
@@ -1,661 +0,0 @@
- GNU AFFERO GENERAL PUBLIC LICENSE
- Version 3, 19 November 2007
-
- Copyright (C) 2007 Free Software Foundation, Inc.
- Everyone is permitted to copy and distribute verbatim copies
- of this license document, but changing it is not allowed.
-
- Preamble
-
- The GNU Affero General Public License is a free, copyleft license for
-software and other kinds of works, specifically designed to ensure
-cooperation with the community in the case of network server software.
-
- The licenses for most software and other practical works are designed
-to take away your freedom to share and change the works. By contrast,
-our General Public Licenses are intended to guarantee your freedom to
-share and change all versions of a program--to make sure it remains free
-software for all its users.
-
- When we speak of free software, we are referring to freedom, not
-price. Our General Public Licenses are designed to make sure that you
-have the freedom to distribute copies of free software (and charge for
-them if you wish), that you receive source code or can get it if you
-want it, that you can change the software or use pieces of it in new
-free programs, and that you know you can do these things.
-
- Developers that use our General Public Licenses protect your rights
-with two steps: (1) assert copyright on the software, and (2) offer
-you this License which gives you legal permission to copy, distribute
-and/or modify the software.
-
- A secondary benefit of defending all users' freedom is that
-improvements made in alternate versions of the program, if they
-receive widespread use, become available for other developers to
-incorporate. Many developers of free software are heartened and
-encouraged by the resulting cooperation. However, in the case of
-software used on network servers, this result may fail to come about.
-The GNU General Public License permits making a modified version and
-letting the public access it on a server without ever releasing its
-source code to the public.
-
- The GNU Affero General Public License is designed specifically to
-ensure that, in such cases, the modified source code becomes available
-to the community. It requires the operator of a network server to
-provide the source code of the modified version running there to the
-users of that server. Therefore, public use of a modified version, on
-a publicly accessible server, gives the public access to the source
-code of the modified version.
-
- An older license, called the Affero General Public License and
-published by Affero, was designed to accomplish similar goals. This is
-a different license, not a version of the Affero GPL, but Affero has
-released a new version of the Affero GPL which permits relicensing under
-this license.
-
- The precise terms and conditions for copying, distribution and
-modification follow.
-
- TERMS AND CONDITIONS
-
- 0. Definitions.
-
- "This License" refers to version 3 of the GNU Affero General Public License.
-
- "Copyright" also means copyright-like laws that apply to other kinds of
-works, such as semiconductor masks.
-
- "The Program" refers to any copyrightable work licensed under this
-License. Each licensee is addressed as "you". "Licensees" and
-"recipients" may be individuals or organizations.
-
- To "modify" a work means to copy from or adapt all or part of the work
-in a fashion requiring copyright permission, other than the making of an
-exact copy. The resulting work is called a "modified version" of the
-earlier work or a work "based on" the earlier work.
-
- A "covered work" means either the unmodified Program or a work based
-on the Program.
-
- To "propagate" a work means to do anything with it that, without
-permission, would make you directly or secondarily liable for
-infringement under applicable copyright law, except executing it on a
-computer or modifying a private copy. Propagation includes copying,
-distribution (with or without modification), making available to the
-public, and in some countries other activities as well.
-
- To "convey" a work means any kind of propagation that enables other
-parties to make or receive copies. Mere interaction with a user through
-a computer network, with no transfer of a copy, is not conveying.
-
- An interactive user interface displays "Appropriate Legal Notices"
-to the extent that it includes a convenient and prominently visible
-feature that (1) displays an appropriate copyright notice, and (2)
-tells the user that there is no warranty for the work (except to the
-extent that warranties are provided), that licensees may convey the
-work under this License, and how to view a copy of this License. If
-the interface presents a list of user commands or options, such as a
-menu, a prominent item in the list meets this criterion.
-
- 1. Source Code.
-
- The "source code" for a work means the preferred form of the work
-for making modifications to it. "Object code" means any non-source
-form of a work.
-
- A "Standard Interface" means an interface that either is an official
-standard defined by a recognized standards body, or, in the case of
-interfaces specified for a particular programming language, one that
-is widely used among developers working in that language.
-
- The "System Libraries" of an executable work include anything, other
-than the work as a whole, that (a) is included in the normal form of
-packaging a Major Component, but which is not part of that Major
-Component, and (b) serves only to enable use of the work with that
-Major Component, or to implement a Standard Interface for which an
-implementation is available to the public in source code form. A
-"Major Component", in this context, means a major essential component
-(kernel, window system, and so on) of the specific operating system
-(if any) on which the executable work runs, or a compiler used to
-produce the work, or an object code interpreter used to run it.
-
- The "Corresponding Source" for a work in object code form means all
-the source code needed to generate, install, and (for an executable
-work) run the object code and to modify the work, including scripts to
-control those activities. However, it does not include the work's
-System Libraries, or general-purpose tools or generally available free
-programs which are used unmodified in performing those activities but
-which are not part of the work. For example, Corresponding Source
-includes interface definition files associated with source files for
-the work, and the source code for shared libraries and dynamically
-linked subprograms that the work is specifically designed to require,
-such as by intimate data communication or control flow between those
-subprograms and other parts of the work.
-
- The Corresponding Source need not include anything that users
-can regenerate automatically from other parts of the Corresponding
-Source.
-
- The Corresponding Source for a work in source code form is that
-same work.
-
- 2. Basic Permissions.
-
- All rights granted under this License are granted for the term of
-copyright on the Program, and are irrevocable provided the stated
-conditions are met. This License explicitly affirms your unlimited
-permission to run the unmodified Program. The output from running a
-covered work is covered by this License only if the output, given its
-content, constitutes a covered work. This License acknowledges your
-rights of fair use or other equivalent, as provided by copyright law.
-
- You may make, run and propagate covered works that you do not
-convey, without conditions so long as your license otherwise remains
-in force. You may convey covered works to others for the sole purpose
-of having them make modifications exclusively for you, or provide you
-with facilities for running those works, provided that you comply with
-the terms of this License in conveying all material for which you do
-not control copyright. Those thus making or running the covered works
-for you must do so exclusively on your behalf, under your direction
-and control, on terms that prohibit them from making any copies of
-your copyrighted material outside their relationship with you.
-
- Conveying under any other circumstances is permitted solely under
-the conditions stated below. Sublicensing is not allowed; section 10
-makes it unnecessary.
-
- 3. Protecting Users' Legal Rights From Anti-Circumvention Law.
-
- No covered work shall be deemed part of an effective technological
-measure under any applicable law fulfilling obligations under article
-11 of the WIPO copyright treaty adopted on 20 December 1996, or
-similar laws prohibiting or restricting circumvention of such
-measures.
-
- When you convey a covered work, you waive any legal power to forbid
-circumvention of technological measures to the extent such circumvention
-is effected by exercising rights under this License with respect to
-the covered work, and you disclaim any intention to limit operation or
-modification of the work as a means of enforcing, against the work's
-users, your or third parties' legal rights to forbid circumvention of
-technological measures.
-
- 4. Conveying Verbatim Copies.
-
- You may convey verbatim copies of the Program's source code as you
-receive it, in any medium, provided that you conspicuously and
-appropriately publish on each copy an appropriate copyright notice;
-keep intact all notices stating that this License and any
-non-permissive terms added in accord with section 7 apply to the code;
-keep intact all notices of the absence of any warranty; and give all
-recipients a copy of this License along with the Program.
-
- You may charge any price or no price for each copy that you convey,
-and you may offer support or warranty protection for a fee.
-
- 5. Conveying Modified Source Versions.
-
- You may convey a work based on the Program, or the modifications to
-produce it from the Program, in the form of source code under the
-terms of section 4, provided that you also meet all of these conditions:
-
- a) The work must carry prominent notices stating that you modified
- it, and giving a relevant date.
-
- b) The work must carry prominent notices stating that it is
- released under this License and any conditions added under section
- 7. This requirement modifies the requirement in section 4 to
- "keep intact all notices".
-
- c) You must license the entire work, as a whole, under this
- License to anyone who comes into possession of a copy. This
- License will therefore apply, along with any applicable section 7
- additional terms, to the whole of the work, and all its parts,
- regardless of how they are packaged. This License gives no
- permission to license the work in any other way, but it does not
- invalidate such permission if you have separately received it.
-
- d) If the work has interactive user interfaces, each must display
- Appropriate Legal Notices; however, if the Program has interactive
- interfaces that do not display Appropriate Legal Notices, your
- work need not make them do so.
-
- A compilation of a covered work with other separate and independent
-works, which are not by their nature extensions of the covered work,
-and which are not combined with it such as to form a larger program,
-in or on a volume of a storage or distribution medium, is called an
-"aggregate" if the compilation and its resulting copyright are not
-used to limit the access or legal rights of the compilation's users
-beyond what the individual works permit. Inclusion of a covered work
-in an aggregate does not cause this License to apply to the other
-parts of the aggregate.
-
- 6. Conveying Non-Source Forms.
-
- You may convey a covered work in object code form under the terms
-of sections 4 and 5, provided that you also convey the
-machine-readable Corresponding Source under the terms of this License,
-in one of these ways:
-
- a) Convey the object code in, or embodied in, a physical product
- (including a physical distribution medium), accompanied by the
- Corresponding Source fixed on a durable physical medium
- customarily used for software interchange.
-
- b) Convey the object code in, or embodied in, a physical product
- (including a physical distribution medium), accompanied by a
- written offer, valid for at least three years and valid for as
- long as you offer spare parts or customer support for that product
- model, to give anyone who possesses the object code either (1) a
- copy of the Corresponding Source for all the software in the
- product that is covered by this License, on a durable physical
- medium customarily used for software interchange, for a price no
- more than your reasonable cost of physically performing this
- conveying of source, or (2) access to copy the
- Corresponding Source from a network server at no charge.
-
- c) Convey individual copies of the object code with a copy of the
- written offer to provide the Corresponding Source. This
- alternative is allowed only occasionally and noncommercially, and
- only if you received the object code with such an offer, in accord
- with subsection 6b.
-
- d) Convey the object code by offering access from a designated
- place (gratis or for a charge), and offer equivalent access to the
- Corresponding Source in the same way through the same place at no
- further charge. You need not require recipients to copy the
- Corresponding Source along with the object code. If the place to
- copy the object code is a network server, the Corresponding Source
- may be on a different server (operated by you or a third party)
- that supports equivalent copying facilities, provided you maintain
- clear directions next to the object code saying where to find the
- Corresponding Source. Regardless of what server hosts the
- Corresponding Source, you remain obligated to ensure that it is
- available for as long as needed to satisfy these requirements.
-
- e) Convey the object code using peer-to-peer transmission, provided
- you inform other peers where the object code and Corresponding
- Source of the work are being offered to the general public at no
- charge under subsection 6d.
-
- A separable portion of the object code, whose source code is excluded
-from the Corresponding Source as a System Library, need not be
-included in conveying the object code work.
-
- A "User Product" is either (1) a "consumer product", which means any
-tangible personal property which is normally used for personal, family,
-or household purposes, or (2) anything designed or sold for incorporation
-into a dwelling. In determining whether a product is a consumer product,
-doubtful cases shall be resolved in favor of coverage. For a particular
-product received by a particular user, "normally used" refers to a
-typical or common use of that class of product, regardless of the status
-of the particular user or of the way in which the particular user
-actually uses, or expects or is expected to use, the product. A product
-is a consumer product regardless of whether the product has substantial
-commercial, industrial or non-consumer uses, unless such uses represent
-the only significant mode of use of the product.
-
- "Installation Information" for a User Product means any methods,
-procedures, authorization keys, or other information required to install
-and execute modified versions of a covered work in that User Product from
-a modified version of its Corresponding Source. The information must
-suffice to ensure that the continued functioning of the modified object
-code is in no case prevented or interfered with solely because
-modification has been made.
-
- If you convey an object code work under this section in, or with, or
-specifically for use in, a User Product, and the conveying occurs as
-part of a transaction in which the right of possession and use of the
-User Product is transferred to the recipient in perpetuity or for a
-fixed term (regardless of how the transaction is characterized), the
-Corresponding Source conveyed under this section must be accompanied
-by the Installation Information. But this requirement does not apply
-if neither you nor any third party retains the ability to install
-modified object code on the User Product (for example, the work has
-been installed in ROM).
-
- The requirement to provide Installation Information does not include a
-requirement to continue to provide support service, warranty, or updates
-for a work that has been modified or installed by the recipient, or for
-the User Product in which it has been modified or installed. Access to a
-network may be denied when the modification itself materially and
-adversely affects the operation of the network or violates the rules and
-protocols for communication across the network.
-
- Corresponding Source conveyed, and Installation Information provided,
-in accord with this section must be in a format that is publicly
-documented (and with an implementation available to the public in
-source code form), and must require no special password or key for
-unpacking, reading or copying.
-
- 7. Additional Terms.
-
- "Additional permissions" are terms that supplement the terms of this
-License by making exceptions from one or more of its conditions.
-Additional permissions that are applicable to the entire Program shall
-be treated as though they were included in this License, to the extent
-that they are valid under applicable law. If additional permissions
-apply only to part of the Program, that part may be used separately
-under those permissions, but the entire Program remains governed by
-this License without regard to the additional permissions.
-
- When you convey a copy of a covered work, you may at your option
-remove any additional permissions from that copy, or from any part of
-it. (Additional permissions may be written to require their own
-removal in certain cases when you modify the work.) You may place
-additional permissions on material, added by you to a covered work,
-for which you have or can give appropriate copyright permission.
-
- Notwithstanding any other provision of this License, for material you
-add to a covered work, you may (if authorized by the copyright holders of
-that material) supplement the terms of this License with terms:
-
- a) Disclaiming warranty or limiting liability differently from the
- terms of sections 15 and 16 of this License; or
-
- b) Requiring preservation of specified reasonable legal notices or
- author attributions in that material or in the Appropriate Legal
- Notices displayed by works containing it; or
-
- c) Prohibiting misrepresentation of the origin of that material, or
- requiring that modified versions of such material be marked in
- reasonable ways as different from the original version; or
-
- d) Limiting the use for publicity purposes of names of licensors or
- authors of the material; or
-
- e) Declining to grant rights under trademark law for use of some
- trade names, trademarks, or service marks; or
-
- f) Requiring indemnification of licensors and authors of that
- material by anyone who conveys the material (or modified versions of
- it) with contractual assumptions of liability to the recipient, for
- any liability that these contractual assumptions directly impose on
- those licensors and authors.
-
- All other non-permissive additional terms are considered "further
-restrictions" within the meaning of section 10. If the Program as you
-received it, or any part of it, contains a notice stating that it is
-governed by this License along with a term that is a further
-restriction, you may remove that term. If a license document contains
-a further restriction but permits relicensing or conveying under this
-License, you may add to a covered work material governed by the terms
-of that license document, provided that the further restriction does
-not survive such relicensing or conveying.
-
- If you add terms to a covered work in accord with this section, you
-must place, in the relevant source files, a statement of the
-additional terms that apply to those files, or a notice indicating
-where to find the applicable terms.
-
- Additional terms, permissive or non-permissive, may be stated in the
-form of a separately written license, or stated as exceptions;
-the above requirements apply either way.
-
- 8. Termination.
-
- You may not propagate or modify a covered work except as expressly
-provided under this License. Any attempt otherwise to propagate or
-modify it is void, and will automatically terminate your rights under
-this License (including any patent licenses granted under the third
-paragraph of section 11).
-
- However, if you cease all violation of this License, then your
-license from a particular copyright holder is reinstated (a)
-provisionally, unless and until the copyright holder explicitly and
-finally terminates your license, and (b) permanently, if the copyright
-holder fails to notify you of the violation by some reasonable means
-prior to 60 days after the cessation.
-
- Moreover, your license from a particular copyright holder is
-reinstated permanently if the copyright holder notifies you of the
-violation by some reasonable means, this is the first time you have
-received notice of violation of this License (for any work) from that
-copyright holder, and you cure the violation prior to 30 days after
-your receipt of the notice.
-
- Termination of your rights under this section does not terminate the
-licenses of parties who have received copies or rights from you under
-this License. If your rights have been terminated and not permanently
-reinstated, you do not qualify to receive new licenses for the same
-material under section 10.
-
- 9. Acceptance Not Required for Having Copies.
-
- You are not required to accept this License in order to receive or
-run a copy of the Program. Ancillary propagation of a covered work
-occurring solely as a consequence of using peer-to-peer transmission
-to receive a copy likewise does not require acceptance. However,
-nothing other than this License grants you permission to propagate or
-modify any covered work. These actions infringe copyright if you do
-not accept this License. Therefore, by modifying or propagating a
-covered work, you indicate your acceptance of this License to do so.
-
- 10. Automatic Licensing of Downstream Recipients.
-
- Each time you convey a covered work, the recipient automatically
-receives a license from the original licensors, to run, modify and
-propagate that work, subject to this License. You are not responsible
-for enforcing compliance by third parties with this License.
-
- An "entity transaction" is a transaction transferring control of an
-organization, or substantially all assets of one, or subdividing an
-organization, or merging organizations. If propagation of a covered
-work results from an entity transaction, each party to that
-transaction who receives a copy of the work also receives whatever
-licenses to the work the party's predecessor in interest had or could
-give under the previous paragraph, plus a right to possession of the
-Corresponding Source of the work from the predecessor in interest, if
-the predecessor has it or can get it with reasonable efforts.
-
- You may not impose any further restrictions on the exercise of the
-rights granted or affirmed under this License. For example, you may
-not impose a license fee, royalty, or other charge for exercise of
-rights granted under this License, and you may not initiate litigation
-(including a cross-claim or counterclaim in a lawsuit) alleging that
-any patent claim is infringed by making, using, selling, offering for
-sale, or importing the Program or any portion of it.
-
- 11. Patents.
-
- A "contributor" is a copyright holder who authorizes use under this
-License of the Program or a work on which the Program is based. The
-work thus licensed is called the contributor's "contributor version".
-
- A contributor's "essential patent claims" are all patent claims
-owned or controlled by the contributor, whether already acquired or
-hereafter acquired, that would be infringed by some manner, permitted
-by this License, of making, using, or selling its contributor version,
-but do not include claims that would be infringed only as a
-consequence of further modification of the contributor version. For
-purposes of this definition, "control" includes the right to grant
-patent sublicenses in a manner consistent with the requirements of
-this License.
-
- Each contributor grants you a non-exclusive, worldwide, royalty-free
-patent license under the contributor's essential patent claims, to
-make, use, sell, offer for sale, import and otherwise run, modify and
-propagate the contents of its contributor version.
-
- In the following three paragraphs, a "patent license" is any express
-agreement or commitment, however denominated, not to enforce a patent
-(such as an express permission to practice a patent or covenant not to
-sue for patent infringement). To "grant" such a patent license to a
-party means to make such an agreement or commitment not to enforce a
-patent against the party.
-
- If you convey a covered work, knowingly relying on a patent license,
-and the Corresponding Source of the work is not available for anyone
-to copy, free of charge and under the terms of this License, through a
-publicly available network server or other readily accessible means,
-then you must either (1) cause the Corresponding Source to be so
-available, or (2) arrange to deprive yourself of the benefit of the
-patent license for this particular work, or (3) arrange, in a manner
-consistent with the requirements of this License, to extend the patent
-license to downstream recipients. "Knowingly relying" means you have
-actual knowledge that, but for the patent license, your conveying the
-covered work in a country, or your recipient's use of the covered work
-in a country, would infringe one or more identifiable patents in that
-country that you have reason to believe are valid.
-
- If, pursuant to or in connection with a single transaction or
-arrangement, you convey, or propagate by procuring conveyance of, a
-covered work, and grant a patent license to some of the parties
-receiving the covered work authorizing them to use, propagate, modify
-or convey a specific copy of the covered work, then the patent license
-you grant is automatically extended to all recipients of the covered
-work and works based on it.
-
- A patent license is "discriminatory" if it does not include within
-the scope of its coverage, prohibits the exercise of, or is
-conditioned on the non-exercise of one or more of the rights that are
-specifically granted under this License. You may not convey a covered
-work if you are a party to an arrangement with a third party that is
-in the business of distributing software, under which you make payment
-to the third party based on the extent of your activity of conveying
-the work, and under which the third party grants, to any of the
-parties who would receive the covered work from you, a discriminatory
-patent license (a) in connection with copies of the covered work
-conveyed by you (or copies made from those copies), or (b) primarily
-for and in connection with specific products or compilations that
-contain the covered work, unless you entered into that arrangement,
-or that patent license was granted, prior to 28 March 2007.
-
- Nothing in this License shall be construed as excluding or limiting
-any implied license or other defenses to infringement that may
-otherwise be available to you under applicable patent law.
-
- 12. No Surrender of Others' Freedom.
-
- If conditions are imposed on you (whether by court order, agreement or
-otherwise) that contradict the conditions of this License, they do not
-excuse you from the conditions of this License. If you cannot convey a
-covered work so as to satisfy simultaneously your obligations under this
-License and any other pertinent obligations, then as a consequence you may
-not convey it at all. For example, if you agree to terms that obligate you
-to collect a royalty for further conveying from those to whom you convey
-the Program, the only way you could satisfy both those terms and this
-License would be to refrain entirely from conveying the Program.
-
- 13. Remote Network Interaction; Use with the GNU General Public License.
-
- Notwithstanding any other provision of this License, if you modify the
-Program, your modified version must prominently offer all users
-interacting with it remotely through a computer network (if your version
-supports such interaction) an opportunity to receive the Corresponding
-Source of your version by providing access to the Corresponding Source
-from a network server at no charge, through some standard or customary
-means of facilitating copying of software. This Corresponding Source
-shall include the Corresponding Source for any work covered by version 3
-of the GNU General Public License that is incorporated pursuant to the
-following paragraph.
-
- Notwithstanding any other provision of this License, you have
-permission to link or combine any covered work with a work licensed
-under version 3 of the GNU General Public License into a single
-combined work, and to convey the resulting work. The terms of this
-License will continue to apply to the part which is the covered work,
-but the work with which it is combined will remain governed by version
-3 of the GNU General Public License.
-
- 14. Revised Versions of this License.
-
- The Free Software Foundation may publish revised and/or new versions of
-the GNU Affero General Public License from time to time. Such new versions
-will be similar in spirit to the present version, but may differ in detail to
-address new problems or concerns.
-
- Each version is given a distinguishing version number. If the
-Program specifies that a certain numbered version of the GNU Affero General
-Public License "or any later version" applies to it, you have the
-option of following the terms and conditions either of that numbered
-version or of any later version published by the Free Software
-Foundation. If the Program does not specify a version number of the
-GNU Affero General Public License, you may choose any version ever published
-by the Free Software Foundation.
-
- If the Program specifies that a proxy can decide which future
-versions of the GNU Affero General Public License can be used, that proxy's
-public statement of acceptance of a version permanently authorizes you
-to choose that version for the Program.
-
- Later license versions may give you additional or different
-permissions. However, no additional obligations are imposed on any
-author or copyright holder as a result of your choosing to follow a
-later version.
-
- 15. Disclaimer of Warranty.
-
- THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
-APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
-HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
-OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
-THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
-PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
-IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
-ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
-
- 16. Limitation of Liability.
-
- IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
-WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
-THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
-GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
-USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
-DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
-PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
-EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
-SUCH DAMAGES.
-
- 17. Interpretation of Sections 15 and 16.
-
- If the disclaimer of warranty and limitation of liability provided
-above cannot be given local legal effect according to their terms,
-reviewing courts shall apply local law that most closely approximates
-an absolute waiver of all civil liability in connection with the
-Program, unless a warranty or assumption of liability accompanies a
-copy of the Program in return for a fee.
-
- END OF TERMS AND CONDITIONS
-
- How to Apply These Terms to Your New Programs
-
- If you develop a new program, and you want it to be of the greatest
-possible use to the public, the best way to achieve this is to make it
-free software which everyone can redistribute and change under these terms.
-
- To do so, attach the following notices to the program. It is safest
-to attach them to the start of each source file to most effectively
-state the exclusion of warranty; and each file should have at least
-the "copyright" line and a pointer to where the full notice is found.
-
-
- Copyright (C)
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see .
-
-Also add information on how to contact you by electronic and paper mail.
-
- If your software can interact with users remotely through a computer
-network, you should also make sure that it provides a way for users to
-get its source. For example, if your program is a web application, its
-interface could display a "Source" link that leads users to an archive
-of the code. There are many ways you could offer source, and different
-solutions will be better for different programs; see section 13 for the
-specific requirements.
-
- You should also get your employer (if you work as a programmer) or school,
-if any, to sign a "copyright disclaimer" for the program, if necessary.
-For more information on this, and how to apply and follow the GNU AGPL, see
-.
diff --git a/ONTOLOGY.md b/ONTOLOGY.md
deleted file mode 100644
index edca164..0000000
--- a/ONTOLOGY.md
+++ /dev/null
@@ -1,281 +0,0 @@
-# Section « File »
-
-Cette section regroupe des informations sur le fichier *properties*.
-
-```
-# [File]
-
-# Classe du fichier (valeur parmi Federation/Organization/Service/Device, obligatoire).
-file.class = federation
-
-# Version de l'ontologie utilisée utilisé (type STRING, recommandé).
-file.protocol = ChatonsInfos-0.5
-
-# Date et horaire de génération du fichier (type DATETIME, recommandé).
-file.datetime = 2020-07-06T14:23:20
-
-# Nom du générateur du fichier (type STRING, recommandé).
-file.generator = Christian avec ses doigts
-
-```
-
-# Section « Federation »
-
-Cette section regroupe des informations sur la fédération.
-```
-# [Federation]
-
-# Nom de la fédération (type STRING, obligatoire).
-federation.name= CHATONS
-
-# Description de la fédération (type STRING, recommandé).
-federation.description = CHATONS est le Collectif des Hébergeurs Alternatifs, Transparents, Ouverts, Neutres et Solidaires.
-
-# Lien du site web de la fédération (type URL, recommandé).
-federation.website = https://www.chatons.org/
-
-# Lien du logo de la fédération (type URL, recommandé).
-federation.logo = https://chatons.org/logo_chatons_v2.png
-
-# Lien du favicon de la fédération (type URL, recommandé).
-federation.favicon = https://chatons.org/sites/default/files/chatons_logo_tiny.png
-
-# Lien de la page web de contact de la fédération (type URL, recommandé).
-federation.contact.url = https://www.chatons.org/contact
-
-# Courriel de contact de la fédération (type EMAIL, recommandé).
-federation.contact.email = contact@chatons.org
-
-# Lien de la page web des mentions légales de la fédération (type URL, recommandé).
-federation.legal.url = https://www.chatons.org/page/mentions-l%C3%A9gales
-
-# Lien de la documentation web de la fédération (type URL, recommandé).
-federation.documentation.url = https://wiki.chatons.org/
-
-# Lien de la documentation technique de la fédération (type URL, recommandé).
-federation.documentation.technical.url =
-
-# Lien des tutoriels web de la fédération (type URL, recommandé).
-federation.documentation.tutorial.url =
-
-# Date de naissance de la fédération (type DATE, recommandé).
-federation.birthdate = 09/02/2016
-```
-
-# Section « Organisation »
-
-Cette section regroupe des informations sur l'organisation.
-
-```
-# [Organisation]
-
-# Nom de l'organisation (type STRING, obligatoire).
-organization.name = Chapril
-
-# Description de l'organisation (type STRING, recommandé).
-organization.description = Chapril est le chaton de l'April
-
-# Lien du site web de l'organisation (type URL, recommandé).
-organization.website = httsp://www.chapril.org/
-
-# Lien du logo de l'organisation (type URL, recommandé).
-organization.logo = https://date.chapril.org/Chapril-banner/v1/chapril-logo-small.png |
-
-# Lien du favicon de l'organisation (type URL, recommandé).
-organization.favicon = https://date.chapril.org/favicon.png
-
-# Nome du propriétaire de l'organisation (type STRING, optionnel).
-organization.owner.name = April
-
-# Lien du site web du propriétaire de l'organisation (type URL, optionnel).
-organization.owner.website = https://www.april.org/
-
-# Lien du logo du propriétaire de l'organisation (type URL, optionnel).
-organization.owner.logo = https://www.april.org/sites/default/themes/zen_april/logo.png
-
-# Lien du favicon du propriétaire de l'organisation (type URL, optionnel).
-organization.owner.favicon = https://www.april.org/sites/default/themes/zen_april/favicon.ico
-
-# Lien de la page web de contact de l'organisation (type URL, recommandé).
-organization.contact.url = https://www.chapril.org/contact.html
-
-# Courriel de contact de l'organisation (type EMAIL, recommandé).
-organization.contact.email = contact@chapril.org
-
-# Lien de la page des mentions légales de l'organisation (type URL, recommandé).
-organization.legal.url = https://www.chapril.org/cgu.html
-
-# Lien de la documentation technique de l'organisation (type URL, recommandé).
-organization.documentation.technical.url = https://admin.chapril.org/
-
-# Date de création de l'organisation (type DATE, recommandé).
-organization.birthdate = 08/11/2018
-
-# Date de fermeture de l'organisation (type DATE, recommandé).
-organization.deathdate = 08/11/2018
-
-```
-
-# Section « service »
-
-Cette section regroupe des informations sur un service.
-
-
-```
-# [Service]
-
-# Nom du service (type STRING, obligatoire).
-service.name = MumbleChaprilOrg
-
-# Description du service (type STRING, recommandé).
-service.description = Service libre de conférence audio
-
-# Lien du site web du service (type URL, recommandé).
-service.website = https://mumble.chapril.org/
-
-# Lien de la page web des mentions légales du service (type URL, recommandé).
-service.legal.url = https://www.chapril.org/cgu.html
-
-# Lien de la documentation web du service (type URL, recommandé).
-service.documentation.technical.url = https://admin.chapril.org/doku.php?id=admin:services:mumble.chapril.org
-
-# Lien des aides web pour le service (type URL, recommandé).
-service.documentation.tutorial = https://www.chapril.org/Mumble.html
-
-# Lien de la page de support du service (type URL, recommandé).
-service.contact.url = https://www.chapril.org/contact.html
-
-# Courriel du support du service (type EMAIL, recommandé).
-service.contact.email = mumble-support@chapril.org
-
-# Date d'ouverture du service (type DATE, recommandé).
-service.birthdate = 20/03/2020 |
-
-# Date de fermture du service (type DATE, optionnel).
-service.deathdate =
-
-# Statut du service (type STATUS, obligatoire).
-service.status = ON
-
-# Inscriptions requises pour utiliser le service (parmi None;Free;Member;Client, obligatoire).
-service.registration = Free,Member
-```
-
-
-# Section « Software »
-
-Cette section regroupe des information sur le logiciel utilisé par un service.
-
-```
-# [Software]
-
-# Nom du logiciel (type STRING, obligatoire).
-software.name = Firefox Send
-
-# Lien du site web du logiciel (type URL, recommandé).
-software.website = https://send.firefox.com/
-
-# Lien web vers la licence du logiciel (type URL, obligatoire).
-software.license.url = https://forge.april.org/Chapril/drop.chapril.org-firefoxsend/src/branch/chapril-v3.0.21/LICENSE
-
-# Nom de la licence du logiciel (type STRING, obligatoire).
-software.license.name = Mozilla Public License Version 2.0
-
-# Version du logiciel (type STRING, recommandé).
-software.version = Chapril-3.0.21
-
-# Lien web vers les sources du logiciel (type URL, recommandé).
-software.source.url = https://forge.april.org/Chapril/drop.chapril.org-firefoxsend/
-```
-
-# Section « Host » (expérimental)
-
-Cette section regroupe des informations sur l'hébergeur.
-
-```
-# [Host]
-
-# Nom de l'hébergeur (type STRING, obligatoire).
-host.name = Foo
-
-#
-host.provider =
-
-# Desription de l'hébergeur (type STRING, recommandé).
-host.description =
-
-# Type d'hébergement (un parmi VPS / CLOUD / LOCATEDSERVER / HOSTSERVER / HOMESERVER / RASPERRY, recommandé).
-host.type =
-
-# Pays de l'hébergeur (type STRING, recommandé).
-host.country.name = France
-
-# Code pays de l'hébergeur (type STRING, recommandé).
-host.country.code = FR
-```
-
-# Section « Subs »
-
-Cette section regroupe des liens vers des entités complémentaires.
-
-Chaque chemin doit être différent mais pas nécessairement signifiant.
-
-```
-# [Subs]
-
-# Un lien vers un fichier properties complémentaire (type URL, optionnel).
-subs.foo = https://date.chapril.org/.well-known/datechaprilorg.properties
-```
-
-Exemple :
-```
-subs.01 = https://date.chapril.org/.well-known/datechaprilorg.properties
-subs.07 = https://paste.chapril.org/.well-known/pastechaprilorg.properties
-subs.dropchaprilorg = https://drop.chapril.org/.well-known/dropchaprilorg.properties
-```
-
-
-# Section « Metrics »
-
-Cette section regroupe des informations de métrologie.
-
-```
-# [Metrics]
-
-# Nom du métrique (type STRING, recommandé).
-metrics.http.total.name = Nombre total de requêtes HTTP
-
-# Description du métriques (type STRING, recommandé).
-metrics.http.total.description = Somme des requêtes HTTP ipv4 et ipv6.
-
-# Métrique à valeur anuelle (type NUMERIC, optionnel).
-metrics.http.total.2020 = 23232
-
-# Métrique à valeur mensuelle (type MONTHS, optionnel).
-metrics.http.total.2020.months=119417,122403,133108,148109,286762,334892
-
-# Métrique à valeur hebdomadaire (type WEEKS, optionnel).
-metrics.http.total.2020.months=1194,1224,1331,1481,2867,3348
-
-# Métrique à valeur quotidienne (type DAYS, optionnel).
-metrics.http.total.2020.days=11,12,13,14,28,33
-```
-
-Exemple :
-```
-metrics.visitors.ipv4.2020=123
-metrics.visitors.ipv6.2020=123
-metrics.visitors.total.2020=246
-
-metrics.visitors.ipv4.2020.months=12;34;56;
-metrics.visitors.ipv6.2020.months=12;34;56;
-metrics.visitors.total.2020.months=24;68;112;
-
-metrics.visitors.ipv4.2020.weeks=123;456;
-metrics.visitors.ipv6.2020.weeks=123;456;
-metrics.visitors.total.2020.weeks=246;912;
-
-metrics.visitors.ipv4.2020.days=123;456;
-metrics.visitors.ipv6.2020.days=123;456;
-metrics.visitors.total.2020.days=246;912;
-```
diff --git a/README.md b/README.md
index ce0f8a1..d217e4c 100644
--- a/README.md
+++ b/README.md
@@ -1,11 +1,11 @@
-# StatoolInfos
+# StatoolInfosWeb
-StatoolInfos is a simple statistic tool software.
+StatoolInfosWeb is a webapp to value the data from StatoolInfos protocol.
## LICENSE
-StatoolInfos is released under the GNU AGPL+ license. Enjoy!
+StatoolInfosWeb is released under the GNU AGPL+ license. Enjoy!
Authors:
* Christian Pierre MOMON
@@ -50,271 +50,22 @@ Read CONCEPT.md and ONTOLOGY.md files.
## Requirements
-- Java 11
-- Eclipse 4.16 (202006).
+- Java 17
+- Eclipse 4.29 (2023-09).
## INSTALL
Install Java :
```
-apt-get install openjdk-11-jre-headless
+apt-get install openjdk-17-jre-headless
```
-Download the last release: https://forge.devinsy.fr/devinsy/statoolinfos/releases
+Download the last release: https://forge.devinsy.fr/statool/statoolinfosweb/releases
-Unzip the package and move the `statoolinfos.jar` and `statoolinfo.sh` files in `/srv/statoolinfos/bin/`.
-
-Create link:
-
-```
-cd /srv/statoolinfos/bin/ ; ln -s statoolinfos.sh statoolinfos
-```
+TODO
## Usage
-```
-Usage:
- statoolinfos [ -h | -help | --help ]
- statoolinfos [ -v | -version | --version ]
-
- statoolinfos build build property files from conf and input
- statoolinfos clear remove property files from conf
- statoolinfos crawl crawl all file from conf and input
- statoolinfos format format property files in tiny way
- statoolinfos htmlize generate web pages from conf
- statoolinfos probe OPTION [|] generate metrics files from conf
- OPTION = [-full|-today|-previousday|-NN] with NN a day count
- statoolinfos tagdate update the file.datetime file
- statoolinfos uptime update uptime journal
-
- statoolinfos list file display http access log files
- statoolinfos list log [-bot|-nobot] display http access log lines
- statoolinfos list ip [-bot|-nobot] generate ip list from http log file
- statoolinfos list ua [-bot|-nobot] generate user agent list from http log file
- statoolinfos list visitor [-bot|-nobot] generate visitors (ip+ua) list from http log file
- statoolinfos stat ip [-bot|-nobot] generate stats about ip from http log file
- statoolinfos stat ua [-bot|-nobot] generate stats about user agent from http log file
- statoolinfos stat visitor [-bot|-nobot] generate stats about visitor (ip+ua) from http log file
- statoolinfos list errfile display http error log files
- statoolinfos list errlog display http error log lines
-```
-
-
-## Generate metrics files
-
-### Basics
-
-Create a configuration file `/srv/statoolInfos/conf/foo.bar.org.conf`:
-
-```
-conf.probe.types=,
-conf.probe.metrictype1param1.file=
-conf.probe.metrictype1param2.file=
-conf.probe.metrictype2param1.file=
-conf.probe.metrictype2param2.file=
-conf.probe.target=/srv/statoolinfos/well-known/statoolinfos/foo.bar.org-metrics.properties
-```
-
-Generate the metric file for the first time:
-
-```
-/srv/statoolinfos/bin/statoolinfos probe -full /srv/statoolinfos/conf/foo.bar.org.conf
-```
-
-Create a cron file in `/etc/cron.d/statoolinfos` to update the metric file everyday:
-```
-1 0,12 * * * root /srv/statoolinfos/bin/statoolinfos probe -previousday /srv/statoolinfos/conf/foo.bar.org.conf >> /srv/statoolinfos/cron.log
-```
-
-In case of several configuration files, just set the configuration directory (without wildcard):
-```
-1 0,12 * * * root /srv/statoolinfos/bin/statoolinfos probe -previousday /srv/statoolinfos/conf/ >> /srv/statoolinfos/cron.log
-```
-
-Warning: in previous day mode, the metrics generated are overwrited for the last month, the last week and the last day. So, **six weeks in logs are required**.
-
-
-### Etherpad metrics
-
-Configuration template:
-
-```
-conf.probe.types=Etherpad
-conf.probe.httpaccesslog.file=/var/log/apache2/foo.bar.org-access.log*
-conf.probe.httpaccesslog.pattern=
-conf.probe.httpaccesslog.pathfilter=
-# This parameter requires real ip proxy setting and log output setting.
-conf.probe.etherpad.logs=/var/log/etherpad/output.log
-# Database URL. Example of the most frequent cases:
-# jdbc:mariadb://localhost:1234/databasename
-# jdbc:mysql://localhost:1234/databasename
-# jdbc:postgresql://localhost:1234/databasename
-# jdbc:sqlite:/foo/bar/databasename.sqlite
-conf.probe.etherpad.database.url=
-conf.probe.etherpad.database.user=
-conf.probe.etherpad.database.password=
-conf.probe.target=/srv/statoolinfos/well-known/statoolinfos/foo.bar.org-metrics.properties
-```
-
-### Framdadate metrics (coming soon)
-
-Configuration template:
-
-```
-conf.probe.types=Framadate
-conf.probe.target=/srv/statoolinfos/well-known/statoolinfos/foo.bar.org-metrics.properties
-```
-
-### Gitea metrics
-
-Configuration template:
-
-```
-conf.probe.types=Gitea
-conf.probe.httpaccesslog.file=/var/log/apache2/foo.bar.org-access.log*
-conf.probe.httpaccesslog.pattern=
-conf.probe.httpaccesslog.pathfilter=
-conf.probe.gitea.data=/opt/gitea/data
-conf.probe.gitea.api.url=https://forge.libre-service.eu/
-conf.probe.gitea.token=b6598c616b1cd350b834258205da4e5e8b951005
-# jdbc:mariadb://localhost:1234/databasename
-# jdbc:mysql://localhost:1234/databasename
-# jdbc:postgresql://localhost:1234/databasename
-# jdbc:sqlite:/foo/bar/databasename.sqlite
-conf.probe.gitea.database.url=
-conf.probe.gitea.database.user=
-conf.probe.gitea.database.password=
-conf.probe.target=/srv/statoolinfos/well-known/statoolinfos/foo.bar.org-metrics.properties
-```
-
-### GSL metrics
-
-Configuration template:
-
-```
-conf.probe.types=GSL
-conf.probe.gsl.stats=/foo/bar/stats.properties
-conf.probe.target=/srv/statoolinfos/well-known/statoolinfos/foo.bar.org-metrics.properties
-```
-
-### LibreQR metrics
-
-Configuration template:
-
-```
-conf.probe.types=LibreQR
-conf.probe.httpaccesslog.file=/var/log/apache2/foo.bar.org-access.log*
-conf.probe.httpaccesslog.pattern=
-conf.probe.httpaccesslog.pathfilter=
-conf.probe.libreqr.datafiles=/var/www/foo.bar.org/temp/
-conf.probe.target=/srv/statoolinfos/well-known/statoolinfos/foo.bar.org-metrics.properties
-```
-
-### Minetest metrics
-
-Configuration template:
-
-```
-conf.probe.types=Minetest
-conf.probe.minetest.logs=/home/cpm/Projets/StatoolInfos/EnvTest/minetest/minetest.log*
-
-conf.probe.minetest.players.database.url=jdbc:postgresql://localhost:5432/minetestdb
-conf.probe.minetest.players.database.user=minetestdba
-conf.probe.minetest.players.database.password=XXXXXXXXXXX
-
-conf.probe.minetest.worlds.database.url=jdbc:postgresql://localhost:5432/minetestdb
-conf.probe.minetest.worlds.database.user=minetestdba
-conf.probe.minetest.worlds.database.password=XXXXXXXXXXX
-
-conf.probe.target=/srv/statoolinfos/well-known/statoolinfos/foo.bar.org-metrics.properties
-
-```
-
-### Mumble metrics
-
-Configuration template:
-
-```
-conf.probe.types=Mumble
-conf.probe.mumble.logs=/var/log/mumble-server/mumble-server.log*
-conf.probe.target=/srv/statoolinfos/well-known/statoolinfos/foo.bar.org-metrics.properties
-```
-
-### Nextcloud metrics (coming soon)
-
-Configuration template:
-
-```
-conf.probe.types=Nextcloud
-conf.probe.httpaccesslog.file=/var/log/apache2/foo.bar.org-access.log*
-conf.probe.httpaccesslog.pattern=
-conf.probe.httpaccesslog.pathfilter=
-conf.probe.target=/srv/statoolinfos/well-known/statoolinfos/foo.bar.org-metrics.properties
-```
-
-### PrivateBin metrics (partial)
-
-Warning: works fine if database, image and comment options are disabled.
-
-Configuration template:
-
-```
-conf.probe.types=PrivateBin
-conf.probe.httpaccesslog.file=/var/log/apache2/foo.bar.org-access.log*
-conf.probe.httpaccesslog.pattern=
-conf.probe.httpaccesslog.pathfilter=
-conf.probe.privatebin.data=/var/www/paste.libre-service.eu/data/
-conf.probe.target=/srv/statoolinfos/well-known/statoolinfos/foo.bar.org-metrics.properties
-```
-
-### Web metrics
-
-Configuration template:
-
-```
-conf.probe.types=HttpAccessLog, HttpErrorLog
-conf.probe.httpaccesslog.file=/var/log/apache2/foo.bar.org-access.log*,/var/log/apache2/foo.bar.org-extraaccess.log*
-conf.probe.httperrorlog.file=/var/log/apache2/foo.bar.org-error.log*,/var/log/apache2/foo.bar.org-extraerror.log*
-conf.probe.target=/srv/statoolinfos/well-known/statoolinfos/foo.bar.org-metrics.properties
-
-# Custom access log pattern with Java regex.
-# Default: ^(?[a-fA-F0-9\:\.]+) - (?[^\[]+) \[(?
-
-
-
-
diff --git a/src/fr/devinsy/statoolinfos/htmlize/stuff/statoolinfos-logo-name.jpg b/src/fr/devinsy/statoolinfos/htmlize/stuff/statoolinfos-logo-name.jpg
deleted file mode 100644
index ed3ead0..0000000
Binary files a/src/fr/devinsy/statoolinfos/htmlize/stuff/statoolinfos-logo-name.jpg and /dev/null differ
diff --git a/src/fr/devinsy/statoolinfos/htmlize/stuff/statoolinfos-logo.jpg b/src/fr/devinsy/statoolinfos/htmlize/stuff/statoolinfos-logo.jpg
deleted file mode 100644
index 5d30f48..0000000
Binary files a/src/fr/devinsy/statoolinfos/htmlize/stuff/statoolinfos-logo.jpg and /dev/null differ
diff --git a/src/fr/devinsy/statoolinfos/htmlize/webCharterView.xhtml b/src/fr/devinsy/statoolinfos/htmlize/webCharterView.xhtml
deleted file mode 100644
index 4722124..0000000
--- a/src/fr/devinsy/statoolinfos/htmlize/webCharterView.xhtml
+++ /dev/null
@@ -1,44 +0,0 @@
-
-
-
-
- StatoolInfos
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/src/fr/devinsy/statoolinfos/io/CSVFile.java b/src/fr/devinsy/statoolinfos/io/CSVFile.java
deleted file mode 100644
index 6d7090f..0000000
--- a/src/fr/devinsy/statoolinfos/io/CSVFile.java
+++ /dev/null
@@ -1,217 +0,0 @@
-/*
- * Copyright (C) 2021-2023 Christian Pierre MOMON
- *
- * This file is part of StatoolInfos, simple service statistics tool.
- *
- * StatoolInfos is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * StatoolInfos is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with StatoolInfos. If not, see .
- */
-package fr.devinsy.statoolinfos.io;
-
-import java.io.File;
-import java.io.IOException;
-
-import org.apache.commons.lang3.StringUtils;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import fr.devinsy.statoolinfos.HtmlizerContext;
-import fr.devinsy.statoolinfos.core.Categories;
-import fr.devinsy.statoolinfos.core.Organization;
-import fr.devinsy.statoolinfos.core.Organizations;
-import fr.devinsy.statoolinfos.core.Service;
-import fr.devinsy.statoolinfos.core.Services;
-import fr.devinsy.statoolinfos.properties.PathProperty;
-import fr.devinsy.strings.StringList;
-import fr.devinsy.strings.StringSet;
-
-/**
- * The Class CSVFile.
- */
-public class CSVFile
-{
- private static final Logger logger = LoggerFactory.getLogger(CSVFile.class);
-
- public static final int MAX_LINE_SIZE = 4096;
- public static final String SEPARATOR = ";";
-
- /**
- * Save.
- *
- * @param file
- * the file
- * @param source
- * the source
- * @throws IOException
- * Signals that an I/O exception has occurred.
- */
- public static void save(final File file, final Organizations source) throws IOException
- {
- CSVWriter out = null;
- try
- {
- out = new CSVWriter(file, ';');
-
- write(out, source);
- }
- finally
- {
- out.close();
- }
- }
-
- /**
- * Save.
- *
- * @param file
- * the file
- * @param source
- * the source
- * @throws IOException
- * Signals that an I/O exception has occurred.
- */
- public static void save(final File file, final Services source) throws IOException
- {
- CSVWriter out = null;
- try
- {
- out = new CSVWriter(file, ';');
- write(out, source);
- }
- finally
- {
- out.close();
- }
- }
-
- /**
- * Write.
- *
- * @param out
- * the out
- * @param organizations
- * the organizations
- * @throws IOException
- * Signals that an I/O exception has occurred.
- */
- public static void write(final SpreadsheetWriter out, final Organizations organizations) throws IOException
- {
- // Build label list.
- StringList labels = new StringList(100);
- StringSet dejavu = new StringSet(100);
- StringList prefixes = new StringList("file", "organization", "crawl");
- for (String prefix : prefixes)
- {
- for (Organization organization : organizations)
- {
- for (PathProperty property : organization.getByPrefix(prefix))
- {
- if (!dejavu.contains(property.getPath()))
- {
- labels.add(property.getPath());
- dejavu.add(property.getPath());
- }
- }
- }
- }
- dejavu.clear();
-
- // Write label line.
- for (String label : labels)
- {
- out.writeCell(label);
- }
- out.writeEndRow();
-
- // Write organization lines.
- for (Organization organization : organizations)
- {
- for (String label : labels)
- {
- String value = organization.get(label);
- out.writeCell(value);
- }
- out.writeEndRow();
- }
- }
-
- /**
- * Write.
- *
- * @param out
- * the out
- * @param services
- * the services
- * @throws IOException
- * Signals that an I/O exception has occurred.
- */
- public static void write(final SpreadsheetWriter out, final Services services) throws IOException
- {
- // Build label list.
- StringList labels = new StringList(100);
- StringSet dejavu = new StringSet(100);
- StringList prefixes = new StringList("file", "service", "host", "software", "crawl");
- for (String prefix : prefixes)
- {
- for (Service service : services)
- {
- for (PathProperty property : service.getByPrefix(prefix))
- {
- if (!dejavu.contains(property.getPath()))
- {
- labels.add(property.getPath());
- dejavu.add(property.getPath());
- }
- }
- }
- }
- dejavu.clear();
- int index = labels.indexOf("service.name");
- labels.add(index, "organization.name");
- index = labels.indexOf("software.name");
- labels.add(index, "software.categories");
-
- // Write label line.
- for (String label : labels)
- {
- out.writeCell(label);
- }
- out.writeEndRow();
-
- Categories categories = HtmlizerContext.instance().getCategories();
-
- // Write service lines.
- for (Service service : services)
- {
- for (String label : labels)
- {
- String value;
- if (StringUtils.equals(label, "organization.name"))
- {
- value = service.getOrganization().getName();
- }
- else if (StringUtils.equals(label, "software.categories"))
- {
- value = categories.findBySoftware(service.getSoftwareName()).toString();
- }
- else
- {
- value = service.get(label);
- }
-
- out.writeCell(value);
- }
- out.writeEndRow();
- }
- }
-}
diff --git a/src/fr/devinsy/statoolinfos/io/CSVWriter.java b/src/fr/devinsy/statoolinfos/io/CSVWriter.java
deleted file mode 100644
index c66e03f..0000000
--- a/src/fr/devinsy/statoolinfos/io/CSVWriter.java
+++ /dev/null
@@ -1,148 +0,0 @@
-/*
- * Copyright (C) 2021-2023 Christian Pierre MOMON
- *
- * This file is part of StatoolInfos, simple service statistics tool.
- *
- * StatoolInfos is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * StatoolInfos is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with StatoolInfos. If not, see .
- */
-package fr.devinsy.statoolinfos.io;
-
-import java.io.File;
-import java.io.FileNotFoundException;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.OutputStreamWriter;
-import java.io.PrintWriter;
-import java.io.UnsupportedEncodingException;
-import java.nio.charset.StandardCharsets;
-
-import org.apache.commons.io.IOUtils;
-import org.apache.commons.lang3.StringUtils;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * The Class CSVWriter.
- */
-public class CSVWriter implements SpreadsheetWriter
-{
- private static final Logger logger = LoggerFactory.getLogger(CSVWriter.class);
-
- private char separator;
- private PrintWriter out;
- private boolean isNewline;
-
- /**
- * Instantiates a new CSV writer.
- *
- * @param file
- * the file
- * @param separator
- * the separator
- * @throws UnsupportedEncodingException
- * the unsupported encoding exception
- * @throws FileNotFoundException
- * the file not found exception
- */
- public CSVWriter(final File file, final char separator) throws UnsupportedEncodingException, FileNotFoundException
- {
- this.separator = separator;
- this.out = new PrintWriter(new OutputStreamWriter(new FileOutputStream(file), StandardCharsets.UTF_8));
- this.isNewline = true;
- }
-
- /**
- * Close.
- *
- * @throws FileNotFoundException
- * the file not found exception
- * @throws IOException
- * Signals that an I/O exception has occurred.
- */
- @Override
- public void close() throws FileNotFoundException, IOException
- {
- IOUtils.closeQuietly(this.out);
- }
-
- /**
- * Escape.
- *
- * @param string
- * the string
- * @return the string
- */
- private String escape(final String string)
- {
- String result;
-
- if (string == null)
- {
- result = null;
- }
- else
- {
- if (StringUtils.containsAny(string, ',', '\n', '"', this.separator))
- {
- result = String.format("\"%s\"", string);
- }
- else
- {
- result = string;
- }
- }
-
- //
- return result;
- }
-
- /**
- * Write cell.
- *
- * @param content
- * the content
- */
- @Override
- public void writeCell(final String content)
- {
- if (this.isNewline)
- {
- this.isNewline = false;
- }
- else
- {
- this.out.print(this.separator);
- }
- this.out.print(StringUtils.defaultIfBlank(escape(content), ""));
- }
-
- /**
- * Write endpage.
- */
- @Override
- public void writeEndpage()
- {
- this.out.println();
- }
-
- /**
- * Write end row.
- */
- @Override
- public void writeEndRow()
- {
- this.out.println();
- this.isNewline = true;
- }
-}
diff --git a/src/fr/devinsy/statoolinfos/io/JSONFile.java b/src/fr/devinsy/statoolinfos/io/JSONFile.java
deleted file mode 100644
index fe8c7c5..0000000
--- a/src/fr/devinsy/statoolinfos/io/JSONFile.java
+++ /dev/null
@@ -1,281 +0,0 @@
-/*
- * Copyright (C) 2021 Christian Pierre MOMON
- *
- * This file is part of StatoolInfos, simple service statistics tool.
- *
- * StatoolInfos is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * StatoolInfos is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with StatoolInfos. If not, see .
- */
-package fr.devinsy.statoolinfos.io;
-
-import java.io.File;
-import java.io.FileNotFoundException;
-import java.io.UnsupportedEncodingException;
-
-import org.apache.commons.lang3.StringUtils;
-import org.apache.commons.text.StringEscapeUtils;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import fr.devinsy.statoolinfos.HtmlizerContext;
-import fr.devinsy.statoolinfos.core.Categories;
-import fr.devinsy.statoolinfos.core.Federation;
-import fr.devinsy.statoolinfos.core.Organization;
-import fr.devinsy.statoolinfos.core.Organizations;
-import fr.devinsy.statoolinfos.core.Service;
-import fr.devinsy.statoolinfos.core.Services;
-import fr.devinsy.statoolinfos.properties.PathProperty;
-import fr.devinsy.statoolinfos.properties.PathPropertyList;
-import fr.devinsy.strings.StringList;
-import fr.devinsy.strings.StringsUtils;
-
-/**
- * The Class JSONFile.
- */
-public class JSONFile
-{
- private static final Logger logger = LoggerFactory.getLogger(JSONFile.class);
-
- /**
- * Escape.
- *
- * @param source
- * the source
- * @return the string
- */
- public static String escapeJSON(final String source)
- {
- String result;
-
- result = StringEscapeUtils.escapeJson(source);
-
- //
- return result;
- }
-
- /**
- * Save.
- *
- * @param file
- * the file
- * @param federation
- * the federation
- * @throws UnsupportedEncodingException
- * the unsupported encoding exception
- * @throws FileNotFoundException
- * the file not found exception
- */
- public static void save(final File file, final Federation federation) throws UnsupportedEncodingException, FileNotFoundException
- {
- StringList lines = new StringList();
-
- lines.appendln("{ \"federation\" : ");
-
- lines.addAll(toJSON(federation));
-
- lines.removeLast();
- lines.appendln(",");
- lines.appendln("\"organizations\" : [");
-
- for (Organization organization : federation.getOrganizations())
- {
- lines.addAll(toJSON(organization));
- lines.removeLast();
-
- lines.appendln(",");
- lines.append("\"services\" : [");
-
- for (Service service : organization.getServices())
- {
- lines.addAll(toJSON(service));
- lines.appendln(",");
- }
- if (!organization.getServices().isEmpty())
- {
- lines.removeLast(2);
- }
- lines.appendln();
- lines.appendln("]");
- lines.append("}");
- lines.appendln(",");
- }
- if (!federation.getOrganizations().isEmpty())
- {
- lines.removeLast(2);
- lines.appendln();
- }
-
- lines.appendln("]");
-
- lines.appendln("}");
- lines.appendln("}");
-
- StringsUtils.writeToFile(file, lines);
- }
-
- /**
- * Save.
- *
- * @param file
- * the file
- * @param organizations
- * the organizations
- * @throws UnsupportedEncodingException
- * the unsupported encoding exception
- * @throws FileNotFoundException
- * the file not found exception
- */
- public static void save(final File file, final Organizations organizations) throws UnsupportedEncodingException, FileNotFoundException
- {
- StringList lines = new StringList();
-
- lines.appendln("{ \"organizations\" : [");
-
- for (Organization organization : organizations)
- {
- lines.addAll(toJSON(organization));
- lines.append(",");
- }
- if (!organizations.isEmpty())
- {
- lines.removeLast();
- }
-
- lines.appendln("] }");
-
- StringsUtils.writeToFile(file, lines);
- }
-
- /**
- * Save.
- *
- * @param file
- * the file
- * @param services
- * the services
- * @throws UnsupportedEncodingException
- * the unsupported encoding exception
- * @throws FileNotFoundException
- * the file not found exception
- */
- public static void save(final File file, final Services services) throws UnsupportedEncodingException, FileNotFoundException
- {
- StringList lines = new StringList();
-
- lines.appendln("{ \"services\" : [");
-
- for (Service service : services)
- {
- lines.addAll(toJSON(service));
- lines.append(",");
- }
- if (!services.isEmpty())
- {
- lines.removeLast();
- }
-
- lines.appendln("] }");
-
- StringsUtils.writeToFile(file, lines);
- }
-
- /**
- * To JSON.
- *
- * @param properties
- * the properties
- * @return the string list
- */
- public static StringList toJSON(final PathPropertyList properties)
- {
- StringList result;
-
- result = new StringList();
-
- result.append("{");
-
- if (properties != null)
- {
- boolean firstDone = false;
- for (PathProperty property : properties)
- {
- if (StringUtils.isNotBlank(property.getValue()))
- {
- firstDone = true;
- result.append("\"");
- result.append(StringEscapeUtils.escapeJson(property.getPath()));
- result.append("\" : \"");
- result.append(StringEscapeUtils.escapeJson(property.getValue()));
- result.append("\"");
- result.append(",");
- }
- }
- if (firstDone)
- {
- result.removeLast();
- }
- }
- result.append("}");
-
- //
- return result;
- }
-
- /**
- * To JSON.
- *
- * @param service
- * the service
- * @return the string list
- */
- public static StringList toJSON(final Service service)
- {
- StringList result;
-
- result = toJSON((PathPropertyList) service);
-
- //
- result.removeLast();
- result.append(",");
-
- //
- String organizationName;
- if (service.getOrganization() == null)
- {
- organizationName = "";
- }
- else
- {
- organizationName = service.getOrganization().getName();
- }
- result.append("\"");
- result.append("organization.name");
- result.append("\" : \"");
- result.append(organizationName);
- result.append("\"");
- result.append(",");
-
- //
- Categories categories = HtmlizerContext.instance().getCategories();
- result.append("\"");
- result.append("software.categories");
- result.append("\" : \"");
- result.append(StringEscapeUtils.escapeJson(categories.findBySoftware(service.getSoftwareName()).toString()));
- result.append("\"");
-
- result.append("}");
-
- //
- return result;
- }
-}
diff --git a/src/fr/devinsy/statoolinfos/io/ODSFile.java b/src/fr/devinsy/statoolinfos/io/ODSFile.java
deleted file mode 100644
index 3c431bb..0000000
--- a/src/fr/devinsy/statoolinfos/io/ODSFile.java
+++ /dev/null
@@ -1,94 +0,0 @@
-/*
- * Copyright (C) 2021 Christian Pierre MOMON
- *
- * This file is part of StatoolInfos, simple service statistics tool.
- *
- * StatoolInfos is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * StatoolInfos is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with StatoolInfos. If not, see .
- */
-package fr.devinsy.statoolinfos.io;
-
-import java.io.File;
-import java.io.IOException;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import fr.devinsy.statoolinfos.core.Organizations;
-import fr.devinsy.statoolinfos.core.Services;
-
-/**
- * The Class ODSFile.
- */
-public class ODSFile
-{
- public static final int MAX_LINE_SIZE = 1024;
-
- private static final Logger logger = LoggerFactory.getLogger(ODSFile.class);;
-
- protected enum Status
- {
- MANDATORY,
- OPTIONAL
- }
-
- /**
- * Save.
- *
- * @param file
- * the file
- * @param source
- * the source
- */
- public static void save(final File file, final Organizations source) throws IOException
- {
- ODSWriter out = null;
- try
- {
- out = new ODSWriter(file);
- CSVFile.write(out, source);
- }
- finally
- {
- if (out != null)
- {
- out.close();
- }
- }
- }
-
- /**
- * Save.
- *
- * @param file
- * the file
- * @param source
- * the source
- */
- public static void save(final File file, final Services source) throws IOException
- {
- ODSWriter out = null;
- try
- {
- out = new ODSWriter(file);
- CSVFile.write(out, source);
- }
- finally
- {
- if (out != null)
- {
- out.close();
- }
- }
- }
-}
diff --git a/src/fr/devinsy/statoolinfos/io/ODSWriter.java b/src/fr/devinsy/statoolinfos/io/ODSWriter.java
deleted file mode 100644
index d7ee475..0000000
--- a/src/fr/devinsy/statoolinfos/io/ODSWriter.java
+++ /dev/null
@@ -1,121 +0,0 @@
-/*
- * Copyright (C) 2021 Christian Pierre MOMON
- *
- * This file is part of StatoolInfos, simple service statistics tool.
- *
- * StatoolInfos is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * StatoolInfos is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with StatoolInfos. If not, see .
- */
-package fr.devinsy.statoolinfos.io;
-
-import java.io.File;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-
-import javax.swing.table.DefaultTableModel;
-
-import org.apache.commons.lang3.StringUtils;
-import org.apache.commons.lang3.math.NumberUtils;
-import org.jopendocument.dom.spreadsheet.Sheet;
-import org.jopendocument.dom.spreadsheet.SpreadSheet;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * The Class ODSWriter.
- */
-public class ODSWriter implements SpreadsheetWriter
-{
- private static final Logger logger = LoggerFactory.getLogger(ODSWriter.class);
-
- private File file;
- private SpreadSheet workbook;
- private Sheet currentSheet;
- private int currentSheetIndex;
- private int currentRow;
- private int currentColumn;
-
- /**
- * Instantiates a new ODS writer.
- *
- * @param file
- * the file
- */
- public ODSWriter(final File file)
- {
- this.file = file;
- this.workbook = SpreadSheet.createEmpty(new DefaultTableModel());
-
- this.workbook.getSheet(0).setName(file.getName());
-
- this.currentSheetIndex = 0;
- this.currentSheet = this.workbook.getSheet(this.currentSheetIndex);
- this.currentRow = 0;
- this.currentColumn = 0;
- }
-
- /**
- * Close.
- *
- * @throws IOException
- *
- * @throws FileNotFoundException
- */
- @Override
- public void close() throws FileNotFoundException, IOException
- {
- this.workbook.saveAs(this.file);
- }
-
- /**
- * Write cell.
- *
- * @param content
- * the content
- */
- @Override
- public void writeCell(final String content)
- {
- this.currentSheet.ensureColumnCount(this.currentColumn + 1);
- this.currentSheet.ensureRowCount(this.currentRow + 1);
-
- if (NumberUtils.isCreatable(content))
- {
- this.currentSheet.getCellAt(this.currentColumn, this.currentRow).setValue(Double.valueOf(content));
- }
- else
- {
- this.currentSheet.getCellAt(this.currentColumn, this.currentRow).setValue(StringUtils.defaultIfBlank(content, ""));
- }
-
- this.currentColumn += 1;
- }
-
- /**
- * Write endpage.
- */
- @Override
- public void writeEndpage()
- {
- }
-
- /**
- * Write end row.
- */
- @Override
- public void writeEndRow()
- {
- this.currentRow += 1;
- this.currentColumn = 0;
- }
-}
diff --git a/src/fr/devinsy/statoolinfos/io/SpreadsheetWriter.java b/src/fr/devinsy/statoolinfos/io/SpreadsheetWriter.java
deleted file mode 100644
index 6bd6332..0000000
--- a/src/fr/devinsy/statoolinfos/io/SpreadsheetWriter.java
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Copyright (C) 2021 Christian Pierre MOMON
- *
- * This file is part of StatoolInfos, simple service statistics tool.
- *
- * StatoolInfos is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * StatoolInfos is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with StatoolInfos. If not, see .
- */
-package fr.devinsy.statoolinfos.io;
-
-import java.io.FileNotFoundException;
-import java.io.IOException;
-
-/**
- * The Interface SpreadsheetWriter.
- */
-public interface SpreadsheetWriter
-{
- void close() throws FileNotFoundException, IOException;
-
- void writeCell(String content);
-
- void writeEndpage();
-
- void writeEndRow();
-}
diff --git a/src/fr/devinsy/statoolinfos/metrics/IpCounters.java b/src/fr/devinsy/statoolinfos/metrics/IpCounters.java
deleted file mode 100644
index c1f0fc0..0000000
--- a/src/fr/devinsy/statoolinfos/metrics/IpCounters.java
+++ /dev/null
@@ -1,154 +0,0 @@
-/*
- * Copyright (C) 2021 Christian Pierre MOMON
- *
- * This file is part of StatoolInfos, simple service statistics tool.
- *
- * StatoolInfos is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * StatoolInfos is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with StatoolInfos. If not, see .
- */
-package fr.devinsy.statoolinfos.metrics;
-
-import java.util.HashMap;
-
-import org.apache.commons.lang3.StringUtils;
-
-import fr.devinsy.statoolinfos.util.IpUtils;
-import fr.devinsy.strings.StringSet;
-
-/**
- * The Class IpCounters.
- */
-public class IpCounters extends HashMap
-{
- private static final long serialVersionUID = -1597516678500117985L;
-
- /**
- * Instantiates a new path counters.
- */
- public IpCounters()
- {
- super();
- }
-
- /**
- * Gets the.
- *
- * @param timeMark
- * the time mark
- * @return the string set
- */
- public StringSet get(final String timeMark)
- {
- StringSet result;
-
- result = super.get(timeMark);
-
- //
- return result;
- }
-
- /**
- * Gets the counters.
- *
- * @return the counters
- */
- public PathCounters getCounters(final String prefix)
- {
- PathCounters result;
-
- result = new PathCounters();
-
- for (String timeMark : keySet())
- {
- StringSet set = get(timeMark);
- result.inc(set.size(), prefix, timeMark);
- }
-
- //
- return result;
- }
-
- /**
- * Put.
- *
- * @param timemark
- * the timemark
- * @param ip
- * the ip
- */
- public void put(final String ip, final String timemark)
- {
- if (!StringUtils.isBlank(ip))
- {
- StringSet set = super.get(timemark);
- if (set == null)
- {
- set = new StringSet();
- put(timemark, set);
- }
-
- set.put(ip);
- }
- }
-
- /**
- * Put.
- *
- * @param ip
- * the ip
- * @param timeMarks
- * the time marks
- */
- public void put(final String ip, final String... timeMarks)
- {
- if (!StringUtils.isBlank(ip))
- {
- for (String timeMark : timeMarks)
- {
- put(ip, timeMark);
- }
- }
- }
-
- /**
- * Put ipv 4.
- *
- * @param ip
- * the ip
- * @param timeMarks
- * the time marks
- */
- public void putIpv4(final String ip, final String... timeMarks)
- {
- if (IpUtils.isIpv4(ip))
- {
- put(ip, timeMarks);
- }
- }
-
- /**
- * Put ipv 6.
- *
- * @param ip
- * the ip
- * @param timeMarks
- * the time marks
- */
- public void putIpv6(final String ip, final String... timeMarks)
- {
- if (IpUtils.isIpv6(ip))
- {
- put(ip, timeMarks);
- }
- }
-}
diff --git a/src/fr/devinsy/statoolinfos/metrics/Metric.java b/src/fr/devinsy/statoolinfos/metrics/Metric.java
deleted file mode 100644
index 35a32de..0000000
--- a/src/fr/devinsy/statoolinfos/metrics/Metric.java
+++ /dev/null
@@ -1,161 +0,0 @@
-/*
- * Copyright (C) 2020 Christian Pierre MOMON
- *
- * This file is part of StatoolInfos, simple service statistics tool.
- *
- * StatoolInfos is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * StatoolInfos is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with StatoolInfos. If not, see .
- */
-package fr.devinsy.statoolinfos.metrics;
-
-import java.time.YearMonth;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import fr.devinsy.statoolinfos.properties.MonthValues;
-import fr.devinsy.strings.StringList;
-
-/**
- * The Class Metric.
- */
-public class Metric
-{
- private static Logger logger = LoggerFactory.getLogger(Metric.class);
-
- public enum Type
- {
- MONTHS,
- WEEKS,
- DAYS
- }
-
- private String path;
- private String name;
- private String description;
- private String startYear;
- private StringList yearValues;
- private StringList monthValues;
- private StringList weekValues;
- private StringList dayValues;
-
- /**
- * Instantiates a new metric.
- */
- public Metric(final String path, final String name, final String description, final String startYear)
- {
- this.path = path;
- this.name = name;
- this.description = description;
- this.startYear = startYear;
- this.yearValues = new StringList();
- this.monthValues = new StringList();
- this.weekValues = new StringList();
- this.dayValues = new StringList();
- }
-
- public StringList getDayValues()
- {
- return this.dayValues;
- }
-
- public String getDescription()
- {
- return this.description;
- }
-
- public StringList getMonthValues()
- {
- return this.monthValues;
- }
-
- public String getName()
- {
- return this.name;
- }
-
- public String getStartYear()
- {
- return this.startYear;
- }
-
- public StringList getWeekValues()
- {
- return this.weekValues;
- }
-
- public StringList getYearValues()
- {
- return this.yearValues;
- }
-
- /**
- * Checks if is empty.
- *
- * @return true, if is empty
- */
- public boolean isEmpty()
- {
- boolean result;
-
- if ((this.monthValues.isEmpty()) && (this.weekValues.isEmpty()) && (this.dayValues.isEmpty()))
- {
- result = true;
- }
- else
- {
- result = false;
- }
-
- //
- return result;
- }
-
- public void setDescription(final String description)
- {
- this.description = description;
- }
-
- public void setName(final String name)
- {
- this.name = name;
- }
-
- public void setStartYear(final String startYear)
- {
- this.startYear = startYear;
- }
-
- /**
- * To month values.
- *
- * @return the month values
- */
- public MonthValues toMonthValues()
- {
- MonthValues result;
-
- result = new MonthValues();
- result.setLabel(this.name);
-
- YearMonth timestamp = YearMonth.of(Integer.valueOf(this.startYear), 01);
- for (String value : this.monthValues)
- {
- result.put(timestamp, Double.valueOf(value));
- timestamp = timestamp.plusMonths(1);
- }
-
- //
- return result;
- }
-}
diff --git a/src/fr/devinsy/statoolinfos/metrics/PathCounter.java b/src/fr/devinsy/statoolinfos/metrics/PathCounter.java
deleted file mode 100644
index 7959a05..0000000
--- a/src/fr/devinsy/statoolinfos/metrics/PathCounter.java
+++ /dev/null
@@ -1,152 +0,0 @@
-/*
- * Copyright (C) 2020 Christian Pierre MOMON
- *
- * This file is part of StatoolInfos, simple service statistics tool.
- *
- * StatoolInfos is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * StatoolInfos is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with StatoolInfos. If not, see .
- */
-package fr.devinsy.statoolinfos.metrics;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * The Class PathCounter.
- */
-public class PathCounter
-{
- private static Logger logger = LoggerFactory.getLogger(PathCounter.class);
-
- private String path;
- private String timeMark;
- private long counter;
-
- /**
- * Instantiates a new path counter.
- *
- * @param path
- * the path
- * @param timeMark
- * the time mark
- */
- public PathCounter(final String path, final String timeMark)
- {
- this.path = path;
- this.timeMark = timeMark;
- this.counter = 0;
- }
-
- public long getCounter()
- {
- return this.counter;
- }
-
- public String getPath()
- {
- return this.path;
- }
-
- public String getTimeMark()
- {
- return this.timeMark;
- }
-
- /**
- * Inc.
- */
- public void inc()
- {
- this.counter += 1;
- }
-
- public void inc(final long value)
- {
- this.counter += value;
- }
-
- /**
- * Checks if is date.
- *
- * @return true, if is date
- */
- public boolean isDate()
- {
- boolean result;
-
- result = TimeMarkUtils.isDate(this.timeMark);
-
- //
- return result;
- }
-
- /**
- * Checks if is year.
- *
- * @return true, if is year
- */
- public boolean isYear()
- {
- boolean result;
-
- result = TimeMarkUtils.isYear(this.timeMark);
-
- //
- return result;
- }
-
- /**
- * Checks if is year mark.
- *
- * @return true, if is year mark
- */
- public boolean isYearMark()
- {
- boolean result;
-
- result = TimeMarkUtils.isYear(this.timeMark);
-
- //
- return result;
- }
-
- /**
- * Checks if is year week.
- *
- * @return true, if is year week
- */
- public boolean isYearWeek()
- {
- boolean result;
-
- result = TimeMarkUtils.isYearWeek(this.timeMark);
-
- //
- return result;
- }
-
- public void setCounter(final long counter)
- {
- this.counter = counter;
- }
-
- public void setPath(final String path)
- {
- this.path = path;
- }
-
- public void setTimeMark(final String timeMark)
- {
- this.timeMark = timeMark;
- }
-}
diff --git a/src/fr/devinsy/statoolinfos/metrics/PathCounters.java b/src/fr/devinsy/statoolinfos/metrics/PathCounters.java
deleted file mode 100644
index 7d49c21..0000000
--- a/src/fr/devinsy/statoolinfos/metrics/PathCounters.java
+++ /dev/null
@@ -1,641 +0,0 @@
-/*
- * Copyright (C) 2020-2024 Christian Pierre MOMON
- *
- * This file is part of StatoolInfos, simple service statistics tool.
- *
- * StatoolInfos is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * StatoolInfos is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with StatoolInfos. If not, see .
- */
-package fr.devinsy.statoolinfos.metrics;
-
-import java.time.LocalDate;
-import java.time.YearMonth;
-import java.time.format.DateTimeFormatter;
-import java.util.HashMap;
-import java.util.Locale;
-
-import org.apache.commons.lang3.StringUtils;
-import org.threeten.extra.YearWeek;
-
-import fr.devinsy.statoolinfos.core.StatoolInfosUtils;
-import fr.devinsy.strings.StringList;
-import fr.devinsy.strings.StringSet;
-
-/**
- * The Class PathCounters.
- */
-public class PathCounters extends HashMap
-{
- private static final long serialVersionUID = 6881726853303684439L;
-
- /**
- * Instantiates a new path counters.
- */
- public PathCounters()
- {
- super();
- }
-
- /**
- * Compute key.
- *
- * @param path
- * the path
- * @param timeMark
- * the time mark
- * @return the string
- */
- public String computeKey(final String path, final String timeMark)
- {
- String result;
-
- result = path + "." + timeMark;
-
- //
- return result;
- }
-
- /**
- * Gets the.
- *
- * @param path
- * the path
- * @param timeMark
- * the time mark
- * @return the path counter
- */
- public PathCounter get(final String path, final String timeMark)
- {
- PathCounter result;
-
- String key = computeKey(path, timeMark);
-
- result = get(key);
-
- //
- return result;
- }
-
- /**
- * Gets the by prefix.
- *
- * @param prefix
- * the prefix
- * @return the by prefix
- */
- public PathCounters getByPrefix(final String prefix)
- {
- PathCounters result;
-
- result = new PathCounters();
-
- for (PathCounter counter : this.values())
- {
- if (StringUtils.equals(counter.getPath(), prefix))
- {
- result.put(counter);
- }
- }
-
- //
- return result;
- }
-
- /**
- * Gets the count.
- *
- * @param path
- * the path
- * @param timeMark
- * the time mark
- * @return the count
- */
- public long getCount(final String path, final String timeMark)
- {
- long result;
-
- PathCounter counter = get(path, timeMark);
- if (counter == null)
- {
- result = 0;
- }
- else
- {
- result = counter.getCounter();
- }
-
- //
- return result;
- }
-
- /**
- * Gets the days values line.
- *
- * @param prefix
- * the prefix
- * @param year
- * the year
- * @return the days values line
- */
- public String getDaysValuesLine(final String prefix, final String year)
- {
- String result;
-
- StringList line = new StringList();
-
- LocalDate day = LocalDate.of(Integer.valueOf(year), 01, 01);
- boolean ended = false;
- while (!ended)
- {
- if (day.getYear() == Integer.valueOf(year))
- {
- String timeMark = day.format(DateTimeFormatter.ofPattern("yyyy-MM-dd", Locale.FRANCE));
- PathCounter dayCounter = get(prefix, timeMark);
- if (dayCounter != null)
- {
- line.append(dayCounter.getCounter());
- }
- line.append(',');
-
- //
- day = day.plusDays(1);
- }
- else
- {
- ended = true;
- }
- }
-
- while ((!line.isEmpty()) && (line.getLast().equals(",")))
- {
- line.removeLast();
- }
-
- if (line.isEmpty())
- {
- result = "";
- }
- else
- {
- result = line.toString();
- }
-
- //
- return result;
- }
-
- /**
- * Gets the months values line.
- *
- * @param prefix
- * the prefix
- * @param year
- * the year
- * @return the months values line
- */
- public String getMonthsValuesLine(final String prefix, final String year)
- {
- String result;
-
- StringList line = new StringList();
- for (int month = 1; month <= 12; month++)
- {
- String timeMark = String.format("%s-%02d", year, month);
- PathCounter monthCounter = get(prefix, timeMark);
- if (monthCounter != null)
- {
- line.append(monthCounter.getCounter());
- }
- line.append(',');
- }
-
- while ((!line.isEmpty()) && (line.getLast().equals(",")))
- {
- line.removeLast();
- }
-
- if (line.isEmpty())
- {
- result = "";
- }
- else
- {
- result = line.toString();
- }
-
- //
- return result;
- }
-
- /**
- * Gets the now time marks.
- *
- * @return the now time marks
- */
- public StringList getNowTimeMarks()
- {
- StringList result;
-
- result = new StringList();
-
- LocalDate now = LocalDate.now();
- String year = TimeMark.yearOf(now).toString();
- String yearMonth = TimeMark.yearMonthOf(now).toString();
- String yearWeek = TimeMark.yearWeekOf(now).toString();
- String date = TimeMark.dayOf(now).toString();
-
- result.add(year);
- result.add(yearMonth);
- result.add(yearWeek);
- result.add(date);
-
- //
- return result;
- }
-
- /**
- * Gets the prefixes.
- *
- * @return the prefixes
- */
- public StringList getPrefixes()
- {
- StringList result;
-
- StringSet paths = new StringSet();
- for (PathCounter counter : this.values())
- {
- paths.put(counter.getPath());
- }
-
- result = new StringList(paths).sort();
-
- //
- return result;
- }
-
- /**
- * Gets the weeks values line.
- *
- * @param prefix
- * the prefix
- * @param year
- * the year
- * @return the weeks values line
- */
- public String getWeeksValuesLine(final String prefix, final String year)
- {
- String result;
-
- StringList line = new StringList();
-
- int weekCount = StatoolInfosUtils.getWeekCountOfYear(Integer.valueOf(year));
-
- for (int week = 1; week <= weekCount; week++)
- {
- String timeMark = String.format("%s-W%02d", year, week);
- PathCounter weekCounter = get(prefix, timeMark);
- if (weekCounter != null)
- {
- line.append(weekCounter.getCounter());
- }
- line.append(',');
- }
-
- while ((!line.isEmpty()) && (line.getLast().equals(",")))
- {
- line.removeLast();
- }
-
- if (line.isEmpty())
- {
- result = "";
- }
- else
- {
- result = line.toString();
- }
- //
- return result;
- }
-
- /**
- * Gets the years.
- *
- * @return the years
- */
- public StringList getYears()
- {
- StringList result;
-
- StringSet years = new StringSet();
- for (PathCounter counter : this.values())
- {
- TimeMark timemark = new TimeMark(counter.getTimeMark());
-
- Integer year = timemark.getYear();
- if (year != null)
- {
- years.put(year);
- }
- }
-
- result = new StringList(years);
-
- //
- return result;
- }
-
- /**
- * Inc.
- *
- * @param value
- * the value
- * @param path
- * the path
- * @param timeMark
- * the time mark
- */
- public void inc(final long value, final String path, final String timeMark)
- {
- PathCounter counter = get(path, timeMark);
- if (counter == null)
- {
- counter = new PathCounter(path, timeMark);
- put(counter);
- }
-
- counter.inc(value);
- }
-
- /**
- * Inc.
- *
- * @param value
- * the value
- * @param path
- * the path
- * @param timeMarks
- * the time marks
- */
- public void inc(final long value, final String path, final String... timeMarks)
- {
- for (String timeMark : timeMarks)
- {
- inc(value, path, timeMark);
- }
- }
-
- /**
- * Put.
- *
- * @param path
- * the path
- * @param timeMark
- * the time mark
- */
- public void inc(final String path, final String timeMark)
- {
- PathCounter counter = get(path, timeMark);
- if (counter == null)
- {
- counter = new PathCounter(path, timeMark);
- put(counter);
- }
-
- counter.inc();
- }
-
- /**
- * Inc.
- *
- * @param path
- * the path
- * @param timeMarks
- * the time marks
- */
- public void inc(final String path, final String... timeMarks)
- {
- for (String timeMark : timeMarks)
- {
- inc(path, timeMark);
- }
- }
-
- /**
- * Put.
- *
- * @param counter
- * the counter
- */
- public void put(final PathCounter counter)
- {
- if (counter != null)
- {
- put(computeKey(counter.getPath(), counter.getTimeMark()), counter);
- }
- }
-
- /**
- * Rename path.
- *
- * @param oldPath
- * the old path
- * @param newPath
- * the new path
- * @return the long
- */
- public long renamePath(final String oldPath, final String newPath)
- {
- long result;
-
- result = 0;
- for (String key : new StringList(this.keySet()))
- {
- if (key.startsWith(oldPath))
- {
- result += 1;
-
- PathCounter counter = get(key);
- counter.setPath(counter.getPath().replace(oldPath, newPath));
- remove(key);
- put(counter);
- System.out.println("Renamed " + key + " to " + counter.getPath());
- }
- }
-
- //
- return result;
- }
-
- /**
- * Search by date.
- *
- * @param date
- * the date
- * @return the path counters
- */
- public PathCounters searchByDate(final LocalDate date)
- {
- PathCounters result;
-
- result = new PathCounters();
-
- if (date != null)
- {
- String day = date.toString();
- String week = YearWeek.from(date).toString();
- String month = YearMonth.from(date).toString();
-
- for (PathCounter counter : this.values())
- {
- TimeMark mark = new TimeMark(counter.getTimeMark());
-
- if (mark.isDate() && (counter.getTimeMark().equals(day)))
- {
- result.put(counter);
- }
- else if (mark.isYearWeek() && (counter.getTimeMark().equals(week)))
- {
- result.put(counter);
- }
- else if (mark.isYearMonth() && (counter.getTimeMark().equals(month)))
- {
- result.put(counter);
- }
- }
- }
-
- //
- return result;
- }
-
- public PathCounters searchByPeriod(final LocalDate startDate, final LocalDate endDate)
- {
- PathCounters result;
-
- result = new PathCounters();
-
- if ((startDate != null) && (endDate != null))
- {
- if (startDate.isAfter(endDate))
- {
- result = searchByPeriod(endDate, startDate);
- }
- else
- {
- StringSet days = new StringSet();
- StringSet weeks = new StringSet();
- StringSet months = new StringSet();
- for (LocalDate current = startDate; !current.isAfter(endDate); current = current.plusDays(1))
- {
- days.add(current.toString());
- weeks.add(YearWeek.from(current).toString());
- months.add(YearMonth.from(current).toString());
- }
-
- for (PathCounter counter : this.values())
- {
- TimeMark mark = new TimeMark(counter.getTimeMark());
-
- if (mark.isDate() && (days.contains(counter.getTimeMark())))
- {
- result.put(counter);
- }
- else if (mark.isYearWeek() && (weeks.contains(counter.getTimeMark())))
- {
- result.put(counter);
- }
- else if (mark.isYearMonth() && (months.contains(counter.getTimeMark())))
- {
- result.put(counter);
- }
- }
- }
- }
-
- //
- return result;
- }
-
- /**
- * Sets the.
- *
- * @param value
- * the value
- * @param path
- * the path
- */
- public void set(final long value, final String path)
- {
- set(value, path, getNowTimeMarks());
- }
-
- /**
- * Sets the.
- *
- * @param value
- * the value
- * @param path
- * the path
- * @param timeMarks
- * the time marks
- */
- public void set(final long value, final String path, final String... timeMarks)
- {
- for (String timeMark : timeMarks)
- {
- set(value, path, timeMark);
- }
- }
-
- /**
- * Sets the.
- *
- * @param value
- * the value
- * @param path
- * the path
- * @param timeMark
- * the time mark
- */
- public void set(final long value, final String path, final String timeMark)
- {
- PathCounter counter = get(path, timeMark);
- if (counter == null)
- {
- counter = new PathCounter(path, timeMark);
- put(counter);
- }
-
- counter.setCounter(value);
- }
-
- /**
- * Sets the.
- *
- * @param value
- * the value
- * @param path
- * the path
- * @param timeMarks
- * the time marks
- */
- public void set(final long value, final String path, final StringList timeMarks)
- {
- for (String timeMark : timeMarks)
- {
- set(value, path, timeMark);
- }
- }
-}
diff --git a/src/fr/devinsy/statoolinfos/metrics/Prober.java b/src/fr/devinsy/statoolinfos/metrics/Prober.java
deleted file mode 100644
index 9c0fd27..0000000
--- a/src/fr/devinsy/statoolinfos/metrics/Prober.java
+++ /dev/null
@@ -1,714 +0,0 @@
-/*
- * Copyright (C) 2020-2024 Christian Pierre MOMON
- *
- * This file is part of StatoolInfos, simple service statistics tool.
- *
- * StatoolInfos is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * StatoolInfos is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with StatoolInfos. If not, see .
- */
-package fr.devinsy.statoolinfos.metrics;
-
-import java.io.File;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.io.UnsupportedEncodingException;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-import java.time.LocalDate;
-import java.time.LocalDateTime;
-import java.time.format.DateTimeFormatter;
-import java.util.Locale;
-import java.util.regex.Pattern;
-
-import org.apache.commons.lang3.StringUtils;
-import org.apache.commons.lang3.math.NumberUtils;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import fr.devinsy.statoolinfos.core.Configuration;
-import fr.devinsy.statoolinfos.core.DatabaseConfig;
-import fr.devinsy.statoolinfos.core.Factory;
-import fr.devinsy.statoolinfos.core.StatoolInfosException;
-import fr.devinsy.statoolinfos.core.StatoolInfosUtils;
-import fr.devinsy.statoolinfos.metrics.etherpad.EtherpadProber;
-import fr.devinsy.statoolinfos.metrics.gitea.GiteaProber;
-import fr.devinsy.statoolinfos.metrics.gsl.GSLProber;
-import fr.devinsy.statoolinfos.metrics.httpaccess.HttpAccessLogAnalyzer;
-import fr.devinsy.statoolinfos.metrics.httpaccess.HttpAccessLogs;
-import fr.devinsy.statoolinfos.metrics.httperrorlog.HttpErrorLogAnalyzer;
-import fr.devinsy.statoolinfos.metrics.httperrorlog.HttpErrorLogs;
-import fr.devinsy.statoolinfos.metrics.libreqr.LibreQRProber;
-import fr.devinsy.statoolinfos.metrics.minetest.MinetestProber;
-import fr.devinsy.statoolinfos.metrics.mumble.MumbleProber;
-import fr.devinsy.statoolinfos.metrics.privatebin.PrivatebinProber;
-import fr.devinsy.statoolinfos.properties.PathProperties;
-import fr.devinsy.statoolinfos.properties.PathProperty;
-import fr.devinsy.statoolinfos.properties.PathPropertyUtils;
-import fr.devinsy.statoolinfos.util.BuildInformation;
-import fr.devinsy.statoolinfos.util.FilesUtils;
-import fr.devinsy.strings.StringList;
-import fr.devinsy.strings.StringsUtils;
-
-/**
- * The Class Prober.
- */
-public class Prober
-{
- private static Logger logger = LoggerFactory.getLogger(Prober.class);
-
- public static final Pattern YEAR_PATTERN = Pattern.compile("^\\d{4}$");
-
- /**
- * Instantiates a new prober.
- */
- private Prober()
- {
- }
-
- /**
- * Extract year.
- *
- * @param line
- * the line
- * @return the string
- */
- private static boolean isYear(final String value)
- {
- boolean result;
-
- result = YEAR_PATTERN.matcher(value).matches();
-
- //
- return result;
- }
-
- /**
- * Probe.
- *
- * @param configuration
- * the configuration
- * @param dayCountFilter
- * the day count filter
- * @throws IOException
- * Signals that an I/O exception has occurred.
- * @throws StatoolInfosException
- * the statool infos exception
- */
- public static void probe(final Configuration configuration, final int dayCountFilter) throws IOException, StatoolInfosException
- {
- StringList types = configuration.getProbeTypes();
-
- System.out.println("Targets=" + types.toStringWithBrackets());
-
- if (!types.isEmpty())
- {
- PathCounters counters = new PathCounters();
- for (String type : types)
- {
- try
- {
- Method method = Prober.class.getMethod("probe" + type, Configuration.class);
- PathCounters subCounters = (PathCounters) method.invoke(null, configuration);
- counters.putAll(subCounters);
- }
- catch (NoSuchMethodException | SecurityException | IllegalAccessException | IllegalArgumentException | InvocationTargetException exception)
- {
- logger.error("Prober not found: [{}]", type);
- }
- }
-
- // Filter.
- logger.info("== Filtering with {}", dayCountFilter);
- if (dayCountFilter >= 0)
- {
- counters = counters.searchByPeriod(LocalDate.now().minusDays(dayCountFilter), LocalDate.now());
- }
-
- //
- File target = configuration.getProbeTarget();
- logger.info("target=[{}]", target);
-
- if (target == null)
- {
- throw new IllegalArgumentException("Undefined target.");
- }
- else
- {
- if (target.exists())
- {
- // Load.
- logger.info("== Reading previous target file.");
- PathCounters previousCounters = readMetrics(target);
- logger.info("previous size={}", previousCounters.size());
-
- // Temporary fixed 2022-02.
- previousCounters.renamePath("metrics.service.files", "metrics.service.datafiles");
- previousCounters.renamePath("metrics.barcodes.count", "metrics.barcodes.created");
-
- // Merge.
- logger.info("== Merging");
- for (PathCounter counter : counters.values())
- {
- PathCounter previousCounter = previousCounters.get(counter.getPath(), counter.getTimeMark());
- if (previousCounter == null)
- {
- previousCounters.put(counter);
- }
- else
- {
- previousCounter.setCounter(counter.getCounter());
- }
- }
-
- //
- counters = previousCounters;
-
- //
- logger.info("== Backing previous target file.");
- target.renameTo(new File(target.getParentFile(), target.getName() + ".bak"));
- }
-
- writeMetrics(target, counters);
- }
-
- //
- logger.info("== Writing.");
- logger.info("size={}", counters.size());
- }
-
- }
-
- /**
- * Stat.
- *
- * @param configurationFile
- * the configuration file
- * @throws IOException
- * @throws StatoolInfosException
- */
- public static void probe(final File configurationFile, final int dayCountFilter) throws StatoolInfosException, IOException
- {
- logger.info("Probe {}", configurationFile.getAbsolutePath());
-
- Configuration configuration = Factory.loadConfiguration(configurationFile);
-
- probe(configuration, dayCountFilter);
- }
-
- /**
- * Probe etherpad.
- *
- * @param configuration
- * the configuration
- * @return the path counters
- * @throws IOException
- * Signals that an I/O exception has occurred.
- * @throws StatoolInfosException
- * the statool infos exception
- */
- public static PathCounters probeEtherpad(final Configuration configuration) throws IOException, StatoolInfosException
- {
- PathCounters result;
-
- logger.info("== Probing Etherpad.");
- String logs = configuration.get("conf.probe.etherpad.logs");
- DatabaseConfig database = configuration.getDatabaseConfig("conf.probe.etherpad");
- logger.info("logs=[{}]", logs);
- logger.info("database={}", database.toString());
-
- String httpLogs = configuration.getProbeHttpAccessLogSource();
- String httpAccessLogPattern = configuration.getProbeHttpAccessLogPattern();
- String httpAccessLogDateTimePattern = configuration.getProbeHttpAccessLogDateTimePattern();
- String httpAccessPathFilter = configuration.getProbeHttpAccessLogPathFilter();
- logger.info("httpLogs=[{}]", httpLogs);
- logger.info("httpAccessPattern=[{}]", httpAccessLogPattern);
- logger.info("httpAccessDateTimePattern=[{}]", httpAccessLogDateTimePattern);
- logger.info("httpAccessPathFilter=[{}]", httpAccessPathFilter);
- HttpAccessLogs httpAccessLogs = new HttpAccessLogs(FilesUtils.searchByWildcard(httpLogs), httpAccessLogPattern, httpAccessLogDateTimePattern, httpAccessPathFilter);
-
- result = EtherpadProber.probe(httpAccessLogs, FilesUtils.searchByWildcard(logs), database);
-
- //
- return result;
- }
-
- /**
- * Probe framadate.
- *
- * @param configuration
- * the configuration
- * @return the path counters
- * @throws IOException
- * Signals that an I/O exception has occurred.
- * @throws StatoolInfosException
- * the statool infos exception
- */
- public static PathCounters probeFramadate(final Configuration configuration) throws IOException, StatoolInfosException
- {
- PathCounters result;
-
- logger.info("== Probing Framadate.");
- String source = configuration.getProbeHttpAccessLogSource();
- logger.info("source=[{}]", source);
-
- // TODO
- // PathCounters datafilesPath =
- // HttpErrorLogAnalyzer.probe(source);
- // counters.putAll(data);
-
- result = new PathCounters();
-
- //
- return result;
- }
-
- /**
- * Probe gitea.
- *
- * @param configuration
- * the configuration
- * @return the path counters
- * @throws IOException
- * Signals that an I/O exception has occurred.
- * @throws StatoolInfosException
- * the statool infos exception
- */
- public static PathCounters probeGitea(final Configuration configuration) throws IOException, StatoolInfosException
- {
- PathCounters result;
-
- logger.info("== Probing Gitea.");
- File dataDirectory = configuration.getAsFile("conf.probe.gitea.data");
- String apiURL = configuration.get("conf.probe.gitea.api.url");
- String apiToken = configuration.get("conf.probe.gitea.api.token");
- DatabaseConfig database = configuration.getDatabaseConfig("conf.probe.gitea");
- logger.info("dataPath=[{}]", dataDirectory);
- logger.info("apiURL=[{}]", apiURL);
- logger.info("apiToken=[{}]", apiToken == null ? "null" : "************************");
- logger.info("database={}", database.toString());
-
- String httpLogs = configuration.getProbeHttpAccessLogSource();
- String httpAccessLogPattern = configuration.getProbeHttpAccessLogPattern();
- String httpAccessLogDateTimePattern = configuration.getProbeHttpAccessLogDateTimePattern();
- String httpAccessLogPathFilter = configuration.getProbeHttpAccessLogPathFilter();
- logger.info("httpLogs=[{}]", httpLogs);
- logger.info("httpAccessPattern=[{}]", httpAccessLogPattern);
- logger.info("httpAccessDateTimePattern=[{}]", httpAccessLogDateTimePattern);
- logger.info("httpAccessPath=[{}]", httpAccessLogPathFilter);
- HttpAccessLogs httpAccessLogs = new HttpAccessLogs(FilesUtils.searchByWildcard(httpLogs), httpAccessLogPattern, httpAccessLogDateTimePattern, httpAccessLogPathFilter);
-
- result = GiteaProber.probe(httpAccessLogs, apiURL, apiToken, dataDirectory, database);
-
- //
- return result;
- }
-
- /**
- * Probe GSL.
- *
- * @param configuration
- * the configuration
- * @return the path counters
- * @throws IOException
- * Signals that an I/O exception has occurred.
- * @throws StatoolInfosException
- * the statool infos exception
- */
- public static PathCounters probeGSL(final Configuration configuration) throws IOException, StatoolInfosException
- {
- PathCounters result;
-
- logger.info("== Probing GSL.");
-
- File statsFile = configuration.getAsFile("conf.probe.gsl.stats");
- logger.info("statsfile=[{}]", statsFile);
-
- result = GSLProber.probe(statsFile);
-
- //
- return result;
- }
-
- /**
- * Probe htt access log.
- *
- * @param configuration
- * the configuration
- * @return the path counters
- * @throws IOException
- * Signals that an I/O exception has occurred.
- * @throws StatoolInfosException
- * the statool infos exception
- */
- public static PathCounters probeHttpAccessLog(final Configuration configuration) throws IOException, StatoolInfosException
- {
- PathCounters result;
-
- logger.info("== Probing HttpAccessLog.");
- String source = configuration.getProbeHttpAccessLogSource();
- String pattern = configuration.getProbeHttpAccessLogPattern();
- String dateTimePattern = configuration.getProbeHttpAccessLogDateTimePattern();
- String pathFilter = configuration.getProbeHttpAccessLogPathFilter();
- logger.info("source=[{}]", source);
- logger.info("pattern=[{}]", pattern);
- logger.info("dateTimePattern=[{}]", dateTimePattern);
- logger.info("path=[{}]", pathFilter);
-
- HttpAccessLogs httpAccessLogs = new HttpAccessLogs(FilesUtils.searchByWildcard(source), pattern, dateTimePattern, pathFilter);
-
- result = HttpAccessLogAnalyzer.probe(httpAccessLogs);
-
- //
- return result;
- }
-
- /**
- * Probe http error log.
- *
- * @param configuration
- * the configuration
- * @return the path counters
- * @throws IOException
- * Signals that an I/O exception has occurred.
- * @throws StatoolInfosException
- * the statool infos exception
- */
- public static PathCounters probeHttpErrorLog(final Configuration configuration) throws IOException, StatoolInfosException
- {
- PathCounters result;
-
- logger.info("== Probing HttpErrorLog.");
- String source = configuration.getProbeHttpErrorLogSource();
- String pattern = configuration.getProbeHttpErrorLogPattern();
- String dateTimePattern = configuration.getProbeHttpErrorLogDateTimePattern();
- logger.info("source=[{}]", source);
- logger.info("pattern=[{}]", pattern);
- logger.info("dateTimePattern=[{}]", dateTimePattern);
-
- HttpErrorLogs httpErrorLogs = new HttpErrorLogs(FilesUtils.searchByWildcard(source), pattern, dateTimePattern);
-
- result = HttpErrorLogAnalyzer.probe(httpErrorLogs);
-
- //
- return result;
- }
-
- /**
- * Probe libre QR.
- *
- * @param configuration
- * the configuration
- * @return the path counters
- * @throws IOException
- * Signals that an I/O exception has occurred.
- * @throws StatoolInfosException
- * the statool infos exception
- */
- public static PathCounters probeLibreQR(final Configuration configuration) throws IOException, StatoolInfosException
- {
- PathCounters result;
-
- logger.info("== Probing LibreQR.");
-
- String httpAccessSource = configuration.getProbeHttpAccessLogSource();
- String httpAccessLogPattern = configuration.getProbeHttpAccessLogPattern();
- String httpAccessLogDateTimePattern = configuration.getProbeHttpAccessLogDateTimePattern();
- String httpAccessLogPathFilter = configuration.getProbeHttpAccessLogPathFilter();
- logger.info("httpAccessSource=[{}]", httpAccessSource);
- logger.info("httpAccessPattern=[{}]", httpAccessLogPattern);
- logger.info("httpAccessDateTimePattern=[{}]", httpAccessLogDateTimePattern);
- logger.info("httpAccessPath=[{}]", httpAccessLogPathFilter);
- HttpAccessLogs httpAccessLogs = new HttpAccessLogs(FilesUtils.searchByWildcard(httpAccessSource), httpAccessLogPattern, httpAccessLogDateTimePattern, httpAccessLogPathFilter);
-
- File dataDirectory = configuration.getAsFile("conf.probe.libreqr.datafiles");
- logger.info("dataDirectory=[{}]", dataDirectory);
-
- result = LibreQRProber.probe(httpAccessLogs, dataDirectory);
-
- //
- return result;
- }
-
- /**
- * Probe minetest.
- *
- * @param configuration
- * the configuration
- * @return the path counters
- * @throws IOException
- * Signals that an I/O exception has occurred.
- * @throws StatoolInfosException
- * the statool infos exception
- */
- public static PathCounters probeMinetest(final Configuration configuration) throws IOException, StatoolInfosException
- {
- PathCounters result;
-
- logger.info("== Probing Minetest.");
- String source = configuration.get("conf.probe.minetest.logs");
- DatabaseConfig playerDatabase = configuration.getDatabaseConfig("conf.probe.minetest.players");
- DatabaseConfig worldDatabase = configuration.getDatabaseConfig("conf.probe.minetest.worlds");
- logger.info("source=[{}]", source);
- logger.info("players database={}", playerDatabase.toString());
- logger.info("wordls database={}", worldDatabase.toString());
-
- result = MinetestProber.probe(source, playerDatabase, worldDatabase);
-
- //
- return result;
- }
-
- /**
- * Probe mumble.
- *
- * @param configuration
- * the configuration
- * @return the path counters
- * @throws IOException
- * Signals that an I/O exception has occurred.
- * @throws StatoolInfosException
- * the statool infos exception
- */
- public static PathCounters probeMumble(final Configuration configuration) throws IOException, StatoolInfosException
- {
- PathCounters result;
-
- logger.info("== Probing Mumble.");
- String source = configuration.get("conf.probe.mumble.logs");
- logger.info("source=[{}]", source);
-
- result = MumbleProber.probe(source);
-
- //
- return result;
- }
-
- /**
- * Probe private bin.
- *
- * @param configuration
- * the configuration
- * @return the path counters
- * @throws IOException
- * Signals that an I/O exception has occurred.
- * @throws StatoolInfosException
- * the statool infos exception
- */
- public static PathCounters probePrivateBin(final Configuration configuration) throws IOException, StatoolInfosException
- {
- PathCounters result;
-
- logger.info("== Probing Privatebin.");
- String httpAccessLogSource = configuration.getProbeHttpAccessLogSource();
- String httpAccessLogPattern = configuration.getProbeHttpAccessLogPattern();
- String httpAccessLogDateTimePattern = configuration.getProbeHttpAccessLogDateTimePattern();
- String httpAccessLogPathFilter = configuration.getProbeHttpAccessLogPathFilter();
- logger.info("source=[{}]", httpAccessLogSource);
- logger.info("pattern=[{}]", httpAccessLogPattern);
- logger.info("httpAccessDateTimePattern=[{}]", httpAccessLogDateTimePattern);
- logger.info("httpAccessPath=[{}]", httpAccessLogPathFilter);
- HttpAccessLogs httpAccessLogs = new HttpAccessLogs(FilesUtils.searchByWildcard(httpAccessLogSource), httpAccessLogPattern, httpAccessLogDateTimePattern, httpAccessLogPathFilter);
-
- File dataDirectory = configuration.getAsFile("conf.probe.privatebin.data");
- logger.info("dataDirectory=[{}]", dataDirectory);
-
- result = PrivatebinProber.probe(httpAccessLogs, dataDirectory);
-
- //
- return result;
- }
-
- /**
- * Read metrics.
- *
- * @param inputFile
- * the input file
- * @return the path counters
- * @throws IOException
- * Signals that an I/O exception has occurred.
- */
- public static PathCounters readMetrics(final File inputFile) throws IOException
- {
- PathCounters result;
-
- result = new PathCounters();
-
- PathProperties lines = PathPropertyUtils.load(inputFile);
-
- for (PathProperty property : lines)
- {
- String metricName = property.getMetricName();
- if (metricName != null)
- {
- String leaf = property.getLeaf();
- if (isYear(leaf))
- {
- PathCounter counter = new PathCounter(metricName, leaf);
- counter.setCounter(NumberUtils.createLong(property.getValue()));
- result.put(counter);
- }
- else if (StringUtils.equals(leaf, "months"))
- {
- String year = property.getMetricYear();
-
- StringList values = StatoolInfosUtils.splitMonthValues(property.getValue());
- int monthIndex = 1;
- for (String value : values)
- {
- if (!StringUtils.isBlank(value))
- {
- PathCounter counter = new PathCounter(metricName, String.format("%s-%02d", year, monthIndex));
- counter.setCounter(NumberUtils.createLong(value));
- result.put(counter);
- }
-
- monthIndex += 1;
- }
- }
- else if (StringUtils.equals(leaf, "weeks"))
- {
- String year = property.getMetricYear();
-
- StringList values = StatoolInfosUtils.splitWeekValues(property.getValue());
- int weekIndex = 1;
- for (String value : values)
- {
- if (!StringUtils.isBlank(value))
- {
- PathCounter counter = new PathCounter(metricName, String.format("%s-W%02d", year, weekIndex));
- counter.setCounter(NumberUtils.createLong(value));
- result.put(counter);
- }
-
- weekIndex += 1;
- }
- }
- else if (StringUtils.equals(leaf, "days"))
- {
- String year = property.getMetricYear();
-
- StringList values = StatoolInfosUtils.splitDayValues(property.getValue());
- LocalDate day = LocalDate.of(Integer.parseInt(year), 1, 1);
- for (String value : values)
- {
- if (!StringUtils.isBlank(value))
- {
- String date = day.format(DateTimeFormatter.ofPattern("yyyy-MM-dd", Locale.FRANCE));
- PathCounter counter = new PathCounter(metricName, date);
- counter.setCounter(NumberUtils.createLong(value));
- result.put(counter);
- }
-
- day = day.plusDays(1);
- }
- }
- }
- }
-
- //
- return result;
- }
-
- /**
- * Write metrics.
- *
- * @param target
- * the target
- * @param counters
- * the counters
- * @throws UnsupportedEncodingException
- * the unsupported encoding exception
- * @throws FileNotFoundException
- * the file not found exception
- */
- public static void writeMetrics(final File target, final PathCounters counters) throws UnsupportedEncodingException, FileNotFoundException
- {
- StringList prefixes = counters.getPrefixes();
-
- StringList metrics = new StringList();
-
- //
- metrics.appendln("# [File]");
- metrics.appendln("file.class=metrics");
- metrics.appendln("file.generator=StatoolInfos");
- metrics.appendln("file.datetime=" + LocalDateTime.now().toString());
- metrics.appendln("file.protocol=" + BuildInformation.instance().protocol());
-
- metrics.appendln();
- metrics.appendln("# [Metrics]");
-
- //
- for (String prefix : prefixes)
- {
- logger.info("====== {}", prefix);
-
- PathCounters prefixCounters = counters.getByPrefix(prefix);
-
- StringList years = prefixCounters.getYears().sort();
-
- for (String year : years)
- {
- // Year stat is complicated to build because needs all the
- // log of one year.
- // {
- // // Year.
- // PathCounter yearCounter = prefixCounters.get(prefix, year);
- // if (yearCounter != null)
- // {
- // String line = String.format("%s.%s=%s",
- // yearCounter.getPath(), yearCounter.getTimeMark(),
- // yearCounter.getCounter());
- // metrics.appendln(line);
- // }
- // }
-
- {
- // Months.
- StringList line = new StringList();
- String values = prefixCounters.getMonthsValuesLine(prefix, year);
- if (!StringUtils.isBlank(values))
- {
- line.append(prefix).append('.').append(year).append(".months=").append(values);
- metrics.appendln(line);
- }
- }
-
- {
- // Weeks.
- StringList line = new StringList();
- String values = prefixCounters.getWeeksValuesLine(prefix, year);
- if (!StringUtils.isBlank(values))
- {
- line.append(prefix).append('.').append(year).append(".weeks=").append(values);
- metrics.appendln(line);
- }
- }
-
- {
- // Days.
- StringList line = new StringList();
- String values = prefixCounters.getDaysValuesLine(prefix, year);
- if (!StringUtils.isBlank(values))
- {
- line.append(prefix).append('.').append(year).append(".days=").append(values);
- metrics.appendln(line);
- }
- }
- }
-
- metrics.appendln();
- }
-
- StringsUtils.writeToFile(target, metrics);
- }
-}
diff --git a/src/fr/devinsy/statoolinfos/metrics/StringCounter.java b/src/fr/devinsy/statoolinfos/metrics/StringCounter.java
deleted file mode 100644
index 5b20caa..0000000
--- a/src/fr/devinsy/statoolinfos/metrics/StringCounter.java
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * Copyright (C) 2021 Christian Pierre MOMON
- *
- * This file is part of StatoolInfos, simple service statistics tool.
- *
- * StatoolInfos is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * StatoolInfos is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with StatoolInfos. If not, see .
- */
-package fr.devinsy.statoolinfos.metrics;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * The Class StringCounter.
- */
-public class StringCounter
-{
- private static Logger logger = LoggerFactory.getLogger(StringCounter.class);
-
- private String string;
- private long counter;
-
- /**
- * Instantiates a new string counter.
- *
- * @param string
- * the value
- */
- public StringCounter(final String string)
- {
- this.string = string;
- this.counter = 0;
- }
-
- public long getCounter()
- {
- return this.counter;
- }
-
- public String getString()
- {
- return this.string;
- }
-
- /**
- * Inc.
- */
- public void inc()
- {
- this.counter += 1;
- }
-
- public void setCounter(final long counter)
- {
- this.counter = counter;
- }
-
- public void setString(final String string)
- {
- this.string = string;
- }
-}
diff --git a/src/fr/devinsy/statoolinfos/metrics/StringCounterComparator.java b/src/fr/devinsy/statoolinfos/metrics/StringCounterComparator.java
deleted file mode 100644
index f36081d..0000000
--- a/src/fr/devinsy/statoolinfos/metrics/StringCounterComparator.java
+++ /dev/null
@@ -1,158 +0,0 @@
-/*
- * Copyright (C) 2021 Christian Pierre MOMON
- *
- * This file is part of StatoolInfos, simple service statistics tool.
- *
- * StatoolInfos is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * StatoolInfos is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with StatoolInfos. If not, see .
- */
-package fr.devinsy.statoolinfos.metrics;
-
-import java.util.Comparator;
-
-import fr.devinsy.statoolinfos.util.CompareUtils;
-
-/**
- * The Class StringCounterComparator.
- */
-public class StringCounterComparator implements Comparator
-{
- public enum Sorting
- {
- STRING,
- COUNTER
- }
-
- private Sorting sorting;
-
- /**
- * Instantiates a new string counter comparator.
- *
- * @param sorting
- * the sorting
- */
- public StringCounterComparator(final Sorting sorting)
- {
- this.sorting = sorting;
- }
-
- /**
- * Compare.
- *
- * @param alpha
- * the alpha
- * @param bravo
- * the bravo
- * @return the int
- */
- @Override
- public int compare(final StringCounter alpha, final StringCounter bravo)
- {
- int result;
-
- result = compare(alpha, bravo, this.sorting);
-
- //
- return result;
- }
-
- /**
- * Compare.
- *
- * @param alpha
- * the alpha
- * @param bravo
- * the bravo
- * @param sorting
- * the sorting
- * @return the int
- */
- public static int compare(final StringCounter alpha, final StringCounter bravo, final Sorting sorting)
- {
- int result;
-
- if (sorting == null)
- {
- result = 0;
- }
- else
- {
- switch (sorting)
- {
- default:
- case STRING:
- result = CompareUtils.compareIgnoreCase(getString(alpha), getString(bravo));
- break;
-
- case COUNTER:
- result = CompareUtils.compare(getCounter(alpha), getCounter(bravo));
- if (result == 0)
- {
- result = CompareUtils.compareIgnoreCase(getString(alpha), getString(bravo));
- }
- break;
- }
- }
-
- //
- return result;
- }
-
- /**
- * Gets the counter.
- *
- * @param source
- * the source
- * @return the counter
- */
- public static Long getCounter(final StringCounter source)
- {
- Long result;
-
- if (source == null)
- {
- result = null;
- }
- else
- {
- result = (long) source.getCounter();
- }
-
- //
- return result;
- }
-
- /**
- * Gets the string.
- *
- * @param source
- * the source
- * @return the string
- */
- public static String getString(final StringCounter source)
- {
- String result;
-
- if (source == null)
- {
- result = null;
- }
- else
- {
- result = source.getString();
- }
-
- //
- return result;
- }
-}
diff --git a/src/fr/devinsy/statoolinfos/metrics/StringCounterList.java b/src/fr/devinsy/statoolinfos/metrics/StringCounterList.java
deleted file mode 100644
index be0faf0..0000000
--- a/src/fr/devinsy/statoolinfos/metrics/StringCounterList.java
+++ /dev/null
@@ -1,104 +0,0 @@
-/*
- * Copyright (C) 2021 Christian Pierre MOMON
- *
- * This file is part of StatoolInfos, simple service statistics tool.
- *
- * StatoolInfos is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * StatoolInfos is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with StatoolInfos. If not, see .
- */
-package fr.devinsy.statoolinfos.metrics;
-
-import java.util.ArrayList;
-import java.util.Collections;
-
-/**
- * The Class StringCounterList.
- */
-public class StringCounterList extends ArrayList
-{
- private static final long serialVersionUID = 6392647621400816570L;
-
- /**
- * Instantiates a new string counter list.
- */
- public StringCounterList()
- {
- super();
- }
-
- /**
- * Reverse.
- *
- * @return the categories
- */
- public StringCounterList reverse()
- {
- StringCounterList result;
-
- Collections.reverse(this);
-
- result = this;
-
- //
- return result;
- }
-
- /**
- * Sort.
- *
- * @param sorting
- * the sorting
- * @return the string counter list
- */
- public StringCounterList sort(final StringCounterComparator.Sorting sorting)
- {
- StringCounterList result;
-
- sort(new StringCounterComparator(sorting));
-
- result = this;
-
- //
- return result;
- }
-
- /**
- * Sort by counter.
- *
- * @return the string counter list
- */
- public StringCounterList sortByCounter()
- {
- StringCounterList result;
-
- result = sort(StringCounterComparator.Sorting.COUNTER);
-
- //
- return result;
- }
-
- /**
- * Sort by name.
- *
- * @return the services
- */
- public StringCounterList sortByString()
- {
- StringCounterList result;
-
- result = sort(StringCounterComparator.Sorting.STRING);
-
- //
- return result;
- }
-}
diff --git a/src/fr/devinsy/statoolinfos/metrics/StringCounters.java b/src/fr/devinsy/statoolinfos/metrics/StringCounters.java
deleted file mode 100644
index 511ddcb..0000000
--- a/src/fr/devinsy/statoolinfos/metrics/StringCounters.java
+++ /dev/null
@@ -1,122 +0,0 @@
-/*
- * Copyright (C) 2021 Christian Pierre MOMON
- *
- * This file is part of StatoolInfos, simple service statistics tool.
- *
- * StatoolInfos is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * StatoolInfos is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with StatoolInfos. If not, see .
- */
-package fr.devinsy.statoolinfos.metrics;
-
-import java.util.HashMap;
-
-import org.apache.commons.lang3.StringUtils;
-
-/**
- * The Class StringCounters.
- */
-public class StringCounters extends HashMap
-{
- private static final long serialVersionUID = -4771969211702752306L;
-
- /**
- * Instantiates a new string counters.
- */
- public StringCounters()
- {
- super();
- }
-
- /**
- * Compute key.
- *
- * @param string
- * the string
- * @return the string
- */
- public String computeKey(final String string)
- {
- String result;
-
- result = StringUtils.toRootLowerCase(string);
-
- //
- return result;
- }
-
- /**
- * Gets the.
- *
- * @param string
- * the string
- * @return the long
- */
- public long get(final String string)
- {
- long result;
-
- String key = computeKey(string);
-
- StringCounter counter = super.get(key);
-
- if (counter == null)
- {
- result = 0L;
- }
- else
- {
- result = counter.getCounter();
- }
-
- //
- return result;
- }
-
- /**
- * Inc.
- *
- * @param string
- * the key
- */
- public void inc(final String string)
- {
- String key = computeKey(string);
-
- StringCounter counter = super.get(key);
-
- if (counter == null)
- {
- counter = new StringCounter(string);
- put(key, counter);
- }
-
- counter.inc();
- }
-
- /**
- * To list.
- *
- * @return the string counter list
- */
- public StringCounterList toList()
- {
- StringCounterList result;
-
- result = new StringCounterList();
-
- result.addAll(values());
-
- //
- return result;
- }
-}
diff --git a/src/fr/devinsy/statoolinfos/metrics/TimeMark.java b/src/fr/devinsy/statoolinfos/metrics/TimeMark.java
deleted file mode 100644
index 54a100c..0000000
--- a/src/fr/devinsy/statoolinfos/metrics/TimeMark.java
+++ /dev/null
@@ -1,351 +0,0 @@
-/*
- * Copyright (C) 2021 Christian Pierre MOMON
- *
- * This file is part of StatoolInfos, simple service statistics tool.
- *
- * StatoolInfos is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * StatoolInfos is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with StatoolInfos. If not, see .
- */
-package fr.devinsy.statoolinfos.metrics;
-
-import java.time.LocalDate;
-import java.time.LocalDateTime;
-import java.time.YearMonth;
-import java.time.format.DateTimeFormatter;
-import java.util.Locale;
-import java.util.regex.Matcher;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * The Class TimeMark.
- */
-public class TimeMark
-{
- private static Logger logger = LoggerFactory.getLogger(TimeMark.class);
-
- private String value;
-
- /**
- * Instantiates a new time mark.
- *
- * @param value
- * the value
- */
- public TimeMark(final String value)
- {
- this.value = value;
- }
-
- /**
- * Gets the year.
- *
- * @return the year
- */
- public Integer getYear()
- {
- Integer result;
-
- if (isYearMark())
- {
- result = Integer.parseInt(this.value);
- }
- else if (isYearMonth())
- {
- Matcher matcher = TimeMarkUtils.YEAR_MONTH_PATTERN.matcher(this.value);
- if (matcher.find())
- {
- result = Integer.parseInt(matcher.group("year"));
- }
- else
- {
- result = null;
- }
- }
- else if (isYearWeek())
- {
- Matcher matcher = TimeMarkUtils.YEAR_WEEK_PATTERN.matcher(this.value);
- if (matcher.find())
- {
- result = Integer.parseInt(matcher.group("year"));
- }
- else
- {
- result = null;
- }
- }
- else if (isDate())
- {
- Matcher matcher = TimeMarkUtils.DATE_PATTERN.matcher(this.value);
- if (matcher.find())
- {
- result = Integer.parseInt(matcher.group("year"));
- }
- else
- {
- result = null;
- }
- }
- else
- {
- result = null;
- }
-
- //
- return result;
- }
-
- /**
- * Checks if is date.
- *
- * @return true, if is date
- */
- public boolean isDate()
- {
- boolean result;
-
- result = TimeMarkUtils.isDate(this.value);
-
- //
- return result;
- }
-
- /**
- * Checks if is year mark.
- *
- * @return true, if is year mark
- */
- public boolean isYearMark()
- {
- boolean result;
-
- result = TimeMarkUtils.isYear(this.value);
-
- //
- return result;
- }
-
- /**
- * Checks if is year month.
- *
- * @return true, if is year month
- */
- public boolean isYearMonth()
- {
- boolean result;
-
- result = TimeMarkUtils.isYearMonth(this.value);
-
- //
- return result;
- }
-
- /**
- * Checks if is year week.
- *
- * @return true, if is year week
- */
- public boolean isYearWeek()
- {
- boolean result;
-
- result = TimeMarkUtils.isYearWeek(this.value);
-
- //
- return result;
- }
-
- public void setValue(final String value)
- {
- this.value = value;
- }
-
- /**
- * To string.
- *
- * @return the string
- */
- @Override
- public String toString()
- {
- String result;
-
- result = this.value;
-
- //
- return result;
- }
-
- /**
- * Day of.
- *
- * @param date
- * the date
- * @return the time mark
- */
- public static TimeMark dayOf(final LocalDate date)
- {
- TimeMark result;
-
- String day = date.format(DateTimeFormatter.ofPattern("yyyy-MM-dd", Locale.FRANCE));
- result = new TimeMark(day);
-
- //
- return result;
- }
-
- /**
- * Day of.
- *
- * @param date
- * the date
- * @return the time mark
- */
- public static TimeMark dayOf(final LocalDateTime date)
- {
- TimeMark result;
-
- String day = date.format(DateTimeFormatter.ofPattern("yyyy-MM-dd", Locale.FRANCE));
- result = new TimeMark(day);
-
- //
- return result;
- }
-
- /**
- * Month of.
- *
- * @param date
- * the date
- * @return the time mark
- */
- public static TimeMark monthOf(final YearMonth date)
- {
- TimeMark result;
-
- String month = date.format(DateTimeFormatter.ofPattern("yyyy-MM", Locale.FRANCE));
- result = new TimeMark(month);
-
- //
- return result;
- }
-
- /**
- * Month of.
- *
- * @param date
- * the date
- * @return the time mark
- */
- public static TimeMark yearMonthOf(final LocalDate date)
- {
- TimeMark result;
-
- String month = date.format(DateTimeFormatter.ofPattern("yyyy-MM", Locale.FRANCE));
- result = new TimeMark(month);
-
- //
- return result;
- }
-
- /**
- * Month of.
- *
- * @param date
- * the date
- * @return the time mark
- */
- public static TimeMark yearMonthOf(final LocalDateTime date)
- {
- TimeMark result;
-
- String month = date.format(DateTimeFormatter.ofPattern("yyyy-MM", Locale.FRANCE));
- result = new TimeMark(month);
-
- //
- return result;
- }
-
- /**
- * Year of.
- *
- * @param date
- * the date
- * @return the time mark
- */
- public static TimeMark yearOf(final LocalDate date)
- {
- TimeMark result;
-
- String year = date.format(DateTimeFormatter.ofPattern("yyyy", Locale.FRANCE));
- result = new TimeMark(year);
-
- //
- return result;
- }
-
- /**
- * Year of.
- *
- * @param date
- * the date
- * @return the time mark
- */
- public static TimeMark yearOf(final LocalDateTime date)
- {
- TimeMark result;
-
- String year = date.format(DateTimeFormatter.ofPattern("yyyy", Locale.FRANCE));
- result = new TimeMark(year);
-
- //
- return result;
- }
-
- /**
- * Year week of.
- *
- * @param date
- * the date
- * @return the time mark
- */
- public static TimeMark yearWeekOf(final LocalDate date)
- {
- TimeMark result;
-
- String yearWeek = date.format(DateTimeFormatter.ofPattern("yyyy-'W'ww", Locale.FRANCE));
- result = new TimeMark(yearWeek);
-
- //
- return result;
- }
-
- /**
- * Year week of.
- *
- * @param date
- * the date
- * @return the time mark
- */
- public static TimeMark yearWeekOf(final LocalDateTime date)
- {
- TimeMark result;
-
- String yearWeek = date.format(DateTimeFormatter.ofPattern("yyyyww", Locale.FRANCE));
- result = new TimeMark(yearWeek);
-
- //
- return result;
- }
-}
diff --git a/src/fr/devinsy/statoolinfos/metrics/TimeMarkCounters.java b/src/fr/devinsy/statoolinfos/metrics/TimeMarkCounters.java
deleted file mode 100644
index c85c5cc..0000000
--- a/src/fr/devinsy/statoolinfos/metrics/TimeMarkCounters.java
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * Copyright (C) 2021 Christian Pierre MOMON
- *
- * This file is part of StatoolInfos, simple service statistics tool.
- *
- * StatoolInfos is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * StatoolInfos is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with StatoolInfos. If not, see .
- */
-package fr.devinsy.statoolinfos.metrics;
-
-import java.util.HashMap;
-
-/**
- * The Class TimeMarkCounters.
- */
-public class TimeMarkCounters extends HashMap
-{
- private static final long serialVersionUID = -3437543089769867597L;
-
- /**
- * Instantiates a new time mark counters.
- */
- public TimeMarkCounters()
- {
- super();
- }
-
- /**
- * Gets the.
- *
- * @param timeMark
- * the time mark
- * @return the long
- */
- public Long get(final String timeMark)
- {
- Long result;
-
- result = super.get(timeMark);
-
- //
- return result;
- }
-
- /**
- * Inc.
- *
- * @param timemark
- * the timemark
- */
- public void inc(final String timemark)
- {
- Long value = super.get(timemark);
- if (value == null)
- {
- value = 0L;
- }
-
- put(timemark, value + 1);
- }
-}
diff --git a/src/fr/devinsy/statoolinfos/metrics/TimeMarkUtils.java b/src/fr/devinsy/statoolinfos/metrics/TimeMarkUtils.java
deleted file mode 100644
index 298c6fa..0000000
--- a/src/fr/devinsy/statoolinfos/metrics/TimeMarkUtils.java
+++ /dev/null
@@ -1,306 +0,0 @@
-/*
- * Copyright (C) 2022 Christian Pierre MOMON
- *
- * This file is part of StatoolInfos, simple service statistics tool.
- *
- * StatoolInfos is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * StatoolInfos is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with StatoolInfos. If not, see .
- */
-package fr.devinsy.statoolinfos.metrics;
-
-import java.time.LocalDate;
-import java.time.LocalDateTime;
-import java.time.YearMonth;
-import java.time.ZonedDateTime;
-import java.time.format.DateTimeFormatter;
-import java.util.Locale;
-import java.util.regex.Pattern;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.threeten.extra.YearWeek;
-
-/**
- * The Class TimeMarkUtils.
- */
-public class TimeMarkUtils
-{
- private static Logger logger = LoggerFactory.getLogger(TimeMarkUtils.class);
-
- public static final Pattern YEAR_PATTERN = Pattern.compile("^(?\\d{4})$");
- public static final Pattern YEAR_MONTH_PATTERN = Pattern.compile("^(?\\d{4})-(?\\d{2})$");
- public static final Pattern YEAR_WEEK_PATTERN = Pattern.compile("^(?\\d{4})-W(?\\d{2})$");
- public static final Pattern DATE_PATTERN = Pattern.compile("^(?\\d{4})-(?\\d{2})-(?\\d{2})$");
-
- /**
- * Instantiates a new time mark utils.
- */
- private TimeMarkUtils()
- {
- }
-
- /**
- * Day of.
- *
- * @param date
- * the date
- * @return the string
- */
- public static String dateOf(final LocalDateTime date)
- {
- String result;
-
- result = date.format(DateTimeFormatter.ofPattern("yyyy-MM-dd", Locale.FRANCE));
-
- //
- return result;
- }
-
- /**
- * Checks if is date.
- *
- * @param value
- * the value
- * @return true, if is date
- */
- public static boolean isDate(final String value)
- {
- boolean result;
-
- result = (DATE_PATTERN.matcher(value).matches());
-
- //
- return result;
- }
-
- /**
- * Checks if is year mark.
- *
- * @param value
- * the value
- * @return true, if is year mark
- */
- public static boolean isYear(final String value)
- {
- boolean result;
-
- result = (YEAR_PATTERN.matcher(value).matches());
-
- //
- return result;
- }
-
- /**
- * Checks if is year month.
- *
- * @param value
- * the value
- * @return true, if is year month
- */
- public static boolean isYearMonth(final String value)
- {
- boolean result;
-
- result = (YEAR_MONTH_PATTERN.matcher(value).matches());
-
- //
- return result;
- }
-
- /**
- * Checks if is year week.
- *
- * @param value
- * the value
- * @return true, if is year week
- */
- public static boolean isYearWeek(final String value)
- {
- boolean result;
-
- result = (YEAR_WEEK_PATTERN.matcher(value).matches());
-
- //
- return result;
- }
-
- /**
- * Parses the date.
- *
- * @param value
- * the value
- * @return the local date
- */
- public static LocalDate parseDate(final String value)
- {
- LocalDate result;
-
- result = LocalDate.parse(value);
-
- //
- return result;
- }
-
- /**
- * Parses the year.
- *
- * @param value
- * the value
- * @return the int
- */
- public static int parseYear(final String value)
- {
- int result;
-
- result = Integer.parseInt(value);
-
- //
- return result;
- }
-
- /**
- * Parses the year month.
- *
- * @param value
- * the value
- * @return the year month
- */
- public static YearMonth parseYearMonth(final String value)
- {
- YearMonth result;
-
- result = YearMonth.parse(value);
-
- //
- return result;
- }
-
- /**
- * Parses the year week.
- *
- * @param value
- * the value
- * @return the year week
- */
- public static YearWeek parseYearWeek(final String value)
- {
- YearWeek result;
-
- result = YearWeek.parse(value);
-
- //
- return result;
- }
-
- /**
- * Month of.
- *
- * @param date
- * the date
- * @return the string
- */
- public static String yearMonthOf(final LocalDateTime date)
- {
- String result;
-
- result = date.format(DateTimeFormatter.ofPattern("yyyy-MM", Locale.FRANCE));
-
- //
- return result;
- }
-
- /**
- * Year month of.
- *
- * @param date
- * the date
- * @return the string
- */
- public static String yearMonthOf(final ZonedDateTime date)
- {
- String result;
-
- result = date.format(DateTimeFormatter.ofPattern("yyyy-MM", Locale.FRANCE));
-
- //
- return result;
- }
-
- /**
- * Year of.
- *
- * @param date
- * the date
- * @return the string
- */
- public static String yearOf(final LocalDateTime date)
- {
- String result;
-
- result = date.format(DateTimeFormatter.ofPattern("yyyy", Locale.FRANCE));
-
- //
- return result;
- }
-
- /**
- * Year of.
- *
- * @param date
- * the date
- * @return the string
- */
- public static String yearOf(final ZonedDateTime date)
- {
- String result;
-
- result = date.format(DateTimeFormatter.ofPattern("yyyy", Locale.FRANCE));
-
- //
- return result;
- }
-
- /**
- * Year week of.
- *
- * @param date
- * the date
- * @return the string
- */
- public static String yearWeekOf(final LocalDateTime date)
- {
- String result;
-
- result = YearWeek.from(date).toString();
-
- //
- return result;
- }
-
- /**
- * Year week of.
- *
- * @param date
- * the date
- * @return the string
- */
- public static String yearWeekOf(final ZonedDateTime date)
- {
- String result;
-
- result = YearWeek.from(date).toString();
-
- //
- return result;
- }
-}
diff --git a/src/fr/devinsy/statoolinfos/metrics/UserCounters.java b/src/fr/devinsy/statoolinfos/metrics/UserCounters.java
deleted file mode 100644
index 71d1726..0000000
--- a/src/fr/devinsy/statoolinfos/metrics/UserCounters.java
+++ /dev/null
@@ -1,121 +0,0 @@
-/*
- * Copyright (C) 2021 Christian Pierre MOMON
- *
- * This file is part of StatoolInfos, simple service statistics tool.
- *
- * StatoolInfos is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * StatoolInfos is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with StatoolInfos. If not, see .
- */
-package fr.devinsy.statoolinfos.metrics;
-
-import java.util.HashMap;
-
-import org.apache.commons.lang3.StringUtils;
-
-import fr.devinsy.strings.StringSet;
-
-/**
- * The Class ActivePlayerCounters.
- */
-public class UserCounters extends HashMap
-{
- private static final long serialVersionUID = 8340304752282908677L;
-
- /**
- * Instantiates a new active player counters.
- */
- public UserCounters()
- {
- super();
- }
-
- /**
- * Gets the.
- *
- * @param timeMark
- * the time mark
- * @return the string set
- */
- public StringSet get(final String timeMark)
- {
- StringSet result;
-
- result = super.get(timeMark);
-
- //
- return result;
- }
-
- /**
- * Gets the counters.
- *
- * @return the counters
- */
- public PathCounters getCounters(final String prefix)
- {
- PathCounters result;
-
- result = new PathCounters();
-
- for (String timeMark : keySet())
- {
- StringSet set = get(timeMark);
- result.inc(set.size(), prefix, timeMark);
- }
-
- //
- return result;
- }
-
- /**
- * Put.
- *
- * @param timemark
- * the timemark
- * @param nickname
- * the nick name
- */
- public void put(final String nickname, final String timemark)
- {
- if (!StringUtils.isBlank(nickname))
- {
- StringSet set = super.get(timemark);
- if (set == null)
- {
- set = new StringSet();
- put(timemark, set);
- }
-
- set.put(nickname);
- }
- }
-
- /**
- * Put.
- *
- * @param nickname
- * the nickname
- * @param timeMarks
- * the time marks
- */
- public void put(final String nickname, final String... timeMarks)
- {
- if (!StringUtils.isBlank(nickname))
- {
- for (String timeMark : timeMarks)
- {
- put(nickname, timeMark);
- }
- }
- }
-}
diff --git a/src/fr/devinsy/statoolinfos/metrics/YearMonthCounters.java b/src/fr/devinsy/statoolinfos/metrics/YearMonthCounters.java
deleted file mode 100644
index 4239264..0000000
--- a/src/fr/devinsy/statoolinfos/metrics/YearMonthCounters.java
+++ /dev/null
@@ -1,107 +0,0 @@
-/*
- * Copyright (C) 2021 Christian Pierre MOMON
- *
- * This file is part of StatoolInfos, simple service statistics tool.
- *
- * StatoolInfos is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * StatoolInfos is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with StatoolInfos. If not, see .
- */
-package fr.devinsy.statoolinfos.metrics;
-
-import java.time.YearMonth;
-import java.util.HashMap;
-import java.util.Iterator;
-
-/**
- * The Class YearMonthCounters.
- */
-public class YearMonthCounters extends HashMap
-{
- private static final long serialVersionUID = 2707786945149971666L;
-
- /**
- * Instantiates a new year month counters.
- */
- public YearMonthCounters()
- {
- super();
- }
-
- /**
- * Gets the.
- *
- * @param timemark
- * the timemark
- * @return the long
- */
- public long get(final YearMonth timemark)
- {
- long result;
-
- Long value = super.get(timemark);
-
- if (value == null)
- {
- result = 0;
- }
- else
- {
- result = value;
- }
-
- //
- return result;
- }
-
- /**
- * Gets the first.
- *
- * @return the first
- */
- public YearMonth getFirstTimeMark()
- {
- YearMonth result;
-
- result = null;
- Iterator iterator = keySet().iterator();
- while (iterator.hasNext())
- {
- YearMonth current = iterator.next();
-
- if ((result == null) || (current.isBefore(result)))
- {
- result = current;
- }
- }
-
- //
- return result;
- }
-
- /**
- * Inc.
- *
- * @param timemark
- * the timemark
- */
- public void inc(final YearMonth timemark)
- {
- Long value = super.get(timemark);
- if (value == null)
- {
- value = 0L;
- }
-
- put(timemark, value + 1);
- }
-}
diff --git a/src/fr/devinsy/statoolinfos/metrics/etherpad/EtherpadHttpLogAnalyzer.java b/src/fr/devinsy/statoolinfos/metrics/etherpad/EtherpadHttpLogAnalyzer.java
deleted file mode 100644
index 1aa77f1..0000000
--- a/src/fr/devinsy/statoolinfos/metrics/etherpad/EtherpadHttpLogAnalyzer.java
+++ /dev/null
@@ -1,142 +0,0 @@
-/*
- * Copyright (C) 2023-2024 Christian Pierre MOMON
- *
- * This file is part of StatoolInfos, simple service statistics tool.
- *
- * StatoolInfos is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * StatoolInfos is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with StatoolInfos. If not, see .
- */
-package fr.devinsy.statoolinfos.metrics.etherpad;
-
-import java.io.IOException;
-import java.util.regex.Pattern;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import fr.devinsy.statoolinfos.core.StatoolInfosException;
-import fr.devinsy.statoolinfos.metrics.PathCounters;
-import fr.devinsy.statoolinfos.metrics.UserCounters;
-import fr.devinsy.statoolinfos.metrics.httpaccess.HttpAccessLog;
-import fr.devinsy.statoolinfos.metrics.httpaccess.HttpAccessLogs;
-
-/**
- * The Class EtherpadHttpLogAnalyzer.
- */
-public class EtherpadHttpLogAnalyzer
-{
- private static Logger logger = LoggerFactory.getLogger(EtherpadHttpLogAnalyzer.class);
-
- public static final Pattern USE_PATTERN = Pattern.compile("^GET /p/\\S+ .*$");
-
- private PathCounters counters;
- private UserCounters users;
- private UserCounters ipv4Users;
- private UserCounters ipv6Users;
-
- /**
- * Instantiates a new http access log prober.
- */
- public EtherpadHttpLogAnalyzer()
- {
- this.counters = new PathCounters();
- this.users = new UserCounters();
- this.ipv4Users = new UserCounters();
- this.ipv6Users = new UserCounters();
- }
-
- /**
- * Gets the counters.
- *
- * @return the counters
- */
- public PathCounters getCounters()
- {
- PathCounters result;
-
- result = new PathCounters();
- result.putAll(this.counters);
-
- result.putAll(this.users.getCounters("metrics.service.users"));
- result.putAll(this.ipv4Users.getCounters("metrics.service.users.ipv4"));
- result.putAll(this.ipv6Users.getCounters("metrics.service.users.ipv6"));
-
- //
- return result;
- }
-
- /**
- * Probe log.
- *
- * @param log
- * the log
- */
- public void probeLog(final HttpAccessLog log)
- {
- if (log != null)
- {
- // General HTTP access logs.
- String year = log.getYear();
- String yearMonth = log.getYearMonth();
- String yearWeek = log.getYearWeek();
- String date = log.getDate();
-
- // metrics.service.users
- // metrics.service.users.ipv4
- // metrics.service.users.ipv6
- if ((!log.isBot()) && (USE_PATTERN.matcher(log.getRequest()).matches()))
- {
- String key = String.format("%s---%s", log.getIp(), log.getUserAgent());
-
- this.users.put(key, year, yearMonth, yearWeek, date);
-
- if (log.isIPv4())
- {
- this.ipv4Users.put(key, year, yearMonth, yearWeek, date);
- }
- else
- {
- this.ipv6Users.put(key, year, yearMonth, yearWeek, date);
- }
- }
- }
- }
-
- /**
- * Probe.
- *
- * @param logs
- * the logs
- * @return the path counters
- * @throws IOException
- * Signals that an I/O exception has occurred.
- * @throws StatoolInfosException
- * the statool infos exception
- */
- public static PathCounters probe(final HttpAccessLogs logs) throws IOException, StatoolInfosException
- {
- PathCounters result;
-
- EtherpadHttpLogAnalyzer analyzer = new EtherpadHttpLogAnalyzer();
-
- for (HttpAccessLog log : logs)
- {
- analyzer.probeLog(log);
- }
-
- result = analyzer.getCounters();
-
- //
- return result;
- }
-}
diff --git a/src/fr/devinsy/statoolinfos/metrics/etherpad/EtherpadLog.java b/src/fr/devinsy/statoolinfos/metrics/etherpad/EtherpadLog.java
deleted file mode 100644
index eabd7e6..0000000
--- a/src/fr/devinsy/statoolinfos/metrics/etherpad/EtherpadLog.java
+++ /dev/null
@@ -1,291 +0,0 @@
-/*
- * Copyright (C) 2022 Christian Pierre MOMON
- *
- * This file is part of StatoolInfos, simple service statistics tool.
- *
- * StatoolInfos is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * StatoolInfos is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with StatoolInfos. If not, see .
- */
-package fr.devinsy.statoolinfos.metrics.etherpad;
-
-import java.time.LocalDateTime;
-import java.time.format.DateTimeFormatter;
-import java.util.Locale;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import fr.devinsy.statoolinfos.metrics.TimeMark;
-import fr.devinsy.statoolinfos.metrics.TimeMarkUtils;
-import fr.devinsy.strings.StringList;
-
-/**
- * The Class EtherpadLog.
- */
-public class EtherpadLog
-{
- private static Logger logger = LoggerFactory.getLogger(EtherpadLog.class);
-
- private LocalDateTime time;
- private String level;
- private String type;
- private String event;
- private String padname;
- private String ip;
- private String author;
-
- /**
- * Instantiates a new etherpad log.
- */
- public EtherpadLog()
- {
- this.time = null;
- this.level = null;
- this.type = null;
- this.event = null;
- this.padname = null;
- this.ip = null;
- this.author = null;
- }
-
- public String getAuthor()
- {
- return this.author;
- }
-
- /**
- * Gets the date.
- *
- * @return the date
- */
- public String getDate()
- {
- String result;
-
- result = this.time.format(DateTimeFormatter.ofPattern("yyyy-MM-dd", Locale.FRANCE));
-
- //
- return result;
- }
-
- public String getEvent()
- {
- return this.event;
- }
-
- public String getIp()
- {
- return this.ip;
- }
-
- public String getLevel()
- {
- return this.level;
- }
-
- public String getPadname()
- {
- return this.padname;
- }
-
- public LocalDateTime getTime()
- {
- return this.time;
- }
-
- /**
- * Gets the time marks.
- *
- * @return the time marks
- */
- public StringList getTimeMarks()
- {
- StringList result;
-
- result = new StringList();
-
- String year = TimeMark.yearOf(this.time).toString();
- String yearMonth = TimeMark.yearMonthOf(this.time).toString();
- String yearWeek = TimeMark.yearWeekOf(this.time).toString();
- String date = TimeMark.dayOf(this.time).toString();
-
- result.add(year);
- result.add(yearMonth);
- result.add(yearWeek);
- result.add(date);
-
- //
- return result;
- }
-
- public String getType()
- {
- return this.type;
- }
-
- /**
- * Gets the year.
- *
- * @return the year
- */
- public String getYear()
- {
- String result;
-
- if (this.time == null)
- {
- result = null;
- }
- else
- {
- result = TimeMarkUtils.yearOf(this.time);
- }
-
- //
- return result;
- }
-
- /**
- * Gets the year month.
- *
- * @return the year month
- */
- public String getYearMonth()
- {
- String result;
-
- if (this.time == null)
- {
- result = null;
- }
- else
- {
- result = TimeMarkUtils.yearMonthOf(this.time);
- }
- //
- return result;
- }
-
- /**
- * Gets the year week.
- *
- * @return the year week
- */
- public String getYearWeek()
- {
- String result;
- if (this.time == null)
- {
- result = null;
- }
- else
- {
- result = TimeMarkUtils.yearWeekOf(this.time);
- }
- //
- return result;
- }
-
- /**
- * Checks if is ipv4.
- *
- * @return true, if is ipv4
- */
- public boolean isIPv4()
- {
- boolean result;
-
- if (this.ip == null)
- {
- result = false;
- }
- else
- {
- result = this.ip.contains(".");
- }
-
- //
- return result;
- }
-
- /**
- * Checks if is ipv6.
- *
- * @return true, if is ipv6
- */
- public boolean isIPv6()
- {
- boolean result;
-
- if (this.ip == null)
- {
- result = false;
- }
- else
- {
- result = this.ip.contains(":");
- }
-
- //
- return result;
- }
-
- public void setAuthor(final String author)
- {
- this.author = author;
- }
-
- public void setEvent(final String event)
- {
- this.event = event;
- }
-
- public void setIp(final String ip)
- {
- this.ip = ip;
- }
-
- public void setLevel(final String level)
- {
- this.level = level;
- }
-
- public void setPadname(final String padname)
- {
- this.padname = padname;
- }
-
- public void setTime(final LocalDateTime time)
- {
- this.time = time;
- }
-
- public void setType(final String type)
- {
- this.type = type;
- }
-
- /* (non-Javadoc)
- * @see java.lang.Object#toString()
- */
- @Override
- public String toString()
- {
- String result;
-
- result = String.format("[time=%s, level=%s, type=%s, event=%s, %padname=%s, ip=%s, auhtor=%s]", this.time, this.level, this.type, this.event, this.padname, this.ip, this.author);
-
- //
- return result;
- }
-}
diff --git a/src/fr/devinsy/statoolinfos/metrics/etherpad/EtherpadLogProber.java b/src/fr/devinsy/statoolinfos/metrics/etherpad/EtherpadLogProber.java
deleted file mode 100644
index d435a3d..0000000
--- a/src/fr/devinsy/statoolinfos/metrics/etherpad/EtherpadLogProber.java
+++ /dev/null
@@ -1,226 +0,0 @@
-/*
- * Copyright (C) 2022 Christian Pierre MOMON
- *
- * This file is part of StatoolInfos, simple service statistics tool.
- *
- * StatoolInfos is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * StatoolInfos is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with StatoolInfos. If not, see .
- */
-package fr.devinsy.statoolinfos.metrics.etherpad;
-
-import java.io.File;
-import java.io.IOException;
-import java.time.LocalDateTime;
-import java.time.format.DateTimeFormatter;
-import java.util.Locale;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-import org.apache.commons.lang3.StringUtils;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import fr.devinsy.statoolinfos.metrics.PathCounters;
-import fr.devinsy.statoolinfos.metrics.UserCounters;
-import fr.devinsy.statoolinfos.util.Files;
-import fr.devinsy.statoolinfos.util.LineIterator;
-
-/**
- * The Class EtherpadLogProber.
- */
-public class EtherpadLogProber
-{
- private static Logger logger = LoggerFactory.getLogger(EtherpadLogProber.class);
-
- // 2021-11-17 01:51:59 DELETE 7922dd508e0cf9b2
- public static final Pattern LOG_PATTERN = Pattern.compile(
- "^\\[(?\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2}(\\.\\d{3})?)]\\s\\[(?[^]]+)]\\s+(?\\S+) - \\[(?[^]]+)]\\spad:(?\\S+)\\ssocket:\\S+\\sIP:(?\\S+) authorID:(?\\S+)( username:.+)?$");
- /*
- [2022-03-28 02:19:35.842] [INFO] access - [ENTER] pad:test socket:Qr8BEX3mP6EmheyLAAAA IP:82.65.227.202 authorID:a.vZ7pRZcyfzUxO26i username:admin
- [2022-03-28 18:50:10.963] [INFO] access - [CREATE] pad:test7 socket:WddndPw_4vt01-0YAAAC IP:82.65.227.202 authorID:a.vZ7pRZcyfzUxO26i username:admin
- [2022-03-28 18:52:00.668] [INFO] access - [ENTER] pad:test7 socket:gA4Ba57988zrGJNmAAAD IP:82.65.227.202 authorID:a.vZ7pRZcyfzUxO26i username:admin
- [2022-03-28 18:52:27.947] [INFO] access - [ENTER] pad:test7 socket:9ZrFheETmDUpUcS1AAAE IP:82.65.227.202 authorID:a.AMpqExl3JHbPL52c
- [2022-03-28 18:59:58.501] [INFO] access - [ENTER] pad:test socket:mCgPMxg2wb7upHP8AAAG IP:82.65.227.202 authorID:a.vZ7pRZcyfzUxO26i username:admin
- [2022-03-28 19:01:24.884] [INFO] access - [LEAVE] pad:test socket:mCgPMxg2wb7upHP8AAAG IP:82.65.227.202 authorID:a.vZ7pRZcyfzUxO26i username:admin
- */
-
- public static final Pattern DELETE_EMPTY_LOG_PATTERN = Pattern.compile(
- "^\\[(?\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2}(\\.\\d{3})?)]\\s\\[(?[^]]+)]\\s+(?\\S+) - Deleting (?\\S+) when user leaved since empty$");
- /*
- [2022-03-29 00:43:57.085] [INFO] ep_delete_empty_pads - Deleting test8 when user leaved since empty
- */
-
- /**
- * Instantiates a new etherpad log prober.
- */
- private EtherpadLogProber()
- {
- }
-
- /**
- * Parses the log.
- *
- * @param line
- * the line
- * @return the http log
- */
- public static EtherpadLog parseLog(final String line)
- {
- EtherpadLog result;
-
- Matcher matcher = LOG_PATTERN.matcher(line);
- if (matcher.matches())
- {
- result = new EtherpadLog();
- result.setTime(LocalDateTime.parse(matcher.group("datetime"), DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSS").withLocale(Locale.ENGLISH)));
- result.setLevel(matcher.group("level"));
- result.setType(matcher.group("type"));
- result.setEvent(matcher.group("event"));
- result.setPadname(matcher.group("padname"));
- result.setIp(matcher.group("ip"));
- result.setAuthor(matcher.group("author"));
- }
- else
- {
- matcher = DELETE_EMPTY_LOG_PATTERN.matcher(line);
- if (matcher.matches())
- {
- result = new EtherpadLog();
- result.setTime(LocalDateTime.parse(matcher.group("datetime"), DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSS").withLocale(Locale.ENGLISH)));
- result.setLevel(matcher.group("level"));
- result.setType(matcher.group("type"));
- result.setEvent("Deleting");
- result.setAuthor(matcher.group("padname"));
- }
- else
- {
- result = null;
- }
- }
-
- //
- return result;
- }
-
- /**
- * Probe.
- *
- * @param files
- * the files
- * @return the path counters
- * @throws IOException
- * Signals that an I/O exception has occurred.
- */
- public static PathCounters probe(final Files files) throws IOException
- {
- PathCounters result;
-
- result = new PathCounters();
-
- UserCounters users = new UserCounters();
- UserCounters ipv4Users = new UserCounters();
- UserCounters ipv6Users = new UserCounters();
- UserCounters actives = new UserCounters();
-
- for (File file : files)
- {
- System.out.println("Probing file [" + file.getAbsolutePath() + "]");
-
- //
- int lineCount = 0;
- LineIterator iterator = new LineIterator(file);
- while (iterator.hasNext())
- {
- lineCount += 1;
- String line = iterator.next();
-
- // Remove ANSI Escape Codes.
- line = line.replaceAll("\u001B\\[[\\d;]*[^\\d;]", "");
-
- try
- {
- EtherpadLog log = parseLog(line);
- // System.out.println("====> " + log);
- if (log == null)
- {
- if (line.contains("access -"))
- {
- logger.warn("LINE IS NOT MATCHING [{}]", line);
- }
- }
- else
- {
- // Timemarks.
- String year = log.getYear();
- String yearMonth = log.getYearMonth();
- String yearWeek = log.getYearWeek();
- String date = log.getDate();
-
- if (StringUtils.equals(log.getType(), "access"))
- {
- // metrics.service.users
- // metrics.service.users.ipv4
- // metrics.service.users.ipv6
- users.put(log.getAuthor(), year, yearMonth, yearWeek, date);
- if (log.isIPv4())
- {
- ipv4Users.put(log.getAuthor(), year, yearMonth, yearWeek, date);
- }
- else
- {
- ipv6Users.put(log.getAuthor(), year, yearMonth, yearWeek, date);
- }
-
- // metrics.etherpad.pads.actives
- actives.put(log.getPadname(), year, yearMonth, yearWeek, date);
-
- // metrics.etherpad.pads.created
- // alias metrics.textprocessors.created
- if (StringUtils.equals(log.getEvent(), "CREATE"))
- {
- result.inc("metrics.etherpad.pads.created", year, yearMonth, yearWeek, date);
- result.inc("metrics.textprocessors.created", year, yearMonth, yearWeek, date);
- }
-
- if (StringUtils.equalsAny(log.getEvent(), "CREATE", "ENTER"))
- {
- result.inc("metrics.etherpad.pads.reads", year, yearMonth, yearWeek, date);
- result.inc("metrics.textprocessors.reads", year, yearMonth, yearWeek, date);
- }
- }
- else if (StringUtils.equals(log.getType(), "ep_delete_empty_pads"))
- {
- result.inc("metrics.etherpad.pads.deleted", year, yearMonth, yearWeek, date);
- result.inc("metrics.textprocessors.deleted", year, yearMonth, yearWeek, date);
- }
- }
- }
- catch (Exception exception)
- {
- logger.warn("Error parsing line [{}][{}]", line, exception.getMessage());
- exception.printStackTrace();
- }
- }
- System.out.println("PrivatebinPatchLog line count=" + lineCount);
- }
-
- //
- result.putAll(users.getCounters("metrics.service.users"));
- result.putAll(ipv4Users.getCounters("metrics.service.users.ipv4"));
- result.putAll(ipv6Users.getCounters("metrics.service.users.ipv6"));
- result.putAll(actives.getCounters("metrics.etherpad.pads.actives"));
-
- //
- return result;
- }
-}
diff --git a/src/fr/devinsy/statoolinfos/metrics/etherpad/EtherpadProber.java b/src/fr/devinsy/statoolinfos/metrics/etherpad/EtherpadProber.java
deleted file mode 100644
index 3348a17..0000000
--- a/src/fr/devinsy/statoolinfos/metrics/etherpad/EtherpadProber.java
+++ /dev/null
@@ -1,177 +0,0 @@
-/*
- * Copyright (C) 2022-2024 Christian Pierre MOMON
- *
- * This file is part of StatoolInfos, simple service statistics tool.
- *
- * StatoolInfos is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * StatoolInfos is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with StatoolInfos. If not, see .
- */
-package fr.devinsy.statoolinfos.metrics.etherpad;
-
-import java.io.IOException;
-import java.sql.SQLException;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import fr.devinsy.statoolinfos.core.DatabaseConfig;
-import fr.devinsy.statoolinfos.core.StatoolInfosException;
-import fr.devinsy.statoolinfos.metrics.PathCounters;
-import fr.devinsy.statoolinfos.metrics.httpaccess.HttpAccessLogs;
-import fr.devinsy.statoolinfos.metrics.util.DatabaseProber;
-import fr.devinsy.statoolinfos.util.Files;
-import fr.devinsy.statoolinfos.util.sql.SQLDatabase;
-import fr.devinsy.strings.StringList;
-
-/**
- * The Class EtherpadProber.
- */
-public class EtherpadProber
-{
- private static Logger logger = LoggerFactory.getLogger(EtherpadProber.class);
-
- /**
- * Instantiates a new etherpad prober.
- */
- public EtherpadProber()
- {
- }
-
- /**
- * Probe.
- *
- * @param httpAccessLogs
- * the http access logs
- * @param logs
- * the logs
- * @param databaseConfig
- * the database config
- * @return the path counters
- * @throws IOException
- * Signals that an I/O exception has occurred.
- * @throws StatoolInfosException
- * the statool infos exception
- */
- public static PathCounters probe(final HttpAccessLogs httpAccessLogs, final Files logs, final DatabaseConfig databaseConfig) throws IOException, StatoolInfosException
- {
- PathCounters result;
-
- // metrics.service.users
- // metrics.service.users.ipv4
- // metrics.service.users.ipv6
- if (logs.isEmpty())
- {
- result = EtherpadHttpLogAnalyzer.probe(httpAccessLogs);
- }
- else
- {
- result = EtherpadLogProber.probe(logs);
- }
-
- try
- {
- if (databaseConfig.isSet())
- {
- SQLDatabase database = new SQLDatabase(databaseConfig.getUrl(), databaseConfig.getUser(), databaseConfig.getPassword());
- database.open();
-
- // metrics.service.database.bytes
- result.putAll(DatabaseProber.probe(database));
-
- // metrics.textprocessors.characters
- // metrics.textprocessors.words
-
- // metrics.etherpad.database.pads
- // metrics.textprocessors.files
- StringList timemarks = result.getNowTimeMarks();
- String sql = "select count(*) from store where key like 'pad:%' and key not like 'pad:%:%';";
- long count = database.queryNumber(sql);
- result.set(count, "metrics.etherpad.pads", timemarks);
- result.set(count, "metrics.textprocessors.files", timemarks);
-
- // metrics.etherpad.database.revs.
- sql = "SELECT count(*) from store where key like 'pad:%:revs:%';";
- count = database.queryNumber(sql);
- result.set(count, "metrics.etherpad.revs", timemarks);
-
- // metrics.etherpad.database.lines
- sql = "SELECT count(*) from store;";
- count = database.queryNumber(sql);
- result.set(count, "metrics.etherpad.database.lines", timemarks);
-
- // metrics.etherpad.database.lines.globalAuthor
- sql = "SELECT count(*) from store where key like 'globalAuthor:%';";
- count = database.queryNumber(sql);
- result.set(count, "metrics.etherpad.database.lines.globalAuthor", timemarks);
-
- // metrics.etherpad.database.lines.pad
- sql = "SELECT count(*) from store where key like 'pad:%';";
- count = database.queryNumber(sql);
- result.set(count, "metrics.etherpad.database.lines.pad", timemarks);
-
- // metrics.etherpad.database.lines.pad2readonly
- sql = "SELECT count(*) from store where key like 'pad2readonly:%';";
- count = database.queryNumber(sql);
- result.set(count, "metrics.etherpad.database.lines.pad2readonly", timemarks);
-
- // metrics.etherpad.database.lines.readonly2pad
- sql = "SELECT count(*) from store where key like 'readonly2pad:%';";
- count = database.queryNumber(sql);
- result.set(count, "metrics.etherpad.database.lines.readonly2pad", timemarks);
-
- // metrics.etherpad.database.lines.sessionstorage
- sql = "SELECT count(*) from store where key like 'sessionstorage:%';";
- count = database.queryNumber(sql);
- result.set(count, "metrics.etherpad.database.lines.sessionstorage", timemarks);
-
- // metrics.etherpad.database.lines.token2author
- sql = "SELECT count(*) from store where key like 'token2author:%';";
- count = database.queryNumber(sql);
- result.set(count, "metrics.etherpad.database.lines.token2author", timemarks);
-
- //
- database.close();
- }
- else
- {
- System.out.println("Etherpad Database undefined.");
- }
-
- // https://etherpad.org/doc/v1.8.18/#index_statistics
- // Etherpad keeps track of the goings-on inside the edit machinery.
- // If you'd like to have a look at this, just point your browser to
- // /stats.
- // We currently measure:
- //
- // totalUsers (counter)
- // connects (meter)
- // disconnects (meter)
- // pendingEdits (counter)
- // edits (timer)
- // failedChangesets (meter)
- // httpRequests (timer)
- // http500 (meter)
- // memoryUsage (gauge)
- //
- // https://pad.libre-service.eu/stats/
-
- }
- catch (SQLException exception)
- {
- logger.error("ERROR with database.", exception);
- }
-
- //
- return result;
- }
-}
diff --git a/src/fr/devinsy/statoolinfos/metrics/gitea/GiteaAPI.java b/src/fr/devinsy/statoolinfos/metrics/gitea/GiteaAPI.java
deleted file mode 100644
index 7a93e82..0000000
--- a/src/fr/devinsy/statoolinfos/metrics/gitea/GiteaAPI.java
+++ /dev/null
@@ -1,384 +0,0 @@
-/*
- * Copyright (C) 2022 Christian Pierre MOMON
- *
- * This file is part of StatoolInfos, simple service statistics tool.
- *
- * StatoolInfos is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * StatoolInfos is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with StatoolInfos. If not, see .
- */
-package fr.devinsy.statoolinfos.metrics.gitea;
-
-import java.io.IOException;
-import java.net.URL;
-import java.nio.charset.Charset;
-import java.time.LocalDateTime;
-import java.time.format.DateTimeFormatter;
-import java.time.format.DateTimeParseException;
-
-import org.apache.commons.io.IOUtils;
-import org.apache.commons.lang3.StringUtils;
-import org.json.simple.JSONArray;
-import org.json.simple.JSONObject;
-import org.json.simple.parser.JSONParser;
-import org.json.simple.parser.ParseException;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * The Class GiteaAPI.
- */
-public class GiteaAPI
-{
- private static Logger logger = LoggerFactory.getLogger(GiteaAPI.class);
-
- private String url;
- private String token;
- private JSONArray users;
- private JSONArray organizations;
- private JSONArray repositories;
-
- /**
- * Instantiates a new gitea API.
- */
- public GiteaAPI(final String url, final String token) throws IOException, ParseException
- {
- try
- {
- this.url = StringUtils.removeEnd(url, "/");
- this.token = token;
-
- //
- String json = IOUtils.toString(new URL(this.url + "/api/v1/admin/users?limit=100000&token=" + token), Charset.defaultCharset());
- this.users = (JSONArray) (new JSONParser().parse(json));
-
- //
- json = IOUtils.toString(new URL(this.url + "/api/v1/admin/orgs?limit=100000&token=" + token), Charset.defaultCharset());
- this.organizations = (JSONArray) (new JSONParser().parse(json));
-
- //
- json = IOUtils.toString(new URL(this.url + "/api/v1/repos/search?limit=100000&token=" + token), Charset.defaultCharset());
- this.repositories = (JSONArray) ((JSONObject) (new JSONParser().parse(json))).get("data");
- }
- catch (IOException exception)
- {
- String message = exception.getMessage();
- if (message.matches(".*token=\\w+.*"))
- {
- message = message.replaceAll("token=\\w+", "token=*******");
- throw new IOException(message);
- }
- else
- {
- throw exception;
- }
- }
- }
-
- /**
- * Gets the active user count.
- *
- * @return the active user count
- */
- public long getActiveUserCount()
- {
- long result;
-
- result = 0;
- LocalDateTime limit = LocalDateTime.now().minusDays(31);
- for (Object user : this.users)
- {
- String lastLogin = getJSONString(user, "last_login");
-
- if (!StringUtils.isBlank(lastLogin))
- {
- try
- {
- LocalDateTime date = LocalDateTime.parse(lastLogin, DateTimeFormatter.ISO_DATE_TIME);
- if (date.isAfter(limit))
- {
- result += 1;
- }
- }
- catch (DateTimeParseException exception)
- {
- System.out.println("OUPS");
- }
- }
- }
-
- //
- return result;
- }
-
- /**
- * Gets the fork repository count.
- *
- * @return the fork repository count
- */
- public long getForkRepositoryCount()
- {
- long result;
-
- result = 0;
- for (Object repository : this.repositories)
- {
- if (getJSONBoolean(repository, "fork"))
- {
- result += 1;
- }
- }
-
- //
- return result;
- }
-
- /**
- * Gets the mirror repository count.
- *
- * @return the mirror repository count
- */
- public long getMirrorRepositoryCount()
- {
- long result;
-
- result = 0;
- for (Object repository : this.repositories)
- {
- if (getJSONBoolean(repository, "mirror"))
- {
- result += 1;
- }
- }
-
- //
- return result;
- }
-
- /**
- * Gets the organization count.
- *
- * @return the organization count
- */
- public long getOrganizationCount()
- {
- long result;
-
- result = this.organizations.size();
-
- //
- return result;
- }
-
- /**
- * Gets the private organization count.
- *
- * @return the private organization count
- */
- public long getPrivateOrganizationCount()
- {
- long result;
-
- result = 0;
- for (Object organization : this.organizations)
- {
- String visibility = getJSONString(organization, "visibility");
-
- if (StringUtils.equals(visibility, "private"))
- {
- result += 1;
- }
- }
-
- //
- return result;
- }
-
- /**
- * Gets the private repository count.
- *
- * @return the private repository count
- */
- public long getPrivateRepositoryCount()
- {
- long result;
-
- result = 0;
- for (Object repository : this.repositories)
- {
- if (getJSONBoolean(repository, "private"))
- {
- result += 1;
- }
- }
-
- //
- return result;
- }
-
- /**
- * Gets the public organization count.
- *
- * @return the public organization count
- */
- public long getPublicOrganizationCount()
- {
- long result;
-
- result = 0;
- for (Object organization : this.organizations)
- {
- String visibility = getJSONString(organization, "visibility");
-
- if (StringUtils.equals(visibility, "public"))
- {
- result += 1;
- }
- }
-
- //
- return result;
- }
-
- /**
- * Gets the public repository count.
- *
- * @return the public repository count
- */
- public long getPublicRepositoryCount()
- {
- long result;
-
- result = 0;
- for (Object repository : this.repositories)
- {
- if (!getJSONBoolean(repository, "private"))
- {
- result += 1;
- }
- }
-
- //
- return result;
- }
-
- /**
- * Gets the repository count.
- *
- * @return the repository count
- */
- public long getRepositoryCount()
- {
- long result;
-
- result = this.repositories.size();
-
- //
- return result;
- }
-
- /**
- * Gets the user count.
- *
- * @return the user count
- */
- public long getUserCount()
- {
- long result;
-
- result = this.users.size();
-
- //
- return result;
- }
-
- /**
- * Gets the boolean.
- *
- * @param object
- * the object
- * @param key
- * the key
- * @return the boolean
- */
- private static boolean getJSONBoolean(final Object object, final String key)
- {
- Boolean result;
-
- Object value = ((JSONObject) object).get(key);
- if (value == null)
- {
- result = false;
- }
- else
- {
- result = (Boolean) value;
- }
-
- //
- return result;
- }
-
- /**
- * Gets the long.
- *
- * @param object
- * the object
- * @param key
- * the key
- * @return the long
- */
- public static long getJSONLong(final Object object, final String key)
- {
- long result;
-
- Object value = ((JSONObject) object).get(key);
- if (value == null)
- {
- result = 0;
- }
- else
- {
- result = (Long) value;
- }
-
- //
- return result;
- }
-
- /**
- * Gets the as string.
- *
- * @param object
- * the object
- * @param key
- * the key
- * @return the as string
- */
- public static String getJSONString(final Object object, final String key)
- {
- String result;
-
- Object value = ((JSONObject) object).get(key);
- if (value == null)
- {
- result = "";
- }
- else
- {
- result = (String) value;
- }
-
- //
- return result;
- }
-}
diff --git a/src/fr/devinsy/statoolinfos/metrics/gitea/GiteaProber.java b/src/fr/devinsy/statoolinfos/metrics/gitea/GiteaProber.java
deleted file mode 100644
index 48afe65..0000000
--- a/src/fr/devinsy/statoolinfos/metrics/gitea/GiteaProber.java
+++ /dev/null
@@ -1,335 +0,0 @@
-/*
- * Copyright (C) 2022-2024 Christian Pierre MOMON
- *
- * This file is part of StatoolInfos, simple service statistics tool.
- *
- * StatoolInfos is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * StatoolInfos is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with StatoolInfos. If not, see .
- */
-package fr.devinsy.statoolinfos.metrics.gitea;
-
-import java.io.File;
-import java.io.IOException;
-import java.sql.SQLException;
-import java.util.regex.Pattern;
-
-import org.apache.commons.lang3.StringUtils;
-import org.json.simple.parser.ParseException;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import fr.devinsy.statoolinfos.core.DatabaseConfig;
-import fr.devinsy.statoolinfos.core.StatoolInfosException;
-import fr.devinsy.statoolinfos.metrics.PathCounters;
-import fr.devinsy.statoolinfos.metrics.UserCounters;
-import fr.devinsy.statoolinfos.metrics.httpaccess.HttpAccessLog;
-import fr.devinsy.statoolinfos.metrics.httpaccess.HttpAccessLogs;
-import fr.devinsy.statoolinfos.metrics.httpaccess.HttpStatusCategory;
-import fr.devinsy.statoolinfos.metrics.util.DatabaseProber;
-import fr.devinsy.statoolinfos.metrics.util.DatafilesProber;
-import fr.devinsy.statoolinfos.util.sql.SQLDatabase;
-import fr.devinsy.strings.StringList;
-
-/**
- * The Class GiteaProber.
- */
-public class GiteaProber
-{
- private static Logger logger = LoggerFactory.getLogger(GiteaProber.class);
-
- /**
- * Instantiates a new nextcloud prober.
- */
- public GiteaProber()
- {
- }
-
- /**
- * Probe.
- *
- * @param httpAccessLogs
- * the http access logs
- * @param apiURL
- * the api URL
- * @param apiToken
- * the api token
- * @param dataPath
- * the data path
- * @param databaseConfig
- * the database config
- * @return the path counters
- * @throws IOException
- * Signals that an I/O exception has occurred.
- * @throws StatoolInfosException
- * the statool infos exception
- */
- public static PathCounters probe(final HttpAccessLogs httpAccessLogs, final String apiURL, final String apiToken, final File dataPath, final DatabaseConfig databaseConfig)
- throws IOException, StatoolInfosException
- {
- PathCounters result;
-
- // metrics.service.users
- // metrics.service.users.ipv4
- // metrics.service.users.ipv6
- result = probeHttpAccessLog(httpAccessLogs);
-
- // metrics.service.database.bytes
- try
- {
- if (databaseConfig.isSet())
- {
- SQLDatabase database = new SQLDatabase(databaseConfig.getUrl(), databaseConfig.getUser(), databaseConfig.getPassword());
- database.open();
- result.putAll(DatabaseProber.probe(database));
- database.close();
- }
- else
- {
- System.out.println("GITEA Database undefined.");
- }
- }
- catch (SQLException exception)
- {
- logger.error("ERROR with database.", exception);
- }
-
- // metrics.service.files.bytes
- // metrics.service.files.count
- result.putAll(DatafilesProber.probe(dataPath));
-
- //
- System.out.println("Probing GiteaAPI [" + apiURL + "]");
- if (!StringUtils.isBlank(apiURL) && (!StringUtils.isBlank(apiToken)))
- {
- try
- {
- GiteaAPI gitea = new GiteaAPI(apiURL, apiToken);
-
- // metrics.service.accounts
- // metrics.service.accounts.active
- result.set(gitea.getUserCount(), "metrics.service.accounts");
- result.set(gitea.getActiveUserCount(), "metrics.service.accounts.active");
-
- // metrics.forge.groups.* =
- // metrics.forge.groups.private.* =
- // metrics.forge.groups.public.* =
- result.set(gitea.getOrganizationCount(), "metrics.forge.groups");
- result.set(gitea.getPublicOrganizationCount(), "metrics.forge.groups.public");
- result.set(gitea.getPrivateOrganizationCount(), "metrics.forge.groups.private");
-
- // metrics.forge.projects.* =
- // metrics.forge.repositories.* =
- // metrics.forge.repositories.private.* =
- // metrics.forge.repositories.public.* =
- result.set(gitea.getRepositoryCount(), "metrics.forge.projects");
- result.set(gitea.getRepositoryCount(), "metrics.forge.repositories");
- result.set(gitea.getPublicRepositoryCount(), "metrics.forge.repositories.public");
- result.set(gitea.getPrivateRepositoryCount(), "metrics.forge.repositories.private");
- result.set(gitea.getForkRepositoryCount(), "metrics.forge.repositories.forks");
- result.set(gitea.getMirrorRepositoryCount(), "metrics.forge.repositories.mirrors");
-
- // metrics.issues.count.* =
- // metrics.issues.issuers.*=
- // metrics.issues.created.* =
- // metrics.issues.closed.* =
-
- }
- catch (IOException | ParseException exception)
- {
- System.out.println("ERROR using GiteaAPI: " + exception.getMessage());
- }
- }
-
- // ///////////////////////////////////////
-
- // # [Metrics spécifiques aux services de forges logicielles].
- //
- //
- // metrics.forge.commits.* =
- // metrics.forge.mergerequests.* =
- // metrics.forge.committers.* =
- // metrics.forge.mergerequesters.* =
- // metrics.forge.files.* =
-
- //
- return result;
- }
-
- /**
- * Probe http access log.
- *
- * @param logs
- * the logs
- * @return the path counters
- * @throws IOException
- * Signals that an I/O exception has occurred.
- * @throws StatoolInfosException
- * the statool infos exception
- */
- private static PathCounters probeHttpAccessLog(final HttpAccessLogs logs) throws IOException, StatoolInfosException
- {
- PathCounters result;
-
- result = new PathCounters();
-
- // metrics.service.users
- // metrics.service.users.ipv4
- // metrics.service.users.ipv6
- UserCounters users = new UserCounters();
- UserCounters ipv4Users = new UserCounters();
- UserCounters ipv6Users = new UserCounters();
-
- StringList regexList = new StringList();
-
- /*
- GET /admin
- GET /admin/auths
- GET /admin/config
- GET /admin/emails
- GET /admin/hooks
- GET /admin/monitor
- GET /admin/notices
- GET /admin/orgs
- GET /admin/repos
- GET /admin/users
- */
- regexList.add("GET /admin(/auths|/config|/emails|/hooks|/monitor|/notices|/orgs|/repos|/users)? .*");
-
- /*
- GET /cpm
- GET /devinsy
- */
- // regexList.add("GET /\\w+ .*");
-
- /*
- GET /devinsy/bacasable
- */
- // regexList.add("GET /\\w+/\\w+ .*");
-
- /*
- GET /devinsy/bacasable/activity
- GET /devinsy/bacasable/commits/branch/master
- GET /devinsy/bacasable/compare/master...master
- GET /devinsy/bacasable/graph
- GET /devinsy/bacasable/issues
- GET /devinsy/bacasable/issues/new?project=1
- GET /devinsy/bacasable/projects
- GET /devinsy/bacasable/projects/1
- GET /devinsy/bacasable/projects/1/edit
- GET /devinsy/bacasable/pulls
- GET /devinsy/bacasable/pulls/1
- GET /devinsy/bacasable/releases
- GET /devinsy/bacasable/releases/tag/0.5.0
- GET /devinsy/bacasable/tags
- GET /devinsy/bacasable/wiki
- GET /devinsy/bacasable/wiki/Home
- */
- regexList.add("GET /\\S+/\\S+(/activity|/commits/branch/master|/compare/\\S+|/graph|/issues|/projects(/\\d+)|/pulls(/\\d+)|/releases(/tag/\\S+|/tags|/wiki|/wiki/\\S+)) .*");
-
- /*
- GET /devinsy/bacasable/settings
- GET /devinsy/bacasable/settings/branches
- GET /devinsy/bacasable/settings/collaboration
- GET /devinsy/bacasable/settings/hooks
- GET /devinsy/bacasable/settings/keys
- GET /devinsy/bacasable/settings/lfs
- GET /devinsy/bacasable/settings/lfs/locks
- GET /devinsy/bacasable/settings/lfs/pointers
- GET /devinsy/bacasable/settings/tags
- */
- regexList.add("GET /\\S+/\\S+/settings(/branches|/collaboration|/hooks|/keys|/lfs|/lfs/locks|/lfs/pointers|/tags)? .*");
-
- /*
- GET /org/create
- GET /org/devinsy/members
- GET /org/devinsy/settings
- GET /org/devinsy/teams
- GET /org/devinsy/teams/new
- */
- regexList.add("GET /org/(create|/\\S+/members|/\\S+/settings|/\\S+/teams|/\\S+/teams/new) .*");
-
- /*
- GET /explore/organizations
- GET /explore/repos
- GET /explore/users
- */
- regexList.add("GET (/explore/organizations|/explore/repos|/explore/users) .*");
-
- /*
- GET /issues
- GET /milestones
- GET /pulls
- */
- regexList.add("GET /(issues|milestones|pulls) .*");
-
- /*
- GET /repo/create
- GET /repo/fork/7
- GET /repo/migrate
- */
- regexList.add("GET /repo/(create|fork/\\d+|migrate) .*");
-
- /*
- GET /user/settings
- GET /user/settings/account
- GET /user/settings/appearance
- GET /user/settings/applications
- GET /user/settings/keys
- GET /user/settings/organization
- GET /user/settings/repos
- GET /user/settings/security
- */
- regexList.add("GET /user/settings(/account|/appearance|/applications|/keys|/organizations|/repos|/security)? .*");
-
- String regex = regexList.toString("(", "|", ")");
-
- Pattern USE_PATTERN = Pattern.compile(regex);
-
- //
- for (HttpAccessLog log : logs)
- {
- // General HTTP access logs.
- String year = log.getYear();
- String yearMonth = log.getYearMonth();
- String yearWeek = log.getYearWeek();
- String date = log.getDate();
-
- // metrics.service.users
- // metrics.service.users.ipv4
- // metrics.service.users.ipv6
- if ((log.getStatus().getCategory() == HttpStatusCategory.SUCCESS) && (!log.isBot()) && (USE_PATTERN.matcher(log.getRequest()).matches()))
- {
- String key = String.format("%s---%s", log.getIp(), log.getUserAgent());
-
- users.put(key, year, yearMonth, yearWeek, date);
-
- if (log.isIPv4())
- {
- ipv4Users.put(key, year, yearMonth, yearWeek, date);
- }
- else
- {
- ipv6Users.put(key, year, yearMonth, yearWeek, date);
- }
- }
- }
-
- //
- result.putAll(users.getCounters("metrics.service.users"));
- result.putAll(ipv4Users.getCounters("metrics.service.users.ipv4"));
- result.putAll(ipv6Users.getCounters("metrics.service.users.ipv6"));
-
- //
- return result;
- }
-}
diff --git a/src/fr/devinsy/statoolinfos/metrics/gsl/GSLProber.java b/src/fr/devinsy/statoolinfos/metrics/gsl/GSLProber.java
deleted file mode 100644
index 87b9047..0000000
--- a/src/fr/devinsy/statoolinfos/metrics/gsl/GSLProber.java
+++ /dev/null
@@ -1,165 +0,0 @@
-/*
- * Copyright (C) 2022 Christian Pierre MOMON
- *
- * This file is part of StatoolInfos, simple service statistics tool.
- *
- * StatoolInfos is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * StatoolInfos is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with StatoolInfos. If not, see .
- */
-package fr.devinsy.statoolinfos.metrics.gsl;
-
-import java.io.File;
-import java.io.FileReader;
-import java.io.IOException;
-import java.util.Properties;
-
-import org.apache.commons.lang3.math.NumberUtils;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import fr.devinsy.statoolinfos.core.StatoolInfosException;
-import fr.devinsy.statoolinfos.metrics.PathCounters;
-import fr.devinsy.strings.StringList;
-
-/**
- * The Class GSLProber.
- */
-public class GSLProber
-{
- private static Logger logger = LoggerFactory.getLogger(GSLProber.class);
-
- /**
- * Instantiates a new GSL prober.
- */
- private GSLProber()
- {
- }
-
- /**
- * Probe.
- *
- * @param statsFile
- * the stats file
- * @return the path counters
- * @throws IOException
- * Signals that an I/O exception has occurred.
- * @throws StatoolInfosException
- * the statool infos exception
- */
- public static PathCounters probe(final File statsFile) throws IOException, StatoolInfosException
- {
- PathCounters result;
-
- result = new PathCounters();
-
- //
- Properties properties = new Properties();
- properties.load(new FileReader(statsFile));
-
- StringList timemarks = result.getNowTimeMarks();
-
- // metrics.gsl.articles =
- String value = properties.getProperty("gsl.articles");
- if (NumberUtils.isDigits(value))
- {
- result.set(Long.valueOf(value), "metrics.gsl.articles", timemarks);
- }
-
- // metrics.gsl.articles.pages=
- value = properties.getProperty("gsl.articles.pages");
- if (NumberUtils.isDigits(value))
- {
- result.set(Long.valueOf(value), "metrics.gsl.articles.pages", timemarks);
- }
-
- // metrics.gsl.articles.posts=
- value = properties.getProperty("gsl.articles.posts");
- if (NumberUtils.isDigits(value))
- {
- result.set(Long.valueOf(value), "metrics.gsl.articles.posts", timemarks);
- }
-
- // metrics.gsl.authors =
- value = properties.getProperty("gsl.authors");
- if (NumberUtils.isDigits(value))
- {
- result.set(Long.valueOf(value), "metrics.gsl.authors", timemarks);
- }
-
- // gsl.articles.tags
- value = properties.getProperty("gsl.tags");
- if (NumberUtils.isDigits(value))
- {
- result.set(Long.valueOf(value), "metrics.gsl.tags", timemarks);
- }
-
- // gsl.articles.words
- value = properties.getProperty("gsl.words");
- if (NumberUtils.isDigits(value))
- {
- result.set(Long.valueOf(value), "metrics.gsl.words", timemarks);
- }
-
- // gsl.articles.quotes
- value = properties.getProperty("gsl.quotes");
- if (NumberUtils.isDigits(value))
- {
- result.set(Long.valueOf(value), "metrics.gsl.quotes", timemarks);
- }
-
- // gsl.articles.paragraphs
- value = properties.getProperty("gsl.paragraphs");
- if (NumberUtils.isDigits(value))
- {
- result.set(Long.valueOf(value), "metrics.gsl.paragraphs", timemarks);
- }
-
- // gsl.articles.links
- value = properties.getProperty("gsl.links");
- if (NumberUtils.isDigits(value))
- {
- result.set(Long.valueOf(value), "metrics.gsl.links", timemarks);
- }
-
- // gsl.articles.links.online
- value = properties.getProperty("gsl.online");
- if (NumberUtils.isDigits(value))
- {
- result.set(Long.valueOf(value), "metrics.gsl.online", timemarks);
- }
-
- // gsl.articles.lists
- value = properties.getProperty("gsl.lists");
- if (NumberUtils.isDigits(value))
- {
- result.set(Long.valueOf(value), "metrics.gsl.lists", timemarks);
- }
-
- // gsl.articles.lists.items
- value = properties.getProperty("gsl.items");
- if (NumberUtils.isDigits(value))
- {
- result.set(Long.valueOf(value), "metrics.gsl.items", timemarks);
- }
-
- // gsl_articles.images
- value = properties.getProperty("gsl.images");
- if (NumberUtils.isDigits(value))
- {
- result.set(Long.valueOf(value), "metrics.gsl.authors", timemarks);
- }
-
- //
- return result;
- }
-}
diff --git a/src/fr/devinsy/statoolinfos/metrics/httpaccess/HttpAccessLog.java b/src/fr/devinsy/statoolinfos/metrics/httpaccess/HttpAccessLog.java
deleted file mode 100644
index 8b84263..0000000
--- a/src/fr/devinsy/statoolinfos/metrics/httpaccess/HttpAccessLog.java
+++ /dev/null
@@ -1,400 +0,0 @@
-/*
- * Copyright (C) 2021-2024 Christian Pierre MOMON
- *
- * This file is part of StatoolInfos, simple service statistics tool.
- *
- * StatoolInfos is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * StatoolInfos is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with StatoolInfos. If not, see .
- */
-package fr.devinsy.statoolinfos.metrics.httpaccess;
-
-import java.time.LocalDateTime;
-import java.time.ZoneId;
-import java.time.ZonedDateTime;
-import java.time.format.DateTimeFormatter;
-import java.util.Locale;
-import java.util.regex.Pattern;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import fr.devinsy.statoolinfos.metrics.TimeMarkUtils;
-import fr.devinsy.strings.StringList;
-
-/**
- * The Class HttpAccessLog.
- *
- */
-public class HttpAccessLog
-{
- private static Logger logger = LoggerFactory.getLogger(HttpAccessLog.class);
-
- public static final Pattern ASSET_PATTERN = Pattern.compile("^.*\\.(avi|css|gif|ico|jpeg|jpg|js|mp3|mp4|ogg|png|svg|wav) HTTP.*$");
-
- private String ip;
- private String remoteUser;
- private ZonedDateTime time;
- private String request;
- private HttpStatus status;
- private long bodyBytesSent;
- private String referer;
- private UserAgent userAgent;
-
- /**
- * Instantiates a new http access log.
- */
- public HttpAccessLog()
- {
- this.ip = null;
- this.remoteUser = null;
- this.time = null;
- this.request = null;
- this.status = null;
- this.bodyBytesSent = 0;
- this.referer = null;
- this.userAgent = null;
- }
-
- public long getBodyBytesSent()
- {
- return this.bodyBytesSent;
- }
-
- public String getDate()
- {
- String result;
-
- result = this.time.format(DateTimeFormatter.ofPattern("yyyy-MM-dd", Locale.FRANCE));
-
- //
- return result;
- }
-
- public String getIp()
- {
- return this.ip;
- }
-
- /**
- * Gets the method.
- *
- * @return the method
- */
- public HttpMethod getMethod()
- {
- HttpMethod result;
-
- if (this.request == null)
- {
- result = HttpMethod.UNKNOWN;
- }
- else
- {
- int space = this.request.indexOf(' ');
- if (space == -1)
- {
- result = HttpMethod.UNKNOWN;
- }
- else
- {
- result = HttpMethod.of(this.request.substring(0, space));
- }
- }
-
- //
- return result;
- }
-
- public String getReferer()
- {
- return this.referer;
- }
-
- public String getRemoteUser()
- {
- return this.remoteUser;
- }
-
- public String getRequest()
- {
- return this.request;
- }
-
- public HttpStatus getStatus()
- {
- return this.status;
- }
-
- public LocalDateTime getTime()
- {
- return this.time.toLocalDateTime();
- }
-
- public UserAgent getUserAgent()
- {
- return this.userAgent;
- }
-
- /**
- * Gets the year.
- *
- * @return the year
- */
- public String getYear()
- {
- String result;
-
- if (this.time == null)
- {
- result = null;
- }
- else
- {
- result = TimeMarkUtils.yearOf(this.time);
- }
-
- //
- return result;
- }
-
- /**
- * Gets the year month.
- *
- * @return the year month
- */
- public String getYearMonth()
- {
- String result;
-
- if (this.time == null)
- {
- result = null;
- }
- else
- {
- result = TimeMarkUtils.yearMonthOf(this.time);
- }
- //
- return result;
- }
-
- /**
- * Gets the year week.
- *
- * @return the year week
- */
- public String getYearWeek()
- {
- String result;
- if (this.time == null)
- {
- result = null;
- }
- else
- {
- result = TimeMarkUtils.yearWeekOf(this.time);
- }
- //
- return result;
- }
-
- /**
- * Checks if is bot.
- *
- * @return true, if is bot
- */
- public boolean isBot()
- {
- boolean result;
-
- result = UserAgentBotDetector.isBot(this.userAgent.toString());
-
- //
- return result;
- }
-
- /**
- * Checks if is ipv4.
- *
- * @return true, if is ipv4
- */
- public boolean isIPv4()
- {
- boolean result;
-
- if (this.ip == null)
- {
- result = false;
- }
- else
- {
- result = this.ip.contains(".");
- }
-
- //
- return result;
- }
-
- /**
- * Checks if is ipv6.
- *
- * @return true, if is ipv6
- */
- public boolean isIPv6()
- {
- boolean result;
-
- if (this.ip == null)
- {
- result = false;
- }
- else
- {
- result = this.ip.contains(":");
- }
-
- //
- return result;
- }
-
- /**
- * Checks if is visit.
- *
- * @return true, if is visit
- */
- public boolean isVisit()
- {
- boolean result;
-
- if ((this.status.getCategory() == HttpStatusCategory.SUCCESS) && (!isBot()) && (this.request.startsWith("GET ")) &&
- (!ASSET_PATTERN.matcher(this.request).matches()))
- {
- result = true;
- }
- else
- {
- result = false;
- }
-
- //
- return result;
- }
-
- public void setBodyBytesSent(final long bodyBytesSent)
- {
- this.bodyBytesSent = bodyBytesSent;
- }
-
- public void setIp(final String ip)
- {
- this.ip = ip;
- }
-
- public void setReferer(final String referer)
- {
- this.referer = referer;
- }
-
- public void setRemoteUser(final String remoteUser)
- {
- this.remoteUser = remoteUser;
- }
-
- public void setRequest(final String request)
- {
- this.request = request;
- }
-
- public void setStatus(final HttpStatus status)
- {
- this.status = status;
- }
-
- /**
- * Sets the time.
- *
- * @param time
- * the new time
- */
- public void setTime(final LocalDateTime time)
- {
- this.time = ZonedDateTime.of(time, ZoneId.systemDefault());
- }
-
- public void setTime(final ZonedDateTime time)
- {
- this.time = time;
- }
-
- public void setUserAgent(final UserAgent userAgent)
- {
- this.userAgent = userAgent;
- }
-
- /**
- * To string.
- *
- * @return the string
- */
- @Override
- public String toString()
- {
- String result;
-
- StringList buffer = new StringList();
-
- buffer.append("[ip=").append(this.ip).append("]");
- buffer.append("[remoteUser=").append(this.remoteUser).append("]");
- buffer.append("[time=").append(this.time).append("]");
- buffer.append("[request=").append(this.request).append("]");
- buffer.append("[status=").append(this.status.getCode()).append("]");
- buffer.append("[bodyBytesSent=").append(this.bodyBytesSent).append("]");
- buffer.append("[referer=").append(this.referer).append("]");
- buffer.append("[userAgent=").append(this.userAgent).append("]");
-
- result = buffer.toString();
-
- //
- return result;
- }
-
- /**
- * To string log.
- *
- * @return the string
- */
- public String toStringLog()
- {
- String result;
-
- // "^(?[a-zA-F0-9\\\\:\\\\.]+) - (?[^\\[]+)
- // \\[(?[^\\]]+)\\] \"(?.*)\" (?\\d+)
- // (?\\d+) \"(?.*)\"
- // \"(?[^\"]*)\".*$");
-
- // result = String.format("%s %s %s \\[%s\\] \"%s\" %d %d \"%s\"
- // \"%s\"",
- result = String.format("%s - %s [%s] \"%s\" %d %d \"%s\" \"%s\"",
- this.ip,
- this.remoteUser,
- this.time.format(DateTimeFormatter.ofPattern("dd/MMM/yyyy:HH:mm:ss Z", Locale.ENGLISH)),
- this.request,
- this.status.getCode(),
- this.bodyBytesSent,
- this.referer,
- this.userAgent);
-
- //
- return result;
- }
-}
diff --git a/src/fr/devinsy/statoolinfos/metrics/httpaccess/HttpAccessLogAnalyzer.java b/src/fr/devinsy/statoolinfos/metrics/httpaccess/HttpAccessLogAnalyzer.java
deleted file mode 100644
index 12a8f8c..0000000
--- a/src/fr/devinsy/statoolinfos/metrics/httpaccess/HttpAccessLogAnalyzer.java
+++ /dev/null
@@ -1,383 +0,0 @@
-/*
- * Copyright (C) 2020-2024 Christian Pierre MOMON
- *
- * This file is part of StatoolInfos, simple service statistics tool.
- *
- * StatoolInfos is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * StatoolInfos is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with StatoolInfos. If not, see .
- */
-package fr.devinsy.statoolinfos.metrics.httpaccess;
-
-import java.io.IOException;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-import org.apache.commons.lang3.StringUtils;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import fr.devinsy.statoolinfos.core.StatoolInfosException;
-import fr.devinsy.statoolinfos.metrics.IpCounters;
-import fr.devinsy.statoolinfos.metrics.PathCounters;
-import fr.devinsy.strings.StringList;
-
-/**
- * The Class HttpAccessLogProber.
- */
-public class HttpAccessLogAnalyzer
-{
- private static Logger logger = LoggerFactory.getLogger(HttpAccessLogAnalyzer.class);
-
- private int ignoredLineCount;
- private int errorCount;
- private PathCounters counters;
- private IpCounters ips;
- private IpCounters ipv4;
- private IpCounters ipv6;
- private IpCounters botIps;
- private IpCounters humanIps;
- private VisitorCounters requesters;
- private VisitorCounters ipv4Requesters;
- private VisitorCounters ipv6Requesters;
- private VisitorCounters botRequesters;
- private VisitorCounters humanRequesters;
- private VisitCounters visits;
- private VisitCounters ipv4Visits;
- private VisitCounters ipv6Visits;
- private VisitorCounters visitors;
- private VisitorCounters ipv4Visitors;
- private VisitorCounters ipv6Visitors;
-
- /**
- * Instantiates a new http access log prober.
- */
- public HttpAccessLogAnalyzer()
- {
- this.errorCount = 0;
- this.ignoredLineCount = 0;
-
- this.counters = new PathCounters();
- this.ips = new IpCounters();
- this.ipv4 = new IpCounters();
- this.ipv6 = new IpCounters();
- this.botIps = new IpCounters();
- this.humanIps = new IpCounters();
-
- this.requesters = new VisitorCounters();
- this.ipv4Requesters = new VisitorCounters();
- this.ipv6Requesters = new VisitorCounters();
- this.humanRequesters = new VisitorCounters();
- this.botRequesters = new VisitorCounters();
-
- this.visits = new VisitCounters();
- this.ipv4Visits = new VisitCounters();
- this.ipv6Visits = new VisitCounters();
-
- this.visitors = new VisitorCounters();
- this.ipv4Visitors = new VisitorCounters();
- this.ipv6Visitors = new VisitorCounters();
- }
-
- /**
- * Gets the counters.
- *
- * @return the counters
- */
- public PathCounters getCounters()
- {
- PathCounters result;
-
- result = new PathCounters();
- result.putAll(this.counters);
-
- result.putAll(this.ips.getCounters("metrics.http.ip"));
- result.putAll(this.ipv4.getCounters("metrics.http.ip.ipv4"));
- result.putAll(this.ipv6.getCounters("metrics.http.ip.ipv6"));
- result.putAll(this.botIps.getCounters("metrics.http.ip.bots"));
- result.putAll(this.humanIps.getCounters("metrics.http.ip.humans"));
-
- result.putAll(this.requesters.getCounters("metrics.http.requesters"));
- result.putAll(this.ipv4Requesters.getCounters("metrics.http.requesters.ipv4"));
- result.putAll(this.ipv6Requesters.getCounters("metrics.http.requesters.ipv6"));
- result.putAll(this.botRequesters.getCounters("metrics.http.requesters.bots"));
- result.putAll(this.humanRequesters.getCounters("metrics.http.requesters.humans"));
-
- result.putAll(this.visits.getCounters("metrics.http.visits"));
- result.putAll(this.ipv4Visits.getCounters("metrics.http.visits.ipv4"));
- result.putAll(this.ipv6Visits.getCounters("metrics.http.visits.ipv6"));
-
- result.putAll(this.visitors.getCounters("metrics.http.visitors"));
- result.putAll(this.ipv4Visitors.getCounters("metrics.http.visitors.ipv4"));
- result.putAll(this.ipv6Visitors.getCounters("metrics.http.visitors.ipv6"));
-
- //
- return result;
- }
-
- /**
- * Probe log.
- *
- * @param log
- * the log
- */
- public void probeLog(final HttpAccessLog log)
- {
- // logger.info("==================");
- if (log != null)
- {
- // logger.info("LINE IS MATCHING [{}]", log);
- // logger.info(log.getHttpUserAgent().toString());
-
- // General HTTP access logs.
- String year = log.getYear();
- String yearMonth = log.getYearMonth();
- String yearWeek = log.getYearWeek();
- String date = log.getDate();
-
- // metrics.http.hits
- // metrics.http.hits.ipv4
- // metrics.http.hits.ipv6
- this.counters.inc("metrics.http.hits", year, yearMonth, yearWeek, date);
-
- if (log.isIPv4())
- {
- this.counters.inc("metrics.http.hits.ipv4", year, yearMonth, yearWeek, date);
- }
- else
- {
- this.counters.inc("metrics.http.hits.ipv6", year, yearMonth, yearWeek, date);
- }
-
- // metrics.http.files
- if (log.getBodyBytesSent() != 0)
- {
- this.counters.inc("metrics.http.files", year, yearMonth, yearWeek, date);
- }
-
- // metrics.http.bytes
- this.counters.inc(log.getBodyBytesSent(), "metrics.http.bytes", year, yearMonth, yearWeek, date);
-
- // metrics.http.hits.bots.* =
- if (log.isBot())
- {
- this.counters.inc("metrics.http.hits.bots", year, yearMonth, yearWeek, date);
- }
- else
- {
- // metrics.http.hits.humans.*
- this.counters.inc("metrics.http.hits.humans", year, yearMonth, yearWeek, date);
-
- if (log.isIPv4())
- {
- // metrics.http.hits.humans.ipv4.*
- this.counters.inc("metrics.http.hits.humans.ipv4", year, yearMonth, yearWeek, date);
- }
- else
- {
- // metrics.http.hits.humans.ipv6.*
- this.counters.inc("metrics.http.hits.humans.ipv6", year, yearMonth, yearWeek, date);
- }
- }
-
- // metrics.http.pages.* =
- if ((log.getStatus().getCategory() == HttpStatusCategory.SUCCESS) && (isPage(log.getRequest())))
- {
- this.counters.inc("metrics.http.pages", year, yearMonth, yearWeek, date);
- }
-
- // metrics.http.ip.* =
- this.ips.put(log.getIp(), year, yearMonth, yearWeek, date);
-
- // metrics.http.ip.ipv4.* =
- // metrics.http.ip.ipv6.* =
- if (log.isIPv4())
- {
- this.ipv4.put(log.getIp(), year, yearMonth, yearWeek, date);
- }
- else
- {
- this.ipv6.put(log.getIp(), year, yearMonth, yearWeek, date);
- }
-
- // metrics.http.ip.bots.*
- // metrics.http.ip.humans.*
- if (log.isBot())
- {
- this.botIps.put(log.getIp(), year, yearMonth, yearWeek, date);
- }
- else
- {
- this.humanIps.put(log.getIp(), year, yearMonth, yearWeek, date);
- }
-
- // metrics.http.requesters.* =
- this.requesters.put(log.getIp(), log.getUserAgent(), year, yearMonth, yearWeek, date);
-
- // metrics.http.requesters.ipv4.* =
- // metrics.http.requesters.ipv6.* =
- if (log.isIPv4())
- {
- this.ipv4Requesters.put(log.getIp(), log.getUserAgent(), year, yearMonth, yearWeek, date);
- }
- else
- {
- this.ipv6Requesters.put(log.getIp(), log.getUserAgent(), year, yearMonth, yearWeek, date);
- }
-
- // metrics.http.requesters.bots.*
- // metrics.http.requesters.humans.*
- if (log.isBot())
- {
- this.botRequesters.put(log.getIp(), log.getUserAgent(), year, yearMonth, yearWeek, date);
- }
- else
- {
- this.humanRequesters.put(log.getIp(), log.getUserAgent(), year, yearMonth, yearWeek, date);
- }
-
- // metrics.http.visits.* =
- // metrics.http.visits.ipv4.* =
- // metrics.http.visits.ipv6.* =
- // metrics.http.visitors.* =
- // metrics.http.visitors.ipv4.* =
- // metrics.http.visitors.ipv6.* =
- if (log.isVisit())
- {
- // metrics.http.visits.* =
- // metrics.http.visits.ipv4.* =
- // metrics.http.visits.ipv6.* =
- this.visits.putVisit(log);
- this.visits.storeTimeMarks(year, yearMonth, yearWeek, date);
-
- if (log.isIPv4())
- {
- this.ipv4Visits.putVisit(log);
- this.ipv4Visits.storeTimeMarks(year, yearMonth, yearWeek, date);
- }
- else
- {
- this.ipv6Visits.putVisit(log);
- this.ipv6Visits.storeTimeMarks(year, yearMonth, yearWeek, date);
- }
-
- // metrics.http.visitors.* =
- // metrics.http.visitors.ipv4.* =
- // metrics.http.visitors.ipv6.* =
- this.visitors.put(log.getIp(), log.getUserAgent(), year, yearMonth, yearWeek, date);
-
- if (log.isIPv4())
- {
- this.ipv4Visitors.put(log.getIp(), log.getUserAgent(), year, yearMonth, yearWeek, date);
- }
- else
- {
- this.ipv6Visitors.put(log.getIp(), log.getUserAgent(), year, yearMonth, yearWeek, date);
- }
- }
-
- // metrics.http.methods.XXXX
- String method = log.getMethod().toString();
- this.counters.inc("metrics.http.methods." + method, year, yearMonth, yearWeek, date);
-
- // metrics.http.status.XXXX
- String status = String.valueOf(log.getStatus().getCode());
- this.counters.inc("metrics.http.status." + status, year, yearMonth, yearWeek, date);
-
- // metrics.http.os.XXXXX
- UserAgentOS os = log.getUserAgent().getOS();
- this.counters.inc("metrics.http.os." + os.toString().toLowerCase(), year, yearMonth, yearWeek, date);
-
- // metrics.http.browsers.XXXXX
- UserAgentBrowser browser = log.getUserAgent().getBrowser();
- this.counters.inc("metrics.http.browsers." + browser.toString().toLowerCase(), year, yearMonth, yearWeek, date);
-
- // metrics.http.devices.XXXXX =
- UserAgentDevice device = log.getUserAgent().getDevice();
- this.counters.inc("metrics.http.devices." + device.toString().toLowerCase(), year, yearMonth, yearWeek, date);
-
- // metrics.http.countries.XX =
- }
- }
-
- /**
- * Checks if is page.
- *
- * @param request
- * the request
- * @return true, if is page
- */
- public static boolean isPage(final String request)
- {
- boolean result;
-
- if (StringUtils.isBlank(request))
- {
- result = false;
- }
- else
- {
- Pattern PAGE_PATTERN = Pattern.compile("^.* (?/[^ \\?]*)(\\?.*| .*)?$");
-
- Matcher matcher = PAGE_PATTERN.matcher(request);
- if (matcher.find())
- {
- String path = matcher.group("path").toLowerCase();
-
- result = path.matches("^.*(/|/[^/]*\\.html|/[^/]*\\.htm|/[^/]*\\.xhtml|/[^/]*\\.cgi|/[^/]*\\.php|/[^/\\.]*[a-z0-9])$");
-
- // System.out.println(result + " [" + path + "] [" + request +
- // "]");
- }
- else
- {
- result = false;
- }
- }
-
- //
- return result;
- }
-
- /**
- * Probe.
- *
- * @param logs
- * the logs
- * @return the path counters
- * @throws IOException
- * Signals that an I/O exception has occurred.
- * @throws StatoolInfosException
- * the statool infos exception
- */
- public static PathCounters probe(final HttpAccessLogs logs) throws IOException, StatoolInfosException
- {
- PathCounters result;
-
- HttpAccessLogAnalyzer analyzer = new HttpAccessLogAnalyzer();
-
- HttpAccessLogIterator logIterator = (HttpAccessLogIterator) logs.iterator();
- while (logIterator.hasNext())
- {
- analyzer.probeLog(logIterator.next());
- }
- result = analyzer.getCounters();
-
- StringList timemarks = result.getNowTimeMarks();
- analyzer.getCounters().set(logIterator.getLogCount(), "metrics.http.logs.count", timemarks);
- analyzer.getCounters().set(logIterator.getIgnoredLogCount(), "metrics.http.logs.ignored", timemarks);
- analyzer.getCounters().set(logIterator.getFailedLogCount(), "metrics.http.logs.failed", timemarks);
-
- //
- return result;
- }
-}
diff --git a/src/fr/devinsy/statoolinfos/metrics/httpaccess/HttpAccessLogIterator.java b/src/fr/devinsy/statoolinfos/metrics/httpaccess/HttpAccessLogIterator.java
deleted file mode 100644
index 7fef2ed..0000000
--- a/src/fr/devinsy/statoolinfos/metrics/httpaccess/HttpAccessLogIterator.java
+++ /dev/null
@@ -1,257 +0,0 @@
-/*
- * Copyright (C) 2022-2024 Christian Pierre MOMON
- *
- * This file is part of StatoolInfos, simple service statistics tool.
- *
- * StatoolInfos is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * StatoolInfos is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with StatoolInfos. If not, see .
- */
-package fr.devinsy.statoolinfos.metrics.httpaccess;
-
-import java.io.IOException;
-import java.time.format.DateTimeFormatter;
-import java.util.Iterator;
-import java.util.Locale;
-import java.util.regex.Pattern;
-
-import org.apache.commons.lang3.StringUtils;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import fr.devinsy.statoolinfos.util.Files;
-import fr.devinsy.statoolinfos.util.FilesLineIterator;
-
-/**
- * The Class HttpAccessLogIterator.
- */
-public class HttpAccessLogIterator implements Iterator
-{
- private static Logger logger = LoggerFactory.getLogger(HttpAccessLogIterator.class);
-
- private FilesLineIterator lineIterator;
- private Pattern pattern;
- private DateTimeFormatter dateTimeFormatter;
- private Pattern requestFilter;
- private HttpAccessLog nextLog;
- private int logCount;
- private int ignoredLogCount;
- private int failedLogCount;
-
- /**
- * Instantiates a new http access log iterator.
- *
- * @param source
- * the source
- * @throws IOException
- * Signals that an I/O exception has occurred.
- */
- public HttpAccessLogIterator(final Files source) throws IOException
- {
- this(source, null, null, null);
- }
-
- /**
- * Instantiates a new http access log iterator.
- *
- * @param source
- * the source
- * @param regex
- * the regex
- * @throws IOException
- * Signals that an I/O exception has occurred.
- */
- public HttpAccessLogIterator(final Files source, final String regex) throws IOException
- {
- this(source, regex, null, null);
- }
-
- /**
- * Instantiates a new http access log iterator.
- *
- * @param source
- * the source
- * @param linePattern
- * the line pattern
- * @param dateTimePattern
- * the date time pattern
- * @param pathFilter
- * the path filter
- * @throws IOException
- * Signals that an I/O exception has occurred.
- */
- public HttpAccessLogIterator(final Files source, final String linePattern, final String dateTimePattern, final String pathFilter) throws IOException
- {
- this.lineIterator = new FilesLineIterator(source);
- this.nextLog = null;
- this.logCount = 0;
- this.ignoredLogCount = 0;
- this.failedLogCount = 0;
-
- if (StringUtils.isBlank(linePattern))
- {
- this.pattern = HttpAccessLogParser.COMBINED_PATTERN;
- }
- else
- {
- this.pattern = Pattern.compile(linePattern);
- }
-
- if (StringUtils.isBlank(dateTimePattern))
- {
- this.dateTimeFormatter = HttpAccessLogParser.DATETIME_FORMATTER;
- }
- else
- {
- String[] split = dateTimePattern.split("\\|");
- if (split.length != 2)
- {
- throw new IllegalArgumentException("Bad dateTimePattern format: [" + dateTimePattern + "].");
- }
- else
- {
- this.dateTimeFormatter = DateTimeFormatter.ofPattern(split[0]).withLocale(Locale.forLanguageTag(split[1]));
- }
- }
-
- if (StringUtils.isBlank(pathFilter))
- {
- this.requestFilter = null;
- }
- else
- {
- String filter = "^\\S+ " + pathFilter + " .*$";
- System.out.println("requestFilter=" + filter);
- this.requestFilter = Pattern.compile(filter);
- }
- }
-
- /**
- * Gets the failed log count.
- *
- * @return the failed log count
- */
- public int getFailedLogCount()
- {
- return this.failedLogCount;
- }
-
- /**
- * Gets the ignored log count.
- *
- * @return the ignored log count
- */
- public int getIgnoredLogCount()
- {
- return this.ignoredLogCount;
- }
-
- /**
- * Gets the log count.
- *
- * @return the log count
- */
- public int getLogCount()
- {
- return this.logCount;
- }
-
- /* (non-Javadoc)
- * @see java.util.Iterator#hasNext()
- */
- @Override
- public boolean hasNext()
- {
- boolean result;
-
- preload();
-
- if (this.nextLog == null)
- {
- result = false;
- }
- else
- {
- result = true;
- }
-
- //
- return result;
- }
-
- /* (non-Javadoc)
- * @see java.util.Iterator#next()
- */
- @Override
- public HttpAccessLog next()
- {
- HttpAccessLog result;
-
- preload();
-
- result = this.nextLog;
- this.nextLog = null;
-
- //
- return result;
- }
-
- /**
- * Forward.
- */
- private void preload()
- {
- if (this.nextLog == null)
- {
- boolean ended = false;
- while (!ended)
- {
- if (this.lineIterator.hasNext())
- {
- String line = this.lineIterator.next();
- this.logCount += 1;
-
- try
- {
- HttpAccessLog log = HttpAccessLogParser.parseLog(line, this.pattern, this.dateTimeFormatter);
- if (log == null)
- {
- logger.warn("LINE IS NOT MATCHING [{}]", line);
- this.failedLogCount += 1;
- }
- else if ((this.requestFilter == null) || (this.requestFilter.matcher(log.getRequest()).matches()))
- {
- this.nextLog = log;
- ended = true;
- }
- else
- {
- this.ignoredLogCount += 1;
- // System.out.println("XX " + log.getRequest());
- }
- }
- catch (Exception exception)
- {
- logger.warn("Error parsing line [{}][{}]", line, exception.getMessage());
- this.failedLogCount += 1;
- // exception.printStackTrace();
- }
- }
- else
- {
- this.nextLog = null;
- ended = true;
- }
- }
- }
- }
-}
diff --git a/src/fr/devinsy/statoolinfos/metrics/httpaccess/HttpAccessLogParser.java b/src/fr/devinsy/statoolinfos/metrics/httpaccess/HttpAccessLogParser.java
deleted file mode 100644
index 7189f5f..0000000
--- a/src/fr/devinsy/statoolinfos/metrics/httpaccess/HttpAccessLogParser.java
+++ /dev/null
@@ -1,139 +0,0 @@
-/*
- * Copyright (C) 2020-2024 Christian Pierre MOMON
- *
- * This file is part of StatoolInfos, simple service statistics tool.
- *
- * StatoolInfos is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * StatoolInfos is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with StatoolInfos. If not, see .
- */
-package fr.devinsy.statoolinfos.metrics.httpaccess;
-
-import java.time.LocalDateTime;
-import java.time.ZonedDateTime;
-import java.time.format.DateTimeFormatter;
-import java.time.format.DateTimeParseException;
-import java.util.Locale;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * The Class HttpAccessLogParser.
- */
-public class HttpAccessLogParser
-{
- private static Logger logger = LoggerFactory.getLogger(HttpAccessLogParser.class);
-
- // log_format combined '$remote_addr - $remote_user [$time_local] '
- // '"$request" $status $body_bytes_sent '
- // '"$http_referer" "$http_user_agent"';
- public static final Pattern COMBINED_PATTERN = Pattern.compile(
- "^(?[a-fA-F0-9\\:\\.]+) - (?[^\\[]+) \\[(?