[DEV] migrate karideo java

This commit is contained in:
Edouard DUPIN 2020-10-25 00:39:52 +02:00
parent 06039dbe12
commit 80f8e81dcb
87 changed files with 4540 additions and 4506 deletions

9
back/.gitignore vendored
View File

@ -1,9 +0,0 @@
#config.*
config.env
.env
config
data
cache
__pycache__
*.pyc

66
back/CheckStyle.xml Executable file
View File

@ -0,0 +1,66 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE module PUBLIC "-//Checkstyle//DTD Check Configuration 1.3//EN" "https://checkstyle.org/dtds/configuration_1_3.dtd">
<!--
This configuration file was written by the eclipse-cs plugin configuration editor
-->
<!--
Checkstyle-Configuration: Marc Checks
Description:
Checkstyle configuration that checks the sun coding conventions.
-->
<module name="Checker">
<property name="severity" value="error"/>
<property name="fileExtensions" value="java, properties, xml"/>
<module name="TreeWalker">
<module name="ConstantName"/>
<module name="LocalFinalVariableName"/>
<module name="LocalVariableName"/>
<module name="MemberName"/>
<module name="MethodName"/>
<module name="PackageName"/>
<module name="ParameterName"/>
<module name="StaticVariableName"/>
<module name="TypeName"/>
<module name="AvoidStarImport"/>
<module name="IllegalImport"/>
<module name="RedundantImport"/>
<module name="UnusedImports">
<property name="processJavadoc" value="false"/>
</module>
<module name="ModifierOrder"/>
<module name="EmptyStatement"/>
<module name="EqualsHashCode"/>
<module name="IllegalInstantiation"/>
<module name="MissingSwitchDefault"/>
<module name="SimplifyBooleanExpression"/>
<module name="SimplifyBooleanReturn"/>
<module name="HideUtilityClassConstructor"/>
<module name="InterfaceIsType"/>
<module name="ArrayTypeStyle"/>
<module name="TodoComment"/>
<module name="UpperEll"/>
<module name="AnnotationUseStyle"/>
<module name="MissingDeprecated"/>
<module name="MissingOverride"/>
<module name="PackageAnnotation"/>
<module name="SuppressWarnings"/>
<module name="AnnotationLocation"/>
<module name="ClassTypeParameterName"/>
<module name="MethodTypeParameterName"/>
<module name="InterfaceTypeParameterName"/>
<module name="CatchParameterName"/>
<module name="LambdaParameterName"/>
<module name="Regexp"/>
<module name="RegexpSinglelineJava"/>
</module>
<module name="BeforeExecutionExclusionFileFilter">
<property name="fileNamePattern" value="module\-info\.java$"/>
</module>
<module name="Translation"/>
<module name="Header"/>
<module name="RegexpHeader"/>
<module name="RegexpMultiline"/>
<module name="RegexpOnFilename"/>
<module name="RegexpSingleline"/>
</module>

66
back/CleanUp.xml Normal file
View File

@ -0,0 +1,66 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE xml>
<profiles version="2">
<profile kind="CleanUpProfile" name="Scenarium" version="2">
<setting id="cleanup.use_autoboxing" value="false"/>
<setting id="cleanup.qualify_static_method_accesses_with_declaring_class" value="false"/>
<setting id="cleanup.always_use_this_for_non_static_method_access" value="false"/>
<setting id="cleanup.organize_imports" value="true"/>
<setting id="cleanup.remove_trailing_whitespaces_ignore_empty" value="false"/>
<setting id="cleanup.format_source_code_changes_only" value="false"/>
<setting id="cleanup.qualify_static_field_accesses_with_declaring_class" value="false"/>
<setting id="cleanup.add_generated_serial_version_id" value="false"/>
<setting id="cleanup.remove_redundant_semicolons" value="false"/>
<setting id="cleanup.qualify_static_member_accesses_through_subtypes_with_declaring_class" value="true"/>
<setting id="cleanup.remove_redundant_type_arguments" value="true"/>
<setting id="cleanup.remove_unused_imports" value="true"/>
<setting id="cleanup.insert_inferred_type_arguments" value="false"/>
<setting id="cleanup.make_private_fields_final" value="true"/>
<setting id="cleanup.use_lambda" value="true"/>
<setting id="cleanup.always_use_blocks" value="false"/>
<setting id="cleanup.use_this_for_non_static_field_access_only_if_necessary" value="false"/>
<setting id="cleanup.sort_members_all" value="false"/>
<setting id="cleanup.remove_trailing_whitespaces_all" value="true"/>
<setting id="cleanup.add_missing_annotations" value="true"/>
<setting id="cleanup.always_use_this_for_non_static_field_access" value="true"/>
<setting id="cleanup.make_parameters_final" value="false"/>
<setting id="cleanup.sort_members" value="false"/>
<setting id="cleanup.remove_private_constructors" value="true"/>
<setting id="cleanup.always_use_parentheses_in_expressions" value="false"/>
<setting id="cleanup.remove_unused_local_variables" value="false"/>
<setting id="cleanup.convert_to_enhanced_for_loop" value="false"/>
<setting id="cleanup.remove_unused_private_fields" value="true"/>
<setting id="cleanup.remove_redundant_modifiers" value="false"/>
<setting id="cleanup.never_use_blocks" value="true"/>
<setting id="cleanup.add_missing_deprecated_annotations" value="true"/>
<setting id="cleanup.use_this_for_non_static_field_access" value="true"/>
<setting id="cleanup.remove_unnecessary_nls_tags" value="true"/>
<setting id="cleanup.qualify_static_member_accesses_through_instances_with_declaring_class" value="true"/>
<setting id="cleanup.add_missing_nls_tags" value="false"/>
<setting id="cleanup.remove_unnecessary_casts" value="true"/>
<setting id="cleanup.use_unboxing" value="false"/>
<setting id="cleanup.use_blocks_only_for_return_and_throw" value="false"/>
<setting id="cleanup.format_source_code" value="true"/>
<setting id="cleanup.convert_functional_interfaces" value="true"/>
<setting id="cleanup.add_default_serial_version_id" value="true"/>
<setting id="cleanup.remove_unused_private_methods" value="true"/>
<setting id="cleanup.remove_trailing_whitespaces" value="true"/>
<setting id="cleanup.make_type_abstract_if_missing_method" value="false"/>
<setting id="cleanup.add_serial_version_id" value="true"/>
<setting id="cleanup.use_this_for_non_static_method_access" value="false"/>
<setting id="cleanup.use_this_for_non_static_method_access_only_if_necessary" value="true"/>
<setting id="cleanup.use_anonymous_class_creation" value="false"/>
<setting id="cleanup.add_missing_override_annotations_interface_methods" value="true"/>
<setting id="cleanup.remove_unused_private_members" value="false"/>
<setting id="cleanup.make_local_variable_final" value="false"/>
<setting id="cleanup.add_missing_methods" value="false"/>
<setting id="cleanup.never_use_parentheses_in_expressions" value="true"/>
<setting id="cleanup.qualify_static_member_accesses_with_declaring_class" value="true"/>
<setting id="cleanup.use_parentheses_in_expressions" value="true"/>
<setting id="cleanup.add_missing_override_annotations" value="true"/>
<setting id="cleanup.use_blocks" value="true"/>
<setting id="cleanup.make_variable_declarations_final" value="true"/>
<setting id="cleanup.correct_indentation" value="true"/>
<setting id="cleanup.remove_unused_private_types" value="true"/>
</profile>
</profiles>

22
back/Dockerfile Normal file
View File

@ -0,0 +1,22 @@
FROM maven:3.6.3-openjdk-16 AS build
COPY pom.xml /tmp/
COPY src /tmp/src/
WORKDIR /tmp/
RUN mvn clean compile assembly:single
FROM bellsoft/liberica-openjdk-alpine:latest
ENV LANG=C.UTF-8
RUN mkdir /application/
COPY --from=build /tmp/out/maven/*.jar /application/application.jar
ADD scenarium-oauth.jar /application/
WORKDIR /application/
EXPOSE 18080
CMD ["java", "-cp", "/application/application.jar", "org.kar.oauth.WebLauncher"]

366
back/Formatter.xml Normal file
View File

@ -0,0 +1,366 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE xml>
<profiles version="18">
<profile kind="CodeFormatterProfile" name="Scenarium" version="18">
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_ellipsis" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_declarations" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_allocation_expression" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_at_in_annotation_type_declaration" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_for_statment" value="common_lines"/>
<setting id="org.eclipse.jdt.core.formatter.comment.new_lines_at_block_boundaries" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_logical_operator" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_parameters" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.insert_new_line_for_parameter" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_package" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_method_invocation" value="common_lines"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_enum_constant" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_after_imports" value="1"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_while" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.insert_new_line_before_root_tags" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_annotation_type_member_declaration" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_throws" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_switch_statement" value="common_lines"/>
<setting id="org.eclipse.jdt.core.formatter.comment.format_javadoc_comments" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.indentation.size" value="4"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_postfix_operator" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_enum_constant_declaration" value="common_lines"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_increments" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_arguments" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_arrow_in_switch_default" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_inits" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_for" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.align_with_spaces" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.disabling_tag" value="@formatter:off"/>
<setting id="org.eclipse.jdt.core.formatter.continuation_indentation" value="2"/>
<setting id="org.eclipse.jdt.core.formatter.number_of_blank_lines_before_code_block" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_switch_case_expressions" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_enum_constants" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_imports" value="1"/>
<setting id="org.eclipse.jdt.core.formatter.number_of_blank_lines_at_end_of_method_body" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_after_package" value="1"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_local_declarations" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_if_while_statement" value="common_lines"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_enum_constant" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_parameterized_type_reference" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.indent_root_tags" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.wrap_before_or_operator_multicatch" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.enabling_tag" value="@formatter:on"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_closing_brace_in_block" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.count_line_length_from_starting_position" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_return" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_method_declaration" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_parameter" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_arrow_in_switch_case" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.wrap_before_multiplicative_operator" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.keep_then_statement_on_same_line" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_field" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_explicitconstructorcall_arguments" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_prefix_operator" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_between_type_declarations" value="1"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_brace_in_array_initializer" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_for" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_catch" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_arguments" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_method" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_switch" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_parameterized_type_references" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_anonymous_type_declaration" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_logical_operator" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_parenthesized_expression" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.keep_annotation_declaration_on_one_line" value="one_line_if_empty"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_enum_constant" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_multiplicative_operator" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.never_indent_line_comments_on_first_column" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_and_in_type_parameter" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_inits" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.indent_statements_compare_to_block" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_anonymous_type_declaration" value="end_of_line"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_question_in_wildcard" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_invocation_arguments" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_switch" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.align_tags_descriptions_grouped" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.comment.line_length" value="200"/>
<setting id="org.eclipse.jdt.core.formatter.use_on_off_tags" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.keep_method_body_on_one_line" value="one_line_if_empty"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_brackets_in_array_allocation_expression" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.keep_loop_body_block_on_one_line" value="one_line_if_empty"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_constant" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_invocation" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_assignment_operator" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_type_declaration" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_for" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.preserve_white_space_between_code_and_line_comments" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_local_variable" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_method_declaration" value="end_of_line"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_abstract_method" value="1"/>
<setting id="org.eclipse.jdt.core.formatter.keep_enum_constant_declaration_on_one_line" value="one_line_if_empty"/>
<setting id="org.eclipse.jdt.core.formatter.align_variable_declarations_on_columns" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_invocation" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_union_type_in_multicatch" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_for" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.keep_type_declaration_on_one_line" value="one_line_if_empty"/>
<setting id="org.eclipse.jdt.core.formatter.number_of_blank_lines_at_beginning_of_method_body" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_arguments" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.keep_else_statement_on_same_line" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_catch_clause" value="common_lines"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_additive_operator" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_parameterized_type_reference" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_array_initializer" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_field_declarations" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_annotation" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_explicit_constructor_call" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_relational_operator" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_multiplicative_operator" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.keep_anonymous_type_declaration_on_one_line" value="one_line_if_empty"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_switch_case_expressions" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.wrap_before_shift_operator" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_annotation_declaration_header" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_superinterfaces" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_default" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_question_in_conditional" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_block" value="end_of_line"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_constructor_declaration" value="end_of_line"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_lambda_body" value="end_of_line"/>
<setting id="org.eclipse.jdt.core.formatter.number_of_blank_lines_at_end_of_code_block" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.compact_else_if" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_parameters" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_catch" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_invocation" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_bitwise_operator" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.put_empty_statement_on_new_line" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_type_parameters" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_invocation_arguments" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_method_invocation" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_constructor_declaration" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_compact_loops" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_block_comment" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_catch_in_try_statement" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_try" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.keep_simple_for_body_on_same_line" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_at_end_of_file_if_missing" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_javadoc_comment" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_relational_operator" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_array_initializer" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_unary_operator" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_expressions_in_array_initializer" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.format_line_comment_starting_on_first_column" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.number_of_empty_lines_to_preserve" value="1"/>
<setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_annotation" value="common_lines"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_case" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_ellipsis" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_additive_operator" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_try_resources" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_assert" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_if" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_arguments" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_and_in_type_parameter" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_string_concatenation" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_parenthesized_expression" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.format_line_comments" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_labeled_statement" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.text_block_indentation" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.align_type_members_on_columns" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_assignment" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_module_statements" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_type_header" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_declaration" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.number_of_blank_lines_after_code_block" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.comment.align_tags_names_descriptions" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_enum_constant" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_type_declaration" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.keep_if_then_body_block_on_one_line" value="one_line_if_empty"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_first_class_body_declaration" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_conditional_expression" value="80"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_closing_brace_in_array_initializer" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_parameters" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.format_guardian_clause_on_one_line" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_if" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.align_assignment_statements_on_columns" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_type" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_block" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_enum_declaration" value="end_of_line"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_block_in_case" value="end_of_line"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_arrow_in_switch_default" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_constructor_declaration" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.insert_new_line_between_different_tags" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_conditional_expression_chain" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.comment.format_header" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_additive_operator" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_invocation" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_while" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_switch" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_method_declaration" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.join_wrapped_lines" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_constructor_declaration" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.wrap_before_conditional_operator" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_cases" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_allocation_expression" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_synchronized" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_shift_operator" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.align_fields_grouping_blank_lines" value="2147483647"/>
<setting id="org.eclipse.jdt.core.formatter.comment.new_lines_at_javadoc_boundaries" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_bitwise_operator" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_annotation_type_declaration" value="end_of_line"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_for" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_resources_in_try" value="80"/>
<setting id="org.eclipse.jdt.core.formatter.use_tabs_only_for_leading_indentations" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_try_clause" value="common_lines"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_selector_in_method_invocation" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.never_indent_block_comments_on_first_column" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.keep_code_block_on_one_line" value="one_line_if_empty"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_synchronized" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_throws" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.tabulation.size" value="4"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_bitwise_operator" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_allocation_expression" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_reference" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_conditional" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.format_source_code" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_array_initializer" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_try" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_try_resources" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_field" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.continuation_indentation_for_array_initializer" value="2"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_question_in_wildcard" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_method" value="1"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_superclass_in_type_declaration" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_enum_declaration" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_throw" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.wrap_before_assignment_operator" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_labeled_statement" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_not_operator" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_switch" value="end_of_line"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_superinterfaces" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_parameters" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_type_annotation" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_brace_in_array_initializer" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_parenthesized_expression" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.format_html" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation_type_declaration" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_parameters" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_method_delcaration" value="common_lines"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_compact_if" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.keep_lambda_body_block_on_one_line" value="one_line_if_empty"/>
<setting id="org.eclipse.jdt.core.formatter.indent_empty_lines" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_type_arguments" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_parameterized_type_reference" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_unary_operator" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_enum_constant" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_annotation" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_declarations" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.keep_empty_array_initializer_on_one_line" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_switch" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_else_in_if_statement" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_assignment_operator" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_constructor_declaration" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_new_chunk" value="1"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_label" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_declaration_header" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_allocation_expression" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_constructor_declaration" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_conditional" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_parameterized_type_reference" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_parameters" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_arguments" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_cast" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_arrow_in_switch_case" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_assert" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_member_type" value="1"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_while_in_do_statement" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_logical_operator" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_type_reference" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_parameterized_type_reference" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_qualified_allocation_expression" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_opening_brace_in_array_initializer" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.indent_breaks_compare_to_cases" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_declaration" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.wrap_before_bitwise_operator" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_if" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_semicolon" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.wrap_before_relational_operator" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_postfix_operator" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_try" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_arguments" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_cast" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.format_block_comments" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_lambda_arrow" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_declaration" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.indent_tag_description" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.keep_imple_if_on_one_line" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_declaration" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_brackets_in_array_type_reference" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_parameters" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_string_concatenation" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_for" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_throws" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_allocation_expression" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_after_last_class_body_declaration" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.indent_statements_compare_to_body" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_multiple_fields" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_constant_arguments" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.keep_simple_while_body_on_same_line" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_prefix_operator" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_array_initializer" value="end_of_line"/>
<setting id="org.eclipse.jdt.core.formatter.wrap_before_logical_operator" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_shift_operator" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_method_declaration" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_parameters" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_catch" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_between_statement_group_in_switch" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_reference" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_annotation" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_constant_arguments" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_lambda_declaration" value="common_lines"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_shift_operator" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_braces_in_array_initializer" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_case" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_local_declarations" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.keep_simple_do_while_body_on_same_line" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_annotation_type_declaration" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_reference" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.keep_enum_declaration_on_one_line" value="one_line_if_empty"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_declaration" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.wrap_outer_expressions_when_nested" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_closing_paren_in_cast" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_enum_constant" value="end_of_line"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_type_declaration" value="end_of_line"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_multiplicative_operator" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_package" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_for" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_synchronized" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_increments" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation_type_member_declaration" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_expressions_in_for_loop_header" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.wrap_before_additive_operator" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.keep_simple_getter_setter_on_one_line" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_while" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_enum_constant" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_explicitconstructorcall_arguments" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_annotation" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_parameters" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_constant_header" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_string_concatenation" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_lambda_arrow" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_constructor_declaration" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_throws" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.join_lines_in_comments" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_parameters" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_question_in_conditional" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.indent_parameter_description" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.number_of_blank_lines_at_beginning_of_code_block" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_finally_in_try_statement" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.tabulation.char" value="tab"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_relational_operator" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_field_declarations" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.wrap_before_string_concatenation" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_between_import_groups" value="1"/>
<setting id="org.eclipse.jdt.core.formatter.lineSplit" value="200"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_annotation" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_switch" value="insert"/>
</profile>
</profiles>

6
back/LICENSE Normal file
View File

@ -0,0 +1,6 @@
PROPIETARY licence
==================
Copyright at Edouard DUPIN
you have no right

17
back/README.md Normal file
View File

@ -0,0 +1,17 @@
Generic backend for karideo in java
===================================
mvn install
// create a single package jar
mvn clean compile assembly:single
java -cp out/maven/karideo-0.1.0-jar-with-dependencies.jar org.kar.karideo.WebLauncher

View File

@ -1,9 +0,0 @@
# sample value with default config:
#DB_HOSTNAME=localhost
#DB_PORT=15032
#DB_NAME=karideo
#DB_USER=root
#DB_PASSWORD=postgress_password

View File

@ -1,19 +0,0 @@
version: "3.7"
services:
REST_video_service:
build: src
restart: always
image: yui.heero/video_rest_api
container_name: video_rest_api
ports:
- "15080:80"
volumes:
- /workspace/data/karideo/media:/application/data
- ./default_images:/default_images:ro
env_file:
- ./config.env

61
back/karideo-back.iml Normal file
View File

@ -0,0 +1,61 @@
<?xml version="1.0" encoding="UTF-8"?>
<module org.jetbrains.idea.maven.project.MavenProjectsManager.isMavenModule="true" type="JAVA_MODULE" version="4">
<component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_14">
<output url="file://$MODULE_DIR$/out/maven/classes" />
<output-test url="file://$MODULE_DIR$/out/maven/test-classes" />
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/test/src" isTestSource="true" />
<excludeFolder url="file://$MODULE_DIR$/out/maven" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="library" name="Maven: org.glassfish.jersey.media:jersey-media-multipart:2.32" level="project" />
<orderEntry type="library" name="Maven: org.glassfish.jersey.core:jersey-common:2.32" level="project" />
<orderEntry type="library" name="Maven: jakarta.annotation:jakarta.annotation-api:1.3.5" level="project" />
<orderEntry type="library" name="Maven: org.glassfish.hk2:osgi-resource-locator:1.0.3" level="project" />
<orderEntry type="library" name="Maven: com.sun.activation:jakarta.activation:1.2.2" level="project" />
<orderEntry type="library" name="Maven: org.jvnet.mimepull:mimepull:1.9.13" level="project" />
<orderEntry type="library" name="Maven: org.glassfish.jersey.inject:jersey-hk2:2.32" level="project" />
<orderEntry type="library" name="Maven: org.glassfish.hk2:hk2-locator:2.6.1" level="project" />
<orderEntry type="library" name="Maven: org.glassfish.hk2.external:aopalliance-repackaged:2.6.1" level="project" />
<orderEntry type="library" name="Maven: org.glassfish.hk2:hk2-api:2.6.1" level="project" />
<orderEntry type="library" name="Maven: org.glassfish.hk2:hk2-utils:2.6.1" level="project" />
<orderEntry type="library" name="Maven: org.javassist:javassist:3.25.0-GA" level="project" />
<orderEntry type="library" name="Maven: org.glassfish.jersey.containers:jersey-container-grizzly2-http:2.32" level="project" />
<orderEntry type="library" name="Maven: org.glassfish.hk2.external:jakarta.inject:2.6.1" level="project" />
<orderEntry type="library" name="Maven: org.glassfish.grizzly:grizzly-http-server:2.4.4" level="project" />
<orderEntry type="library" name="Maven: org.glassfish.grizzly:grizzly-http:2.4.4" level="project" />
<orderEntry type="library" name="Maven: org.glassfish.grizzly:grizzly-framework:2.4.4" level="project" />
<orderEntry type="library" name="Maven: org.glassfish.jersey.core:jersey-server:2.32" level="project" />
<orderEntry type="library" name="Maven: org.glassfish.jersey.core:jersey-client:2.32" level="project" />
<orderEntry type="library" name="Maven: org.glassfish.jersey.media:jersey-media-jaxb:2.32" level="project" />
<orderEntry type="library" name="Maven: jakarta.validation:jakarta.validation-api:2.0.2" level="project" />
<orderEntry type="library" name="Maven: jakarta.xml.bind:jakarta.xml.bind-api:2.3.3" level="project" />
<orderEntry type="library" name="Maven: jakarta.ws.rs:jakarta.ws.rs-api:2.1.6" level="project" />
<orderEntry type="library" name="Maven: javax.xml.bind:jaxb-api:2.3.1" level="project" />
<orderEntry type="library" name="Maven: javax.activation:javax.activation-api:1.2.0" level="project" />
<orderEntry type="library" name="Maven: javax.ws.rs:javax.ws.rs-api:2.1.1" level="project" />
<orderEntry type="library" name="Maven: com.sun.xml.bind:jaxb-impl:2.3.1" level="project" />
<orderEntry type="library" name="Maven: com.sun.istack:istack-commons-runtime:3.0.7" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.glassfish.jersey.test-framework.providers:jersey-test-framework-provider-grizzly2:2.32" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: jakarta.servlet:jakarta.servlet-api:4.0.3" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.glassfish.jersey.test-framework:jersey-test-framework-core:2.32" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.glassfish.jersey.containers:jersey-container-servlet-core:2.32" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.glassfish.jersey.containers:jersey-container-grizzly2-servlet:2.32" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.glassfish.jersey.containers:jersey-container-servlet:2.32" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.glassfish.grizzly:grizzly-http-servlet:2.4.4" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: junit:junit:4.12" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.hamcrest:hamcrest-core:1.3" level="project" />
<orderEntry type="library" name="Maven: mysql:mysql-connector-java:5.1.45" level="project" />
<orderEntry type="library" name="Maven: org.glassfish.jersey.media:jersey-media-json-jackson:2.32" level="project" />
<orderEntry type="library" name="Maven: org.glassfish.jersey.ext:jersey-entity-filtering:2.32" level="project" />
<orderEntry type="library" name="Maven: com.fasterxml.jackson.core:jackson-annotations:2.10.1" level="project" />
<orderEntry type="library" name="Maven: com.fasterxml.jackson.module:jackson-module-jaxb-annotations:2.10.1" level="project" />
<orderEntry type="library" name="Maven: jakarta.activation:jakarta.activation-api:1.2.1" level="project" />
<orderEntry type="library" name="Maven: com.fasterxml.jackson.core:jackson-databind:2.8.10" level="project" />
<orderEntry type="library" name="Maven: com.fasterxml.jackson.core:jackson-core:2.8.10" level="project" />
<orderEntry type="library" name="Maven: javax.servlet:javax.servlet-api:3.0.1" level="project" />
<orderEntry type="library" name="Maven: org.jetbrains:annotations:20.1.0" level="project" />
</component>
</module>

61
back/karideo.iml Normal file
View File

@ -0,0 +1,61 @@
<?xml version="1.0" encoding="UTF-8"?>
<module org.jetbrains.idea.maven.project.MavenProjectsManager.isMavenModule="true" type="JAVA_MODULE" version="4">
<component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_14">
<output url="file://$MODULE_DIR$/out/maven/classes" />
<output-test url="file://$MODULE_DIR$/out/maven/test-classes" />
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/test/src" isTestSource="true" />
<excludeFolder url="file://$MODULE_DIR$/out/maven" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="library" name="Maven: org.glassfish.jersey.media:jersey-media-multipart:2.32" level="project" />
<orderEntry type="library" name="Maven: org.glassfish.jersey.core:jersey-common:2.32" level="project" />
<orderEntry type="library" name="Maven: jakarta.annotation:jakarta.annotation-api:1.3.5" level="project" />
<orderEntry type="library" name="Maven: org.glassfish.hk2:osgi-resource-locator:1.0.3" level="project" />
<orderEntry type="library" name="Maven: com.sun.activation:jakarta.activation:1.2.2" level="project" />
<orderEntry type="library" name="Maven: org.jvnet.mimepull:mimepull:1.9.13" level="project" />
<orderEntry type="library" name="Maven: org.glassfish.jersey.inject:jersey-hk2:2.32" level="project" />
<orderEntry type="library" name="Maven: org.glassfish.hk2:hk2-locator:2.6.1" level="project" />
<orderEntry type="library" name="Maven: org.glassfish.hk2.external:aopalliance-repackaged:2.6.1" level="project" />
<orderEntry type="library" name="Maven: org.glassfish.hk2:hk2-api:2.6.1" level="project" />
<orderEntry type="library" name="Maven: org.glassfish.hk2:hk2-utils:2.6.1" level="project" />
<orderEntry type="library" name="Maven: org.javassist:javassist:3.25.0-GA" level="project" />
<orderEntry type="library" name="Maven: org.glassfish.jersey.containers:jersey-container-grizzly2-http:2.32" level="project" />
<orderEntry type="library" name="Maven: org.glassfish.hk2.external:jakarta.inject:2.6.1" level="project" />
<orderEntry type="library" name="Maven: org.glassfish.grizzly:grizzly-http-server:2.4.4" level="project" />
<orderEntry type="library" name="Maven: org.glassfish.grizzly:grizzly-http:2.4.4" level="project" />
<orderEntry type="library" name="Maven: org.glassfish.grizzly:grizzly-framework:2.4.4" level="project" />
<orderEntry type="library" name="Maven: org.glassfish.jersey.core:jersey-server:2.32" level="project" />
<orderEntry type="library" name="Maven: org.glassfish.jersey.core:jersey-client:2.32" level="project" />
<orderEntry type="library" name="Maven: org.glassfish.jersey.media:jersey-media-jaxb:2.32" level="project" />
<orderEntry type="library" name="Maven: jakarta.validation:jakarta.validation-api:2.0.2" level="project" />
<orderEntry type="library" name="Maven: jakarta.xml.bind:jakarta.xml.bind-api:2.3.3" level="project" />
<orderEntry type="library" name="Maven: jakarta.ws.rs:jakarta.ws.rs-api:2.1.6" level="project" />
<orderEntry type="library" name="Maven: javax.xml.bind:jaxb-api:2.3.1" level="project" />
<orderEntry type="library" name="Maven: javax.activation:javax.activation-api:1.2.0" level="project" />
<orderEntry type="library" name="Maven: javax.ws.rs:javax.ws.rs-api:2.1.1" level="project" />
<orderEntry type="library" name="Maven: com.sun.xml.bind:jaxb-impl:2.3.1" level="project" />
<orderEntry type="library" name="Maven: com.sun.istack:istack-commons-runtime:3.0.7" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.glassfish.jersey.test-framework.providers:jersey-test-framework-provider-grizzly2:2.32" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: jakarta.servlet:jakarta.servlet-api:4.0.3" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.glassfish.jersey.test-framework:jersey-test-framework-core:2.32" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.glassfish.jersey.containers:jersey-container-servlet-core:2.32" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.glassfish.jersey.containers:jersey-container-grizzly2-servlet:2.32" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.glassfish.jersey.containers:jersey-container-servlet:2.32" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.glassfish.grizzly:grizzly-http-servlet:2.4.4" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: junit:junit:4.12" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.hamcrest:hamcrest-core:1.3" level="project" />
<orderEntry type="library" name="Maven: mysql:mysql-connector-java:5.1.45" level="project" />
<orderEntry type="library" name="Maven: org.glassfish.jersey.media:jersey-media-json-jackson:2.32" level="project" />
<orderEntry type="library" name="Maven: org.glassfish.jersey.ext:jersey-entity-filtering:2.32" level="project" />
<orderEntry type="library" name="Maven: com.fasterxml.jackson.core:jackson-annotations:2.10.1" level="project" />
<orderEntry type="library" name="Maven: com.fasterxml.jackson.module:jackson-module-jaxb-annotations:2.10.1" level="project" />
<orderEntry type="library" name="Maven: jakarta.activation:jakarta.activation-api:1.2.1" level="project" />
<orderEntry type="library" name="Maven: com.fasterxml.jackson.core:jackson-databind:2.8.10" level="project" />
<orderEntry type="library" name="Maven: com.fasterxml.jackson.core:jackson-core:2.8.10" level="project" />
<orderEntry type="library" name="Maven: javax.servlet:javax.servlet-api:3.0.1" level="project" />
<orderEntry type="library" name="Maven: org.jetbrains:annotations:20.1.0" level="project" />
</component>
</module>

12
back/module-info.java Normal file
View File

@ -0,0 +1,12 @@
/** Basic module interface.
*
* @author Edouard DUPIN */
open module io.scenarium.store {
exports io.scenarium.oauth;
requires java.util;
requires javax.ws.rs.api;
requires java.xml.bind;
requires jackson.annotations;
requires jersey.server;
}

247
back/pom.xml Normal file
View File

@ -0,0 +1,247 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>kar</groupId>
<artifactId>karideo</artifactId>
<version>0.1.0</version>
<properties>
<jaxrs.version>2.1</jaxrs.version>
<jersey.version>2.32</jersey.version>
<jaxb.version>2.3.1</jaxb.version>
<istack.version>3.0.7</istack.version>
<maven.compiler.version>3.1</maven.compiler.version>
<maven.compiler.source>14</maven.compiler.source>
<maven.compiler.target>14</maven.compiler.target>
<maven.dependency.version>3.1.1</maven.dependency.version>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.glassfish.jersey</groupId>
<artifactId>jersey-bom</artifactId>
<version>${jersey.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<!-- https://mvnrepository.com/artifact/org.glassfish.jersey.media/jersey-media-multipart -->
<dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-multipart</artifactId>
<version>${jersey.version}</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.inject</groupId>
<artifactId>jersey-hk2</artifactId>
<version>${jersey.version}</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.containers</groupId>
<artifactId>jersey-container-grizzly2-http</artifactId>
<version>${jersey.version}</version>
</dependency>
<dependency>
<groupId>javax.xml.bind</groupId>
<artifactId>jaxb-api</artifactId>
<version>${jaxb.version}</version>
</dependency>
<dependency>
<groupId>javax.ws.rs</groupId>
<artifactId>javax.ws.rs-api</artifactId>
<version>2.1.1</version>
</dependency>
<dependency>
<groupId>com.sun.xml.bind</groupId>
<artifactId>jaxb-impl</artifactId>
<version>${jaxb.version}</version>
</dependency>
<dependency>
<groupId>com.sun.istack</groupId>
<artifactId>istack-commons-runtime</artifactId>
<version>${istack.version}</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.test-framework.providers</groupId>
<artifactId>jersey-test-framework-provider-grizzly2</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.45</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-json-jackson</artifactId>
<version>${jersey.version}</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.8.10</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.0.1</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.jetbrains</groupId>
<artifactId>annotations</artifactId>
<version>RELEASE</version>
<scope>compile</scope>
</dependency>
</dependencies>
<build>
<sourceDirectory>src</sourceDirectory>
<testSourceDirectory>test/src</testSourceDirectory>
<directory>${project.basedir}/out/maven/</directory>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>${maven.compiler.version}</version>
<configuration>
<source>${maven.compiler.source}</source>
<target>${maven.compiler.target}</target>
<!--<encoding>${project.build.sourceEncoding}</encoding>-->
</configuration>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>1.4.0</version>
<configuration>
<mainClass>io.scenarium.oauth.WebLauncher</mainClass>
</configuration>
</plugin>
<!-- Create the source bundle -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<executions>
<execution>
<id>attach-sources</id>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
<!-- junit results -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>3.0.0-M5</version>
</plugin>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<configuration>
<archive>
<manifest>
<mainClass>fully.qualified.MainClass</mainClass>
</manifest>
</archive>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
</configuration>
</plugin>
<!-- Create coverage -->
<!--
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>0.8.5</version>
<executions>
<execution>
<goals>
<goal>prepare-agent</goal>
</goals>
</execution>
<execution>
<id>report</id>
<phase>test</phase>
<goals>
<goal>report</goal>
</goals>
</execution>
</executions>
</plugin>
-->
<!-- Java-doc generation for stand-alone site -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>3.2.0</version>
<configuration>
<show>private</show>
<nohelp>true</nohelp>
</configuration>
</plugin>
<!-- Check the style of the code -->
<!--
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-checkstyle-plugin</artifactId>
<version>3.1.0</version>
<configuration>
<configLocation>CheckStyle.xml</configLocation>
<consoleOutput>true</consoleOutput>
<failOnViolation>true</failOnViolation>
<failsOnError>true</failsOnError>
<includeTestSourceDirectory>true</includeTestSourceDirectory>
</configuration>
</plugin>
<plugin>
<groupId>net.revelc.code.formatter</groupId>
<artifactId>formatter-maven-plugin</artifactId>
<version>2.12.2</version>
<configuration>
<encoding>UTF-8</encoding>
<lineEnding>LF</lineEnding>
<configFile>Formatter.xml</configFile>
<directories>
<directory>src/</directory>
<directory>test/src</directory>
</directories>
<includes>
<include>**/*.java</include>
</includes>
<excludes>
<exclude>module-info.java</exclude>
</excludes>
</configuration>
<executions>
<execution>
<goals>
<goal>validate</goal>
</goals>
</execution>
</executions>
</plugin>
-->
</plugins>
</build>
<!-- Generate Java-docs As Part Of Project Reports -->
<reporting>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>3.2.0</version>
<configuration>
<show>public</show>
</configuration>
</plugin>
</plugins>
</reporting>
</project>

View File

@ -1,63 +0,0 @@
REST video API
==============
REST API for video streaming for personal web / application interface
Download the project
====================
simply download the application:
```
mkdir WORKSPACE & cd $_
git clone http://xxx/HeeroYui/rest_video.git restvideo
cd rest_video
```
**Note:** It is important to remove ```-``` and ```_``` becose some docker remove these element in the network name _(like ubuntu ...)_
**Note:** The networkname of a docker compose is ```thefoldername_default```
Run the application
===================
Create configuration:
```
cp config_sample.env config.env
# set your server IP in the hostname
vim config.env
```
Start the application:
```
docker-compose up -d
```
Stop the application:
```
docker-compose down
```
Restart the application (on the fly):
```
docker-compose up -d --force-recreate --build
```
Run the application (debug)
===========================
before the first run:
```
cp -r data_base data
```
```
./src/app_video.py
```
or
```
SANIC_REST_PORT=15080 ./src/app_video.py
```

View File

@ -0,0 +1,17 @@
FROM bellsoft/liberica-openjdk-alpine:latest
ENV LANG=C.UTF-8
#ENV JAVA_HOME=/usr/lib/jvm/java-14-openjdk
#ENV JAVAFX_HOME=$JAVA_HOME
#ENV PATH=/usr/lib/jvm/java-14-openjdk/bin/:$PATH
#ENV JAVA_VERSION=14.0.2
RUN mkdir /application/
ADD karideo.jar /application/
WORKDIR /application/
EXPOSE 18080
CMD ["java", "-cp", "/application/karideo.jar", "org.kar.karideo.WebLauncher"]

View File

@ -0,0 +1,12 @@
version: '3'
services:
karideo_back_service_2:
build: .
restart: always
image: org.kar/karideo
container_name: org.kar.karideo
ports:
- 22080:18080
volumes:
- ./properties.txt:/application/properties.txt
- /workspace/data/karideo/media:/application/data

Binary file not shown.

View File

@ -0,0 +1,9 @@
org.kar.karideo.dataTmpFolder=/application/data/tmp
org.kar.karideo.dataTmpFolder=/application/data/media
org.kar.karideo.rest.oauth=http://192.168.1.156:21080/oauth/api/
org.kar.karideo.db.host=1992.156.1.156
org.kar.karideo.db.port=20306
org.kar.karideo.db.login=root
org.kar.karideo.db.port=klkhj456gkgtkhjgvkujfhjgkjhgsdfhb3467465fgdhdesfgh
org.kar.karideo.db.name=karideo
org.kar.karideo.address=http://0.0.0.0:18080/karideo/api/

View File

@ -1,36 +0,0 @@
FROM python:alpine3.6
RUN apk update && \
apk upgrade && \
apk add --update-cache \
--repository http://dl-cdn.alpinelinux.org/alpine/edge/community \
--repository http://dl-cdn.alpinelinux.org/alpine/edge/main \
--repository http://dl-cdn.alpinelinux.org/alpine/edge/testing \
build-base mediainfo postgresql-dev gcc python3-dev musl-dev
RUN pip3 install --upgrade pip
RUN pip3 install sanic==19.9.0
RUN pip3 install sanic-cors
RUN pip3 install sanic-simple-swagger
RUN pip3 install python-dateutil
RUN pip3 install realog
RUN pip3 install python-magic
RUN pip3 install pymediainfo
RUN pip3 install psycopg2
EXPOSE 80
ADD . /application/
WORKDIR /application/
CMD ["python3", "-u", "./app_video.py"]

View File

@ -1,189 +0,0 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
##
## @author Edouard DUPIN
##
## @copyright 2019, Edouard DUPIN, all right reserved
##
## @license MPL v2.0 (see license file)
##
import time
import json
import os
import sys
import datetime
import time, threading
import realog.debug as debug
from aiofiles import os as async_os
from pymediainfo import MediaInfo
from sanic import Sanic
from sanic import response
from sanic import views
from sanic import Blueprint
from sanic.exceptions import ServerError
from sanic.response import file_stream
from sanic_simple_swagger import swagger_blueprint, openapi_blueprint
from sanic_simple_swagger import doc
import tools
import data_interface
import data_global_elements
import hashlib
import shutil
import random
tmp_value = 0
#curl -F 'file=@Totally_Spies.mp4;type=application/octet-stream' -H 'transfer-encoding:chunked' 127.0.0.1:15080/data -X POST -O; echo ;
def add(_app, _name_api):
elem_blueprint = Blueprint(_name_api)
"""
@elem_blueprint.get('/' + _name_api, strict_slashes=True)
@doc.summary("Show saisons")
@doc.description("Display a listing of the resource.")
@doc.produces(content_type='application/json')
async def list(request):
return response.json(data_global_elements.get_interface(_name_api).gets())
"""
dataModelBdd = [
{
"name": "id",
"type": "int",
"modifiable": False,
"creatable": False,
"can_be_null": False,
"visible": True,
},
{
"name": "size",
"type": "int",
"modifiable": False,
"creatable": True,
"can_be_null": False,
"visible": True,
},
{
"name": "sha512",
"type": "str",
"modifiable": False,
"creatable": True,
"can_be_null": False,
"visible": True,
},
{
"name": "mime_type",
"type": "str",
"modifiable": False,
"creatable": True,
"can_be_null": False,
"visible": True,
},
{
"name": "original_name",
"type": "str",
"modifiable": False,
"creatable": True,
"can_be_null": True,
"visible": False,
},
]
data_global_elements.get_interface(_name_api).set_data_model(dataModelBdd)
@elem_blueprint.get('/' + _name_api + '/exist/<sha512:string>', strict_slashes=True)
@doc.summary("check resource existance")
@doc.description("simply check if the resource is already uploaded.")
@doc.produces(content_type='application/json')
async def check_existance(request, sha512):
value = data_global_elements.get_interface(_name_api).find("sha512", sha512)
if value != None:
return response.json(value)
return response.HTTPResponse("No data found", status=404)
@elem_blueprint.post('/' + _name_api, strict_slashes=True, stream=True)
@doc.summary("send new file data")
@doc.description("Create a new data file (associated with his sha512.")
#@doc.consumes(DataModel, location='body')#, required=True)
@doc.response_success(status=201, description='If successful created')
async def create(_request):
debug.info("request streaming " + str(_request));
args_with_blank_values = _request.headers
debug.info("List arguments: " + str(args_with_blank_values));
async def streaming(_response):
global tmp_value
#debug.info("streaming " + str(_response));
total_size = 0
tmp_value += random.randint(1,50)
temporary_file = os.path.join(_app.config['REST_TMP_DATA'], str(tmp_value) + ".tmp")
if not os.path.exists(_app.config['REST_TMP_DATA']):
os.makedirs(_app.config['REST_TMP_DATA'])
if not os.path.exists(_app.config['REST_MEDIA_DATA']):
os.makedirs(_app.config['REST_MEDIA_DATA'])
file_stream = open(temporary_file,"wb")
sha1 = hashlib.sha512()
while True:
#debug.warning("ploufffff " + str(dir(_request.stream)))
body = await _request.stream.read()
if body is None:
debug.warning("empty body");
break
total_size += len(body)
debug.verbose("body " + str(len(body)) + "/" + str(total_size))
file_stream.write(body)
sha1.update(body)
file_stream.close()
print("SHA512: " + str(sha1.hexdigest()))
new_data = {
"size": total_size,
"sha512": str(sha1.hexdigest()),
'original_name': _request.headers["filename"],
'mime_type': _request.headers["mime-type"]
}
# TODO: Check if the element already exist ...
return_bdd = data_global_elements.get_interface(_name_api).post(new_data)
basic_data_path = os.path.join(_app.config['REST_MEDIA_DATA'], str(return_bdd["id"]))
if not os.path.exists(basic_data_path):
os.makedirs(basic_data_path)
destination_filename = os.path.join(basic_data_path, "data")
"""
if os.path.isfile(destination_filename) == True:
answer_data = {
"size": total_size,
"sha512": str(sha1.hexdigest()),
'filename': _request.headers["filename"],
'mime_type': _request.headers["mime-type"],
"already_exist": True,
}
await _response.write(json.dumps(answer_data, sort_keys=True, indent=4))
return
"""
# move the file
shutil.move(temporary_file, destination_filename)
# collect media info ...
media_info = MediaInfo.parse(destination_filename)
data_metafile = {
"sha512": str(sha1.hexdigest()),
"size": total_size,
'filename': _request.headers["filename"],
'mime_type': _request.headers["mime-type"],
'media_info': json.loads(media_info.to_json())
}
tools.file_write_data(os.path.join(basic_data_path, "meta.json"), json.dumps(data_metafile, sort_keys=True, indent=4))
await _response.write(json.dumps(return_bdd, sort_keys=True, indent=4))
return response.stream(streaming, content_type='application/json')

View File

@ -1,155 +0,0 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
##
## @author Edouard DUPIN
##
## @copyright 2019, Edouard DUPIN, all right reserved
##
## @license MPL v2.0 (see license file)
##
import time
import json
import os
import sys
import datetime
import time, threading
import realog.debug as debug
from sanic import Sanic
from sanic import response
from sanic import views
from sanic import Blueprint
from sanic.exceptions import ServerError
from sanic_simple_swagger import swagger_blueprint, openapi_blueprint
from sanic_simple_swagger import doc
import tools
import data_interface
import data_global_elements
def add(_app, _name_api):
elem_blueprint = Blueprint(_name_api)
dataModelBdd = [
{
"name": "id",
"type": "int",
"modifiable": False,
"creatable": False,
"can_be_null": False,
},
{
"name": "type",
"type": "string",
"modifiable": False,
"creatable": True,
"can_be_null": False,
},
{
"name": "name",
"type": "str",
"modifiable": True,
"creatable": True,
"can_be_null": False,
},
{
"name": "description",
"type": "str",
"modifiable": True,
"creatable": True,
"can_be_null": False,
}
]
data_global_elements.get_interface(_name_api).set_data_model(dataModelBdd)
data_global_elements.get_interface(_name_api).set_add_where(" AND type='serie' ")
class DataModel:
name = str
description = str
@elem_blueprint.get('/' + _name_api, strict_slashes=True)
@doc.summary("Show resources")
@doc.description("Display a listing of the resource.")
@doc.produces(content_type='application/json')
async def list(request):
if "select" in request.args:
if request.args["select"] == "*":
list_values = data_global_elements.get_interface(_name_api).gets_where(select=[["!=", "id", None]], order_by=["name"])
else:
list_values = data_global_elements.get_interface(_name_api).gets_where(select=[["!=", "id", None]], order_by=["name"], filter=request.args["select"])
return response.json(list_values)
return response.json(data_global_elements.get_interface(_name_api).gets())
@elem_blueprint.post('/' + _name_api, strict_slashes=True)
@doc.summary("Create new resource")
@doc.description("Store a newly created resource in storage.")
@doc.consumes(DataModel, location='body')#, required=True)
@doc.response_success(status=201, description='If successful created')
async def create(request):
data = request.json
data["type"] = 'serie'
return response.json(data_global_elements.get_interface(_name_api).post(data))
@elem_blueprint.post('/' + _name_api + "/find", strict_slashes=True)
@doc.summary("Create new resource if the name does not already exist")
@doc.description("Store a newly created resource in storage.")
@doc.consumes(DataModel, location='body')#, required=True)
@doc.response_success(status=201, description='If successful created')
async def find_with_name(request):
value = data_global_elements.get_interface(_name_api).find("name", request.json["name"])
if value != None:
return response.json(value)
return response.HTTPResponse("No data found", status=404)
@elem_blueprint.get('/' + _name_api + '/<id:int>', strict_slashes=True)
@doc.summary("Show resources")
@doc.description("Display a listing of the resource.")
@doc.produces(content_type='application/json')
async def retrive(request, id):
value = data_global_elements.get_interface(_name_api).get(id)
if value != None:
return response.json(value)
return response.HTTPResponse("No data found", status=404)
@elem_blueprint.put('/' + _name_api + '/<id:int>', strict_slashes=True)
@doc.summary("Update resource")
@doc.description("Update the specified resource in storage.")
@doc.response_success(status=201, description='If successful updated')
async def update(request, id):
ret = data_global_elements.get_interface(_name_api).put(id, request.json)
return response.json({})
@elem_blueprint.delete('/' + _name_api + '/<id:int>', strict_slashes=True)
@doc.summary("Remove resource")
@doc.description("Remove the specified resource from storage.")
@doc.response_success(status=201, description='If successful deleted')
async def delete(request, id):
ret = data_global_elements.get_interface(_name_api).delete(id)
if ret == True:
return response.json({})
return response.HTTPResponse("No data found", status=404)
@elem_blueprint.post('/' + _name_api + "/<id:int>/add_cover", strict_slashes=True)
@doc.summary("Add cover on group")
@doc.description("Add a cover data ID to the group.")
@doc.consumes(DataModel, location='body')#, required=True)
@doc.response_success(status=201, description='If successful added')
async def create_cover(request, id):
for type_key in ["data_id"]:
if type_key not in request.json.keys():
return response.HTTPResponse("Bad Request: Missing Key '" + type_key + "'", status=400)
data = {}
data["node_id"] = id
data["data_id"] = request.json["data_id"]
value = data_global_elements.get_interface(_name_api).get(id)
if value == None:
return response.HTTPResponse("No data found", status=404)
data_global_elements.get_interface(data_global_elements.API_COVER).post(data)
value = data_global_elements.get_interface(_name_api).get(id)
return response.json(value)
_app.blueprint(elem_blueprint)

View File

@ -1,43 +0,0 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
##
## @author Edouard DUPIN
##
## @copyright 2019, Edouard DUPIN, all right reserved
##
## @license MPL v2.0 (see license file)
##
import time
import json
import os
import sys
import datetime
import time, threading
import realog.debug as debug
from sanic import Sanic
from sanic import response
from sanic import views
from sanic import Blueprint
from sanic.exceptions import ServerError
from sanic_simple_swagger import swagger_blueprint, openapi_blueprint
from sanic_simple_swagger import doc
import tools
import data_interface
import data_global_elements
def add(_app):
@_app.route("/")
@doc.description("get api system information")
async def test(request):
return response.json({
"api-type": "video-broker",
"api-version": _app.config['API_VERSION'],
"title": _app.config['API_TITLE'],
"description": _app.config['API_DESCRIPTION'],
"contact": _app.config['API_CONTACT_EMAIL'],
"licence": _app.config['API_LICENSE_NAME']
})

View File

@ -1,160 +0,0 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
##
## @author Edouard DUPIN
##
## @copyright 2019, Edouard DUPIN, all right reserved
##
## @license MPL v2.0 (see license file)
##
import time
import json
import os
import sys
import datetime
import time, threading
import realog.debug as debug
from sanic import Sanic
from sanic import response
from sanic import views
from sanic import Blueprint
from sanic.exceptions import ServerError
from sanic_simple_swagger import swagger_blueprint, openapi_blueprint
from sanic_simple_swagger import doc
import tools
import data_interface
import data_global_elements
def add(_app, _name_api):
elem_blueprint = Blueprint(_name_api)
dataModelBdd = [
{
"name": "id",
"type": "int",
"modifiable": False,
"creatable": False,
"can_be_null": False,
"visible": True,
},
{
"name": "type",
"type": "string",
"modifiable": False,
"creatable": True,
"can_be_null": False,
},
{
"name": "name",
"type": "string",
"modifiable": True,
"creatable": True,
"can_be_null": False,
"visible": True,
},
{
"name": "description",
"type": "str",
"modifiable": True,
"creatable": True,
"can_be_null": False,
"visible": True,
},
{
"name": "parent_id",
"type": "int",
"modifiable": True,
"creatable": True,
"can_be_null": False,
"visible": True,
},
]
data_global_elements.get_interface(_name_api).set_data_model(dataModelBdd)
data_global_elements.get_interface(_name_api).set_add_where(" AND type='saison' ")
class DataModel:
name = int
description = str
parent_id = int
@elem_blueprint.get('/' + _name_api, strict_slashes=True)
@doc.summary("Show saisons")
@doc.description("Display a listing of the resource.")
@doc.produces(content_type='application/json')
async def list(request):
return response.json(data_global_elements.get_interface(_name_api).gets())
@elem_blueprint.post('/' + _name_api, strict_slashes=True)
@doc.summary("Create new saison")
@doc.description("Create a new saison for a aspecific group id.")
@doc.consumes(DataModel, location='body')#, required=True)
@doc.response_success(status=201, description='If successful created')
async def create(request):
data = request.json
data["type"] = 'saison'
return response.json(data_global_elements.get_interface(_name_api).post(data))
@elem_blueprint.post('/' + _name_api + "/find", strict_slashes=True)
@doc.summary("find a season existance")
@doc.description("return the ID of the season table.")
@doc.consumes(DataModel, location='body')
@doc.response_success(status=201, description='If successful created')
async def find_with_name(request):
value = data_global_elements.get_interface(_name_api).find2("parent_id", request.json["parent_id"], "name", request.json["name"])
if value != None:
return response.json(value)
return response.HTTPResponse("No data found", status=404)
@elem_blueprint.get('/' + _name_api + '/<id:int>', strict_slashes=True)
@doc.summary("Show resources")
@doc.description("Display a listing of the resource.")
@doc.produces(content_type='application/json')
async def retrive(request, id):
value = data_global_elements.get_interface(_name_api).get(id)
if value != None:
return response.json(value)
return response.HTTPResponse("No data found", status=404)
@elem_blueprint.put('/' + _name_api + '/<id:int>', strict_slashes=True)
@doc.summary("Update resource")
@doc.description("Update the specified resource in storage.")
@doc.response_success(status=201, description='If successful updated')
async def update(request, id):
ret = data_global_elements.get_interface(_name_api).put(id, request.json)
return response.json({})
@elem_blueprint.delete('/' + _name_api + '/<id:int>', strict_slashes=True)
@doc.summary("Remove resource")
@doc.description("Remove the specified resource from storage.")
@doc.response_success(status=201, description='If successful deleted')
async def delete(request, id):
ret = data_global_elements.get_interface(_name_api).delete(id)
if ret == True:
return response.json({})
return response.HTTPResponse("No data found", status=404)
@elem_blueprint.post('/' + _name_api + "/<id:int>/add_cover", strict_slashes=True)
@doc.summary("Add cover on video")
@doc.description("Add a cover data ID to the video.")
@doc.consumes(DataModel, location='body')#, required=True)
@doc.response_success(status=201, description='If successful added')
async def create_cover(request, id):
for type_key in ["data_id"]:
if type_key not in request.json.keys():
return response.HTTPResponse("Bad Request: Missing Key '" + type_key + "'", status=400)
data = {}
data["node_id"] = id
data["data_id"] = request.json["data_id"]
value = data_global_elements.get_interface(_name_api).get(id)
if value == None:
return response.HTTPResponse("No data found", status=404)
data_global_elements.get_interface(data_global_elements.API_COVER).post(data)
value = data_global_elements.get_interface(_name_api).get(id)
return response.json(value)
_app.blueprint(elem_blueprint)

View File

@ -1,141 +0,0 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
##
## @author Edouard DUPIN
##
## @copyright 2019, Edouard DUPIN, all right reserved
##
## @license MPL v2.0 (see license file)
##
import time
import json
import os
import sys
import datetime
import time, threading
import realog.debug as debug
from sanic import Sanic
from sanic import response
from sanic import views
from sanic import Blueprint
from sanic.exceptions import ServerError
from sanic_simple_swagger import swagger_blueprint, openapi_blueprint
from sanic_simple_swagger import doc
import tools
import data_interface
import data_global_elements
def add(_app, _name_api):
elem_blueprint = Blueprint(_name_api)
dataModelBdd = [
{
"name": "id",
"type": "int",
"modifiable": False,
"creatable": False,
"can_be_null": False,
"visible": True,
},
{
"name": "type",
"type": "string",
"modifiable": False,
"creatable": True,
"can_be_null": False,
},
{
"name": "name",
"type": "str",
"modifiable": True,
"creatable": True,
"can_be_null": False,
"visible": True,
},
{
"name": "description",
"type": "str",
"modifiable": True,
"creatable": True,
"can_be_null": False,
"visible": True,
},
]
data_global_elements.get_interface(_name_api).set_data_model(dataModelBdd)
data_global_elements.get_interface(_name_api).set_add_where(" AND type='type' ")
class DataModel:
name = str
description = str
@elem_blueprint.get('/' + _name_api, strict_slashes=True)
@doc.summary("Show resources")
@doc.description("Display a listing of the resource.")
@doc.produces(content_type='application/json')
async def list(request):
return response.json(data_global_elements.get_interface(_name_api).gets())
@elem_blueprint.post('/' + _name_api, strict_slashes=True)
@doc.summary("Create new resource")
@doc.description("Store a newly created resource in storage.")
@doc.consumes(DataModel, location='body')#, required=True)
@doc.response_success(status=201, description='If successful created')
async def create(request):
data = request.json
data["type"] = 'type'
return response.json(data_global_elements.get_interface(_name_api).post(data))
@elem_blueprint.get('/' + _name_api + '/<id:int>', strict_slashes=True)
@doc.summary("Show resources")
@doc.description("Display a listing of the resource.")
@doc.produces(content_type='application/json')
async def retrive(request, id):
value = data_global_elements.get_interface(_name_api).get(id)
if value != None:
return response.json(value)
return response.HTTPResponse("No data found", status=404)
@elem_blueprint.put('/' + _name_api + '/<id:int>', strict_slashes=True)
@doc.summary("Update resource")
@doc.description("Update the specified resource in storage.")
@doc.response_success(status=201, description='If successful updated')
async def update(request, id):
ret = data_global_elements.get_interface(_name_api).put(id, request.json)
return response.json({})
@elem_blueprint.delete('/' + _name_api + '/<id:int>', strict_slashes=True)
@doc.summary("Remove resource")
@doc.description("Remove the specified resource from storage.")
@doc.response_success(status=201, description='If successful deleted')
async def delete(request, id):
ret = data_global_elements.get_interface(_name_api).delete(id)
if ret == True:
return response.json({})
return response.HTTPResponse("No data found", status=404)
@elem_blueprint.post('/' + _name_api + "/<id:int>/add_cover", strict_slashes=True)
@doc.summary("Add cover on video")
@doc.description("Add a cover data ID to the video.")
@doc.consumes(DataModel, location='body')#, required=True)
@doc.response_success(status=201, description='If successful added')
async def create_cover(request, id):
for type_key in ["data_id"]:
if type_key not in request.json.keys():
return response.HTTPResponse("Bad Request: Missing Key '" + type_key + "'", status=400)
data = {}
data["node_id"] = id
data["data_id"] = request.json["data_id"]
value = data_global_elements.get_interface(_name_api).get(id)
if value == None:
return response.HTTPResponse("No data found", status=404)
data_global_elements.get_interface(data_global_elements.API_COVER).post(data)
value = data_global_elements.get_interface(_name_api).get(id)
return response.json(value)
_app.blueprint(elem_blueprint)

View File

@ -1,139 +0,0 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
##
## @author Edouard DUPIN
##
## @copyright 2019, Edouard DUPIN, all right reserved
##
## @license MPL v2.0 (see license file)
##
import time
import json
import os
import sys
import datetime
import time, threading
import realog.debug as debug
from sanic import Sanic
from sanic import response
from sanic import views
from sanic import Blueprint
from sanic.exceptions import ServerError
from sanic_simple_swagger import swagger_blueprint, openapi_blueprint
from sanic_simple_swagger import doc
import tools
import data_interface
import data_global_elements
def add(_app, _name_api):
elem_blueprint = Blueprint(_name_api)
dataModelBdd = [
{
"name": "id",
"type": "int",
"modifiable": False,
"creatable": False,
"can_be_null": False,
"visible": True,
},
{
"name": "type",
"type": "string",
"modifiable": False,
"creatable": True,
"can_be_null": False,
},
{
"name": "name",
"type": "str",
"modifiable": True,
"creatable": True,
"can_be_null": False,
"visible": True,
},
{
"name": "description",
"type": "str",
"modifiable": True,
"creatable": True,
"can_be_null": False,
"visible": True,
},
]
data_global_elements.get_interface(_name_api).set_data_model(dataModelBdd)
data_global_elements.get_interface(_name_api).set_add_where(" AND type='univers' ")
class DataModel:
name = str
description = str
@elem_blueprint.get('/' + _name_api, strict_slashes=True)
@doc.summary("Show resources")
@doc.description("Display a listing of the resource.")
@doc.produces(content_type='application/json')
async def list(request):
return response.json(data_global_elements.get_interface(_name_api).gets())
@elem_blueprint.post('/' + _name_api, strict_slashes=True)
@doc.summary("Create new resource")
@doc.description("Store a newly created resource in storage.")
@doc.consumes(DataModel, location='body')#, required=True)
@doc.response_success(status=201, description='If successful created')
async def create(request):
data = request.json
data["type"] = 'univers'
return response.json(data_global_elements.get_interface(_name_api).post(data))
@elem_blueprint.get('/' + _name_api + '/<id:int>', strict_slashes=True)
@doc.summary("Show resources")
@doc.description("Display a listing of the resource.")
@doc.produces(content_type='application/json')
async def retrive(request, id):
value = data_global_elements.get_interface(_name_api).get(id)
if value != None:
return response.json(value)
return response.HTTPResponse("No data found", status=404)
@elem_blueprint.put('/' + _name_api + '/<id:int>', strict_slashes=True)
@doc.summary("Update resource")
@doc.description("Update the specified resource in storage.")
@doc.response_success(status=201, description='If successful updated')
async def update(request, id):
ret = data_global_elements.get_interface(_name_api).put(id, request.json)
return response.json({})
@elem_blueprint.delete('/' + _name_api + '/<id:int>', strict_slashes=True)
@doc.summary("Remove resource")
@doc.description("Remove the specified resource from storage.")
@doc.response_success(status=201, description='If successful deleted')
async def delete(request, id):
ret = data_global_elements.get_interface(_name_api).delete(id)
if ret == True:
return response.json({})
return response.HTTPResponse("No data found", status=404)
@elem_blueprint.post('/' + _name_api + "/<id:int>/add_cover", strict_slashes=True)
@doc.summary("Add cover on univers")
@doc.description("Add a cover data ID to the univers.")
@doc.consumes(DataModel, location='body')#, required=True)
@doc.response_success(status=201, description='If successful added')
async def create_cover(request, id):
for type_key in ["data_id"]:
if type_key not in request.json.keys():
return response.HTTPResponse("Bad Request: Missing Key '" + type_key + "'", status=400)
data = {}
data["node_id"] = id
data["data_id"] = request.json["data_id"]
value = data_global_elements.get_interface(_name_api).get(id)
if value == None:
return response.HTTPResponse("No data found", status=404)
data_global_elements.get_interface(data_global_elements.API_COVER).post(data)
value = data_global_elements.get_interface(_name_api).get(id)
return response.json(value)
_app.blueprint(elem_blueprint)

View File

@ -1,266 +0,0 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
##
## @author Edouard DUPIN
##
## @copyright 2019, Edouard DUPIN, all right reserved
##
## @license MPL v2.0 (see license file)
##
import time
import json
import os
import sys
import copy
import datetime
import time, threading
import realog.debug as debug
from sanic import Sanic
from sanic import response
from sanic import views
from sanic import Blueprint
from sanic.exceptions import ServerError
from sanic_simple_swagger import swagger_blueprint, openapi_blueprint
from sanic_simple_swagger import doc
import tools
import data_interface
import data_global_elements
def generate_name(_value):
group_name = ""
if "univers_id" in _value.keys():
univers_property = data_global_elements.get_interface(data_global_elements.API_UNIVERS).get(_value["univers_id"])
if univers_property != None:
group_name = univers_property["name"] + ":"
if "serie_id" in _value.keys():
group_property = data_global_elements.get_interface(data_global_elements.API_GROUP).get(_value["serie_id"])
if group_property != None:
group_name = group_property["name"]
saison_number = ""
if "saison_id" in _value.keys():
saison_property = data_global_elements.get_interface(data_global_elements.API_SAISON).get(_value["saison_id"])
if saison_property != None:
saison_number = str(saison_property["number"])
if len(saison_number) == 1:
saison_number = "0" + saison_number
out = ""
if group_name != "":
out += group_name + "-"
if saison_number != "":
out += "s" + saison_number + "-"
if "episode" in _value.keys() and _value["episode"] != None:
episode_id = _value["episode"];
if type(episode_id) == str:
episode_id = int(episode_id)
if episode_id < 10:
out += "e00" + str(episode_id) + "-"
elif episode_id < 100:
out += "e0" + str(episode_id) + "-"
else:
out += "e" + str(episode_id) + "-"
out += _value["name"]
if "time" in _value.keys() and _value["time"] != None:
out += "(" + _value["name"] + ")"
return out
def add(_app, _name_api):
elem_blueprint = Blueprint(_name_api)
dataModelBdd = [
{
"name": "id",
"type": "int",
"modifiable": False,
"creatable": False,
"can_be_null": False,
"visible": True,
},
{
"name": "type",
"type": "string",
"modifiable": False,
"creatable": True,
"can_be_null": False,
},
{
"name": "data_id",
"type": "int",
"modifiable": True,
"creatable": True,
"can_be_null": False,
"visible": True,
},
{
"name": "type_id",
"type": "int",
"modifiable": True,
"creatable": True,
"can_be_null": True,
"visible": True,
},
{
"name": "saison_id",
"type": "int",
"modifiable": True,
"creatable": True,
"can_be_null": True,
"visible": True,
},
{
"name": "episode",
"type": "int",
"modifiable": True,
"creatable": True,
"can_be_null": True,
"visible": True,
},
{
"name": "univers_id",
"type": "int",
"modifiable": True,
"creatable": True,
"can_be_null": True,
"visible": True,
},
{
"name": "serie_id",
"type": "int",
"modifiable": True,
"creatable": True,
"can_be_null": True,
"visible": True,
},
{
"name": "name",
"type": "str",
"modifiable": True,
"creatable": True,
"can_be_null": True,
"visible": True,
},
{
"name": "description",
"type": "str",
"modifiable": True,
"creatable": True,
"can_be_null": True,
"visible": True,
},
{
"name": "date",
"type": "int",
"modifiable": True,
"creatable": True,
"can_be_null": True,
"visible": True,
},
{
"name": "time",
"type": "int",
"modifiable": True,
"creatable": True,
"can_be_null": True,
"visible": True,
},
]
data_global_elements.get_interface(_name_api).set_data_model(dataModelBdd)
data_global_elements.get_interface(_name_api).set_add_where(" AND type='media' ")
class DataModel:
type_id = int
saison_id = int
episode = int
univers_id = int
serie_id = int
name = str
description = str
# creating time
create_date = str
# date of the video
date = str
# number of second
time = int
@elem_blueprint.get('/' + _name_api, strict_slashes=True)
@doc.summary("Show saisons")
@doc.description("Display a listing of the resource.")
@doc.produces(content_type='application/json')
async def list(request):
return response.json(data_global_elements.get_interface(_name_api).gets())
@elem_blueprint.post('/' + _name_api, strict_slashes=True)
@doc.summary("Create new saison")
@doc.description("Create a new saison for a aspecific group id.")
@doc.consumes(DataModel, location='body')#, required=True)
@doc.response_success(status=201, description='If successful created')
async def create(request):
data = request.json
for type_key in ["data_id","name"]:
if type_key not in data.keys():
raise ServerError("Bad Request: Missing Key '" + type_key + "'", status_code=400)
for type_key in ["create_date"]:
if type_key in data.keys():
raise ServerError("Forbidden: Must not be set Key '" + type_key + "'", status_code=403)
#Find if already exist
data["type"] = 'media'
return response.json(data_global_elements.get_interface(_name_api).post(data))
@elem_blueprint.get('/' + _name_api + '/<id:int>', strict_slashes=True)
@doc.summary("Show resources")
@doc.description("Display a listing of the resource.")
@doc.produces(content_type='application/json')
async def retrive(request, id):
value = data_global_elements.get_interface(_name_api).get(id)
if value != None:
generated_name = generate_name(value)
tmp = copy.deepcopy(value)
tmp["generated_name"] = generated_name
return response.json(tmp)
return response.HTTPResponse("No data found", status=404)
@elem_blueprint.put('/' + _name_api + '/<id:int>', strict_slashes=True)
@doc.summary("Update resource")
@doc.description("Update the specified resource in storage.")
@doc.response_success(status=201, description='If successful updated')
async def update(request, id):
ret = data_global_elements.get_interface(_name_api).put(id, request.json)
return response.json(ret);
@elem_blueprint.delete('/' + _name_api + '/<id:int>', strict_slashes=True)
@doc.summary("Remove resource")
@doc.description("Remove the specified resource from storage.")
@doc.response_success(status=201, description='If successful deleted')
async def delete(request, id):
ret = data_global_elements.get_interface(_name_api).delete(id)
if ret == True:
return response.json({})
return response.HTTPResponse("No data found", status=404)
@elem_blueprint.post('/' + _name_api + "/<id:int>/add_cover", strict_slashes=True)
@doc.summary("Add cover on video")
@doc.description("Add a cover data ID to the video.")
@doc.consumes(DataModel, location='body')#, required=True)
@doc.response_success(status=201, description='If successful added')
async def create_cover(request, id):
for type_key in ["data_id"]:
if type_key not in request.json.keys():
return response.HTTPResponse("Bad Request: Missing Key '" + type_key + "'", status=400)
data = {}
data["node_id"] = id
data["data_id"] = request.json["data_id"]
value = data_global_elements.get_interface(_name_api).get(id)
if value == None:
return response.HTTPResponse("No data found", status=404)
data_global_elements.get_interface(data_global_elements.API_COVER).post(data)
value = data_global_elements.get_interface(_name_api).get(id)
return response.json(value)
_app.blueprint(elem_blueprint)

View File

@ -1,115 +0,0 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
##
## @author Edouard DUPIN
##
## @copyright 2019, Edouard DUPIN, all right reserved
##
## @license MPL v2.0 (see license file)
##
#pip install flask --user
#pip install flask_restful --user
#pip install python-dateutil --user
#pip install sanic --user
from sanic import Sanic
from sanic import response
from sanic import views
from sanic import Blueprint
from sanic.exceptions import ServerError
from spf import SanicPluginsFramework
import dateutil.parser
import time
import json
import os
import sys
import datetime
import time, threading
import realog.debug as debug
debug.enable_color()
import tools
import data_interface
import data_global_elements
import create_bdd
create_bdd.create_if_needed();
from sanic_cors.extension import cors
app = Sanic(__name__)
spf = SanicPluginsFramework(app)
spf.register_plugin(cors, automatic_options=True)
app.config['API_VERSION'] = '2.0.0'
app.config['API_TITLE'] = 'Rest personal video API'
app.config['API_DESCRIPTION'] = 'Simple API for the Video broker.'
app.config['API_CONTACT_EMAIL'] = "yui.heero@gmail.com"
app.config['API_LICENSE_NAME'] = 'MPL 2.0'
app.config['API_LICENSE_URL'] = 'https://www.mozilla.org/en-US/MPL/2.0/'
app.config['schemes'] = ['http', 'https']
if "REST_TMP_DATA" not in app.config.keys():
app.config['REST_TMP_DATA'] = os.path.join("data", "tmp")
if "REST_MEDIA_DATA" not in app.config.keys():
app.config['REST_MEDIA_DATA'] = os.path.join("data", "media")
if "REST_DATA" not in app.config.keys():
app.config['REST_DATA'] = "data"
if "REST_HOST" not in app.config.keys():
app.config['REST_HOST'] = "0.0.0.0"
if "REST_PORT" not in app.config.keys():
app.config['REST_PORT'] = "80"
def add_interface(_name, _base_name, _name_view):
interface = data_interface.DataInterface(_name, _base_name, _name_view)
data_global_elements.add_interface(_name, interface)
add_interface(data_global_elements.API_DATA, data_global_elements.API_DATA, "view_data")
add_interface(data_global_elements.API_TYPE, "node", "view_type")
add_interface(data_global_elements.API_UNIVERS, "node", "view_univers")
add_interface(data_global_elements.API_GROUP, "node", "view_serie")
add_interface(data_global_elements.API_SAISON, "node", "view_saison")
add_interface(data_global_elements.API_VIDEO, "media", "view_video")
add_interface(data_global_elements.API_COVER, data_global_elements.API_COVER, data_global_elements.API_COVER)
import api.root as api_root
api_root.add(app)
import api.type as api_type
api_type.add(app, data_global_elements.API_TYPE)
import api.univers as api_univers
api_univers.add(app, data_global_elements.API_UNIVERS)
import api.group as api_group
api_group.add(app, data_global_elements.API_GROUP)
import api.saison as api_saison
api_saison.add(app, data_global_elements.API_SAISON)
import api.video as api_video
api_video.add(app, data_global_elements.API_VIDEO)
import api.data as api_data
api_data.add(app, data_global_elements.API_DATA)
if __name__ == "__main__":
debug.info("Start REST application: " + str(app.config['REST_HOST']) + ":" + str(app.config['REST_PORT']))
app.config.REQUEST_MAX_SIZE=10*1024*1024*1024
app.config.REQUEST_TIMEOUT=60*60
#app.run(host=app.config['REST_HOST'], port=int(app.config['REST_PORT']), workers=100)
app.run(host=app.config['REST_HOST'], port=int(app.config['REST_PORT']), log_config=None)
#app.stop()
debug.info("Sync all BDD ... (do not force stop ...)");
data_global_elements.save_all_before_stop();
debug.info("END program");
sys.exit(0)

View File

@ -1,27 +0,0 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
##
## @author Edouard DUPIN
##
## @copyright 2012, Edouard DUPIN, all right reserved
##
## @license MPL v2.0 (see license file)
##
#pip install paho-mqtt --user
import os
def get_rest_config():
variable = {
#"tmp_data": "tmp",
#"data": "data",
#"data_media": "data/media",
#"host": os.getenv('REST_HOSTNAME', "0.0.0.0"),
#"port": int(os.getenv('REST_PORT', 80)),
"db_host": os.getenv('DB_HOSTNAME', "localhost"),
"db_port": int(os.getenv('DB_PORT', 15032)),
"db_name": os.getenv('DB_NAME', "karideo"),
"db_user": os.getenv('DB_USER', "root"),
"db_password": os.getenv('DB_PASSWORD', "postgress_password"),
}
return variable

View File

@ -1,373 +0,0 @@
#!/usr/bin/python3
# -*- coding: utf-8 -*-
##
## @author Edouard DUPIN
##
## @copyright 2012, Edouard DUPIN, all right reserved
##
## @license MPL v2.0 (see license file)
##
#pip install paho-mqtt --user
from realog import debug
import json
import os
import random
import copy
import config
import tools
from dateutil import parser
import db
import psycopg2
def create_if_needed():
connection = db.connect_bdd();
debug.info("create the table:")
c = connection.cursor()
need_to_create_table = False
try:
c.execute('''
SELECT * FROM object LIMIT 2;
''');
connection.commit()
except psycopg2.errors.UndefinedTable:
need_to_create_table = True
if need_to_create_table == False:
debug.info("Does not need to create the BDD");
connection.commit()
db.remove_connection();
return
connection.commit()
debug.info("Add default BDD format");
c.execute('''
CREATE TYPE node_type AS ENUM ('type', 'univers', 'serie', 'saison', 'media');
CREATE TYPE age_type AS ENUM ('-', '5', '9', '12', '14', '16', '18');
''')
connection.commit()
# Create table
c.execute('''
CREATE SEQUENCE kar_id_sequence;
''')
connection.commit()
# Create table
c.execute('''
CREATE OR REPLACE FUNCTION trigger_set_timestamp()
RETURNS TRIGGER AS $$
BEGIN
NEW.modify_date = NOW();
RETURN NEW;
END;
$$ LANGUAGE plpgsql;
''')
connection.commit()
aaa = '''
CREATE OR REPLACE FUNCTION check_exist(_table character, _id INTEGER)
RETURNS BOOLEAN AS $$
DECLARE vvv int;
DECLARE eee text;
BEGIN
raise WARNING 'check_exist(%,%)%', _table, _id, E'\n';
IF _id IS NULL THEN
raise WARNING ' ==> return 1 (detect NULL)%', E'\n';
RETURN 1;
END IF;
eee = 'select 1 FROM ' || quote_ident(_table) || ' WHERE id = ' || _id;
raise WARNING 'Execute: % %', eee, E'\n';
EXECUTE 'select 1 FROM ' || quote_ident(_table) || ' WHERE id = ' || _id INTO vvv;
raise WARNING 'Value vvv: % %', vvv, E'\n';
IF vvv = 1 THEN
raise WARNING ' ==> return 1 %', E'\n';
RETURN 1;
ELSE
raise WARNING ' ==> return 0 %', E'\n';
RETURN 0;
END IF;
END;
$$ LANGUAGE plpgsql;
'''
c.execute('''
CREATE OR REPLACE FUNCTION check_exist(_table character, _id INTEGER)
RETURNS BOOLEAN AS $$
DECLARE vvv int;
DECLARE eee text;
BEGIN
IF _id IS NULL THEN
RETURN 1;
END IF;
EXECUTE 'select 1 FROM ' || quote_ident(_table) || ' WHERE id = ' || _id INTO vvv;
IF vvv = 1 THEN
RETURN 1;
ELSE
RETURN 0;
END IF;
END;
$$ LANGUAGE plpgsql;
''')
connection.commit()
c.execute("""
CREATE OR REPLACE FUNCTION check_node_exist(_type character, _id INTEGER)
RETURNS BOOLEAN AS $$
DECLARE vvv int;
DECLARE eee text;
BEGIN
IF _id IS NULL THEN
RETURN 1;
END IF;
EXECUTE 'select 1 FROM node WHERE type = ''' || quote_ident(_type) || ''' AND id = ' || _id INTO vvv;
IF vvv = 1 THEN
RETURN 1;
ELSE
RETURN 0;
END IF;
END;
$$ LANGUAGE plpgsql;
""")
connection.commit()
debug.info("Add Main Object interface");
# Create table
c.execute('''
CREATE TABLE object (
id INTEGER PRIMARY KEY default nextval('kar_id_sequence'),
deleted BOOLEAN NOT NULL DEFAULT FALSE,
create_date TIMESTAMPTZ NOT NULL DEFAULT NOW(),
modify_date TIMESTAMPTZ NOT NULL DEFAULT NOW());
COMMENT ON TABLE object IS 'Basic element in this BDD (manage the create and modfy property, the deletion and the unique ID.';
COMMENT ON COLUMN object.id IS 'Unique global ID in the BDD.';
COMMENT ON COLUMN object.deleted IS 'If true the element is dead and must not be shown.';
COMMENT ON COLUMN object.create_date IS 'Creation date of this Object (automatically setup by the BDD).';
COMMENT ON COLUMN object.modify_date IS 'Modify date of this object (automatically updated by the BDD).';
''')
c.execute('''
CREATE TRIGGER set_timestamp
AFTER UPDATE ON object
FOR EACH ROW
EXECUTE PROCEDURE trigger_set_timestamp();
''')
connection.commit()
debug.info("Add DATA interface");
# Create table
c.execute('''
CREATE TABLE data (
sha512 VARCHAR(129) NOT NULL,
mime_type VARCHAR(128) NOT NULL,
size BIGINT NOT NULL,
original_name TEXT
) INHERITS (object);
COMMENT ON TABLE data IS 'Data basic reference on the big data managed.';
COMMENT ON COLUMN data.sha512 IS 'Unique Sha512 of the file.';
COMMENT ON COLUMN data.mime_type IS 'Type of the object with his mine-type description.';
COMMENT ON COLUMN data.size IS 'Size of the file in Byte.';
COMMENT ON COLUMN data.original_name IS 'Name of the file when upload it in the BDD ==> MUST be remove later.';
''')
connection.commit()
debug.info("Add NODE interface");
# Create table
c.execute('''
CREATE TABLE node (
type node_type NOT NULL,
name TEXT NOT NULL,
description TEXT,
parent_id INTEGER CHECK(check_exist('node', parent_id))
) INHERITS (object);
COMMENT ON TABLE node IS 'Node is a basic element of what must be hierarchie apears.';
COMMENT ON COLUMN node.name IS 'Name of the Node.';
COMMENT ON COLUMN node.description IS 'Description of the Node.';
''')
connection.commit()
debug.info("Add Cover interface");
# Create table
c.execute('''
CREATE TABLE cover_link (
node_id INTEGER CHECK(check_exist('node', node_id)),
data_id INTEGER CHECK(check_exist('data', data_id))
) INHERITS (object);
COMMENT ON TABLE cover_link IS 'Link between cover data id and Nodes.';
''')
connection.commit()
debug.info("Add MEDIA interface");
# Create table
c.execute('''
CREATE TABLE media (
data_id INTEGER CHECK(check_exist('data', data_id)),
type_id INTEGER CHECK(check_node_exist('type', type_id)),
univers_id INTEGER CHECK(check_node_exist('univers', univers_id)),
serie_id INTEGER CHECK(check_node_exist('serie', serie_id)),
saison_id INTEGER CHECK(check_node_exist('saison', saison_id)),
episode INTEGER CHECK(episode >=0),
date INTEGER CHECK(date > 1850),
time INTEGER CHECK(time >= 0),
age_limit age_type NOT NULL DEFAULT '-'
) INHERITS (node);
COMMENT ON TABLE media IS 'Media Media that is visible.';
COMMENT ON COLUMN media.episode IS 'Number of the episode in the saison sequence.';
COMMENT ON COLUMN media.date IS 'Simple date in years of the creation of the media.';
COMMENT ON COLUMN media.time IS 'Time in second of the media';
COMMENT ON COLUMN media.age_limit IS 'Limitation of the age to show the display ("-" for no limitation)';
''')
# Save (commit) the changes
connection.commit()
debug.info("Add Views models");
c.execute('''
CREATE VIEW view_data AS
SELECT id, sha512, mime_type, size
FROM data
WHERE deleted = false
ORDER BY id;
CREATE VIEW view_type AS
SELECT id, name, description,
array(
SELECT data_id
FROM cover_link
WHERE cover_link.node_id = node.id
) AS covers
FROM node
WHERE deleted = false AND type = 'type'
ORDER BY name;
CREATE VIEW view_univers AS
SELECT id, name, description,
array(
SELECT data_id
FROM cover_link
WHERE cover_link.node_id = node.id
) AS covers
FROM node
WHERE deleted = false AND type = 'univers'
ORDER BY name;
CREATE VIEW view_serie AS
SELECT id, name, description,
array(
SELECT data_id
FROM cover_link
WHERE cover_link.node_id = node.id
) AS covers
FROM node
WHERE deleted = false AND type = 'serie'
ORDER BY name;
CREATE VIEW view_saison AS
SELECT id, name, description, parent_id,
array(
SELECT data_id
FROM cover_link
WHERE cover_link.node_id = node.id
) AS covers
FROM node
WHERE deleted = false AND type = 'saison'
ORDER BY name;
CREATE VIEW view_video AS
SELECT id, name, description, data_id, type_id, univers_id, serie_id, saison_id, episode, date, time, age_limit,
array(
SELECT data_id
FROM cover_link
WHERE cover_link.node_id = media.id
) AS covers
FROM media
WHERE deleted = false AND type = 'media'
ORDER BY name;
''')
connection.commit()
debug.info("Add default type");
default_values_type = [
{
"id": 0,
"name": "Documentary",
"description": "Documentary (annimals, space, earth...)",
"image": "../default_images/type_documentary.svg"
},{
"id": 1,
"name": "Movie",
"description": "Movie with real humans (film)",
"image": "../default_images/type_film.svg"
},{
"id": 2,
"name": "Annimation",
"description": "Annimation movies (film)",
"image": "../default_images/type_annimation.svg"
},{
"id": 3,
"name": "Short movie",
"description": "Small movies (less 2 minutes)",
"image": "../default_images/type_film-short.svg"
},{
"id": 4,
"name": "TV show",
"description": "Tv show form old peoples",
"image": "../default_images/type_tv-show.svg"
}, {
"id": 5,
"name": "Anniation TV show",
"description": "Tv show form young peoples",
"image": "../default_images/type_tv-show-annimation.svg"
}, {
"id": 6,
"name": "Theater",
"description": "recorder theater pices",
"image": "../default_images/type_theater.svg"
}, {
"id": 7,
"name": "One man show",
"description": "Recorded stand up",
"image": "../default_images/type_one-man-show.svg"
}, {
"id": 8,
"name": "Concert",
"description": "Recorded concert",
"image": "../default_images/type_concert.svg"
}, {
"id": 9,
"name": "Opera",
"description": "Recorded Opera",
"image": "../default_images/type_opera.svg"
}
]
tmp_config = config.get_rest_config()
for elem in default_values_type:
debug.info(" add type: " + elem["name"]);
request_insert = (elem["name"], elem["description"])
c.execute('INSERT INTO node (type, name, description) VALUES (\'type\', %s, %s) RETURNING id', request_insert)
elem["id"] = c.fetchone()[0]
connection.commit()
if elem["image"] != None and elem["image"] != "":
# calculate sha512:
local_file_name = os.path.join(tools.get_current_path(__file__), elem["image"])
sha512 = tools.calculate_sha512(local_file_name)
mime_type = "image/svg+xml"
size = tools.file_size(local_file_name)
original_name = local_file_name
c.execute('INSERT INTO data (sha512, mime_type, size, original_name) VALUES (%s, %s, %s, %s) RETURNING id', (sha512, mime_type, size, original_name))
connection.commit()
elem["data_id"] = c.fetchone()[0]
c.execute('INSERT INTO cover_link (node_id, data_id) VALUES (%s, %s)', (elem["id"], elem["data_id"]))
connection.commit()
tools.file_copy(local_file_name, os.path.join(tmp_config["data_media"] , str(elem["data_id"]), "data"))
connection.commit()
# We can also close the connection if we are done with it.
# Just be sure any changes have been committed or they will be lost.
db.remove_connection();

View File

@ -1,64 +0,0 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
##
## @author Edouard DUPIN
##
## @copyright 2019, Edouard DUPIN, all right reserved
##
## @license MPL v2.0 (see license file)
##
interfaces = {}
def get_list_interface():
global interfaces
return interfaces
def get_interface(_name):
global interfaces
return interfaces[_name]
def add_interface(_name, _interface):
global interfaces
interfaces[_name] = _interface
import time, threading
system_stop = False
system_counter = 0
def save_all():
global system_counter
system_counter += 1
if system_counter <= 10:
return
system_counter = 0
print(time.ctime())
for elem in interfaces.keys():
if system_stop == True:
return
interfaces[elem].check_save()
def save_all_before_stop():
global system_stop
system_stop = True
for elem in interfaces.keys():
interfaces[elem].check_save()
def check_save():
save_all()
if system_stop == True:
return
threading.Timer(1, check_save).start()
check_save()
API_TYPE = "type"
API_UNIVERS = "univers"
API_GROUP = "group"
API_SAISON = "saison"
API_VIDEO = "video"
API_DATA = "data"
API_COVER = "cover_link"

View File

@ -1,272 +0,0 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
##
## @author Edouard DUPIN
##
## @copyright 2019, Edouard DUPIN, all right reserved
##
## @license MPL v2.0 (see license file)
##
import tools
import json
from realog import debug
import random
import copy
from sanic.exceptions import ServerError
from psycopg2.extras import RealDictCursor
import psycopg2
import db
def is_str(s, authorise):
if s == None:
if authorise == True:
return True
return False;
if type(s) == str:
return True
return False
def is_boolean(s, authorise):
if s == None:
if authorise == True:
return True
return False;
if s == True or s == False:
return True
return False
def is_int(s, authorise):
if s == None:
if authorise == True:
return True
return False;
try:
int(s)
return True
except ValueError:
return False
return False
def is_float(s, authorise):
if s == None:
if authorise == True:
return True
return False;
try:
float(s)
return True
except ValueError:
return False
return False
##
## @breif Generic interface to access to the BDD (no BDD, direct file IO)
##
class DataInterface():
def __init__(self, _name, _base_name, _name_view):
self.model = None
self.name = _name
self.name_view = _name_view
self.extract_base = "*"
self.base_name = _base_name
self.connection = db.connect_bdd();
self.need_save = False
self.where_expand = "";
#self.conn = self.connection.cursor()
def __del__(self):
db.remove_connection();
def set_data_model(self, _data_model):
self.model = _data_model
"""
self.extract_base = ""
for elem in self.model:
if elem["visible"] == True:
if self.extract_base != "":
self.extract_base += ","
self.extract_base += elem["name"]
"""
def set_add_where(self, _expand):
self.where_expand = _expand
##
## @brief Mark the current BDD to store all in File system (sync)
##
def mark_to_store(self):
self.need_save = True
##
## @brief Check if the Bdd need to be stored. It is stored if it has been requested.
## The BDD is store in a separate file and move in the old one. Safe way to store
##
def check_save(self):
if self.need_save == False:
return
debug.warning("Save bdd: ")
self.connection.commit()
self.need_save = False
def gets(self, filter=None):
debug.info("gets " + self.name)
cursor = self.connection.cursor(cursor_factory=RealDictCursor)
cursor.execute('SELECT * FROM ' + self.name_view + '')
results = cursor.fetchall()
#debug.info("gets data = " + json.dumps(results, indent=4))
if filter == None:
return results
debug.warning("BDD does not suppor filter now ...");
self.connection.commit()
return results
def get(self, _id):
if type(_id) != int:
debug.warning("get wrong input type...")
debug.info("get " + self.name + ": " + str(_id))
cursor = self.connection.cursor(cursor_factory=RealDictCursor)
#cursor.execute('SELECT * FROM data WHERE deleted=0')
#results = cursor.fetchall()
#debug.info("display data = " + json.dumps(results, indent=4))
req = (_id,)
try:
cursor.execute('SELECT * FROM ' + self.name_view + ' WHERE id=%s', req)
except psycopg2.errors.UndefinedFunction:
raise ServerError("INTERNAL_ERROR fail request SQL ...", status_code=500)
finally:
self.connection.commit()
results = cursor.fetchone()
#debug.info("get specific data = " + json.dumps(results))
return results;
def find(self, _key, _value):
debug.info("get " + self.name + ": " + str(_value))
cursor = self.connection.cursor(cursor_factory=RealDictCursor)
req = (_value,)
try:
cursor.execute('SELECT * FROM ' + self.name_view + ' WHERE ' + _key + '=%s', req)
except psycopg2.errors.UndefinedFunction:
raise ServerError("INTERNAL_ERROR fail request SQL ...", status_code=500)
finally:
self.connection.commit()
results = cursor.fetchone()
#debug.info("get specific data = " + json.dumps(results))
return results;
def find2(self, _key1, _value1, _key2, _value2):
debug.info("get " + self.name + ": " + str(_value1))
cursor = self.connection.cursor(cursor_factory=RealDictCursor)
req = (_value1,_value2)
try:
cursor.execute('SELECT * FROM ' + self.name_view + ' WHERE ' + _key1 + '=%s AND ' + _key2 + '=%s', req)
except psycopg2.errors.UndefinedFunction:
raise ServerError("INTERNAL_ERROR fail request SQL ...", status_code=500)
finally:
self.connection.commit()
results = cursor.fetchone()
#debug.info("get specific data = " + json.dumps(results))
return results;
def delete(self, _id):
debug.info("delete " + self.name + ": " + str(_id))
cursor = self.connection.cursor()
req = (_id,)
try:
cursor.execute('UPDATE ' + self.base_name + ' SET deleted=true WHERE id=%s' + self.where_expand, req)
except psycopg2.errors.UndefinedFunction:
raise ServerError("INTERNAL_ERROR fail request SQL ...", status_code=500)
finally:
self.connection.commit()
self.mark_to_store();
return True
def is_value_modifiable_and_good_type(self, _key, _value, _check_with="modifiable"):
if self.model == None:
return True
for elem in self.model:
if _key == elem["name"]:
if elem[_check_with] == False:
debug.warning("Try to set an input '" + str(_key) + "' but the element is not modifiable ... ");
raise ServerError("FORBIDDEN Try to set an input '" + str(_key) + "' but the element is not modifiable", status_code=403)
if elem["type"] == "str":
if is_str(_value, elem["can_be_null"]) == True:
return True
elif elem["type"] == "int":
if is_int(_value, elem["can_be_null"]) == True:
return True
elif elem["type"] == "float":
if is_float(_value, elem["can_be_null"]) == True:
return True
elif elem["type"] == "boolean":
if is_boolean(_value, elem["can_be_null"]) == True:
return True
else:
return True;
debug.warning("get element type == '" + str(type(_value)) + "' but request " + str(elem["type"]));
raise ServerError("FORBIDDEN get element type == '" + str(type(_value)) + "' but request " + str(elem["type"]), status_code=403)
# The key does not exist ...
debug.warning("The KEY: '" + str(_key) + "' Is not in the list of availlable keys");
raise ServerError("FORBIDDEN The KEY: '" + str(_key) + "' Is not in the list of availlable keys", status_code=403)
return False
def put(self, _id, _value):
debug.info("put in " + self.name + ": " + str(_id))
cursor = self.connection.cursor()
request = 'UPDATE ' + self.base_name + ' SET'
list_data = []
first = True;
for elem in _value.keys():
if elem == "id":
continue
if self.is_value_modifiable_and_good_type(elem, _value[elem]) == False:
return;
if first == True:
first = False
else:
request += " , "
list_data.append(_value[elem])
request += " " + elem + " = %s"
request += " WHERE id = %s " + self.where_expand
list_data.append(_id)
debug.info("Request executed : '" + request + "'")
try:
cursor.execute(request, list_data)
except psycopg2.errors.UndefinedFunction:
raise ServerError("INTERNAL_ERROR fail request SQL ...", status_code=500)
finally:
self.connection.commit()
self.mark_to_store();
return self.get(_id);
def post(self, _value):
debug.info("post " + self.name)
cursor = self.connection.cursor()
request = 'INSERT INTO ' + self.base_name
list_data = []
first = True;
aaa = ""
bbb = ""
for elem in _value.keys():
if elem == "id":
continue
if self.is_value_modifiable_and_good_type(elem, _value[elem], "creatable") == False:
return;
if aaa != "":
aaa += " , "
if bbb != "":
bbb += " , "
aaa += elem
bbb += "%s"
list_data.append(_value[elem])
request += " ( " + aaa + ") VALUES ( " + bbb + ") RETURNING id"
debug.info("Request executed : '" + request + "'")
try:
cursor.execute(request, list_data)
except psycopg2.errors.UndefinedFunction:
raise ServerError("INTERNAL_ERROR fail request SQL ...", status_code=500)
finally:
self.connection.commit()
id_of_new_row = cursor.fetchone()[0]
self.mark_to_store();
return self.get(id_of_new_row);

View File

@ -1,34 +0,0 @@
from realog import debug
import psycopg2
import config
connection = None
connection_count = 0
def connect_bdd():
global connection
global connection_count
if connection == None:
debug.info("connect BDD: ")
conf = config.get_rest_config()
connection = psycopg2.connect(dbname=conf["db_name"], user=conf["db_user"], password=conf["db_password"], host=conf["db_host"], port=conf["db_port"])
connection_count += 1
return connection
def remove_connection():
global connection
global connection_count
connection_count -= 1
if connection_count < 0:
debug.warning("Request remove too much time the BDD connection");
connection_count = 0;
return;
if connection_count == 0:
debug.warning("dicconnect BDD");
connection.commit()
connection.close()
connection = None
return;
base_bdd_name = "karideo_"

View File

@ -0,0 +1,93 @@
package org.kar.karideo;
import org.kar.karideo.model.User;
import org.kar.karideo.model.UserSmall;
import javax.annotation.Priority;
import javax.ws.rs.Priorities;
import javax.ws.rs.container.ContainerRequestContext;
import javax.ws.rs.container.ContainerRequestFilter;
import javax.ws.rs.core.HttpHeaders;
import javax.ws.rs.core.Response;
import javax.ws.rs.ext.Provider;
import java.io.IOException;
// https://stackoverflow.com/questions/26777083/best-practice-for-rest-token-based-authentication-with-jax-rs-and-jersey
// https://stackoverflow.com/questions/26777083/best-practice-for-rest-token-based-authentication-with-jax-rs-and-jersey/45814178#45814178
// https://stackoverflow.com/questions/32817210/how-to-access-jersey-resource-secured-by-rolesallowed
//@Provider
//@PreMatching
@Secured
@Provider
@Priority(Priorities.AUTHENTICATION)
public class AuthenticationFilter implements ContainerRequestFilter {
private static final String REALM = "example";
private static final String AUTHENTICATION_SCHEME = "Yota";
@Override
public void filter(ContainerRequestContext requestContext) throws IOException {
System.out.println("-----------------------------------------------------");
System.out.println("---- Check if have authorization ----");
System.out.println("-----------------------------------------------------");
// Get the Authorization header from the request
String authorizationHeader = requestContext.getHeaderString(HttpHeaders.AUTHORIZATION);
System.out.println("authorizationHeader: " + authorizationHeader);
// Validate the Authorization header
if (!isTokenBasedAuthentication(authorizationHeader)) {
abortWithUnauthorized(requestContext);
return;
}
// Extract the token from the Authorization header
String token = authorizationHeader.substring(AUTHENTICATION_SCHEME.length()).trim();
System.out.println("token: " + token);
User user = null;
try {
user = validateToken(token);
} catch (Exception e) {
abortWithUnauthorized(requestContext);
}
if (user == null) {
abortWithUnauthorized(requestContext);
}
String scheme = requestContext.getUriInfo().getRequestUri().getScheme();
requestContext.setSecurityContext(new MySecurityContext(user, scheme));
System.out.println("Get local user : " + user);
}
private boolean isTokenBasedAuthentication(String authorizationHeader) {
// Check if the Authorization header is valid
// It must not be null and must be prefixed with "Bearer" plus a whitespace
// The authentication scheme comparison must be case-insensitive
return authorizationHeader != null && authorizationHeader.toLowerCase()
.startsWith(AUTHENTICATION_SCHEME.toLowerCase() + " ");
}
private void abortWithUnauthorized(ContainerRequestContext requestContext) {
// Abort the filter chain with a 401 status code response
// The WWW-Authenticate header is sent along with the response
requestContext.abortWith(
Response.status(Response.Status.UNAUTHORIZED)
.header(HttpHeaders.WWW_AUTHENTICATE,
AUTHENTICATION_SCHEME + " realm=\"" + REALM + "\"")
.build());
}
private User validateToken(String authorization) throws Exception {
System.out.println("-----------------------------------------------------");
System.out.println("---- TODO validate token ----");
System.out.println("-----------------------------------------------------");
// Check if the token was issued by the server and if it's not expired
// Throw an Exception if the token is invalid
String[] value = authorization.split(":");
long user = Long.valueOf(value[0]);
String token = value[1];
UserSmall userOAuth = UserDB.getUserOAuth(user, token);
System.out.println("Get local userOAuth : " + userOAuth);
return UserDB.getUserOrCreate(userOAuth);
}
}

View File

@ -0,0 +1,26 @@
package org.kar.karideo;
import javax.ws.rs.container.ContainerRequestContext;
import javax.ws.rs.container.ContainerResponseContext;
import javax.ws.rs.container.ContainerResponseFilter;
import javax.ws.rs.ext.Provider;
import java.io.IOException;
@Provider
public class CORSFilter implements ContainerResponseFilter {
@Override
public void filter(ContainerRequestContext request,
ContainerResponseContext response) throws IOException {
//System.err.println("filter cors ..." + request.toString());
response.getHeaders().add("Access-Control-Allow-Origin", "*");
response.getHeaders().add("Access-Control-Allow-Headers", "*");
// "Origin, content-type, Content-type, Accept, authorization, mime-type, filename");
response.getHeaders().add("Access-Control-Allow-Credentials", "true");
response.getHeaders().add("Access-Control-Allow-Methods",
"GET, POST, PUT, DELETE, OPTIONS, HEAD");
}
}

View File

@ -0,0 +1,76 @@
package org.kar.karideo;
public class ConfigVariable {
public static String getTmpDataFolder() {
String out = System.getProperty("org.kar.karideo.dataTmpFolder");
if (out == null) {
return "/application/data/tmp";
}
return out;
}
public static String getMediaDataFolder() {
String out = System.getProperty("org.kar.karideo.dataFolder");
if (out == null) {
return "/application/data/media";
}
return out;
}
public static String getRestOAuthServer() {
String out = System.getProperty("org.kar.karideo.rest.oauth");
if (out == null) {
return "http://localhost:17080/oauth/api/";
}
return out;
}
public static String getDBHost() {
String out = System.getProperty("org.kar.karideo.db.host");
if (out == null) {
return "localhost";
}
return out;
}
public static String getDBPort() {
String out = System.getProperty("org.kar.karideo.db.port");
if (out == null) {
return "3306";
}
return out;
}
public static String getDBLogin() {
String out = System.getProperty("org.kar.karideo.db.login");
if (out == null) {
return "root";
}
return out;
}
public static String getDBPassword() {
String out = System.getProperty("org.kar.karideo.db.password");
if (out == null) {
return "klkhj456gkgtkhjgvkujfhjgkjhgsdfhb3467465fgdhdesfgh";
}
return out;
}
public static String getDBName() {
String out = System.getProperty("org.kar.karideo.db.name");
if (out == null) {
return "karideo";
}
return out;
}
public static String getlocalAddress() {
String out = System.getProperty("org.kar.karideo.address");
if (out == null) {
return "http://localhost:18080/karideo/api/";
}
return out;
}
}

View File

@ -0,0 +1,22 @@
package org.kar.karideo;
import org.kar.karideo.model.User;
import java.security.Principal;
public class GenericContext implements Principal {
public User user;
public GenericContext(User user) {
this.user = user;
}
@Override
public String getName() {
if (user == null) {
return "???";
}
return user.login;
}
}

View File

@ -0,0 +1,46 @@
package org.kar.karideo;
import org.kar.karideo.model.User;
import javax.ws.rs.core.SecurityContext;
import java.security.Principal;
// https://simplapi.wordpress.com/2015/09/19/jersey-jax-rs-securitycontext-in-action/
class MySecurityContext implements SecurityContext {
private final GenericContext contextPrincipale;
private final String sheme;
public MySecurityContext(User user, String sheme) {
this.contextPrincipale = new GenericContext(user);
this.sheme = sheme;
}
@Override
public Principal getUserPrincipal() {
return contextPrincipale;
}
@Override
public boolean isUserInRole(String role) {
if (role.contentEquals("ADMIN")) {
return contextPrincipale.user.admin == true;
}
if (role.contentEquals("USER")) {
return contextPrincipale.user.admin == false;
}
return false;
}
@Override
public boolean isSecure() {
return true;
}
@Override
public String getAuthenticationScheme() {
return "Yota";
}
}

View File

@ -0,0 +1,21 @@
package org.kar.karideo;
import javax.ws.rs.container.ContainerRequestContext;
import javax.ws.rs.container.ContainerRequestFilter;
import javax.ws.rs.container.PreMatching;
import javax.ws.rs.core.Response;
import javax.ws.rs.ext.Provider;
import java.io.IOException;
@Provider
@PreMatching
public class OptionFilter implements ContainerRequestFilter {
@Override
public void filter(ContainerRequestContext requestContext) throws IOException {
if (requestContext.getMethod().contentEquals("OPTIONS")) {
requestContext.abortWith(Response.status(Response.Status.NO_CONTENT).build());
}
}
}

View File

@ -0,0 +1,15 @@
package org.kar.karideo;
import javax.ws.rs.NameBinding;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.ElementType.TYPE;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
@NameBinding
@Retention(RUNTIME)
@Target({TYPE, METHOD})
public @interface Secured {
}

View File

@ -0,0 +1,216 @@
package org.kar.karideo;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.kar.karideo.db.DBEntry;
import org.kar.karideo.model.State;
import org.kar.karideo.model.User;
import org.kar.karideo.model.UserSmall;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
public class UserDB {
public UserDB() {
}
public static User getUsers(long userId) {
DBEntry entry = new DBEntry(WebLauncher.dbConfig);
String query = "SELECT * FROM user WHERE id = ?";
try {
PreparedStatement ps = entry.connection.prepareStatement(query);
ps.setLong(1, userId);
ResultSet rs = ps.executeQuery();
if (rs.next()) {
User out = new User(rs);
entry.disconnect();
return out;
}
} catch (SQLException throwables) {
throwables.printStackTrace();
}
entry.disconnect();
return null;
}
@Deprecated
public static User getAndCreate(long userId, String token) throws IOException {
// check Token:
URL obj = new URL(WebLauncher.getOAuthURI() + "users/check_token?id=" + userId + "&token=" + token);
HttpURLConnection con = (HttpURLConnection) obj.openConnection();
con.setRequestMethod("GET");
con.setRequestProperty("User-Agent", "karideo");
con.setRequestProperty("Cache-Control", "no-cache");
con.setRequestProperty("Content-Type", "application/json");
con.setRequestProperty("Accept", "application/json");
int responseCode = con.getResponseCode();
System.out.println("GET Response Code :: " + responseCode);
if (responseCode == HttpURLConnection.HTTP_OK) { // success
BufferedReader in = new BufferedReader(new InputStreamReader(
con.getInputStream()));
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
response.append(inputLine);
}
in.close();
// print result
System.out.println(response.toString());
ObjectMapper mapper = new ObjectMapper();
;
UserSmall value = mapper.readValue(response.toString(), UserSmall.class);
System.out.println("user SMALL " + value);
return null;
} else {
System.out.println("GET request not worked");
}
return null;
}
public static UserSmall getUserOAuth(long userId, String token) throws IOException {
// check Token:
URL obj = new URL(WebLauncher.getOAuthURI() + "users/check_token?id=" + userId + "&token=" + token);
HttpURLConnection con = (HttpURLConnection) obj.openConnection();
con.setRequestMethod("GET");
con.setRequestProperty("User-Agent", "karideo");
con.setRequestProperty("Cache-Control", "no-cache");
con.setRequestProperty("Content-Type", "application/json");
con.setRequestProperty("Accept", "application/json");
int responseCode = con.getResponseCode();
System.out.println("GET Response Code :: " + responseCode);
if (responseCode == HttpURLConnection.HTTP_OK) { // success
BufferedReader in = new BufferedReader(new InputStreamReader(
con.getInputStream()));
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
response.append(inputLine);
}
in.close();
// print result
System.out.println(response.toString());
ObjectMapper mapper = new ObjectMapper();
;
return mapper.readValue(response.toString(), UserSmall.class);
}
System.out.println("GET request not worked");
return null;
}
public static User getUserOrCreate(UserSmall userOAuth) {
User user = getUsers(userOAuth.id);
if (user != null) {
boolean blocked = false;
boolean removed = false;
if (userOAuth.authorisationLevel == State.BLOCKED) {
blocked = true;
} else if (userOAuth.authorisationLevel == State.REMOVED) {
removed = true;
}
if (user.email != userOAuth.email || user.login != userOAuth.login || user.blocked != blocked || user.removed != removed) {
updateUsersInfoFromOAuth(userOAuth.id, userOAuth.email, userOAuth.login, blocked, removed);
} else {
updateUsersConnectionTime(userOAuth.id);
}
return getUsers(userOAuth.id);
} else {
if (userOAuth.authorisationLevel == State.BLOCKED) {
return null;
} else if (userOAuth.authorisationLevel == State.REMOVED) {
return null;
}
createUsersInfoFromOAuth(userOAuth.id, userOAuth.email, userOAuth.login);
}
return getUsers(userOAuth.id);
}
private static void updateUsersConnectionTime(long userId) {
DBEntry entry = new DBEntry(WebLauncher.dbConfig);
String query = "UPDATE `user` SET `lastConnection`=now(3) WHERE `id` = ?";
try {
PreparedStatement ps = entry.connection.prepareStatement(query);
ps.setLong(1, userId);
ps.executeUpdate();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
entry.disconnect();
}
private static void updateUsersInfoFromOAuth(long userId, String email, String login, boolean blocked, boolean removed) {
DBEntry entry = new DBEntry(WebLauncher.dbConfig);
String query = "UPDATE `user` SET `login`=?, `email`=?, `lastConnection`=now(3), `blocked`=?, `removed`=? WHERE id = ?";
try {
PreparedStatement ps = entry.connection.prepareStatement(query);
ps.setString(1, login);
ps.setString(2, email);
ps.setString(3, blocked ? "TRUE" : "FALSE");
ps.setString(4, removed ? "TRUE" : "FALSE");
ps.setLong(5, userId);
ps.executeUpdate();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
entry.disconnect();
}
private static void createUsersInfoFromOAuth(long userId, String email, String login) {
DBEntry entry = new DBEntry(WebLauncher.dbConfig);
String query = "INSERT INTO `user` (`id`, `login`, `email`, `lastConnection`, `admin`, `blocked`, `removed`) VALUE (?,?,?,now(3),'FALSE','FALSE','FALSE')";
try {
PreparedStatement ps = entry.connection.prepareStatement(query);
ps.setLong(1, userId);
ps.setString(2, login);
ps.setString(3, email);
ps.executeUpdate();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
entry.disconnect();
}
}

View File

@ -0,0 +1,108 @@
package org.kar.karideo;
import org.glassfish.grizzly.http.server.HttpServer;
import org.glassfish.jersey.grizzly2.httpserver.GrizzlyHttpServerFactory;
import org.glassfish.jersey.media.multipart.MultiPartFeature;
import org.glassfish.jersey.server.ResourceConfig;
import org.kar.karideo.api.*;
import org.kar.karideo.db.DBConfig;
import org.glassfish.jersey.jackson.JacksonFeature;
import javax.ws.rs.core.UriBuilder;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.net.URI;
import java.util.Properties;
public class WebLauncher {
public static DBConfig dbConfig;
private WebLauncher() {
}
private static URI getBaseURI() {
return UriBuilder.fromUri(ConfigVariable.getlocalAddress()).build();
}
public static String getOAuthURI() {
return ConfigVariable.getRestOAuthServer();
}
public static void main(String[] args) {
try {
FileInputStream propFile = new FileInputStream( "/application/properties.txt");
Properties p = new Properties(System.getProperties());
p.load(propFile);
for (String name : p.stringPropertyNames()) {
String value = p.getProperty(name);
// inject property if not define in cmdline:
if (System.getProperty(name) == null) {
System.setProperty(name, value);
}
}
} catch (FileNotFoundException e) {
System.out.println("File of environment variable not found: 'properties.txt'");
} catch (IOException e) {
e.printStackTrace();
}
ResourceConfig rc = new ResourceConfig();
// add multipart models ..
//rc.register(new MultiPartFeature());
//rc.register(new InjectionBinder());
rc.register(new MultiPartFeature());
//rc.register(new MyFileUploader());
// global authentication system
rc.register(new OptionFilter());
// remove cors ==> all time called by an other system...
rc.register(new CORSFilter());
// global authentication system
rc.register(new AuthenticationFilter());
// add default resource:
rc.registerClasses(UserResource.class);
rc.registerClasses(SeriesResource.class);
rc.registerClasses(DataResource.class);
rc.registerClasses(SeasonResource.class);
rc.registerClasses(TypeResource.class);
rc.registerClasses(UniverseResource.class);
rc.registerClasses(VideoResource.class);
// add jackson to be discovenr when we are ins standalone server
rc.register(JacksonFeature.class);
// enable this to show low level request
//rc.property(LoggingFeature.LOGGING_FEATURE_LOGGER_LEVEL_SERVER, Level.WARNING.getName());
System.out.println("Connect on the BDD:");
System.out.println(" getDBHost: '" + ConfigVariable.getDBHost() + "'");
System.out.println(" getDBPort: '" + ConfigVariable.getDBPort() + "'");
System.out.println(" getDBLogin: '" + ConfigVariable.getDBLogin() + "'");
System.out.println(" getDBPassword: '" + ConfigVariable.getDBPassword() + "'");
System.out.println(" getDBName: '" + ConfigVariable.getDBName() + "'");
dbConfig = new DBConfig(ConfigVariable.getDBHost(),
Integer.parseInt(ConfigVariable.getDBPort()),
ConfigVariable.getDBLogin(),
ConfigVariable.getDBPassword(),
ConfigVariable.getDBName());
System.out.println(" ==> " + dbConfig);
System.out.println("OAuth service " + ConfigVariable.getRestOAuthServer());
HttpServer server = GrizzlyHttpServerFactory.createHttpServer(getBaseURI(), rc);
Runtime.getRuntime().addShutdownHook(new Thread(new Runnable() {
@Override
public void run() {
System.out.println("Stopping server..");
server.shutdownNow();
}
}, "shutdownHook"));
// run
try {
server.start();
System.out.println("Jersey app started at " + getBaseURI());
System.out.println("Press CTRL^C to exit..");
Thread.currentThread().join();
} catch (Exception e) {
System.out.println("There was an error while starting Grizzly HTTP server.");
e.printStackTrace();
}
}
}

View File

@ -0,0 +1,507 @@
package org.kar.karideo.api;
import org.glassfish.jersey.media.multipart.FormDataContentDisposition;
import org.glassfish.jersey.media.multipart.FormDataParam;
import org.kar.karideo.ConfigVariable;
import org.kar.karideo.WebLauncher;
import org.kar.karideo.db.DBEntry;
import org.kar.karideo.model.Data;
import org.kar.karideo.model.DataSmall;
import javax.annotation.security.PermitAll;
import javax.imageio.ImageIO;
import javax.ws.rs.*;
import javax.ws.rs.core.HttpHeaders;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.StreamingOutput;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.*;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Date;
// https://stackoverflow.com/questions/35367113/jersey-webservice-scalable-approach-to-download-file-and-reply-to-client
// https://gist.github.com/aitoroses/4f7a2b197b732a6a691d
@Path("/data")
@PermitAll
@Produces({MediaType.APPLICATION_JSON})
public class DataResource {
private final static int CHUNK_SIZE = 1024 * 1024; // 1MB chunks
private final static int CHUNK_SIZE_IN = 50 * 1024 * 1024; // 1MB chunks
/**
* Upload some datas
*/
private static long tmpFolderId = 1;
private static void createFolder(String path) throws IOException {
if (!Files.exists(java.nio.file.Path.of(path))) {
//Log.print("Create folder: " + path);
Files.createDirectories(java.nio.file.Path.of(path));
}
}
public static long getTmpDataId() {
return tmpFolderId++;
}
public static String getTmpFileInData(long tmpFolderId) {
String filePath = ConfigVariable.getTmpDataFolder() + File.separator + tmpFolderId;
try {
createFolder(ConfigVariable.getTmpDataFolder() + File.separator);
} catch (IOException e) {
e.printStackTrace();
}
return filePath;
}
public static String getFileData(long tmpFolderId) {
String filePath = ConfigVariable.getMediaDataFolder() + File.separator + tmpFolderId + File.separator + "data";
try {
createFolder(ConfigVariable.getMediaDataFolder() + File.separator + tmpFolderId + File.separator);
} catch (IOException e) {
e.printStackTrace();
}
return filePath;
}
public static Data getWithSha512(String sha512) {
System.out.println("find sha512 = " + sha512);
DBEntry entry = new DBEntry(WebLauncher.dbConfig);
String query = "SELECT `id`, `deleted`, `sha512`, `mime_type`, `size` FROM `data` WHERE `sha512` = ?";
try {
PreparedStatement ps = entry.connection.prepareStatement(query);
ps.setString(1, sha512);
ResultSet rs = ps.executeQuery();
if (rs.next()) {
Data out = new Data(rs);
entry.disconnect();
return out;
}
} catch (SQLException throwables) {
throwables.printStackTrace();
}
entry.disconnect();
return null;
}
public static Data getWithId(long id) {
DBEntry entry = new DBEntry(WebLauncher.dbConfig);
String query = "SELECT `id`, `deleted`, `sha512`, `mime_type`, `size` FROM `data` WHERE `deleted` = false AND `id` = ?";
try {
PreparedStatement ps = entry.connection.prepareStatement(query);
ps.setLong(1, id);
ResultSet rs = ps.executeQuery();
if (rs.next()) {
Data out = new Data(rs);
entry.disconnect();
return out;
}
} catch (SQLException throwables) {
throwables.printStackTrace();
}
entry.disconnect();
return null;
}
public static Data createNewData(long tmpUID, String originalFileName, String sha512) throws IOException, SQLException {
// determine mime type:
String mimeType = "";
String extension = originalFileName.substring(originalFileName.lastIndexOf('.') + 1);
switch (extension.toLowerCase()) {
case "jpg":
case "jpeg":
mimeType = "image/jpeg";
break;
case "png":
mimeType = "image/png";
break;
case "webp":
mimeType = "image/webp";
break;
case "mka":
mimeType = "audio/x-matroska";
break;
case "mkv":
mimeType = "video/x-matroska";
break;
case "webm":
mimeType = "video/webm";
break;
default:
throw new IOException("Can not find the mime type of data input: '" + extension + "'");
}
String tmpPath = getTmpFileInData(tmpUID);
long fileSize = Files.size(Paths.get(tmpPath));
DBEntry entry = new DBEntry(WebLauncher.dbConfig);
long uniqueSQLID = -1;
try {
// prepare the request:
String query = "INSERT INTO `data` (`sha512`, `mime_type`, `size`, `original_name`) VALUES (?, ?, ?, ?)";
PreparedStatement ps = entry.connection.prepareStatement(query,
Statement.RETURN_GENERATED_KEYS);
int iii = 1;
ps.setString(iii++, sha512);
ps.setString(iii++, mimeType);
ps.setLong(iii++, fileSize);
ps.setString(iii++, originalFileName);
// execute the request
int affectedRows = ps.executeUpdate();
if (affectedRows == 0) {
throw new SQLException("Creating data failed, no rows affected.");
}
// retreive uid inserted
try (ResultSet generatedKeys = ps.getGeneratedKeys()) {
if (generatedKeys.next()) {
uniqueSQLID = generatedKeys.getLong(1);
} else {
throw new SQLException("Creating user failed, no ID obtained (1).");
}
} catch (Exception ex) {
System.out.println("Can not get the UID key inserted ... ");
ex.printStackTrace();
throw new SQLException("Creating user failed, no ID obtained (2).");
}
} catch (SQLException ex) {
ex.printStackTrace();
}
entry.disconnect();
System.out.println("Add Data raw done. uid data=" + uniqueSQLID);
Data out = getWithId(uniqueSQLID);
String mediaPath = getFileData(out.id);
System.out.println("src = " + tmpPath);
System.out.println("dst = " + mediaPath);
Files.move(Paths.get(tmpPath), Paths.get(mediaPath), StandardCopyOption.ATOMIC_MOVE);
System.out.println("Move done");
// all is done the file is corectly installed...
return out;
}
public static void undelete(Long id) {
DBEntry entry = new DBEntry(WebLauncher.dbConfig);
String query = "UPDATE `data` SET `deleted` = false WHERE `id` = ?";
try {
PreparedStatement ps = entry.connection.prepareStatement(query);
ps.setLong(1, id);
ps.execute();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
entry.disconnect();
}
static String saveTemporaryFile(InputStream uploadedInputStream, long idData) {
return saveFile(uploadedInputStream, DataResource.getTmpFileInData(idData));
}
static void removeTemporaryFile(long idData) {
String filepath = DataResource.getTmpFileInData(idData);
if (Files.exists(Paths.get(filepath))) {
try {
Files.delete(Paths.get(filepath));
} catch (IOException e) {
System.out.println("can not delete temporary file : " + Paths.get(filepath));
e.printStackTrace();
}
}
}
// save uploaded file to a defined location on the server
static String saveFile(InputStream uploadedInputStream, String serverLocation) {
String out = "";
try {
OutputStream outpuStream = new FileOutputStream(new File(
serverLocation));
int read = 0;
byte[] bytes = new byte[CHUNK_SIZE_IN];
MessageDigest md = MessageDigest.getInstance("SHA-512");
outpuStream = new FileOutputStream(new File(serverLocation));
while ((read = uploadedInputStream.read(bytes)) != -1) {
//System.out.println("write " + read);
md.update(bytes, 0, read);
outpuStream.write(bytes, 0, read);
}
System.out.println("Flush input stream ... " + serverLocation);
System.out.flush();
outpuStream.flush();
outpuStream.close();
// create the end of sha512
byte[] sha512Digest = md.digest();
// convert in hexadecimal
out = bytesToHex(sha512Digest);
uploadedInputStream.close();
} catch (IOException ex) {
System.out.println("Can not write in temporary file ... ");
ex.printStackTrace();
} catch (NoSuchAlgorithmException ex) {
System.out.println("Can not find sha512 algorithms");
ex.printStackTrace();
}
return out;
}
// curl http://localhost:9993/api/users/3
//@Secured
/*
@GET
@Path("{id}")
//@RolesAllowed("GUEST")
@Produces(MediaType.APPLICATION_OCTET_STREAM)
public Response retriveData(@HeaderParam("Range") String range, @PathParam("id") Long id) throws Exception {
return retriveDataFull(range, id, "no-name");
}
*/
public static String bytesToHex(byte[] bytes) {
StringBuilder sb = new StringBuilder();
for (byte b : bytes) {
sb.append(String.format("%02x", b));
}
return sb.toString();
}
/*
@POST
@Path("/upload")
@Consumes(MediaType.MULTIPART_FORM_DATA)
public Response uploadFile(FormDataMultiPart form) {
FormDataBodyPart filePart = form.getField("file");
ContentDisposition headerOfFilePart = filePart.getContentDisposition();
InputStream fileInputStream = filePart.getValueAs(InputStream.class);
String filePath = ConfigVariable.getTmpDataFolder() + File.separator + tmpFolderId++;
//headerOfFilePart.getFileName();
// save the file to the server
saveFile(fileInputStream, filePath);
String output = "File saved to server location using FormDataMultiPart : " + filePath;
return Response.status(200).entity(output).build();
}
*/
public DataSmall getSmall(Long id) {
DBEntry entry = new DBEntry(WebLauncher.dbConfig);
String query = "SELECT `id`, `sha512`, `mime_type`, `size` FROM `data` WHERE `deleted` = false AND `id` = ?";
try {
PreparedStatement ps = entry.connection.prepareStatement(query);
ps.setLong(1, id);
ResultSet rs = ps.executeQuery();
if (rs.next()) {
DataSmall out = new DataSmall(rs);
entry.disconnect();
return out;
}
} catch (SQLException throwables) {
throwables.printStackTrace();
}
entry.disconnect();
return null;
}
@POST
@Path("/upload/")
@Consumes({MediaType.MULTIPART_FORM_DATA})
public Response uploadFile(@FormDataParam("file") InputStream fileInputStream, @FormDataParam("file") FormDataContentDisposition fileMetaData) {
//public NodeSmall uploadFile(final FormDataMultiPart form) {
System.out.println("Upload file: ");
String filePath = ConfigVariable.getTmpDataFolder() + File.separator + tmpFolderId++;
try {
createFolder(ConfigVariable.getTmpDataFolder() + File.separator);
} catch (IOException e) {
e.printStackTrace();
}
saveFile(fileInputStream, filePath);
return Response.ok("Data uploaded successfully !!").build();
//return null;
}
//@Secured
@GET
@Path("{id}")
//@RolesAllowed("GUEST")
@Produces(MediaType.APPLICATION_OCTET_STREAM)
public Response retriveDataId(/*@Context SecurityContext sc,*/ @HeaderParam("Range") String range, @PathParam("id") Long id) throws Exception {
/*
GenericContext gc = (GenericContext) sc.getUserPrincipal();
System.out.println("===================================================");
System.out.println("== USER get data ? " + gc.user);
System.out.println("===================================================");
*/
DataSmall value = getSmall(id);
if (value == null) {
Response.status(404).
entity("media NOT FOUND: " + id).
type("text/plain").
build();
}
return buildStream(ConfigVariable.getMediaDataFolder() + File.separator + id + File.separator + "data", range, value.mimeType);
}
//@Secured
@GET
@Path("thumbnail/{id}")
//@RolesAllowed("GUEST")
@Produces(MediaType.APPLICATION_OCTET_STREAM)
public Response retriveDataThumbnailId(/*@Context SecurityContext sc,*/ @HeaderParam("Range") String range, @PathParam("id") Long id) throws Exception {
/*
GenericContext gc = (GenericContext) sc.getUserPrincipal();
System.out.println("===================================================");
System.out.println("== USER get data ? " + gc.user);
System.out.println("===================================================");
*/
DataSmall value = getSmall(id);
if (value == null) {
Response.status(404).
entity("media NOT FOUND: " + id).
type("text/plain").
build();
}
String filePathName = ConfigVariable.getMediaDataFolder() + File.separator + id + File.separator + "data";
if ( value.mimeType.contentEquals("image/jpeg")
|| value.mimeType.contentEquals("image/png")
// || value.mimeType.contentEquals("image/webp")
) {
// reads input image
File inputFile = new File(filePathName);
BufferedImage inputImage = ImageIO.read(inputFile);
int scaledWidth = 250;
int scaledHeight = (int)((float)inputImage.getHeight() / (float)inputImage.getWidth() * (float) scaledWidth);
// creates output image
BufferedImage outputImage = new BufferedImage(scaledWidth,
scaledHeight, inputImage.getType());
// scales the input image to the output image
Graphics2D g2d = outputImage.createGraphics();
g2d.drawImage(inputImage, 0, 0, scaledWidth, scaledHeight, null);
g2d.dispose();
// create the oputput stream:
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ImageIO.write(outputImage, "JPG", baos);
byte[] imageData = baos.toByteArray();
Response.ok(new ByteArrayInputStream(imageData)).build();
Response.ResponseBuilder out = Response.ok(imageData)
.header(HttpHeaders.CONTENT_LENGTH, imageData.length);
out.type("image/jpeg");
return out.build();
}
return buildStream(filePathName, range, value.mimeType);
}
//@Secured
@GET
@Path("{id}/{name}")
//@RolesAllowed("GUEST")
@Produces(MediaType.APPLICATION_OCTET_STREAM)
public Response retriveDataFull(/*@Context SecurityContext sc,*/ @HeaderParam("Range") String range, @PathParam("id") Long id, @PathParam("name") String name) throws Exception {
/*
GenericContext gc = (GenericContext) sc.getUserPrincipal();
System.out.println("===================================================");
System.out.println("== USER get data ? " + gc.user);
System.out.println("===================================================");
*/
DataSmall value = getSmall(id);
if (value == null) {
Response.status(404).
entity("media NOT FOUND: " + id).
type("text/plain").
build();
}
return buildStream(ConfigVariable.getMediaDataFolder() + File.separator + id + File.separator + "data", range, value.mimeType);
}
/**
* Adapted from http://stackoverflow.com/questions/12768812/video-streaming-to-ipad-does-not-work-with-tapestry5/12829541#12829541
*
* @param range range header
* @return Streaming output
* @throws Exception IOException if an error occurs in streaming.
*/
private Response buildStream(final String filename, final String range, String mimeType) throws Exception {
File file = new File(filename);
//System.out.println("request range : " + range);
// range not requested : Firefox does not send range headers
if (range == null) {
final StreamingOutput output = new StreamingOutput() {
@Override
public void write(OutputStream out) {
try (FileInputStream in = new FileInputStream(file)) {
byte[] buf = new byte[1024 * 1024];
int len;
while ((len = in.read(buf)) != -1) {
try {
out.write(buf, 0, len);
out.flush();
//System.out.println("---- wrote " + len + " bytes file ----");
} catch (IOException ex) {
System.out.println("remote close connection");
break;
}
}
} catch (IOException ex) {
throw new InternalServerErrorException(ex);
}
}
};
Response.ResponseBuilder out = Response.ok(output)
.header(HttpHeaders.CONTENT_LENGTH, file.length());
if (mimeType != null) {
out.type(mimeType);
}
return out.build();
}
String[] ranges = range.split("=")[1].split("-");
final long from = Long.parseLong(ranges[0]);
//System.out.println("request range : " + ranges.length);
//Chunk media if the range upper bound is unspecified. Chrome, Opera sends "bytes=0-"
long to = CHUNK_SIZE + from;
if (ranges.length == 1) {
to = file.length() - 1;
} else {
if (to >= file.length()) {
to = (long) (file.length() - 1);
}
}
final String responseRange = String.format("bytes %d-%d/%d", from, to, file.length());
//System.out.println("responseRange : " + responseRange);
final RandomAccessFile raf = new RandomAccessFile(file, "r");
raf.seek(from);
final long len = to - from + 1;
final MediaStreamer streamer = new MediaStreamer(len, raf);
Response.ResponseBuilder out = Response.ok(streamer)
.status(Response.Status.PARTIAL_CONTENT)
.header("Accept-Ranges", "bytes")
.header("Content-Range", responseRange)
.header(HttpHeaders.CONTENT_LENGTH, streamer.getLenth())
.header(HttpHeaders.LAST_MODIFIED, new Date(file.lastModified()));
if (mimeType != null) {
out.type(mimeType);
}
return out.build();
}
}

View File

@ -0,0 +1,71 @@
package org.kar.karideo.api;
import javax.ws.rs.InternalServerErrorException;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.StreamingOutput;
import java.io.IOException;
import java.io.OutputStream;
import java.io.RandomAccessFile;
public class MediaStreamer implements StreamingOutput {
private final int CHUNK_SIZE = 1024 * 1024; // 1MB chunks
final byte[] buf = new byte[CHUNK_SIZE];
private long length;
private RandomAccessFile raf;
public MediaStreamer(long length, RandomAccessFile raf) throws IOException {
//System.out.println("request stream of " + length / 1024 + " data");
if (length<0) {
throw new IOException("Wrong size of the file to stream: " + length);
}
this.length = length;
this.raf = raf;
}
/*
public void write(OutputStream out) {
try (FileInputStream in = new FileInputStream(file)) {
byte[] buf = new byte[1024*1024];
int len;
while ((len = in.read(buf)) != -1) {
out.write(buf, 0, len);
out.flush();
//System.out.println("---- wrote " + len + " bytes file ----");
}
} catch (IOException ex) {
throw new InternalServerErrorException(ex);
}
}
*/
@Override
public void write(OutputStream outputStream) {
try {
while (length != 0) {
int read = raf.read(buf, 0, buf.length > length ? (int) length : buf.length);
try {
outputStream.write(buf, 0, read);
} catch (IOException ex) {
System.out.println("remote close connection");
break;
}
length -= read;
}
} catch (IOException ex) {
throw new InternalServerErrorException(ex);
} catch (WebApplicationException ex) {
throw new InternalServerErrorException(ex);
} finally {
try {
raf.close();
} catch (IOException ex) {
ex.printStackTrace();
throw new InternalServerErrorException(ex);
}
}
}
public long getLenth() {
return length;
}
}

View File

@ -0,0 +1,472 @@
package org.kar.karideo.api;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.glassfish.jersey.media.multipart.FormDataContentDisposition;
import org.kar.karideo.WebLauncher;
import org.kar.karideo.db.DBEntry;
import org.kar.karideo.model.Data;
import org.kar.karideo.model.NodeSmall;
import javax.ws.rs.core.Response;
import java.io.IOException;
import java.io.InputStream;
import java.sql.*;
import java.util.ArrayList;
import java.util.List;
public class NodeInterface {
/* test en SQL qui fait joli...
SELECT node.id,
node.name,
node.description,
node.parent_id,
GROUP_CONCAT(cover_link_node.data_id SEPARATOR '-') as covers
FROM node, cover_link_node
WHERE node.deleted = false AND cover_link_node.deleted = false AND node.type = "TYPE" AND cover_link_node.node_id = node.id
GROUP BY node.id
ORDER BY node.name
// bon c'est bien mais c'est mieux en faisant un left join avec préfiltrage ...
SELECT node.id,
node.name,
node.description,
node.parent_id,
cover_link_node.data_id
FROM node
LEFT JOIN cover_link_node
ON node.id = cover_link_node.node_id
AND cover_link_node.deleted = false
WHERE node.deleted = false
AND node.type = "TYPE"
ORDER BY node.name
// marche pas:
SELECT node.id,
node.name,
node.description,
node.parent_id,
`extract.covers`
FROM node
LEFT JOIN (SELECT tmp.node_id,
GROUP_CONCAT(`tmp.data_id` SEPARATOR '-') as `covers`
FROM cover_link_node tmp
WHERE tmp.deleted = false
GROUP BY tmp.node_id) extract
ON node.id = extract.node_id
WHERE node.deleted = false
AND node.type = "TYPE"
ORDER BY node.name
// et enfin une version qui fonctionne ...
SELECT node.id,
node.name,
node.description,
node.parent_id,
(SELECT GROUP_CONCAT(tmp.data_id)
FROM cover_link_node tmp
WHERE tmp.deleted = false
AND node.id = tmp.node_id
GROUP BY tmp.node_id) AS covers
FROM node
WHERE node.deleted = false
AND node.type = "TYPE"
ORDER BY node.name
*/
public static List<NodeSmall> get(String typeInNode) {
System.out.println(typeInNode + " get");
DBEntry entry = new DBEntry(WebLauncher.dbConfig);
List<NodeSmall> out = new ArrayList<>();
String query = "SELECT node.id," +
" node.name," +
" node.description," +
" node.parent_id," +
" (SELECT GROUP_CONCAT(tmp.data_id SEPARATOR '-')" +
" FROM cover_link_node tmp" +
" WHERE tmp.deleted = false" +
" AND node.id = tmp.node_id" +
" GROUP BY tmp.node_id) AS covers" +
" FROM node" +
" WHERE node.deleted = false " +
" AND node.type = ?" +
" ORDER BY node.name";
try {
PreparedStatement ps = entry.connection.prepareStatement(query);
int iii = 1;
ps.setString(iii++, typeInNode);
ResultSet rs = ps.executeQuery();
while (rs.next()) {
out.add(new NodeSmall(rs));
}
} catch (SQLException throwables) {
throwables.printStackTrace();
}
entry.disconnect();
entry = null;
System.out.println("retrieve " + out.size() + " " + typeInNode);
return out;
}
public static NodeSmall getWithId(String typeInNode, long id) {
DBEntry entry = new DBEntry(WebLauncher.dbConfig);
String query = "SELECT node.id," +
" node.name," +
" node.description," +
" node.parent_id," +
" (SELECT GROUP_CONCAT(tmp.data_id SEPARATOR '-')" +
" FROM cover_link_node tmp" +
" WHERE tmp.deleted = false" +
" AND node.id = tmp.node_id" +
" GROUP BY tmp.node_id) AS covers" +
" FROM node" +
" WHERE node.deleted = false " +
" AND node.type = ?" +
" AND node.id = ?" +
" ORDER BY node.name";
try {
PreparedStatement ps = entry.connection.prepareStatement(query);
int iii = 1;
ps.setString(iii++, typeInNode);
ps.setLong(iii++, id);
ResultSet rs = ps.executeQuery();
if (rs.next()) {
NodeSmall out = new NodeSmall(rs);
entry.disconnect();
entry = null;
return out;
}
} catch (SQLException throwables) {
throwables.printStackTrace();
}
entry.disconnect();
entry = null;
return null;
}
public static List<NodeSmall> getWithName(String typeInNode, String name) {
DBEntry entry = new DBEntry(WebLauncher.dbConfig);
List<NodeSmall> out = new ArrayList<>();
String query = "SELECT node.id," +
" node.name," +
" node.description," +
" node.parent_id," +
" (SELECT GROUP_CONCAT(tmp.data_id SEPARATOR '-')" +
" FROM cover_link_node tmp" +
" WHERE tmp.deleted = false" +
" AND node.id = tmp.node_id" +
" GROUP BY tmp.node_id) AS covers" +
" FROM node" +
" WHERE node.deleted = false " +
" AND node.type = ?" +
" AND node.name = ?" +
" ORDER BY node.name";
try {
PreparedStatement ps = entry.connection.prepareStatement(query);
int iii = 1;
ps.setString(iii++, typeInNode);
ps.setString(iii++, name);
ResultSet rs = ps.executeQuery();
while (rs.next()) {
out.add(new NodeSmall(rs));
}
} catch (SQLException throwables) {
throwables.printStackTrace();
}
entry.disconnect();
entry = null;
return out;
}
public static NodeSmall getWithNameAndParent(String typeInNode, String name, long parentId) {
DBEntry entry = new DBEntry(WebLauncher.dbConfig);
String query = "SELECT node.id," +
" node.name," +
" node.description," +
" node.parent_id," +
" (SELECT GROUP_CONCAT(tmp.data_id SEPARATOR '-')" +
" FROM cover_link_node tmp" +
" WHERE tmp.deleted = false" +
" AND node.id = tmp.node_id" +
" GROUP BY tmp.node_id) AS covers" +
" FROM node" +
" WHERE node.deleted = false " +
" AND node.type = ?" +
" AND node.name = ?" +
" AND node.parent_id = ?" +
" ORDER BY node.name";
try {
PreparedStatement ps = entry.connection.prepareStatement(query);
int iii = 1;
ps.setString(iii++, typeInNode);
ps.setString(iii++, name);
ps.setLong(iii++, parentId);
ResultSet rs = ps.executeQuery();
if (rs.next()) {
NodeSmall out = new NodeSmall(rs);
entry.disconnect();
entry = null;
return out;
}
} catch (SQLException throwables) {
throwables.printStackTrace();
}
entry.disconnect();
entry = null;
return null;
}
public static NodeSmall createNode(String typeInNode, String name, String descrition, Long parentId) {
DBEntry entry = new DBEntry(WebLauncher.dbConfig);
long uniqueSQLID = -1;
// real add in the BDD:
try {
// prepare the request:
String query = "INSERT INTO node (`type`, `name`, `description`, `parent_id`) VALUES (?, ?, ?, ?)";
PreparedStatement ps = entry.connection.prepareStatement(query,
Statement.RETURN_GENERATED_KEYS);
int iii = 1;
ps.setString(iii++, typeInNode);
ps.setString(iii++, name);
if (descrition == null) {
ps.setNull(iii++, Types.VARCHAR);
} else {
ps.setString(iii++, descrition);
}
if (parentId == null) {
ps.setNull(iii++, Types.BIGINT);
} else {
ps.setLong(iii++, parentId);
}
// execute the request
int affectedRows = ps.executeUpdate();
if (affectedRows == 0) {
throw new SQLException("Creating node failed, no rows affected.");
}
// retreive uid inserted
try (ResultSet generatedKeys = ps.getGeneratedKeys()) {
if (generatedKeys.next()) {
uniqueSQLID = generatedKeys.getLong(1);
} else {
throw new SQLException("Creating node failed, no ID obtained (1).");
}
} catch (Exception ex) {
System.out.println("Can not get the UID key inserted ... ");
ex.printStackTrace();
throw new SQLException("Creating node failed, no ID obtained (2).");
}
ps.execute();
} catch (SQLException ex) {
ex.printStackTrace();
}
return getWithId(typeInNode, uniqueSQLID);
}
public static NodeSmall getOrCreate(String typeInNode, String name, Long parentId) {
if (name == null || name.isEmpty()) {
return null;
}
NodeSmall node = getWithNameAndParent(typeInNode, name, parentId);
if (node != null) {
return node;
}
return createNode(typeInNode, name, null, parentId);
}
static private String multipartCorrection(String data) {
if (data == null) {
return null;
}
if (data.isEmpty()) {
return null;
}
if (data.contentEquals("null")) {
return null;
}
return data;
}
static public Response uploadCover(String typeInNode,
Long nodeId,
String file_name,
InputStream fileInputStream,
FormDataContentDisposition fileMetaData
) {
try {
// correct input string stream :
file_name = multipartCorrection(file_name);
//public NodeSmall uploadFile(final FormDataMultiPart form) {
System.out.println("Upload media file: " + fileMetaData);
System.out.println(" - id: " + nodeId);
System.out.println(" - file_name: " + file_name);
System.out.println(" - fileInputStream: " + fileInputStream);
System.out.println(" - fileMetaData: " + fileMetaData);
System.out.flush();
NodeSmall media = getWithId(typeInNode, nodeId);
if (media == null) {
return Response.notModified("Media Id does not exist or removed...").build();
}
long tmpUID = DataResource.getTmpDataId();
String sha512 = DataResource.saveTemporaryFile(fileInputStream, tmpUID);
Data data = DataResource.getWithSha512(sha512);
if (data == null) {
System.out.println("Need to add the data in the BDD ... ");
System.out.flush();
try {
data = DataResource.createNewData(tmpUID, file_name, sha512);
} catch (IOException ex) {
DataResource.removeTemporaryFile(tmpUID);
ex.printStackTrace();
return Response.notModified("can not create input media").build();
} catch (SQLException ex) {
ex.printStackTrace();
DataResource.removeTemporaryFile(tmpUID);
return Response.notModified("Error in SQL insertion ...").build();
}
} else if (data.deleted == true) {
System.out.println("Data already exist but deleted");
System.out.flush();
DataResource.undelete(data.id);
data.deleted = false;
} else {
System.out.println("Data already exist ... all good");
System.out.flush();
}
// Fist step: retrieve all the Id of each parents:...
System.out.println("Find typeNode");
DBEntry entry = new DBEntry(WebLauncher.dbConfig);
long uniqueSQLID = -1;
// real add in the BDD:
try {
// prepare the request:
String query = "INSERT INTO cover_link_node (create_date, modify_date, node_id, data_id)" +
" VALUES (now(3), now(3), ?, ?)";
PreparedStatement ps = entry.connection.prepareStatement(query,
Statement.RETURN_GENERATED_KEYS);
int iii = 1;
ps.setLong(iii++, media.id);
ps.setLong(iii++, data.id);
// execute the request
int affectedRows = ps.executeUpdate();
if (affectedRows == 0) {
throw new SQLException("Creating data failed, no rows affected.");
}
// retreive uid inserted
try (ResultSet generatedKeys = ps.getGeneratedKeys()) {
if (generatedKeys.next()) {
uniqueSQLID = generatedKeys.getLong(1);
} else {
throw new SQLException("Creating user failed, no ID obtained (1).");
}
} catch (Exception ex) {
System.out.println("Can not get the UID key inserted ... ");
ex.printStackTrace();
throw new SQLException("Creating user failed, no ID obtained (2).");
}
} catch (SQLException ex) {
ex.printStackTrace();
entry.disconnect();
return Response.serverError().build();
}
// if we do not une the file .. remove it ... otherwise this is meamory leak...
DataResource.removeTemporaryFile(tmpUID);
System.out.println("uploaded .... compleate: " + uniqueSQLID);
return Response.ok(getWithId(typeInNode, nodeId)).build();
} catch (Exception ex) {
System.out.println("Cat ann unexpected error ... ");
ex.printStackTrace();
}
return Response.serverError().build();
}
static public Response removeCover(String typeInNode, Long nodeId, Long coverId) {
DBEntry entry = new DBEntry(WebLauncher.dbConfig);
String query = "UPDATE `cover_link_node` SET `modify_date`=now(3), `deleted`=true WHERE `node_id` = ? AND `data_id` = ?";
try {
PreparedStatement ps = entry.connection.prepareStatement(query);
int iii = 1;
ps.setLong(iii++, nodeId);
ps.setLong(iii++, coverId);
ps.executeUpdate();
} catch (SQLException throwables) {
throwables.printStackTrace();
entry.disconnect();
return Response.serverError().build();
}
entry.disconnect();
return Response.ok(getWithId(typeInNode, nodeId)).build();
}
static public Response put(String typeInNode, Long id, String jsonRequest) {
ObjectMapper mapper = new ObjectMapper();
try {
JsonNode root = mapper.readTree(jsonRequest);
String query = "UPDATE `node` SET `modify_date`=now(3)";
if (!root.path("name").isMissingNode()) {
query += ", `name` = ? ";
}
if (!root.path("description").isMissingNode()) {
query += ", `description` = ? ";
}
query += " WHERE `id` = ?";
DBEntry entry = new DBEntry(WebLauncher.dbConfig);
try {
PreparedStatement ps = entry.connection.prepareStatement(query);
int iii = 1;
if (!root.path("name").isMissingNode()) {
if (root.path("name").isNull()) {
ps.setString(iii++, "???");
} else {
ps.setString(iii++, root.path("name").asText());
}
}
if (!root.path("description").isMissingNode()) {
if (root.path("description").isNull()) {
ps.setNull(iii++, Types.VARCHAR);
} else {
ps.setString(iii++, root.path("description").asText());
}
}
ps.setLong(iii++, id);
System.out.println(" request : " + ps.toString());
ps.executeUpdate();
} catch (SQLException throwables) {
throwables.printStackTrace();
entry.disconnect();
entry = null;
return Response.notModified("SQL error").build();
}
entry.disconnect();
entry = null;
} catch (IOException e) {
e.printStackTrace();
return Response.notModified("input json error error").build();
}
return Response.ok(getWithId(typeInNode, id)).build();
}
static public Response delete(String typeInNode, Long nodeId) {
DBEntry entry = new DBEntry(WebLauncher.dbConfig);
String query = "UPDATE `node` SET `modify_date`=now(3), `deleted`=true WHERE `id` = ? AND `type` = ?";
try {
PreparedStatement ps = entry.connection.prepareStatement(query);
int iii = 1;
ps.setLong(iii++, nodeId);
ps.setString(iii++, typeInNode);
ps.executeUpdate();
} catch (SQLException throwables) {
throwables.printStackTrace();
entry.disconnect();
return Response.serverError().build();
}
entry.disconnect();
return Response.ok().build();
}
}

View File

@ -0,0 +1,67 @@
package org.kar.karideo.api;
import org.glassfish.jersey.media.multipart.FormDataContentDisposition;
import org.glassfish.jersey.media.multipart.FormDataParam;
import org.kar.karideo.model.NodeSmall;
import javax.annotation.security.PermitAll;
import javax.ws.rs.*;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import java.io.InputStream;
import java.util.List;
@Path("/season")
@PermitAll
@Produces({MediaType.APPLICATION_JSON})
public class SeasonResource {
private static final String typeInNode = "SEASON";
@GET
@Path("{id}")
public static NodeSmall getWithId(@PathParam("id") Long id) {
return NodeInterface.getWithId(typeInNode, id);
}
public static List<NodeSmall> getWithName(String name) {
return NodeInterface.getWithName(typeInNode, name);
}
public static NodeSmall getOrCreate(int season, Long seriesId) {
return NodeInterface.getOrCreate(typeInNode, Integer.toString(season), seriesId);
}
@GET
public List<NodeSmall> get() {
return NodeInterface.get(typeInNode);
}
@PUT
@Path("{id}")
@Consumes(MediaType.APPLICATION_JSON)
public Response put(@PathParam("id") Long id, String jsonRequest) {
return NodeInterface.put(typeInNode, id, jsonRequest);
}
@DELETE
@Path("{id}")
public Response delete(@PathParam("id") Long id) {
return NodeInterface.delete(typeInNode, id);
}
@POST
@Path("{id}/add_cover")
@Consumes({MediaType.MULTIPART_FORM_DATA})
public Response uploadCover(@PathParam("id") Long id,
@FormDataParam("file_name") String file_name,
@FormDataParam("file") InputStream fileInputStream,
@FormDataParam("file") FormDataContentDisposition fileMetaData
) {
return NodeInterface.uploadCover(typeInNode, id, file_name, fileInputStream, fileMetaData);
}
@GET
@Path("{id}/rm_cover/{cover_id}")
public Response removeCover(@PathParam("id") Long nodeId, @PathParam("cover_id") Long coverId) {
return NodeInterface.removeCover(typeInNode, nodeId, coverId);
}
}

View File

@ -0,0 +1,68 @@
package org.kar.karideo.api;
import org.glassfish.jersey.media.multipart.FormDataContentDisposition;
import org.glassfish.jersey.media.multipart.FormDataParam;
import org.kar.karideo.model.NodeSmall;
import javax.annotation.security.PermitAll;
import javax.ws.rs.*;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import java.io.InputStream;
import java.util.List;
@Path("/series")
@PermitAll
@Produces({MediaType.APPLICATION_JSON})
public class SeriesResource {
private static final String typeInNode = "SERIES";
@GET
@Path("{id}")
public static NodeSmall getWithId(@PathParam("id") Long id) {
return NodeInterface.getWithId(typeInNode, id);
}
public static List<NodeSmall> getWithName(String name) {
return NodeInterface.getWithName(typeInNode, name);
}
public static NodeSmall getOrCreate(String series, Long typeId) {
return NodeInterface.getOrCreate(typeInNode, series, typeId);
}
@GET
public List<NodeSmall> get() {
return NodeInterface.get(typeInNode);
}
@PUT
@Path("{id}")
@Consumes(MediaType.APPLICATION_JSON)
public Response put(@PathParam("id") Long id, String jsonRequest) {
return NodeInterface.put(typeInNode, id, jsonRequest);
}
@DELETE
@Path("{id}")
public Response delete(@PathParam("id") Long id) {
return NodeInterface.delete(typeInNode, id);
}
@POST
@Path("{id}/add_cover")
@Consumes({MediaType.MULTIPART_FORM_DATA})
public Response uploadCover(@PathParam("id") Long id,
@FormDataParam("file_name") String file_name,
@FormDataParam("file") InputStream fileInputStream,
@FormDataParam("file") FormDataContentDisposition fileMetaData
) {
return NodeInterface.uploadCover(typeInNode, id, file_name, fileInputStream, fileMetaData);
}
@GET
@Path("{id}/rm_cover/{cover_id}")
public Response removeCover(@PathParam("id") Long nodeId, @PathParam("cover_id") Long coverId) {
return NodeInterface.removeCover(typeInNode, nodeId, coverId);
}
}

View File

@ -0,0 +1,63 @@
package org.kar.karideo.api;
import org.glassfish.jersey.media.multipart.FormDataContentDisposition;
import org.glassfish.jersey.media.multipart.FormDataParam;
import org.kar.karideo.model.NodeSmall;
import javax.annotation.security.PermitAll;
import javax.ws.rs.*;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import java.io.InputStream;
import java.util.List;
@Path("/type")
@PermitAll
@Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
public class TypeResource {
private static final String typeInNode = "TYPE";
@GET
@Path("{id}")
public static NodeSmall getWithId(@PathParam("id") Long id) {
return NodeInterface.getWithId(typeInNode, id);
}
public static List<NodeSmall> getWithName(String name) {
return NodeInterface.getWithName(typeInNode, name);
}
@GET
public List<NodeSmall> get() {
return NodeInterface.get(typeInNode);
}
@PUT
@Path("{id}")
@Consumes(MediaType.APPLICATION_JSON)
public Response put(@PathParam("id") Long id, String jsonRequest) {
return NodeInterface.put(typeInNode, id, jsonRequest);
}
@DELETE
@Path("{id}")
public Response delete(@PathParam("id") Long id) {
return NodeInterface.delete(typeInNode, id);
}
@POST
@Path("{id}/add_cover")
@Consumes({MediaType.MULTIPART_FORM_DATA})
public Response uploadCover(@PathParam("id") Long id,
@FormDataParam("file_name") String file_name,
@FormDataParam("file") InputStream fileInputStream,
@FormDataParam("file") FormDataContentDisposition fileMetaData
) {
return NodeInterface.uploadCover(typeInNode, id, file_name, fileInputStream, fileMetaData);
}
@GET
@Path("{id}/rm_cover/{cover_id}")
public Response removeCover(@PathParam("id") Long nodeId, @PathParam("cover_id") Long coverId) {
return NodeInterface.removeCover(typeInNode, nodeId, coverId);
}
}

View File

@ -0,0 +1,67 @@
package org.kar.karideo.api;
import org.glassfish.jersey.media.multipart.FormDataContentDisposition;
import org.glassfish.jersey.media.multipart.FormDataParam;
import org.kar.karideo.model.NodeSmall;
import javax.annotation.security.PermitAll;
import javax.ws.rs.*;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import java.io.InputStream;
import java.util.List;
@Path("/universe")
@PermitAll
@Produces({MediaType.APPLICATION_JSON})
public class UniverseResource {
private static final String typeInNode = "UNIVERSE";
@GET
@Path("{id}")
public static NodeSmall getWithId(@PathParam("id") Long id) {
return NodeInterface.getWithId(typeInNode, id);
}
public static List<NodeSmall> getWithName(String name) {
return NodeInterface.getWithName(typeInNode, name);
}
public static NodeSmall getOrCreate(String universe) {
return NodeInterface.getOrCreate(typeInNode, universe, null);
}
@GET
public List<NodeSmall> get() {
return NodeInterface.get(typeInNode);
}
@PUT
@Path("{id}")
@Consumes(MediaType.APPLICATION_JSON)
public Response put(@PathParam("id") Long id, String jsonRequest) {
return NodeInterface.put(typeInNode, id, jsonRequest);
}
@DELETE
@Path("{id}")
public Response delete(@PathParam("id") Long id) {
return NodeInterface.delete(typeInNode, id);
}
@POST
@Path("{id}/add_cover")
@Consumes({MediaType.MULTIPART_FORM_DATA})
public Response uploadCover(@PathParam("id") Long id,
@FormDataParam("file_name") String file_name,
@FormDataParam("file") InputStream fileInputStream,
@FormDataParam("file") FormDataContentDisposition fileMetaData
) {
return NodeInterface.uploadCover(typeInNode, id, file_name, fileInputStream, fileMetaData);
}
@GET
@Path("{id}/rm_cover/{cover_id}")
public Response removeCover(@PathParam("id") Long nodeId, @PathParam("cover_id") Long coverId) {
return NodeInterface.removeCover(typeInNode, nodeId, coverId);
}
}

View File

@ -0,0 +1,259 @@
package org.kar.karideo.api;
import org.kar.karideo.GenericContext;
import org.kar.karideo.Secured;
import org.kar.karideo.UserDB;
import org.kar.karideo.WebLauncher;
import org.kar.karideo.db.DBEntry;
import org.kar.karideo.model.User;
import org.kar.karideo.model.UserExtern;
import org.kar.karideo.model.UserPerso;
import javax.annotation.security.PermitAll;
import javax.annotation.security.RolesAllowed;
import javax.ws.rs.*;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.SecurityContext;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
@Path("/users")
@PermitAll
@Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
public class UserResource {
public UserResource() {
}
private static String randomString(int count) {
Random rand = new Random(System.nanoTime());
String s = new String();
int nbChar = count;
for (int i = 0; i < nbChar; i++) {
char c = (char) rand.nextInt();
while ((c < 'a' || c > 'z') && (c < 'A' || c > 'Z') && (c < '0' || c > '9'))
c = (char) rand.nextInt();
s = s + c;
}
return s;
}
// I do not understand why angular request option before, but this is needed..
/*
@OPTIONS
public Response getOption(){
return Response.ok()
.header("Allow", "POST")
.header("Allow", "GET")
.header("Allow", "OPTIONS")
.build();
}
*/
// curl http://localhost:9993/api/users
@GET
public List<UserExtern> getUsers() {
System.out.println("getUsers");
DBEntry entry = new DBEntry(WebLauncher.dbConfig);
List<UserExtern> out = new ArrayList<>();
String query = "SELECT * FROM user";
try {
Statement st = entry.connection.createStatement();
ResultSet rs = st.executeQuery(query);
while (rs.next()) {
out.add(new UserExtern(new User(rs)));
}
} catch (SQLException throwables) {
throwables.printStackTrace();
}
entry.disconnect();
entry = null;
return out;
}
// I do not understand why angular request option before, but this is needed..
/*
@OPTIONS
@Path("{id}")
public Response getTokenOption(@PathParam("id") long userId){
return Response.ok()
.header("Allow", "POST")
.header("Allow", "GET")
.header("Allow", "OPTIONS")
.build();
}
*/
// curl http://localhost:9993/api/users/3
@Secured
@GET
@Path("{id}")
@RolesAllowed("USER")
public UserExtern getUser(@Context SecurityContext sc, @PathParam("id") long userId) {
System.out.println("getUser " + userId);
GenericContext gc = (GenericContext) sc.getUserPrincipal();
System.out.println("===================================================");
System.out.println("== USER ? " + gc.user);
System.out.println("===================================================");
return new UserExtern(UserDB.getUsers(userId));
}
/*
@OPTIONS
@Path("me")
public Response getOptionMe(){
return Response.ok()
.header("Allow", "GET")
.header("Allow", "OPTIONS")
.build();
}
*/
// curl http://localhost:9993/api/users/3
@Secured
@GET
@Path("me")
@RolesAllowed("USER")
public UserPerso getMe(@Context SecurityContext sc) {
System.out.println("getMe()");
GenericContext gc = (GenericContext) sc.getUserPrincipal();
System.out.println("===================================================");
System.out.println("== USER ? " + gc.user);
System.out.println("===================================================");
return new UserPerso(gc.user);
}
// curl -d '{"id":3,"login":"HeeroYui","password":"bouloued","email":"yui.heero@gmail.com","emailValidate":0,"newEmail":null,"authorisationLevel":"ADMIN"}' -H "Content-Type: application/json" -X POST http://localhost:9993/api/users
@POST
public Response createUser(User user) {
System.out.println("getUser " + user);
/*
DBEntry entry = new DBEntry(WebLauncher.dbConfig);
String query = "SELECT * FROM user WHERE id = ?";
try {
PreparedStatement ps = entry.connection.prepareStatement(query);
ps.setLong(1, userId);
ResultSet rs = ps.executeQuery();
if (rs.next()) {
User out = new User(rs);
entry.disconnect();
return out;
}
} catch (SQLException throwables) {
throwables.printStackTrace();
}
entry.disconnect();
entry = null;
return null;
*/
String result = "User saved ... : " + user;
return Response.status(201).entity(result).build();
}
@GET
@Path("/check_login")
public Response checkLogin(@QueryParam("login") String login) {
System.out.println("checkLogin: " + login);
DBEntry entry = new DBEntry(WebLauncher.dbConfig);
String query = "SELECT COUNT(*) FROM user WHERE login = ?";
try {
PreparedStatement ps = entry.connection.prepareStatement(query);
ps.setString(1, login);
ResultSet rs = ps.executeQuery();
if (rs.next()) {
int count = rs.getInt(1);
entry.disconnect();
if (count >= 1) {
return Response.ok().build();
}
return Response.status(404).build();
}
} catch (SQLException ex) {
ex.printStackTrace();
}
entry.disconnect();
return Response.status(520).build();
}
@GET
@Path("/check_email")
public Response checkEmail(@QueryParam("email") String email) {
System.out.println("checkEmail: " + email);
DBEntry entry = new DBEntry(WebLauncher.dbConfig);
String query = "SELECT COUNT(*) FROM user WHERE email = ?";
try {
PreparedStatement ps = entry.connection.prepareStatement(query);
ps.setString(1, email);
ResultSet rs = ps.executeQuery();
if (rs.next()) {
int count = rs.getInt(1);
entry.disconnect();
if (count >= 1) {
return Response.ok().build();
}
return Response.status(404).build();
}
} catch (SQLException ex) {
ex.printStackTrace();
}
entry.disconnect();
return Response.status(520).build();
}
public String getSHA512(String passwordToHash) {
try {
MessageDigest md = MessageDigest.getInstance("SHA-512");
byte[] bytes = md.digest(passwordToHash.getBytes(StandardCharsets.UTF_8));
StringBuilder sb = new StringBuilder();
for (int i = 0; i < bytes.length; i++) {
sb.append(Integer.toString((bytes[i] & 0xff) + 0x100, 16).substring(1));
}
return sb.toString();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
return null;
}
}

View File

@ -0,0 +1,555 @@
package org.kar.karideo.api;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.glassfish.jersey.media.multipart.FormDataContentDisposition;
import org.glassfish.jersey.media.multipart.FormDataParam;
import org.kar.karideo.WebLauncher;
import org.kar.karideo.db.DBEntry;
import org.kar.karideo.model.Data;
import org.kar.karideo.model.MediaSmall;
import org.kar.karideo.model.NodeSmall;
import javax.annotation.security.PermitAll;
import javax.ws.rs.*;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import java.io.IOException;
import java.io.InputStream;
import java.sql.*;
import java.util.ArrayList;
import java.util.List;
@Path("/video")
@PermitAll
@Produces({MediaType.APPLICATION_JSON})
public class VideoResource {
// UPDATE `node` SET `type` = "SEASON" WHERE `type` = "SAISON"
// UPDATE `node` SET `type` = "UNIVERSE" WHERE `type` = "UNIVERS"
// UPDATE `node` SET `type` = "SERIES" WHERE `type` = "SERIE"
@GET
public List<MediaSmall> get() {
System.out.println("VIDEO get");
DBEntry entry = new DBEntry(WebLauncher.dbConfig);
List<MediaSmall> out = new ArrayList<>();
String query = "SELECT media.id," +
" media.name," +
" media.description," +
" media.data_id," +
" media.type_id," +
" media.universe_id," +
" media.series_id," +
" media.season_id," +
" media.episode," +
" media.date," +
" media.time," +
" media.age_limit," +
" (SELECT GROUP_CONCAT(tmp.data_id SEPARATOR '-')" +
" FROM cover_link_media tmp" +
" WHERE tmp.deleted = false" +
" AND media.id = tmp.media_id" +
" GROUP BY tmp.media_id) AS covers" +
" FROM media" +
" WHERE media.deleted = false " +
" GROUP BY media.id" +
" ORDER BY media.name";
try {
Statement st = entry.connection.createStatement();
ResultSet rs = st.executeQuery(query);
while (rs.next()) {
out.add(new MediaSmall(rs));
}
} catch (SQLException throwables) {
throwables.printStackTrace();
}
entry.disconnect();
entry = null;
System.out.println("retrieve " + out.size() + " VIDEO");
return out;
}
@GET
@Path("{id}")
public MediaSmall get(@PathParam("id") Long id) {
System.out.println("VIDEO get " + id);
DBEntry entry = new DBEntry(WebLauncher.dbConfig);
String query = "SELECT media.id," +
" media.name," +
" media.description," +
" media.data_id," +
" media.type_id," +
" media.universe_id," +
" media.series_id," +
" media.season_id," +
" media.episode," +
" media.date," +
" media.time," +
" media.age_limit," +
" (SELECT GROUP_CONCAT(tmp.data_id SEPARATOR '-')" +
" FROM cover_link_media tmp" +
" WHERE tmp.deleted = false" +
" AND media.id = tmp.media_id" +
" GROUP BY tmp.media_id) AS covers" +
" FROM media" +
" WHERE media.deleted = false " +
" AND media.id = ? " +
" GROUP BY media.id" +
" ORDER BY media.name";
try {
PreparedStatement ps = entry.connection.prepareStatement(query);
int iii = 1;
ps.setLong(iii++, id);
ResultSet rs = ps.executeQuery();
if (rs.next()) {
MediaSmall out = new MediaSmall(rs);
entry.disconnect();
entry = null;
return out;
}
} catch (SQLException throwables) {
throwables.printStackTrace();
}
entry.disconnect();
entry = null;
return null;
}
@PUT
@Path("{id}")
@Consumes(MediaType.APPLICATION_JSON)
public Response put(@PathParam("id") Long id, String jsonRequest) {
ObjectMapper mapper = new ObjectMapper();
try {
JsonNode root = mapper.readTree(jsonRequest);
String query = "UPDATE `media` SET `modify_date`=now(3)";
if (!root.path("name").isMissingNode()) {
query += ", `name` = ? ";
}
if (!root.path("description").isMissingNode()) {
query += ", `description` = ? ";
}
if (!root.path("episode").isMissingNode()) {
query += ", `episode` = ? ";
}
if (!root.path("time").isMissingNode()) {
query += ", `time` = ? ";
}
if (!root.path("type_id").isMissingNode()) {
query += ", `type_id` = ? ";
}
if (!root.path("universe_id").isMissingNode()) {
query += ", `universe_id` = ? ";
}
if (!root.path("series_id").isMissingNode()) {
query += ", `series_id` = ? ";
}
if (!root.path("season_id").isMissingNode()) {
query += ", `season_id` = ? ";
}
query += " WHERE `id` = ?";
DBEntry entry = new DBEntry(WebLauncher.dbConfig);
try {
PreparedStatement ps = entry.connection.prepareStatement(query);
int iii = 1;
if (!root.path("name").isMissingNode()) {
if (root.path("name").isNull()) {
ps.setString(iii++, "???");
} else {
ps.setString(iii++, root.path("name").asText());
}
}
if (!root.path("description").isMissingNode()) {
if (root.path("description").isNull()) {
ps.setNull(iii++, Types.VARCHAR);
} else {
ps.setString(iii++, root.path("description").asText());
}
}
if (!root.path("episode").isMissingNode()) {
if (root.path("episode").isNull()) {
ps.setNull(iii++, Types.INTEGER);
} else {
ps.setInt(iii++, root.path("episode").asInt());
}
}
if (!root.path("time").isMissingNode()) {
if (root.path("time").isNull()) {
ps.setNull(iii++, Types.INTEGER);
} else {
ps.setInt(iii++, root.path("time").asInt());
}
}
if (!root.path("type_id").isMissingNode()) {
if (root.path("type_id").isNull()) {
ps.setNull(iii++, Types.BIGINT);
} else {
ps.setLong(iii++, root.path("type_id").asLong());
}
}
if (!root.path("universe_id").isMissingNode()) {
if (root.path("universe_id").isNull()) {
ps.setNull(iii++, Types.BIGINT);
} else {
ps.setLong(iii++, root.path("universe_id").asLong());
}
}
if (!root.path("series_id").isMissingNode()) {
if (root.path("series_id").isNull()) {
ps.setNull(iii++, Types.BIGINT);
} else {
ps.setLong(iii++, root.path("series_id").asLong());
}
}
if (!root.path("season_id").isMissingNode()) {
if (root.path("season_id").isNull()) {
ps.setNull(iii++, Types.BIGINT);
} else {
ps.setLong(iii++, root.path("season_id").asLong());
}
}
ps.setLong(iii++, id);
System.out.println(" request : " + ps.toString());
ps.executeUpdate();
} catch (SQLException throwables) {
throwables.printStackTrace();
entry.disconnect();
entry = null;
return Response.notModified("SQL error").build();
}
entry.disconnect();
entry = null;
} catch (IOException e) {
e.printStackTrace();
return Response.notModified("input json error error").build();
}
return Response.ok(get(id)).build();
}
/*
public static void update_time(String table, Long id, Timestamp dateCreate, Timestamp dateModify) {
DBEntry entry = new DBEntry(WebLauncher.dbConfig);
String query = "UPDATE " + table + " SET create_date = ?, modify_date = ? WHERE id = ?";
try {
PreparedStatement ps = entry.connection.prepareStatement(query);
ps.setTimestamp(1, dateCreate);
ps.setTimestamp(2, dateModify);
ps.setLong(3, id);
ps.execute();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
entry.disconnect();
}
*/
private String multipartCorrection(String data) {
if (data == null) {
return null;
}
if (data.isEmpty()) {
return null;
}
if (data.contentEquals("null")) {
return null;
}
return data;
}
@POST
@Path("/upload/")
@Consumes({MediaType.MULTIPART_FORM_DATA})
public Response uploadFile(@FormDataParam("file_name") String file_name,
@FormDataParam("universe") String universe,
@FormDataParam("series") String series,
@FormDataParam("season") String season,
@FormDataParam("episode") String episode,
@FormDataParam("title") String title,
@FormDataParam("type_id") String type_id,
@FormDataParam("file") InputStream fileInputStream,
@FormDataParam("file") FormDataContentDisposition fileMetaData
) {
try {
// correct input string stream :
file_name = multipartCorrection(file_name);
universe = multipartCorrection(universe);
series = multipartCorrection(series);
season = multipartCorrection(season);
episode = multipartCorrection(episode);
title = multipartCorrection(title);
type_id = multipartCorrection(type_id);
//public NodeSmall uploadFile(final FormDataMultiPart form) {
System.out.println("Upload media file: " + fileMetaData);
System.out.println(" - file_name: " + file_name);
System.out.println(" - universe: " + universe);
System.out.println(" - series: " + series);
System.out.println(" - season: " + season);
System.out.println(" - episode: " + episode);
System.out.println(" - title: " + title);
System.out.println(" - type_id: " + type_id);
System.out.println(" - fileInputStream: " + fileInputStream);
System.out.println(" - fileMetaData: " + fileMetaData);
System.out.flush();
long tmpUID = DataResource.getTmpDataId();
String sha512 = DataResource.saveTemporaryFile(fileInputStream, tmpUID);
Data data = DataResource.getWithSha512(sha512);
if (data == null) {
System.out.println("Need to add the data in the BDD ... ");
System.out.flush();
try {
data = DataResource.createNewData(tmpUID, file_name, sha512);
} catch (IOException ex) {
DataResource.removeTemporaryFile(tmpUID);
ex.printStackTrace();
return Response.notModified("can not create input media").build();
} catch (SQLException ex) {
ex.printStackTrace();
DataResource.removeTemporaryFile(tmpUID);
return Response.notModified("Error in SQL insertion ...").build();
}
} else if (data.deleted == true) {
System.out.println("Data already exist but deleted");
System.out.flush();
DataResource.undelete(data.id);
data.deleted = false;
} else {
System.out.println("Data already exist ... all good");
System.out.flush();
}
// Fist step: retive all the Id of each parents:...
System.out.println("Find typeNode");
// check if id of type exist:
NodeSmall typeNode = TypeResource.getWithId(Long.parseLong(type_id));
if (typeNode == null) {
DataResource.removeTemporaryFile(tmpUID);
return Response.notModified("TypeId does not exist ...").build();
}
System.out.println(" ==> " + typeNode);
System.out.println("Find universeNode");
// get id of universe:
NodeSmall universeNode = UniverseResource.getOrCreate(universe);
System.out.println(" ==> " + universeNode);
System.out.println("Find seriesNode");
// get uid of group:
NodeSmall seriesNode = SeriesResource.getOrCreate(series, typeNode.id);
System.out.println(" ==> " + seriesNode);
System.out.println("Find seasonNode");
// get uid of season:
Integer seasonId = null;
NodeSmall seasonNode = null;
try {
seasonId = Integer.parseInt(season);
seasonNode = SeasonResource.getOrCreate(Integer.parseInt(season), seriesNode.id);
} catch (java.lang.NumberFormatException ex) {
// nothing to do ....
}
System.out.println(" ==> " + seasonNode);
System.out.println("add media");
DBEntry entry = new DBEntry(WebLauncher.dbConfig);
long uniqueSQLID = -1;
// real add in the BDD:
try {
// prepare the request:
String query = "INSERT INTO media (create_date, modify_date, name, data_id, type_id, universe_id, series_id, season_id, episode)" +
" VALUES (now(3), now(3), ?, ?, ?, ?, ?, ?, ?)";
PreparedStatement ps = entry.connection.prepareStatement(query,
Statement.RETURN_GENERATED_KEYS);
int iii = 1;
ps.setString(iii++, title);
ps.setLong(iii++, data.id);
ps.setLong(iii++, typeNode.id);
if (universeNode == null) {
ps.setNull(iii++, Types.BIGINT);
} else {
ps.setLong(iii++, universeNode.id);
}
if (seriesNode == null) {
ps.setNull(iii++, Types.BIGINT);
} else {
ps.setLong(iii++, seriesNode.id);
}
if (seasonNode == null) {
ps.setNull(iii++, Types.BIGINT);
} else {
ps.setLong(iii++, seasonNode.id);
}
if (episode == null || episode.contentEquals("")) {
ps.setNull(iii++, Types.INTEGER);
} else {
ps.setInt(iii++, Integer.parseInt(episode));
}
// execute the request
int affectedRows = ps.executeUpdate();
if (affectedRows == 0) {
throw new SQLException("Creating data failed, no rows affected.");
}
// retreive uid inserted
try (ResultSet generatedKeys = ps.getGeneratedKeys()) {
if (generatedKeys.next()) {
uniqueSQLID = generatedKeys.getLong(1);
} else {
throw new SQLException("Creating user failed, no ID obtained (1).");
}
} catch (Exception ex) {
System.out.println("Can not get the UID key inserted ... ");
ex.printStackTrace();
throw new SQLException("Creating user failed, no ID obtained (2).");
}
} catch (SQLException ex) {
ex.printStackTrace();
}
// if we do not une the file .. remove it ... otherwise this is meamory leak...
DataResource.removeTemporaryFile(tmpUID);
System.out.println("uploaded .... compleate: " + uniqueSQLID);
MediaSmall creation = get(uniqueSQLID);
return Response.ok(creation).build();
} catch (Exception ex) {
System.out.println("Cat ann unexpected error ... ");
ex.printStackTrace();
}
return Response.serverError().build();
}
@POST
@Path("{id}/add_cover")
@Consumes({MediaType.MULTIPART_FORM_DATA})
public Response uploadCover(@PathParam("id") Long id,
@FormDataParam("file_name") String file_name,
@FormDataParam("file") InputStream fileInputStream,
@FormDataParam("file") FormDataContentDisposition fileMetaData
) {
try {
// correct input string stream :
file_name = multipartCorrection(file_name);
//public NodeSmall uploadFile(final FormDataMultiPart form) {
System.out.println("Upload media file: " + fileMetaData);
System.out.println(" - id: " + id);
System.out.println(" - file_name: " + file_name);
System.out.println(" - fileInputStream: " + fileInputStream);
System.out.println(" - fileMetaData: " + fileMetaData);
System.out.flush();
MediaSmall media = get(id);
if (media == null) {
return Response.notModified("Media Id does not exist or removed...").build();
}
long tmpUID = DataResource.getTmpDataId();
String sha512 = DataResource.saveTemporaryFile(fileInputStream, tmpUID);
Data data = DataResource.getWithSha512(sha512);
if (data == null) {
System.out.println("Need to add the data in the BDD ... ");
System.out.flush();
try {
data = DataResource.createNewData(tmpUID, file_name, sha512);
} catch (IOException ex) {
DataResource.removeTemporaryFile(tmpUID);
ex.printStackTrace();
return Response.notModified("can not create input media").build();
} catch (SQLException ex) {
ex.printStackTrace();
DataResource.removeTemporaryFile(tmpUID);
return Response.notModified("Error in SQL insertion ...").build();
}
} else if (data.deleted == true) {
System.out.println("Data already exist but deleted");
System.out.flush();
DataResource.undelete(data.id);
data.deleted = false;
} else {
System.out.println("Data already exist ... all good");
System.out.flush();
}
// Fist step: retrieve all the Id of each parents:...
System.out.println("Find typeNode");
DBEntry entry = new DBEntry(WebLauncher.dbConfig);
long uniqueSQLID = -1;
// real add in the BDD:
try {
// prepare the request:
String query = "INSERT INTO cover_link_media (create_date, modify_date, media_id, data_id)" +
" VALUES (now(3), now(3), ?, ?)";
PreparedStatement ps = entry.connection.prepareStatement(query,
Statement.RETURN_GENERATED_KEYS);
int iii = 1;
ps.setLong(iii++, media.id);
ps.setLong(iii++, data.id);
// execute the request
int affectedRows = ps.executeUpdate();
if (affectedRows == 0) {
throw new SQLException("Creating data failed, no rows affected.");
}
// retreive uid inserted
try (ResultSet generatedKeys = ps.getGeneratedKeys()) {
if (generatedKeys.next()) {
uniqueSQLID = generatedKeys.getLong(1);
} else {
throw new SQLException("Creating user failed, no ID obtained (1).");
}
} catch (Exception ex) {
System.out.println("Can not get the UID key inserted ... ");
ex.printStackTrace();
throw new SQLException("Creating user failed, no ID obtained (2).");
}
} catch (SQLException ex) {
ex.printStackTrace();
}
// if we do not une the file .. remove it ... otherwise this is meamory leak...
DataResource.removeTemporaryFile(tmpUID);
System.out.println("uploaded .... compleate: " + uniqueSQLID);
MediaSmall creation = get(id);
return Response.ok(creation).build();
} catch (Exception ex) {
System.out.println("Cat ann unexpected error ... ");
ex.printStackTrace();
}
return Response.serverError().build();
}
@GET
@Path("{id}/rm_cover/{cover_id}")
public Response removeCover(@PathParam("id") Long mediaId, @PathParam("cover_id") Long coverId) {
DBEntry entry = new DBEntry(WebLauncher.dbConfig);
String query = "UPDATE `cover_link_media` SET `modify_date`=now(3), `deleted`=true WHERE `media_id` = ? AND `data_id` = ?";
try {
PreparedStatement ps = entry.connection.prepareStatement(query);
int iii = 1;
ps.setLong(iii++, mediaId);
ps.setLong(iii++, coverId);
ps.executeUpdate();
} catch (SQLException throwables) {
throwables.printStackTrace();
entry.disconnect();
return Response.serverError().build();
}
entry.disconnect();
return Response.ok(get(mediaId)).build();
}
@DELETE
@Path("{id}")
public Response delete(@PathParam("id") Long id) {
DBEntry entry = new DBEntry(WebLauncher.dbConfig);
String query = "UPDATE `media` SET `modify_date`=now(3), `deleted`=true WHERE `id` = ? and `deleted` = false ";
try {
PreparedStatement ps = entry.connection.prepareStatement(query);
int iii = 1;
ps.setLong(iii++, id);
ps.executeUpdate();
} catch (SQLException throwables) {
throwables.printStackTrace();
entry.disconnect();
return Response.serverError().build();
}
entry.disconnect();
return Response.ok().build();
}
}

View File

@ -0,0 +1,60 @@
package org.kar.karideo.db;
public class DBConfig {
private final String hostname;
private final int port;
private final String login;
private final String password;
private final String dbName;
public DBConfig(String hostname, Integer port, String login, String password, String dbName) {
if (hostname == null) {
this.hostname = "localhost";
} else {
this.hostname = hostname;
}
if (port == null) {
this.port = 3306;
} else {
this.port = port;
}
this.login = login;
this.password = password;
this.dbName = dbName;
}
@Override
public String toString() {
return "DBConfig{" +
"hostname='" + hostname + '\'' +
", port=" + port +
", login='" + login + '\'' +
", password='" + password + '\'' +
", dbName='" + dbName + '\'' +
'}';
}
public String getHostname() {
return hostname;
}
public int getPort() {
return port;
}
public String getLogin() {
return login;
}
public String getPassword() {
return password;
}
public String getDbName() {
return dbName;
}
public String getUrl() {
return "jdbc:mysql://" + this.hostname + ":" + this.port + "/" + this.dbName + "?useSSL=false&serverTimezone=UTC";
}
}

View File

@ -0,0 +1,44 @@
package org.kar.karideo.db;
import org.kar.karideo.model.User;
import java.sql.*;
public class DBEntry {
public DBConfig config;
public Connection connection;
public DBEntry(DBConfig config) {
this.config = config;
connect();
}
public void connect() {
try {
connection = DriverManager.getConnection(config.getUrl(), config.getLogin(), config.getPassword());
} catch (SQLException ex) {
ex.printStackTrace();
}
}
public void disconnect() {
try {
//connection.commit();
connection.close();
} catch (SQLException ex) {
ex.printStackTrace();
}
}
public void test() throws SQLException {
String query = "SELECT * FROM user";
Statement st = connection.createStatement();
ResultSet rs = st.executeQuery(query);
System.out.println("List of user:");
if (rs.next()) {
User user = new User(rs);
System.out.println(" - " + user);
}
}
}

View File

@ -0,0 +1,60 @@
package org.kar.karideo.internal;
//import io.scenarium.logger.LogLevel;
//import io.scenarium.logger.Logger;
public class Log {
// private static final String LIB_NAME = "logger";
// private static final String LIB_NAME_DRAW = Logger.getDrawableName(LIB_NAME);
// private static final boolean PRINT_CRITICAL = Logger.getNeedPrint(LIB_NAME, LogLevel.CRITICAL);
// private static final boolean PRINT_ERROR = Logger.getNeedPrint(LIB_NAME, LogLevel.ERROR);
// private static final boolean PRINT_WARNING = Logger.getNeedPrint(LIB_NAME, LogLevel.WARNING);
// private static final boolean PRINT_INFO = Logger.getNeedPrint(LIB_NAME, LogLevel.INFO);
// private static final boolean PRINT_DEBUG = Logger.getNeedPrint(LIB_NAME, LogLevel.DEBUG);
// private static final boolean PRINT_VERBOSE = Logger.getNeedPrint(LIB_NAME, LogLevel.VERBOSE);
// private static final boolean PRINT_TODO = Logger.getNeedPrint(LIB_NAME, LogLevel.TODO);
// private static final boolean PRINT_PRINT = Logger.getNeedPrint(LIB_NAME, LogLevel.PRINT);
//
// private Log() {}
//
// public static void print(String data) {
// if (PRINT_PRINT)
// Logger.print(LIB_NAME_DRAW, data);
// }
//
// public static void todo(String data) {
// if (PRINT_TODO)
// Logger.todo(LIB_NAME_DRAW, data);
// }
//
// public static void critical(String data) {
// if (PRINT_CRITICAL)
// Logger.critical(LIB_NAME_DRAW, data);
// }
//
// public static void error(String data) {
// if (PRINT_ERROR)
// Logger.error(LIB_NAME_DRAW, data);
// }
//
// public static void warning(String data) {
// if (PRINT_WARNING)
// Logger.warning(LIB_NAME_DRAW, data);
// }
//
// public static void info(String data) {
// if (PRINT_INFO)
// Logger.info(LIB_NAME_DRAW, data);
// }
//
// public static void debug(String data) {
// if (PRINT_DEBUG)
// Logger.debug(LIB_NAME_DRAW, data);
// }
//
// public static void verbose(String data) {
// if (PRINT_VERBOSE)
// Logger.verbose(LIB_NAME_DRAW, data);
// }
}

View File

@ -0,0 +1,5 @@
package org.kar.karideo.model;
public enum AgeLimit {
}

View File

@ -0,0 +1,12 @@
package org.kar.karideo.model;
/*
CREATE TABLE `cover_link_media` (
`id` bigint NOT NULL COMMENT 'table ID' AUTO_INCREMENT PRIMARY KEY,
`deleted` BOOLEAN NOT NULL DEFAULT false,
`media_id` bigint,
`data_id` bigint
) AUTO_INCREMENT=10;
*/
public class CoverLinkMedia {
}

View File

@ -0,0 +1,13 @@
package org.kar.karideo.model;
/*
CREATE TABLE `cover_link_node` (
`id` bigint NOT NULL COMMENT 'table ID' AUTO_INCREMENT PRIMARY KEY,
`deleted` BOOLEAN NOT NULL DEFAULT false,
`node_id` bigint,
`data_id` bigint
) AUTO_INCREMENT=10;
*/
public class CoverLinkNode {
}

View File

@ -0,0 +1,32 @@
package org.kar.karideo.model;
import java.sql.ResultSet;
import java.sql.SQLException;
public class Data {
public Long id;
public boolean deleted;
public String sha512;
public String mimeType;
public Long size;
public Data() {
}
public Data(ResultSet rs) {
int iii = 1;
try {
this.id = rs.getLong(iii++);
this.deleted = rs.getBoolean(iii++);
this.sha512 = rs.getString(iii++);
this.mimeType = rs.getString(iii++);
this.size = rs.getLong(iii++);
if (rs.wasNull()) {
this.size = null;
}
} catch (SQLException ex) {
ex.printStackTrace();
}
}
}

View File

@ -0,0 +1,8 @@
package org.kar.karideo.model;
public class DataGetToken {
public String login;
public String method;
public String time;
public String password;
}

View File

@ -0,0 +1,39 @@
package org.kar.karideo.model;
/*
CREATE TABLE `data` (
`id` bigint NOT NULL COMMENT 'table ID' AUTO_INCREMENT PRIMARY KEY,
`deleted` BOOLEAN NOT NULL DEFAULT false,
`create_date` datetime NOT NULL DEFAULT now() COMMENT 'Time the element has been created',
`modify_date` datetime NOT NULL DEFAULT now() COMMENT 'Time the element has been update',
`sha512` varchar(129) COLLATE 'utf8_general_ci' NOT NULL,
`mime_type` varchar(128) COLLATE 'utf8_general_ci' NOT NULL,
`size` bigint,
`original_name` TEXT
) AUTO_INCREMENT=64;
*/
import java.sql.ResultSet;
import java.sql.SQLException;
public class DataSmall {
public Long id;
public String sha512;
public String mimeType;
public Long size;
public DataSmall() {
}
public DataSmall(ResultSet rs) {
int iii = 1;
try {
this.id = rs.getLong(iii++);
this.sha512 = rs.getString(iii++);
this.mimeType = rs.getString(iii++);
this.size = rs.getLong(iii++);
} catch (SQLException ex) {
ex.printStackTrace();
}
}
}

View File

@ -0,0 +1,5 @@
package org.kar.karideo.model;
public class Group {
}

View File

@ -0,0 +1,24 @@
package org.kar.karideo.model;
/*
CREATE TABLE `media` (
`id` bigint NOT NULL COMMENT 'table ID' AUTO_INCREMENT PRIMARY KEY,
`deleted` BOOLEAN NOT NULL DEFAULT false,
`create_date` datetime NOT NULL DEFAULT now() COMMENT 'Time the element has been created',
`modify_date` datetime NOT NULL DEFAULT now() COMMENT 'Time the element has been update',
`name` TEXT COLLATE 'utf8_general_ci' NOT NULL,
`description` TEXT COLLATE 'utf8_general_ci',
`parent_id` bigint,
`data_id` bigint,
`type_id` bigint,
`universe_id` bigint,
`series_id` bigint,
`season_id` bigint,
`episode` int,
`date` int,
`age_limit` enum("-", "5", "9", "12", "14", "16", "18") NOT NULL DEFAULT '-'
) AUTO_INCREMENT=85;
*/
public class Media {
}

View File

@ -0,0 +1,86 @@
package org.kar.karideo.model;
/*
CREATE TABLE `node` (
`id` bigint NOT NULL COMMENT 'table ID' AUTO_INCREMENT PRIMARY KEY,
`deleted` BOOLEAN NOT NULL DEFAULT false,
`create_date` datetime NOT NULL DEFAULT now() COMMENT 'Time the element has been created',
`modify_date` datetime NOT NULL DEFAULT now() COMMENT 'Time the element has been update',
`type` enum("TYPE", "UNIVERSE", "SERIES", "SEASON") NOT NULL DEFAULT 'TYPE',
`name` TEXT COLLATE 'utf8_general_ci' NOT NULL,
`description` TEXT COLLATE 'utf8_general_ci',
`parent_id` bigint
) AUTO_INCREMENT=10;
*/
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
public class MediaSmall {
public Long id;
public String name;
public String description;
public Long data_id;
public Long type_id;
public Long universe_id;
public Long series_id;
public Long season_id;
public Integer episode;
public Integer date;
public Integer time;
public String age_limit;
public List<Long> covers = new ArrayList<>();
public MediaSmall(ResultSet rs) {
int iii = 1;
try {
this.id = rs.getLong(iii++);
this.name = rs.getString(iii++);
this.description = rs.getString(iii++);
this.data_id = rs.getLong(iii++);
if (rs.wasNull()) {
this.data_id = null;
}
this.type_id = rs.getLong(iii++);
if (rs.wasNull()) {
this.type_id = null;
}
this.universe_id = rs.getLong(iii++);
if (rs.wasNull()) {
this.universe_id = null;
}
this.series_id = rs.getLong(iii++);
if (rs.wasNull()) {
this.series_id = null;
}
this.season_id = rs.getLong(iii++);
if (rs.wasNull()) {
this.season_id = null;
}
this.episode = rs.getInt(iii++);
if (rs.wasNull()) {
this.episode = null;
}
this.date = rs.getInt(iii++);
if (rs.wasNull()) {
this.date = null;
}
this.time = rs.getInt(iii++);
if (rs.wasNull()) {
this.time = null;
}
this.age_limit = rs.getString(iii++);
String coversString = rs.getString(iii++);
if (!rs.wasNull()) {
String[] elements = coversString.split("-");
for (String elem : elements) {
Long tmp = Long.parseLong(elem);
covers.add(tmp);
}
}
} catch (SQLException ex) {
ex.printStackTrace();
}
}
}

View File

@ -0,0 +1,60 @@
package org.kar.karideo.model;
/*
CREATE TABLE `node` (
`id` bigint NOT NULL COMMENT 'table ID' AUTO_INCREMENT PRIMARY KEY,
`deleted` BOOLEAN NOT NULL DEFAULT false,
`create_date` datetime NOT NULL DEFAULT now() COMMENT 'Time the element has been created',
`modify_date` datetime NOT NULL DEFAULT now() COMMENT 'Time the element has been update',
`type` enum("TYPE", "UNIVERS", "SERIE", "SAISON", "MEDIA") NOT NULL DEFAULT 'TYPE',
`name` TEXT COLLATE 'utf8_general_ci' NOT NULL,
`description` TEXT COLLATE 'utf8_general_ci',
`parent_id` bigint
) AUTO_INCREMENT=10;
*/
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
public class NodeSmall {
public Long id;
public String name;
public String description;
public Long parent_id;
public List<Long> covers = new ArrayList<>();
public NodeSmall(ResultSet rs) {
int iii = 1;
try {
this.id = rs.getLong(iii++);
this.name = rs.getString(iii++);
this.description = rs.getString(iii++);
this.parent_id = rs.getLong(iii++);
if (rs.wasNull()) {
this.parent_id = null;
}
String coversString = rs.getString(iii++);
if (!rs.wasNull()) {
String[] elements = coversString.split("-");
for (String elem : elements) {
Long tmp = Long.parseLong(elem);
covers.add(tmp);
}
}
} catch (SQLException ex) {
ex.printStackTrace();
}
}
@Override
public String toString() {
return "NodeSmall{" +
"id=" + id +
", name='" + name + '\'' +
", description='" + description + '\'' +
", parent_id=" + parent_id +
", covers=" + covers +
'}';
}
}

View File

@ -0,0 +1,4 @@
package org.kar.karideo.model;
public class Saison {
}

View File

@ -0,0 +1,10 @@
package org.kar.karideo.model;
public enum State {
// User has remove his account
REMOVED,
// User has been blocked his account
BLOCKED,
// generic user
USER
}

View File

@ -0,0 +1,57 @@
package org.kar.karideo.model;
import java.sql.ResultSet;
import java.sql.SQLException;
/*
CREATE TABLE `token` (
`id` bigint NOT NULL COMMENT 'Unique ID of the TOKEN' AUTO_INCREMENT PRIMARY KEY,
`userId` bigint NOT NULL COMMENT 'Unique ID of the user',
`token` varchar(128) COLLATE 'latin1_bin' NOT NULL COMMENT 'Token (can be not unique)',
`createTime` datetime NOT NULL COMMENT 'Time the token has been created',
`endValidityTime` datetime NOT NULL COMMENT 'Time of the token end validity'
) AUTO_INCREMENT=10;
*/
public class Token {
public Long id;
public Long userId;
public String token;
public String createTime;
public String endValidityTime;
public Token() {
}
public Token(long id, long userId, String token, String createTime, String endValidityTime) {
this.id = id;
this.userId = userId;
this.token = token;
this.createTime = createTime;
this.endValidityTime = endValidityTime;
}
public Token(ResultSet rs) {
int iii = 1;
try {
this.id = rs.getLong(iii++);
this.userId = rs.getLong(iii++);
this.token = rs.getString(iii++);
this.createTime = rs.getString(iii++);
this.endValidityTime = rs.getString(iii++);
} catch (SQLException ex) {
ex.printStackTrace();
}
}
@Override
public String toString() {
return "Token{" +
"id=" + id +
", userId=" + userId +
", token='" + token + '\'' +
", createTime=" + createTime +
", endValidityTime=" + endValidityTime +
'}';
}
}

View File

@ -0,0 +1,6 @@
package org.kar.karideo.model;
public class Type {
}

View File

@ -0,0 +1,4 @@
package org.kar.karideo.model;
public class Univers {
}

View File

@ -0,0 +1,77 @@
package org.kar.karideo.model;
/*
CREATE TABLE `user` (
`id` bigint NOT NULL COMMENT 'table ID' AUTO_INCREMENT PRIMARY KEY,
`login` varchar(128) COLLATE 'utf8_general_ci' NOT NULL COMMENT 'login of the user',
`email` varchar(512) COLLATE 'utf8_general_ci' NOT NULL COMMENT 'email of the user',
`lastConnection` datetime NOT NULL COMMENT 'last connection time',
`admin` enum("TRUE", "FALSE") NOT NULL DEFAULT 'FALSE',
`blocked` enum("TRUE", "FALSE") NOT NULL DEFAULT 'FALSE',
`removed` enum("TRUE", "FALSE") NOT NULL DEFAULT 'FALSE',
`avatar` bigint DEFAULT NULL,
) AUTO_INCREMENT=10;
*/
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Timestamp;
public class User {
public Long id;
public String login;
public String email;
public Timestamp lastConnection;
public boolean admin;
public boolean blocked;
public boolean removed;
public Long avatar;
public User() {
}
public User(Long id, String login, Timestamp lastConnection, String email, boolean admin, boolean blocked, boolean removed, Long avatar) {
this.id = id;
this.login = login;
this.lastConnection = lastConnection;
this.email = email;
this.admin = admin;
this.blocked = blocked;
this.removed = removed;
this.avatar = avatar;
}
public User(ResultSet rs) {
int iii = 1;
try {
this.id = rs.getLong(iii++);
this.lastConnection = rs.getTimestamp(iii++);
this.login = rs.getString(iii++);
this.email = rs.getString(iii++);
this.admin = Boolean.getBoolean(rs.getString(iii++));
this.blocked = Boolean.getBoolean(rs.getString(iii++));
this.removed = Boolean.getBoolean(rs.getString(iii++));
this.avatar = rs.getLong(iii++);
if (rs.wasNull()) {
this.avatar = null;
}
} catch (SQLException ex) {
ex.printStackTrace();
}
}
@Override
public String toString() {
return "User{" +
"id=" + id +
", login='" + login + '\'' +
", email='" + email + '\'' +
", lastConnection='" + lastConnection + '\'' +
", admin=" + admin +
", blocked=" + blocked +
", removed=" + removed +
", avatar=" + avatar +
'}';
}
}

View File

@ -0,0 +1,39 @@
package org.kar.karideo.model;
/*
CREATE TABLE `user` (
`id` bigint NOT NULL COMMENT 'table ID' AUTO_INCREMENT PRIMARY KEY,
`login` varchar(128) COLLATE 'utf8_general_ci' NOT NULL COMMENT 'login of the user',
`email` varchar(512) COLLATE 'utf8_general_ci' NOT NULL COMMENT 'email of the user',
`lastConnection` datetime NOT NULL COMMENT 'last connection time',
`admin` enum("TRUE", "FALSE") NOT NULL DEFAULT 'FALSE',
`blocked` enum("TRUE", "FALSE") NOT NULL DEFAULT 'FALSE',
`removed` enum("TRUE", "FALSE") NOT NULL DEFAULT 'FALSE'
) AUTO_INCREMENT=10;
*/
public class UserExtern {
public Long id;
public String login;
public boolean admin;
public Long avatar;
public UserExtern(User other) {
this.id = other.id;
this.login = other.login;
this.admin = other.admin;
this.avatar = other.avatar;
}
@Override
public String toString() {
return "User{" +
"id=" + id +
", login='" + login + '\'' +
", admin=" + admin +
", avatar=" + avatar +
'}';
}
}

View File

@ -0,0 +1,48 @@
package org.kar.karideo.model;
/*
CREATE TABLE `user` (
`id` bigint NOT NULL COMMENT 'table ID' AUTO_INCREMENT PRIMARY KEY,
`login` varchar(128) COLLATE 'utf8_general_ci' NOT NULL COMMENT 'login of the user',
`email` varchar(512) COLLATE 'utf8_general_ci' NOT NULL COMMENT 'email of the user',
`lastConnection` datetime NOT NULL COMMENT 'last connection time',
`admin` enum("TRUE", "FALSE") NOT NULL DEFAULT 'FALSE',
`blocked` enum("TRUE", "FALSE") NOT NULL DEFAULT 'FALSE',
`removed` enum("TRUE", "FALSE") NOT NULL DEFAULT 'FALSE'
) AUTO_INCREMENT=10;
*/
public class UserPerso {
public Long id;
public String login;
public String email;
public boolean admin;
public boolean blocked;
public boolean removed;
public Long avatar;
public UserPerso(User other) {
this.id = other.id;
this.login = other.login;
this.email = other.email;
this.admin = other.admin;
this.blocked = other.blocked;
this.removed = other.removed;
this.avatar = other.avatar;
}
@Override
public String toString() {
return "User{" +
"id=" + id +
", login='" + login + '\'' +
", email='" + email + '\'' +
", admin=" + admin +
", blocked=" + blocked +
", removed=" + removed +
", avatar=" + avatar +
'}';
}
}

View File

@ -0,0 +1,73 @@
package org.kar.karideo.model;
/*
CREATE TABLE `user` (
`id` bigint NOT NULL COMMENT 'table ID' AUTO_INCREMENT PRIMARY KEY,
`login` varchar(128) COLLATE 'utf8_general_ci' NOT NULL COMMENT 'login of the user',
`password` varchar(128) COLLATE 'latin1_bin' NOT NULL COMMENT 'password of the user hashed (sha512)',
`email` varchar(512) COLLATE 'utf8_general_ci' NOT NULL COMMENT 'email of the user',
`emailValidate` bigint COMMENT 'date of the email validation',
`newEmail` varchar(512) COLLATE 'utf8_general_ci' COMMENT 'email of the user if he want to change',
`authorisationLevel` enum("REMOVED", "USER", "ADMIN") NOT NULL COMMENT 'user level of authorization'
) AUTO_INCREMENT=10;
*/
import java.sql.ResultSet;
import java.sql.SQLException;
public class UserSmall {
public long id;
public String login;
public String email;
public State authorisationLevel;
public UserSmall() {
}
public UserSmall(long id, String login, String email, State authorisationLevel) {
this.id = id;
this.login = login;
this.email = email;
this.authorisationLevel = authorisationLevel;
}
public UserSmall(ResultSet rs) {
int iii = 1;
try {
this.id = rs.getLong(iii++);
this.login = rs.getString(iii++);
this.email = rs.getString(iii++);
this.authorisationLevel = State.valueOf(rs.getString(iii++));
} catch (SQLException ex) {
ex.printStackTrace();
}
}
/*
public void serialize(ResultSet rs) {
int iii = 1;
try {
this.id = rs.getLong(iii++);
this.login = rs.getString(iii++);
this.password = rs.getString(iii++);
this.email = rs.getString(iii++);
this.emailValidate = rs.getLong(iii++);
this.newEmail = rs.getString(iii++);
this.authorisationLevel = State.valueOf(rs.getString(iii++));
} catch (SQLException ex) {
ex.printStackTrace();
}
}
*/
@Override
public String toString() {
return "UserSmall{" +
"id='" + id + '\'' +
", login='" + login + '\'' +
", email='" + email + '\'' +
", authorisationLevel=" + authorisationLevel +
'}';
}
}

View File

@ -1,205 +0,0 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
##
## @author Edouard DUPIN
##
## @copyright 2012, Edouard DUPIN, all right reserved
##
## @license MPL v2.0 (see license file)
##
import os
import shutil
import errno
import fnmatch
import stat
# Local import
from realog import debug
"""
"""
def get_run_path():
return os.getcwd()
"""
"""
def get_current_path(file):
return os.path.dirname(os.path.realpath(file))
def create_directory_of_file(file):
debug.info("Create directory of path: '" + file + "'")
path = os.path.dirname(file)
debug.info("Create directory: '" + path + "'")
try:
os.stat(path)
except:
os.makedirs(path)
def get_list_sub_path(path):
# TODO : os.listdir(path)
for dirname, dirnames, filenames in os.walk(path):
return dirnames
return []
def remove_path_and_sub_path(path):
if os.path.isdir(path):
debug.verbose("remove path : '" + path + "'")
shutil.rmtree(path)
def remove_file(path):
if os.path.isfile(path):
os.remove(path)
elif os.path.islink(path):
os.remove(path)
def exist(path):
if os.path.isdir(path):
return True
if os.path.isfile(path):
return True
if os.path.islink(path):
return True
return False
def file_size(path):
if not os.path.isfile(path):
return 0
statinfo = os.stat(path)
return statinfo.st_size
def file_read_data(path, binary=False):
debug.verbose("path= " + path)
if not os.path.isfile(path):
return ""
if binary == True:
file = open(path, "rb")
else:
file = open(path, "r")
data_file = file.read()
file.close()
return data_file
def version_to_string(version):
version_ID = ""
for id in version:
if len(version_ID) != 0:
if type(id) == str:
version_ID += "-"
else:
version_ID += "."
version_ID += str(id)
return version_ID
##
## @brief Write data in a specific path.
## @param[in] path Path of the data might be written.
## @param[in] data Data To write in the file.
## @param[in] only_if_new (default: False) Write data only if data is different.
## @return True Something has been copied
## @return False Nothing has been copied
##
def file_write_data(path, data, only_if_new=False):
if only_if_new == True:
if os.path.exists(path) == True:
old_data = file_read_data(path)
if old_data == data:
return False
#real write of data:
create_directory_of_file(path)
file = open(path, "w")
file.write(data)
file.close()
return True
def file_write_data_safe(path, data):
#real write of data:
create_directory_of_file(path)
file = open(path + ".tmp", "w")
file.write(data)
file.close()
shutil.move(path + ".tmp", path)
return True
def file_move(path_src, path_dst):
create_directory_of_file(path_dst)
shutil.move(path_src, path_dst)
return True
def file_copy(path_src, path_dst):
create_directory_of_file(path_dst)
shutil.copyfile(path_src, path_dst)
return True
def list_to_str(list):
if type(list) == type(str()):
return list + " "
else:
result = ""
# mulyiple imput in the list ...
for elem in list:
result += list_to_str(elem)
return result
import hashlib
def str_limit_4(_data):
data = str(_data)
if len(data) >= 4:
return data
if len(data) == 3:
return " " + data
if len(data) == 2:
return " " + data
return " " + data
def int_to_human(_data, _bigger = False):
tera = int(_data/(1024*1024*1024*1024))%1024
giga = int(_data/(1024*1024*1024))%1024
mega = int(_data/(1024*1024))%1024
kilo = int(_data/(1024))%1024
byte = int(_data)%1024
tera_str = str_limit_4(tera)
giga_str = str_limit_4(giga)
mega_str = str_limit_4(mega)
kilo_str = str_limit_4(kilo)
byte_str = str_limit_4(byte)
out = ""
if tera != 0:
out += tera_str + "T"
if _bigger == True:
return out
if giga != 0 or len(out) != 0:
out += giga_str + "G"
if _bigger == True:
return out
if mega != 0 or len(out) != 0:
out += mega_str + "M"
if _bigger == True:
return out
if kilo != 0 or len(out) != 0:
out += kilo_str + "k"
if _bigger == True:
return out
out += byte_str + "B"
return out
def calculate_sha512(_path):
sha1 = hashlib.sha512()
file = open(_path, "rb")
totalsize = os.path.getsize(_path)
current = 0
while True:
body = file.read(10*1024*1024)
if len(body) == 0:
break;
current += len(body)
sha1.update(body)
percent = current/totalsize*100
debug.debug("\r Checking data: {percent:3.0f}% {size} / {total_size}".format(percent=percent, size=int_to_human(current), total_size=int_to_human(totalsize)))
file.close()
return str(sha1.hexdigest())

View File

@ -1,42 +0,0 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
##
## @author Edouard DUPIN
##
## @copyright 2019, Edouard DUPIN, all right reserved
##
## @license MPL v2.0 (see license file)
##
import os
import sys
import requests # pip install requests
class upload_in_chunks(object):
def __init__(self, filename, chunksize=1 << 13):
self.filename = filename
self.chunksize = chunksize
self.totalsize = os.path.getsize(filename)
self.readsofar = 0
def __iter__(self):
with open(self.filename, 'rb') as file:
while True:
data = file.read(self.chunksize)
if not data:
sys.stderr.write("\n")
break
self.readsofar += len(data)
percent = self.readsofar * 1e2 / self.totalsize
sys.stderr.write("\rSendfing data: {percent:3.0f}% {size:14.0f} / {total_size}".format(percent=percent, size=self.readsofar, total_size=self.totalsize))
yield data
def __len__(self):
return self.totalsize
filename = 'Totally_Spies.mp4'
result = requests.post("http://127.0.0.1:15080/data", data=upload_in_chunks(filename, chunksize=4096))
print("result : " + str(result) + " " + result.text)#str(dir(result)))

View File

@ -1,987 +0,0 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
##
## @author Edouard DUPIN
##
## @copyright 2019, Edouard DUPIN, all right reserved
##
## @license MPL v2.0 (see license file)
##
import os
import copy
import sys
import datetime
import hashlib
import requests # pip install requests
import realog.debug as debug
#import magic
import json
import shutil
from pymediainfo import MediaInfo
debug.enable_color();
def get_run_path():
return os.getcwd()
folder = get_run_path()
src_path = folder
dst_path = os.path.join(folder, "..", "zzz_video_push_done")
property = {
"hostname": "192.168.1.156",
#"hostname": "127.0.0.1",
"port": 15080,
"login": None,
"password": None,
}
def get_base_url():
return "http://" + property["hostname"] + ":" + str(property["port"]) + "/"
def check_correct_format(_file):
media_info = MediaInfo.parse(_file)
print("media-info: ... " + str(len(media_info.tracks)))
need_trascode_audio = False
for elem_track in media_info.tracks:
data_print = "[" + str(elem_track.track_id) + "] " + str(elem_track.track_type)
#print('track_id = ' + str(elem_track.track_id))
#print('track_type = ' + str(elem_track.track_type))
if elem_track.track_type == "Audio":
data_print += " (" + str(elem_track.language) + ") enc=" + str(elem_track.format);
#print('language = ' + str(elem_track.language))
#print('format = ' + str(elem_track.format))
if elem_track.format != "Opus":
need_trascode_audio = True
elif elem_track.track_type == "Video":
data_print += " enc=" + str(elem_track.format);
print(" - " + data_print)
#print("media-info: ..." + str(dir(elem_track)))
if need_trascode_audio == False:
return True
print(" ==> NEED transcoding, AUDIO in the good format...")
return False
def create_directory_of_file(file):
path = os.path.dirname(file)
try:
os.stat(path)
except:
os.makedirs(path)
def file_move(path_src, path_dst):
#real write of data:
print("Move file from: " + path_src)
print(" to: " + path_dst)
create_directory_of_file(path_dst)
shutil.move(path_src, path_dst)
return True
def str_limit_4(_data):
data = str(_data)
if len(data) >= 4:
return data
if len(data) == 3:
return " " + data
if len(data) == 2:
return " " + data
return " " + data
def int_to_human(_data, _bigger = False):
tera = int(_data/(1024*1024*1024*1024))%1024
giga = int(_data/(1024*1024*1024))%1024
mega = int(_data/(1024*1024))%1024
kilo = int(_data/(1024))%1024
byte = int(_data)%1024
tera_str = str_limit_4(tera)
giga_str = str_limit_4(giga)
mega_str = str_limit_4(mega)
kilo_str = str_limit_4(kilo)
byte_str = str_limit_4(byte)
out = ""
if tera != 0:
out += tera_str + "T"
if _bigger == True:
return out
if giga != 0 or len(out) != 0:
out += giga_str + "G"
if _bigger == True:
return out
if mega != 0 or len(out) != 0:
out += mega_str + "M"
if _bigger == True:
return out
if kilo != 0 or len(out) != 0:
out += kilo_str + "k"
if _bigger == True:
return out
out += byte_str + "B"
return out
class upload_in_chunks(object):
def __init__(self, filename, chunksize=1 + 13):
self.filename = filename
self.chunksize = chunksize
self.totalsize = os.path.getsize(filename)
self.start_time = datetime.datetime.utcnow()
self.performance_time = datetime.datetime.utcnow()
self.performance_data = 0
self.readsofar = 0
self.performance_result = 0
def __iter__(self):
with open(self.filename, 'rb') as file:
while True:
data = file.read(self.chunksize)
if not data:
sys.stderr.write("\n")
break
self.readsofar += len(data)
self.performance_data += len(data)
percent = self.readsofar * 1e2 / self.totalsize
since_time = datetime.datetime.utcnow() - self.start_time
delta_time = datetime.datetime.utcnow() - self.performance_time
if delta_time > datetime.timedelta(seconds=2):
delta_seconds = delta_time.total_seconds()
self.performance_result = self.performance_data / delta_seconds
self.performance_time = datetime.datetime.utcnow()
self.performance_data = 0
#sys.stderr.write("\rSending data: {percent:3.0f}% {size:14.0f} / {total_size} {timeee}".format(percent=percent, size=self.readsofar, total_size=self.totalsize, timeee=str(since_time)))
sys.stderr.write("\r Sending data: {percent:3.0f}% {size} / {total_size} {timeee} {speed}/s".format(percent=percent, size=int_to_human(self.readsofar), total_size=int_to_human(self.totalsize), timeee=str(since_time), speed=int_to_human(self.performance_result, True)))
yield data
def __len__(self):
return self.totalsize
#filename = 'Totally_Spies.mp4'
#result = requests.post(get_base_url() + "data", data=upload_in_chunks(filename, chunksize=4096))
#debug.info("result : " + str(result) + " " + result.text)#str(dir(result)))
def extract_and_remove(_input_value, _start_mark, _stop_mark):
values = []
out = ""
inside = False
inside_data = ""
for it in _input_value:
if inside == False \
and it == _start_mark:
inside = True
elif inside == True \
and it == _stop_mark:
inside = False
values.append(inside_data)
inside_data = ""
elif inside == True:
inside_data += it
else:
out += it
return (out, values)
def create_directory_of_file(_file):
path = os.path.dirname(_file)
try:
os.stat(path)
except:
os.makedirs(path)
##
## @brief Write data in a specific path.
## @param[in] path Path of the data might be written.
## @param[in] data Data To write in the file.
## @param[in] only_if_new (default: False) Write data only if data is different.
## @return True Something has been copied
## @return False Nothing has been copied
##
def file_write_data(_path, _data, _only_if_new=False):
if _only_if_new == True:
if os.path.exists(_path) == True:
old_data = file_read_data(_path)
if old_data == _data:
return False
#real write of data:
create_directory_of_file(_path)
file = open(_path, "w")
file.write(_data)
file.close()
return True
def get_modify_time(_path):
return os.stat(_path).st_mtime
def file_read_data(_path, _binary=False):
debug.verbose("path= " + _path)
if not os.path.isfile(_path):
return ""
if _binary == True:
file = open(_path, "rb")
else:
file = open(_path, "r")
data_file = file.read()
file.close()
return data_file
def calculate_sha512(_path):
sha1 = hashlib.sha512()
file = open(_path, "rb")
totalsize = os.path.getsize(_path)
current = 0
while True:
body = file.read(10*1024*1024)
if len(body) == 0:
break;
current += len(body)
sha1.update(body)
percent = current/totalsize*100
sys.stderr.write("\r Checking data: {percent:3.0f}% {size} / {total_size}".format(percent=percent, size=int_to_human(current), total_size=int_to_human(totalsize)))
file.close()
sys.stderr.write("\n")
return str(sha1.hexdigest())
result_list_types = requests.get(get_base_url() + "type")
debug.info(" List of types *********** : " + str(result_list_types))
#debug.info(" " + str(result_list_types.json()))
result_list_types = result_list_types.json()
def get_type_id(_name):
for elem in result_list_types:
if elem["name"] == _name:
return elem["id"]
return None
def print_list_of_type():
print("List of type:")
for elem in result_list_types:
print(" - '" + elem["name"] + "'")
def get_list_of_type():
print("List of type:")
out = []
for elem in result_list_types:
out.append(elem["name"])
return out
#exit(-1);
nb_file_try_send = 0
nb_file_sended = 0
def push_video_file(_path, _basic_key={}):
file_name, file_extension = os.path.splitext(_path);
# internal file_extension ...
if file_extension == "sha512":
debug.verbose(" file: '" + _path + "' sha512 extention ...")
return True
debug.verbose(" Add media : '" + _path + "'")
# "avi", , "mov", , "ts", "cover_1.tiff", "cover_1.bmp", "cover_1.tga"] copy only file that is supported by the html5 video player (chrome mode only)
if file_extension[1:] not in ["webm", "mkv", "mp4"] \
and file_name not in ["cover_1.jpg","cover_1.png"]:
debug.verbose(" Not send file : " + _path + " Not manage file_extension... " + file_extension)
return False
debug.info("=======================================================================")
debug.info("Send file: '" + file_name + "' with extention " + file_extension)
debug.info("=======================================================================")
if file_name in ["cover_1.jpg","cover_1.png", "cover_1.till", "cover_1.bmp", "cover_1.tga"]:
# find a cover...
return True
global nb_file_try_send
nb_file_try_send += 1
mime_type = "unknown"
# do it by myself .. it is better ...
filename___, file_extension = os.path.splitext(_path)
if file_extension in ["mkv", ".mkv"]:
mime_type = "video/x-matroska"
elif file_extension in ["mka", ".mka"]:
mime_type = "audio/x-matroska"
elif file_extension in ["mp4", ".mp4"]:
mime_type = "video/mp4"
elif file_extension in ["webm", ".webm"]:
mime_type = "video/webm"
elif file_extension in ["json", ".json"]:
mime_type = "application/json"
elif file_extension in ["jpeg", ".jpeg", ".JPEG", "JPEG", "jpg", ".jpg", ".JPG", "JPG"]:
mime_type = "image/jpeg"
elif file_extension in ["png", ".png"]:
mime_type = "image/png"
try:
_path.encode('latin-1')
path_send = _path;
except UnicodeEncodeError:
path_send = "";
for elem in _path:
if elem in "azertyuiopqsdfghjklmwxcvbnAZERTYUIOPQSDFGHJKLMWXCVBN1234567890_- []{})(:.,;?/\%$&~#'|@=+°*!²":
path_send += elem
#debug.warning(" value " + _path)
#debug.error(" ==> " + path_send)
headers_values = {
'filename': path_send,
'mime-type': mime_type
}
debug.info(" Check correct format SHA ...")
valid = check_correct_format(_path)
if valid == False:
debug.warning("wrong format ====> !!!! need trancode");
return;
debug.info(" Calculate SHA ...")
local_sha = calculate_sha512(_path)
debug.info(" ==> sha is " + local_sha)
result_check_sha = requests.get(get_base_url() + "data/exist/" + local_sha)
remote_id_data = None
if result_check_sha.status_code == 200:
debug.debug(" Find the data : " + str(result_check_sha) + " " + result_check_sha.text)
remote_id_data = result_check_sha.json()["id"]
elif result_check_sha.status_code == 404:
debug.info(" Did not find the file ... ==> need to send it")
else:
debug.warning(" error interface ...")
if remote_id_data == None:
result_send_data = requests.post(get_base_url() + "data", headers=headers_values, data=upload_in_chunks(_path, chunksize=4096))
debug.debug(" result *********** : " + str(result_send_data) + " " + result_send_data.text)
remote_id_data = result_send_data.json()["id"]
if remote_id_data == None:
debug.warning(" pb in file sending ....");
return
file_name = os.path.basename(file_name)
debug.info(" Find file_name : '" + file_name + "'");
debug.verbose("1111111");
# Remove Date (XXXX) or other titreadsofarle
file_name, dates = extract_and_remove(file_name, '(', ')');
have_date = False
have_Title = False
debug.verbose("1111111 2222222 ");
for it in dates:
#debug.info(" 2222222 ==> 1 " + it);
if len(it) == 0:
continue
#debug.info(" 2222222 ==> 2 ");
if it[0] == '0' \
or it[0] == '1' \
or it[0] == '2' \
or it[0] == '3' \
or it[0] == '4' \
or it[0] == '5' \
or it[0] == '6' \
or it[0] == '7' \
or it[0] == '8' \
or it[0] == '9':
#debug.info(" 2222222 ==> 3 ");
# find a date ...
if have_date == True:
debug.debug(" '" + file_name + "'")
debug.error(" Parse Date error : () : " + it + " ==> multiple date")
continue
#debug.info(" 2222222 ==> 4 ");
try:
tmppppppppp = int(it)
if tmppppppppp >= 1900 and tmppppppppp < 3000:
_basic_key["date"] = tmppppppppp
have_date = True
except ValueError:
debug.warning(" Parse Date error : () : " + it + " ==> not a date ...")
else:
#debug.info(" 2222222 ==> 9 ");
if have_Title == True:
debug.debug(" '" + file_name + "'")
debug.error(" Parse Title error : () : " + it + " ==> multiple title")
continue
#debug.info(" 2222222 ==> 10 ");
have_Title = True
# Other title
_basic_key["title2"] = it;
#debug.info(" 2222222 ==> 11 ");
debug.verbose("1111111 2222222 3333333 ");
# Remove the actors [XXX YYY][EEE TTT]...
file_name, actors = extract_and_remove(file_name, '[', ']');
if len(actors) > 0:
debug.info(" '" + file_name + "'")
actor_list = []
for it_actor in actors:
if actor_list != "":
actor_list += ";"
actor_list.append(it_actor)
_basic_key["actors"] = actor_list
list_element_base = file_name.split('-')
debug.debug(" ==> Title file: " + file_name)
debug.debug(" ==> Title cut : " + str(list_element_base))
debug.verbose("1111111 2222222 3333333 555555");
list_element = [];
tmp_start_string = "";
iii = 0
if len(list_element_base) == 1:
list_element = list_element_base
else:
while iii < len(list_element_base):
if list_element_base[iii][0] != 's' \
and list_element_base[iii][0] != 'e':
if tmp_start_string != "":
tmp_start_string += '-'
tmp_start_string += list_element_base[iii]
else:
list_element.append(tmp_start_string)
tmp_start_string = ""
while iii<len(list_element_base):
list_element.append(list_element_base[iii])
iii += 1
iii += 1
debug.debug(" ==> start elem: " + str(tmp_start_string))
debug.verbose("1111111 2222222 3333333 555555 666666");
if tmp_start_string != "":
list_element.append(tmp_start_string)
debug.debug(" ==> list_element : " + str(list_element))
if len(list_element) == 1:
# nothing to do , it might be a film ...
_basic_key["title"] = list_element[0]
else:
if len(list_element) > 3 \
and list_element[1][0] == 's' \
and list_element[2][0] == 'e':
debug.debug(" Parse format: xxx-sXX-eXX-kjhlkjlkj(1234).*")
# internal formalisme ...
saison = -1;
episode = -1;
series_name = list_element[0];
if "series-name" not in _basic_key.keys():
_basic_key["series-name"] = series_name
full_episode_name = list_element[3]
for yyy in range(4, len(list_element)):
full_episode_name += "-" + list_element[yyy]
_basic_key["title"] = full_episode_name
if list_element[1][1:] == "XX":
# saison unknow ... ==> nothing to do ...
#saison = 123456789;
pass
else:
try:
saison = int(list_element[1][1:]);
finally:
pass
if list_element[2][1:] == "XX":
# episode unknow ... ==> nothing to do ...
pass
else:
try:
episode = int(list_element[2][1:]);
_basic_key["episode"] = int(episode)
except ValueError:
pass
debug.debug(" Find a internal mode series: :");
debug.debug(" origin : '" + file_name + "'");
saisonPrint = "XX";
episodePrint = "XX";
if saison < 0:
# nothing to do
pass
else:
try:
saisonPrint = str(saison)
_basic_key["saison"] = str(saison)
except ValueError:
pass
if episode < 0:
# nothing to do
pass
elif episode < 10:
episodePrint = "0" + str(episode);
_basic_key["episode"] = episode
else:
episodePrint = str(episode);
_basic_key["episode"] = episode
debug.info(" ==> '" + series_name + "-s" + saisonPrint + "-e" + episodePrint + "-" + full_episode_name + "'");
elif len(list_element) > 2 \
and list_element[1][0] == 'e':
debug.debug(" Parse format: xxx-eXX-kjhlkjlkj(1234).*")
# internal formalisme ...
saison = -1;
episode = -1;
series_name = list_element[0];
_basic_key["series-name"] = series_name
full_episode_name = list_element[2]
for yyy in range(3, len(list_element)):
full_episode_name += "-" + list_element[yyy]
_basic_key["title"] = full_episode_name
if list_element[1][1:] == "XX":
# episode unknow ... ==> nothing to do ...
pass
else:
try:
episode = int(list_element[1][1:]);
_basic_key["episode"] = int(episode)
finally:
pass
debug.debug(" Find a internal mode series: :");
debug.debug(" origin : '" + file_name + "'");
saisonPrint = "XX";
episodePrint = "XX";
if episode < 0:
# nothing to do
pass
elif episode < 10:
episodePrint = "0" + str(episode);
_basic_key["episode"] = episode
else:
episodePrint = str(episode);
_basic_key["episode"] = episode
debug.info(" ==> '" + series_name + "-s" + saisonPrint + "-e" + episodePrint + "-" + full_episode_name + "'");
debug.verbose("1111111 2222222 3333333 555555 666666 777777 ");
if "title" not in _basic_key.keys():
debug.warning(" ===> No title parsed ...")
_basic_key["title"] = "---"
debug.debug(" pared meta data: " + json.dumps(_basic_key, sort_keys=True, indent=4))
data_model = {
"type_id": _basic_key["type"],
"data_id": remote_id_data,
#"group_id": int,
"name": _basic_key["title"],
# number of second
"time": None,
}
for elem in ["date", "description", "episode"]: #["actors", "date", "description", "episode", "title2"]:
if elem in _basic_key.keys():
data_model[elem] = _basic_key[elem]
debug.verbose("1111111 2222222 3333333 555555 666666 777777 888888");
if "series-name" in _basic_key.keys():
result_group_data = requests.post(get_base_url() + "group/find", data=json.dumps({"name":_basic_key["series-name"]}, sort_keys=True, indent=4))
debug.debug(" Create group ??? *********** : " + str(result_group_data) + " " + result_group_data.text)
if result_group_data.status_code == 404:
result_group_data = requests.post(get_base_url() + "group", data=json.dumps({"name":_basic_key["series-name"]}, sort_keys=True, indent=4))
debug.debug(" yes we create new group *********** : " + str(result_group_data) + " " + result_group_data.text)
group_id = result_group_data.json()["id"]
data_model["serie_id"] = group_id
if "saison" in _basic_key.keys():
result_saison_data = requests.post(get_base_url() + "saison/find", data=json.dumps({"name":str(_basic_key["saison"]), "parent_id":group_id}, sort_keys=True, indent=4))
debug.debug(" Create saison ??? *********** : " + str(result_saison_data) + " " + result_saison_data.text)
if result_saison_data.status_code == 404:
result_saison_data = requests.post(get_base_url() + "saison", data=json.dumps({"name":str(_basic_key["saison"]), "parent_id":group_id}, sort_keys=True, indent=4))
debug.debug(" yes we create new saison *********** : " + str(result_saison_data) + " " + result_saison_data.text)
saison_id = result_saison_data.json()["id"]
data_model["saison_id"] = saison_id
debug.verbose("1111111 2222222 3333333 555555 666666 777777 888888 999999 ");
debug.debug(" Send media information : " + json.dumps(data_model, sort_keys=True))
result_send_data = requests.post(get_base_url() + "video", data=json.dumps(data_model, sort_keys=True, indent=4))
debug.verbose(" result: " + str(result_send_data) + " " + result_send_data.text)
if result_send_data.status_code == 200:
debug.info(" ====================================");
debug.info(" == Send OK ==");
debug.info(" ====================================");
global nb_file_sended
nb_file_sended += 1
else:
debug.warning(" ====================================");
debug.warning(" == ERROR sending Media ==");
debug.warning(" ====================================");
return False
debug.verbose("1111111 2222222 3333333 555555 666666 777777 888888 999999 101010");
file_move(_path, os.path.join(dst_path, _path[len(src_path)+1:]))
debug.verbose("1111111 2222222 3333333 555555 666666 777777 888888 999999 101010 111111");
return True
def install_video_path( _path, _basic_key = {}):
debug.info("Parse : '" + _path + "'");
list_sub_path = [fff for fff in os.listdir(_path) if os.path.isdir(os.path.join(_path, fff))]
list_sub_path.sort()
for it_path in list_sub_path:
try:
basic_key_tmp = copy.deepcopy(_basic_key)
debug.info("Add Sub path: '" + it_path + "'");
if len(basic_key_tmp) == 0:
debug.info("find A '" + it_path + "' " + str(len(basic_key_tmp)));
basic_key_tmp["type"] = get_type_id(it_path);
if basic_key_tmp["type"] == None:
debug.warning("Not supported type: '" + str(it_path) + "' availlable: " + str(get_list_of_type()))
continue
else:
debug.info("find B '" + it_path + "' " + str(len(basic_key_tmp)))
it_path_tmp = it_path.lower()
if it_path_tmp.startswith("saison_"):
if it_path_tmp.startswith("saison_01") or it_path_tmp == "saison_1":
basic_key_tmp["saison"] = 1
elif it_path_tmp.startswith("saison_02") or it_path_tmp == "saison_2":
basic_key_tmp["saison"] = 2
elif it_path_tmp.startswith("saison_03") or it_path_tmp == "saison_3":
basic_key_tmp["saison"] = 3
elif it_path_tmp.startswith("saison_04") or it_path_tmp == "saison_4":
basic_key_tmp["saison"] = 4
elif it_path_tmp.startswith("saison_05") or it_path_tmp == "saison_5":
basic_key_tmp["saison"] = 5
elif it_path_tmp.startswith("saison_06") or it_path_tmp == "saison_6":
basic_key_tmp["saison"] = 6
elif it_path_tmp.startswith("saison_07") or it_path_tmp == "saison_7":
basic_key_tmp["saison"] = 7
elif it_path_tmp.startswith("saison_08") or it_path_tmp == "saison_8":
basic_key_tmp["saison"] = 8
elif it_path_tmp.startswith("saison_09") or it_path_tmp == "saison_9":
basic_key_tmp["saison"] = 9
elif it_path_tmp.startswith("saison_10"):
basic_key_tmp["saison"] = 10
elif it_path_tmp.startswith("saison_11"):
basic_key_tmp["saison"] = 11
elif it_path_tmp.startswith("saison_12"):
basic_key_tmp["saison"] = 12
elif it_path_tmp.startswith("saison_13"):
basic_key_tmp["saison"] = 13
elif it_path_tmp.startswith("saison_14"):
basic_key_tmp["saison"] = 14
elif it_path_tmp.startswith("saison_15"):
basic_key_tmp["saison"] = 15
elif it_path_tmp.startswith("saison_16"):
basic_key_tmp["saison"] = 16
elif it_path_tmp.startswith("saison_17"):
basic_key_tmp["saison"] = 17
elif it_path_tmp.startswith("saison_18"):
basic_key_tmp["saison"] = 18
elif it_path_tmp.startswith("saison_19"):
basic_key_tmp["saison"] = 19
elif it_path_tmp.startswith("saison_20"):
basic_key_tmp["saison"] = 20
elif it_path_tmp.startswith("saison_21"):
basic_key_tmp["saison"] = 21
elif it_path_tmp.startswith("saison_22"):
basic_key_tmp["saison"] = 22
elif it_path_tmp.startswith("saison_23"):
basic_key_tmp["saison"] = 23
elif it_path_tmp.startswith("saison_24"):
basic_key_tmp["saison"] = 24
elif it_path_tmp.startswith("saison_25"):
basic_key_tmp["saison"] = 25
elif it_path_tmp.startswith("saison_26"):
basic_key_tmp["saison"] = 26
elif it_path_tmp.startswith("saison_27"):
basic_key_tmp["saison"] = 27
elif it_path_tmp.startswith("saison_28"):
basic_key_tmp["saison"] = 28
elif it_path_tmp.startswith("saison_29"):
basic_key_tmp["saison"] = 29
else:
basic_key_tmp["saison"] = 99
else:
basic_key_tmp["series-name"] = it_path
debug.info("add a path " + os.path.join(_path, it_path) + " with keys " + str(basic_key_tmp))
install_video_path(os.path.join(_path, it_path), basic_key_tmp);
except KeyboardInterrupt:
print('Interrupted')
try:
sys.exit(0)
except SystemExit:
os._exit(0)
except UnicodeEncodeError:
debug.warning("Can not send file.1. " + os.path.join(_path, it_path))
raise
continue
except:
debug.warning("Can not send file.2. " + os.path.join(_path, it_path))
#raise
debug.warning( "get exception:" + str(sys.exc_info()[0]))
#import traceback
#traceback.print_stack()
#continue
raise
# Add files :
list_sub_file = [fff for fff in os.listdir(_path) if os.path.isfile(os.path.join(_path, fff))]
for it_file in list_sub_file:
basic_key_tmp = copy.deepcopy(_basic_key)
try:
push_video_file(os.path.join(_path, it_file), basic_key_tmp);
except KeyboardInterrupt:
print('Interrupted')
try:
sys.exit(0)
except SystemExit:
os._exit(0)
except UnicodeEncodeError:
debug.warning("Can not send file.3. " + os.path.join(_path, it_file))
raise
"""
except:
debug.warning("Can not send file.4. " + os.path.join(_path, it_file))
#debug.warning( "get exception:" + str(sys.exc_info()[0]))
#debug.warning("------------------------------")
#traceback.print_exc(file=sys.stdout)
#continue
#raise
"""
import death.Arguments as arguments
import death.ArgElement as arg_element
my_args = arguments.Arguments()
my_args.add_section("option", "Can be set one time in all case")
my_args.add("h", "help", desc="Display this help")
my_args.add("", "version", desc="Display the application version")
my_args.add("v", "verbose", list=[
["0","None"],
["1","error"],
["2","warning"],
["3","info"],
["4","debug"],
["5","verbose"],
["6","extreme_verbose"],
], desc="display debug level (verbose) default =2")
my_args.add("a", "action", list=[
["tree","List all the files in a tree view ..."],
["list","List all the files"],
["push","push a single file"],
["push_path","push a full folder"],
["types","List all the types availlable"],
], desc="possible action")
my_args.add("c", "color", desc="Display message in color")
my_args.add("f", "folder", haveParam=False, desc="Display the folder instead of the git repository name")
local_argument = my_args.parse()
##
## @brief Display the help of this package.
##
def usage():
color = debug.get_color_set()
# generic argument displayed :
my_args.display()
exit(0)
##
## @brief Display the version of this package.
##
def version():
color = debug.get_color_set()
import pkg_resources
debug.info("version: 0.0.0")
foldername = os.path.dirname(__file__)
debug.info("source folder is: " + foldername)
exit(0)
requestAction = "list"
# preparse the argument to get the verbose element for debug mode
def parse_arg(argument):
debug.warning("parse arg : " + argument.get_option_name() + " " + argument.get_arg())
if argument.get_option_name() == "help":
usage()
return True
elif argument.get_option_name() == "version":
version()
return True
elif argument.get_option_name() == "verbose":
debug.set_level(int(argument.get_arg()))
return True
elif argument.get_option_name() == "color":
if check_boolean(argument.get_arg()) == True:
debug.enable_color()
else:
debug.disable_color()
return True
elif argument.get_option_name() == "folder":
folder = argument.get_arg()
return True
elif argument.get_option_name() == "action":
global requestAction
requestAction = argument.get_arg()
return True
return False
# parse default unique argument:
for argument in local_argument:
parse_arg(argument)
debug.info("==================================");
debug.info("== ZEUS test client start ==");
debug.info("==================================");
def show_video(elem_video_id, indent):
indent_data = ""
while indent > 0:
indent_data += "\t"
indent -= 1
result_video = requests.get(get_base_url() + "video/" + str(elem_video_id) + "")
if result_video.status_code == 200:
video = result_video.json()
debug.info(indent_data + "- " + str(video["generated_name"]))
else:
debug.warning(indent_data + "get video id: " + str(elem_video_id) + " !!!!!! " + str(result_video.status_code) + "")
# ****************************************************************************************
# ** Clear All the data base ...
# ****************************************************************************************
if requestAction == "clear":
debug.info("============================================");
debug.info("== Clear data base: ");
debug.info("============================================");
# TODO : Do it :
debug.error("NEED to add check in cmd line to execute it ...");
"""
uint32_t count = remoteServiceVideo.count().wait().get();
debug.debug("have " + count + " medias");
for (uint32_t iii=0; iii<count ; iii += 1024:
uint32_t tmpMax = etk::min(iii + 1024, count);
debug.debug("read section " + iii + " -> " + tmpMax);
etk::Vector<uint32_t> list = remoteServiceVideo.getIds(iii,tmpMax).wait().get();
zeus::FutureGroup groupWait;
for (auto& it : list:
debug.info("remove ELEMENT : " + it);
groupWait.add(remoteServiceVideo.remove(it));
groupWait.waitFor(echrono::seconds(2000));
"""
debug.info("============================================");
debug.info("== DONE ==");
debug.info("============================================");
elif requestAction == "list":
debug.info("============================================");
debug.info("== list files: ");
debug.info("============================================");
list_types = requests.get(get_base_url() + "type")
if list_types.status_code != 200:
debug.warning(" !! ca, ot get type list ... " + str(list_types.status_code) + "")
for elem in list_types.json():
debug.info(" get type id: " + str(elem["id"]))
debug.info(" name: " + str(elem["name"]))
# get the count of video in this type
result_count = requests.get(get_base_url() + "type/" + str(elem["id"]) + "/count")
if result_count.status_code == 200:
debug.info(" count: " + str(result_count.json()["count"]))
else:
debug.warning(" count: !!!!!! " + str(result_count.status_code) + "")
# get all the video list
result_video = requests.get(get_base_url() + "type/" + str(elem["id"]) + "/video")
if result_video.status_code == 200:
if len(result_video.json()) != 0:
debug.info(" List video: " + str(result_video.json()))
else:
debug.warning(" List video: !!!!!! " + str(result_video.status_code) + "")
# get list of groups for this type
result_groups = requests.get(get_base_url() + "type/" + str(elem["id"]) + "/group")
if result_groups.status_code == 200:
if len(result_groups.json()) != 0:
debug.info(" List group: " + str(result_groups.json()))
else:
debug.warning(" List group: !!!!!! " + str(result_groups.status_code) + "")
# get list of video without groups
result_video_solo = requests.get(get_base_url() + "type/" + str(elem["id"]) + "/video_no_group")
if result_video_solo.status_code == 200:
if len(result_video_solo.json()) != 0:
debug.info(" List video solo: " + str(result_video_solo.json()))
else:
debug.warning(" List video solo: !!!!!! " + str(result_video_solo.status_code) + "")
elif requestAction == "tree":
debug.info("============================================");
debug.info("== tree files: ");
debug.info("============================================");
for elem in result_list_types:
debug.info("-------------------------------------------------")
debug.info(" " + str(elem["name"]))
debug.info("-------------------------------------------------")
# Does not work anymore...
"""
# First get all the groups:
result_groups = requests.get(get_base_url() + "type/" + str(elem["id"]) + "/group")
if result_groups.status_code == 200:
for elem_group_id in result_groups.json():
result_group = requests.get(get_base_url() + "group/" + str(elem_group_id) + "")
if result_group.status_code == 200:
group = result_group.json()
debug.info("\to- " + str(group["name"]))
# step 1: all the saison:
result_saison_in_group = requests.get(get_base_url() + "group/" + str(elem_group_id) + "/saison")
if result_saison_in_group.status_code == 200:
for elem_saison_id in result_saison_in_group.json():
result_saison = requests.get(get_base_url() + "saison/" + str(elem_saison_id) + "")
if result_saison.status_code == 200:
debug.info("\t\t* saison " + str(result_saison.json()["name"]))
result_videos_in_saison = requests.get(get_base_url() + "saison/" + str(result_saison.json()["id"]) + "/video")
if result_videos_in_saison.status_code == 200:
for elem_video_id in result_videos_in_saison.json():
show_video(elem_video_id, 3)
else:
debug.warning("\t\tget video in saison id: " + str(elem_saison_id) + " !!!!!! " + str(result_videos_in_saison.status_code) + "")
show_video(elem_video_id, 2)
else:
debug.warning("\t\tget saison id: " + str(elem_saison_id) + " !!!!!! " + str(result_saison.status_code) + "")
else:
debug.warning("\t\tget saison in group id: " + str(elem_group_id) + " !!!!!! " + str(result_saison_in_group.status_code) + "")
# step 2: all the video with no saison:
result_videos_in_group = requests.get(get_base_url() + "group/" + str(elem_group_id) + "/video_no_saison")
if result_videos_in_group.status_code == 200:
for elem_video_id in result_videos_in_group.json():
show_video(elem_video_id, 2)
else:
debug.warning("\t\tget video in group id: " + str(elem_group_id) + " !!!!!! " + str(result_videos_in_group.status_code) + "")
else:
debug.warning("\tget group id: " + str(elem_group_id) + " !!!!!! " + str(result_group.status_code) + "")
else:
debug.warning("\t\tList group: !!!!!! " + str(result_groups.status_code) + "")
# get list of video without groups
result_video_solo = requests.get(get_base_url() + "type/" + str(elem["id"]) + "/video_no_group")
if result_video_solo.status_code == 200:
for elem_video_id in result_video_solo.json():
show_video(elem_video_id, 1)
else:
debug.warning("\t\tList video solo: !!!!!! " + str(result_video_solo.status_code) + "")
"""
debug.info("============================================");
debug.info("== DONE ==");
debug.info("============================================");
elif requestAction == "push":
debug.info("============================================");
debug.info("== push file: ");
debug.info("============================================");
push_video_file(folder);
debug.info("============================================");
debug.info("== DONE ==");
debug.info("============================================");
elif requestAction == "push_path":
debug.info("============================================");
debug.info("== push path: ");
debug.info("============================================");
install_video_path(folder);
debug.info(" Send: " + str(nb_file_sended) + " / " + str(nb_file_try_send))
debug.info("============================================");
debug.info("== DONE ==");
debug.info("============================================");
elif requestAction == "types":
debug.info("============================================");
debug.info("== Display list of types: ");
debug.info("============================================");
print_list_of_type();
debug.info("============================================");
debug.info("== DONE ==");
debug.info("============================================");
else:
debug.info("============================================");
debug.error("== Unknow action: '" + requestAction + "'");
debug.info("============================================");

View File

@ -1,354 +0,0 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
##
## @author Edouard DUPIN
##
## @copyright 2016, Edouard DUPIN, all right reserved
##
## @license APACHE v2.0 (see license file)
##
import os
import fnmatch
import sys
import subprocess
import shlex
##
## @brief Execute the command with no get of output
##
def run_command(cmd_line):
# prepare command line:
args = shlex.split(cmd_line)
print("[INFO] cmd = " + str(args))
try:
# create the subprocess
p = subprocess.Popen(args)
except subprocess.CalledProcessError as e:
print("[ERROR] subprocess.CalledProcessError : " + str(args))
return False
#except:
# debug.error("Exception on : " + str(args))
# launch the subprocess:
output, err = p.communicate()
# Check error :
if p.returncode == 0:
return True
else:
return False
##
## @brief Get list of all Files in a specific path (with a regex)
## @param[in] path (string) Full path of the machine to search files (start with / or x:)
## @param[in] regex (string) Regular expression to search data
## @param[in] recursive (bool) List file with recursive search
## @param[in] remove_path (string) Data to remove in the path
## @return (list) return files requested
##
def get_list_of_file_in_path(path, regex="*", recursive = False, remove_path=""):
out = []
if os.path.isdir(os.path.realpath(path)):
tmp_path = os.path.realpath(path)
tmp_rule = regex
else:
debug.error("path does not exist : '" + str(path) + "'")
for root, dirnames, filenames in os.walk(tmp_path):
deltaRoot = root[len(tmp_path):]
while len(deltaRoot) > 0 \
and ( deltaRoot[0] == '/' \
or deltaRoot[0] == '\\' ):
deltaRoot = deltaRoot[1:]
if recursive == False \
and deltaRoot != "":
return out
tmpList = filenames
if len(tmp_rule) > 0:
tmpList = fnmatch.filter(filenames, tmp_rule)
# Import the module :
for cycleFile in tmpList:
#for cycleFile in filenames:
add_file = os.path.join(tmp_path, deltaRoot, cycleFile)
if len(remove_path) != 0:
if add_file[:len(remove_path)] != remove_path:
print("ERROR : Request remove start of a path that is not the same: '" + add_file[:len(remove_path)] + "' demand remove of '" + str(remove_path) + "'")
else:
add_file = add_file[len(remove_path)+1:]
out.append(add_file)
return out;
#ffmpeg -i 000.ts -threads 0 -vcodec libx264 -crf 20 -force_key_frames expr:gte\(t,n_forced*1\) -s 720x540 -acodec mp2 -ac 2 -ab 192k -ar 48000 -async 1 -deinterlace 000_transcoded.ts
#ffmpeg -i 000.ts -threads 0 -vcodec libx264 -crf 20 -force_key_frames expr:gte\(t,n_forced*1\) -acodec mp2 -ac 2 -ab 192k -ar 48000 -async 1 -deinterlace 000_transcoded.ts
"""
def remove_group(list_of_file=[], total_count_of_file=0):
id_elem = 0
for elem in list_of_file:
id_elem += 1
tmpfile_name = elem.replace(" ", "\ ").replace("!", "\\!").replace("'", "\\'")
print(" [" + str(id_elem) + " / " + str(total_count_of_file) + "] " + tmpfile_name)
cmd_line = "rm " + tmpfile_name
ret = run_command(cmd_line)
list_files_tmp = get_list_of_file_in_path('.', "*__", recursive = True)
remove_group(list_files_tmp, len(list_files_tmp))
list_files_sha512 = get_list_of_file_in_path('.', "*.sha512", recursive = True)
remove_group(list_files_sha512, len(list_files_sha512))
exit(0)
"""
list_files_ts = get_list_of_file_in_path('.', "*.ts", recursive = True)
list_files_flv = get_list_of_file_in_path('.', "*.flv", recursive = True)
list_files_mp4 = get_list_of_file_in_path('.', "*.mp4", recursive = True)
list_files_avi = get_list_of_file_in_path('.', "*.avi", recursive = True)
list_files_mkv = get_list_of_file_in_path('.', "*.mkv", recursive = True)
list_files_wmv = get_list_of_file_in_path('.', "*.wmv", recursive = True)
list_files_divx = get_list_of_file_in_path('.', "*.divx", recursive = True)
list_files_webm = get_list_of_file_in_path('.', "*.webm", recursive = True)
"""
# remove all encoded element in the other files (TS)
for elem_mkv in list_files_mkv:
index = 0
for elem_ts in list_files_ts:
if elem_mkv[:-3]+"ts" == elem_ts:
break;
index += 1
if index != len(list_files_ts):
print("[INFO] remove from list '" + list_files_ts[index] + "' ==> already transcoded")
del list_files_ts[index]
# remove all encoded element in the other files (FLV)
for elem_mkv in list_files_mkv:
index = 0
for elem_flv in list_files_flv:
if elem_mkv[:-3]+"flv" == elem_flv:
break;
index += 1
if index != len(list_files_flv):
print("[INFO] remove from list '" + list_files_flv[index] + "' ==> already transcoded")
del list_files_flv[index]
# remove all encoded element in the other files (mp4)
for elem_mkv in list_files_mkv:
index = 0
for elem_mp4 in list_files_mp4:
if elem_mkv[:-3]+"mp4" == elem_mp4:
break;
index += 1
if index != len(list_files_mp4):
print("[INFO] remove from list '" + list_files_mp4[index] + "' ==> already transcoded")
del list_files_mp4[index]
# remove all encoded element in the other files (TS)
for elem_mkv in list_files_mkv:
index = 0
for elem_avi in list_files_avi:
if elem_mkv[:-3]+"ts" == elem_avi:
break;
index += 1
if index != len(list_files_avi):
print("[INFO] remove from list '" + list_files_avi[index] + "' ==> already transcoded")
del list_files_avi[index]
# remove all encoded element in the other files (wmv)
for elem_mkv in list_files_mkv:
index = 0
for elem_wmv in list_files_wmv:
if elem_mkv[:-3]+"wmv" == elem_wmv:
break;
index += 1
if index != len(list_files_wmv):
print("[INFO] remove from list '" + list_files_wmv[index] + "' ==> already transcoded")
del list_files_wmv[index]
# remove all encoded element in the other files (divx)
for elem_mkv in list_files_mkv:
index = 0
for elem_divx in list_files_divx:
if elem_mkv[:-3]+"divx" == elem_divx:
break;
index += 1
if index != len(list_files_divx):
print("[INFO] remove from list '" + list_files_divx[index] + "' ==> already transcoded")
del list_files_divx[index]
"""
print("list of elements TS : ")
for elem in list_files_ts:
print(" - '" + str(elem) + "'")
print("list of elements MP4 : ")
for elem in list_files_mp4:
print(" - '" + str(elem) + "'")
print("list of elements FLV : ")
for elem in list_files_flv:
print(" - '" + str(elem) + "'")
print("list of elements AVI : ")
for elem in list_files_avi:
print(" - '" + str(elem) + "'")
print("list of elements WMV : ")
for elem in list_files_wmv:
print(" - '" + str(elem) + "'")
print("list of elements MKV : ")
for elem in list_files_mkv:
print(" - '" + str(elem) + "'")
print("list of elements divx : ")
for elem in list_files_divx:
print(" - '" + str(elem) + "'")
print("list of elements webm : ")
for elem in list_files_webm:
print(" - '" + str(elem) + "'")
import random
from pymediainfo import MediaInfo
for arg in sys.argv:
print("arg: " + arg)
id_value = 0
if len(sys.argv) == 2:
id_value = int(sys.argv[1])
tmp_name_encoded_file = "zzz_transcoded_" + str(id_value) + ".mkv"
print("lement name: " + tmp_name_encoded_file)
element_error=[]
def trancode_local(list_of_file=[], extention="ts", total_count_of_file=0, offset=0) :
global element_error;
print("Start strancoding: '." + extention + "' ... " + str(len(list_of_file)))
id_elem = 0
for elem in list_of_file:
id_elem += 1
print(" ========================================================================================")
print(" == " + str(offset+id_elem) + " / " + str(total_count_of_file))
print(" == Trancode: '" + elem.replace("'", "\'") + "'")
print(" ========================================================================================")
if not os.path.isfile(elem):
print(" ==> file does not exist")
continue
cmd_line = "rm " + tmp_name_encoded_file
ret = run_command(cmd_line)
# collect media info ...
#if it is a mk: .. chack the opus format...
if extention == "mkv":
media_info = MediaInfo.parse(elem)
print("media-info: ... " + str(len(media_info.tracks)))
need_trascode_audio = False
for elem_track in media_info.tracks:
data_print = "[" + str(elem_track.track_id) + "] " + str(elem_track.track_type)
#print('track_id = ' + str(elem_track.track_id))
#print('track_type = ' + str(elem_track.track_type))
if elem_track.track_type == "Audio":
data_print += " (" + str(elem_track.language) + ") enc=" + str(elem_track.format);
#print('language = ' + str(elem_track.language))
#print('format = ' + str(elem_track.format))
if elem_track.format != "Opus":
need_trascode_audio = True
elif elem_track.track_type == "Video":
data_print += " enc=" + str(elem_track.format);
print(" - " + data_print)
#print("media-info: ..." + str(dir(elem_track)))
if need_trascode_audio == False:
print(" ==> No transcoding, already in the good format...")
continue
"""
media_info = MediaInfo.parse(elem)
print("media-info: ..." + str(len(media_info.tracks)))
for elem_track in media_info.tracks:
print('track_type = ' + str(elem_track.track_type))
print('track_id = ' + str(elem_track.track_id))
print('language = ' + str(elem_track.language))
#print("media-info: ..." + str(dir(elem_track)))
continue
"""
if extention != "mkv":
cmd_line = "ffmpeg -fflags +genpts -i "
#cmd_line = "ffmpeg -fflags +igndts -i "
else:
cmd_line = "ffmpeg -i "
cmd_line += elem.replace(" ", "\ ").replace("'", "\\'")
#cmd_line += " -threads 4 -vcodec libx264 -crf 22 -force_key_frames expr:gte\(t,n_forced*1\) -acodec mp2 -ac 2 -ab 192k -ar 48000 -async 1 -deinterlace zzz_transcoded.mkv_tmp"
#cmd_line += " -threads 4 -vcodec copy -acodec mp2 -ac 2 -ab 192k -ar 48000 -async 1 -deinterlace tmp_transcoded.avi"
#cmd_line += " -threads 4 -vcodec copy -acodec mp2 -ac 2 -ab 192k -ar 48000 -async 1 -deinterlace tmp_transcoded.mp4"
#cmd_line += " -threads 6 -c:v libvpx-vp9 -lossless 1 -c:a libopus -b:a 128k -deinterlace tmp_transcoded.webm"
#cmd_line += " -threads 6 -c:v libvpx-vp9 -row-mt 1 -c:a libopus -b:a 128k -deinterlace tmp_transcoded.webm"
# -map 0:v ==> copy all video stream
# -map 0:a ==> copy all audio stream
# -map 0:s ==> copy all subtitle stream
cmd_line += " -map 0:v -map 0:a -c:v copy -c:a libopus -ac 2 -b:a 192k -r:a 48000 -deinterlace -threads 6 " + tmp_name_encoded_file
#cmd_line += " -threads 4 -vcodec copy -acodec copy tmp_transcoded.webm"
ret = run_command(cmd_line)
print(" ret value = " + str(ret))
if ret == False:
print("[ERROR] Trancode: error occured ...")
element_error.append(elem)
#exit(-1)
continue
print(" move in: '" + elem[:-len(extention)] + "mkv'")
# cmd_line = "mv " + elem.replace(" ", "\ ").replace("'", "\\'") + " last_transcoded.xx"
cmd_line = "mv " + elem.replace(" ", "\ ").replace("!", "\\!").replace("'", "\\'") + " last_transcoded"
ret = run_command(cmd_line)
cmd_line = "mv " + tmp_name_encoded_file + " " + elem.replace(" ", "\ ").replace("!", "\\!").replace("'", "\\'")[:-len(extention)] + "mkv"
ret = run_command(cmd_line)
#cmd_line = "mv " + elem.replace(" ", "\ ").replace("'", "\\'") + " last_transcoded.ts"
#ret = run_command(cmd_line)
#break
full_list_size = len(list_files_ts) + len(list_files_mp4) + len(list_files_flv) + len(list_files_avi) + len(list_files_wmv) + len(list_files_divx) + len(list_files_mkv) + len(list_files_webm)
offset = 0;
reverse_sort = False
list_files_ts.sort(reverse=reverse_sort)
list_files_mp4.sort(reverse=reverse_sort)
list_files_flv.sort(reverse=reverse_sort)
list_files_avi.sort(reverse=reverse_sort)
list_files_wmv.sort(reverse=reverse_sort)
list_files_divx.sort(reverse=reverse_sort)
list_files_mkv.sort(reverse=reverse_sort)
list_files_webm.sort(reverse=reverse_sort)
random.shuffle(list_files_mp4)
random.shuffle(list_files_avi)
random.shuffle(list_files_mkv)
trancode_local(list_files_ts , "ts", full_list_size, offset)
offset += len(list_files_ts)
trancode_local(list_files_mp4 , "mp4", full_list_size, offset)
offset += len(list_files_mp4)
trancode_local(list_files_flv , "flv", full_list_size, offset)
offset += len(list_files_flv)
trancode_local(list_files_avi , "avi", full_list_size, offset)
offset += len(list_files_avi)
trancode_local(list_files_wmv , "wmv", full_list_size, offset)
offset += len(list_files_wmv)
trancode_local(list_files_divx , "divx", full_list_size, offset)
offset += len(list_files_divx)
trancode_local(list_files_mkv , "mkv", full_list_size, offset)
offset += len(list_files_mkv)
#trancode_local(list_files_webm , "webm", full_list_size, offset)
#offset += len(list_files_webm)
print("List error transcode: " + len(element_error))
for elem in element_error:
print(" == Trancode: '" + elem.replace("'", "\'") + "'")
## extract a thumb from a video
## ffmpeg -i Passenger.mkv -ss 00:05:00 -f image2 -vframes 1 thumb.jpg

View File

@ -1,173 +0,0 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
##
## @author Edouard DUPIN
##
## @copyright 2016, Edouard DUPIN, all right reserved
##
## @license APACHE v2.0 (see license file)
##
import os
import fnmatch
import sys
import subprocess
import shlex
import shutil
##
## @brief Execute the command with no get of output
##
def run_command(cmd_line):
# prepare command line:
args = shlex.split(cmd_line)
print("[INFO] cmd = " + str(args))
try:
# create the subprocess
p = subprocess.Popen(args)
except subprocess.CalledProcessError as e:
print("[ERROR] subprocess.CalledProcessError : " + str(args))
return False
#except:
# debug.error("Exception on : " + str(args))
# launch the subprocess:
output, err = p.communicate()
# Check error :
if p.returncode == 0:
return True
else:
return False
##
## @brief Get list of all Files in a specific path (with a regex)
## @param[in] path (string) Full path of the machine to search files (start with / or x:)
## @param[in] regex (string) Regular expression to search data
## @param[in] recursive (bool) List file with recursive search
## @param[in] remove_path (string) Data to remove in the path
## @return (list) return files requested
##
def get_list_of_file_in_path(path, regex="*", recursive = False, remove_path=""):
out = []
if os.path.isdir(os.path.realpath(path)):
tmp_path = os.path.realpath(path)
tmp_rule = regex
else:
debug.error("path does not exist : '" + str(path) + "'")
for root, dirnames, filenames in os.walk(tmp_path):
deltaRoot = root[len(tmp_path):]
while len(deltaRoot) > 0 \
and ( deltaRoot[0] == '/' \
or deltaRoot[0] == '\\' ):
deltaRoot = deltaRoot[1:]
if recursive == False \
and deltaRoot != "":
return out
tmpList = filenames
if len(tmp_rule) > 0:
tmpList = fnmatch.filter(filenames, tmp_rule)
# Import the module :
for cycleFile in tmpList:
#for cycleFile in filenames:
add_file = os.path.join(tmp_path, deltaRoot, cycleFile)
if len(remove_path) != 0:
if add_file[:len(remove_path)] != remove_path:
print("ERROR : Request remove start of a path that is not the same: '" + add_file[:len(remove_path)] + "' demand remove of '" + str(remove_path) + "'")
else:
add_file = add_file[len(remove_path)+1:]
out.append(add_file)
return out;
def get_run_path():
return os.getcwd()
src_path = get_run_path()
dst_path = os.path.join(src_path, "..", "zzz_video_push_correct")
list_files_mkv = get_list_of_file_in_path(src_path, "*.mkv", recursive = True)
list_files_webm = get_list_of_file_in_path(src_path, "*.webm", recursive = True)
list_files_jpg = get_list_of_file_in_path(src_path, "*.jpg", recursive = True)
list_files_png = get_list_of_file_in_path(src_path, "*.png", recursive = True)
print("list of elements MKV : ")
for elem in list_files_mkv:
print(" - '" + str(elem) + "'")
print("list of elements webm : ")
for elem in list_files_webm:
print(" - '" + str(elem) + "'")
import random
from pymediainfo import MediaInfo
for arg in sys.argv:
print("arg: " + arg)
id_value = 0
if len(sys.argv) == 2:
id_value = int(sys.argv[1])
def create_directory_of_file(file):
path = os.path.dirname(file)
try:
os.stat(path)
except:
os.makedirs(path)
def file_move(path_src, path_dst):
#real write of data:
print("Move file from: " + path_src)
print(" to: " + path_dst)
create_directory_of_file(path_dst)
shutil.move(path_src, path_dst)
return True
def move_local(list_of_file=[], extention="mkv") :
global element_error;
print("Start strancoding: '." + extention + "' ... " + str(len(list_of_file)))
id_elem = 0
total_count_of_file = len(list_of_file)
for elem in list_of_file:
id_elem += 1
print(" ========================================================================================")
print(" == " + str(id_elem) + " / " + str(total_count_of_file))
print(" == Trancode: '" + elem.replace("'", "\'") + "'")
print(" ========================================================================================")
if not os.path.isfile(elem):
print(" ==> file does not exist")
continue
# collect media info ...
#if it is a mk: .. chack the opus format...
if extention == "mkv":
media_info = MediaInfo.parse(elem)
print("media-info: ... " + str(len(media_info.tracks)))
need_move_file = True
for elem_track in media_info.tracks:
data_print = "[" + str(elem_track.track_id) + "] " + str(elem_track.track_type)
#print('track_id = ' + str(elem_track.track_id))
#print('track_type = ' + str(elem_track.track_type))
if elem_track.track_type == "Audio":
data_print += " (" + str(elem_track.language) + ") enc=" + str(elem_track.format);
#print('language = ' + str(elem_track.language))
#print('format = ' + str(elem_track.format))
if elem_track.format != "Opus":
need_move_file = False
elif elem_track.track_type == "Video":
data_print += " enc=" + str(elem_track.format);
if elem_track.format != "AVC":
need_move_file = False
print(" - " + data_print)
#print("media-info: ..." + str(dir(elem_track)))
if need_move_file == False:
print(" ==> Need transcode, NOT already in the good format...")
continue
file_move(elem, os.path.join(dst_path, elem[len(src_path)+1:]))
move_local(list_files_mkv, "mkv")
move_local(list_files_webm, "webm")
move_local(list_files_jpg, "jpg")
move_local(list_files_png, "png")

View File

@ -1,37 +0,0 @@
#!/usr/bin/python3
# -*- coding: utf-8 -*-
##
## @author Edouard DUPIN
##
## @copyright 2012, Edouard DUPIN, all right reserved
##
## @license MPL v2.0 (see license file)
##
#pip install paho-mqtt --user
from realog import debug
import json
import os
import random
import copy
from dateutil import parser
data_mapping = {}
print(" =================================================== Send DATA ");
import transfert_data
data_mapping = transfert_data.transfert_db()
print(" =================================================== Send TYPE ");
import transfert_type
type_mapping = transfert_type.transfert_db(data_mapping)
print(" =================================================== Send GROUP ");
import transfert_group
group_mapping = transfert_group.transfert_db(data_mapping, type_mapping)
print(" =================================================== Send SAISON ");
import transfert_saison
saison_mapping = transfert_saison.transfert_db(data_mapping, type_mapping, group_mapping)
##print(" =================================================== Send UNIVERS ");
##import transfert_univers
##univers_mapping = transfert_univers.transfert_db(data_mapping, type_mapping, group_mapping)
print(" =================================================== Send Medias ");
import transfert_video
video_mapping = transfert_video.transfert_db(data_mapping, type_mapping, group_mapping, saison_mapping)

View File

@ -1,12 +0,0 @@
from realog import debug
import psycopg2
def connect_bdd():
debug.info("connect BDD: ")
conn = psycopg2.connect(dbname="karideo", user="root", password="postgress_password", host="localhost", port="15032")
return conn
base_bdd_name = "karideo_"

View File

@ -1,97 +0,0 @@
#!/usr/bin/python3
# -*- coding: utf-8 -*-
##
## @author Edouard DUPIN
##
## @copyright 2012, Edouard DUPIN, all right reserved
##
## @license MPL v2.0 (see license file)
##
#pip install paho-mqtt --user
from realog import debug
import json
import os
import random
import copy
import shutil
from dateutil import parser
import db
def file_read_data(path):
if not os.path.isfile(path):
return ""
file = open(path, "r")
data_file = file.read()
file.close()
return data_file
def create_directory_of_file(file):
debug.info("Create directory of path: '" + file + "'")
path = os.path.dirname(file)
debug.info("Create directory: '" + path + "'")
try:
os.stat(path)
except:
os.makedirs(path)
def file_move(path_src, path_dst):
#real write of data:
create_directory_of_file(path_dst)
shutil.move(path_src, path_dst)
return True
def transfert_db():
out = {}
out[str(None)] = None
connection = db.connect_bdd();
debug.info("Load old BDD: ")
data = file_read_data('bdd_data.json')
my_old_bdd = json.loads(data)
debug.info("create the table:")
c = connection.cursor()
file_object = open("data_transfer.txt", "w")
file_object2 = open("data_transfer2.txt", "w")
debug.info("insert elements: ")
iii = 0;
for elem in my_old_bdd:
iii+=1;
debug.info("[" + str(iii) + "/" + str(len(my_old_bdd)) + "] send new element " + str(elem["id"]))
id = elem["id"]
time_create = elem["create_date"];
mime_type = elem["mime_type"]
original_name = elem["original_name"]
sha512 = elem["sha512"]
size = elem["size"]
if mime_type == "unknown" and len(original_name) > 3 and original_name[-3:] == "mkv":
mime_type = "video/x-matroska"
request_insert = (time_create, sha512, mime_type, size, original_name)
c.execute('INSERT INTO data (create_date, sha512, mime_type, size, original_name) VALUES (%s,%s,%s,%s,%s) RETURNING id', request_insert)
id_of_new_row = c.fetchone()[0]
debug.info("data transform: " + str(id) + " => " + str(id_of_new_row))
out[str(id)] = id_of_new_row
file_object.write("mv \"media2/" + str(id_of_new_row) + "/data\" \"media/" + str(id) + "/video\"\n")
file_object.write("mv \"media2/" + str(id_of_new_row) + "/meta.json\" \"media/" + str(id) + "/meta.json\"\n\n")
file_object2.write("mkdir -p \"media2/" + str(id_of_new_row) + "\"\n")
file_object2.write("mv \"media/" + str(id) + "/video\" \"media2/" + str(id_of_new_row) + "/data\"\n")
file_object2.write("mv \"media/" + str(id) + "/meta.json\" \"media2/" + str(id_of_new_row) + "/meta.json\"\n\n")
#file_move("media/" + str(id) + "/video", "media2/" + str(id_of_new_row) + "/data")
#file_move("media/" + str(id) + "/meta.json", "media2/" + str(id_of_new_row) + "/meta.json")
file_object.close()
file_object2.close()
# Save (commit) the changes
connection.commit()
# We can also close the connection if we are done with it.
# Just be sure any changes have been committed or they will be lost.
connection.close()
return out

View File

@ -1,87 +0,0 @@
#!/usr/bin/python3
# -*- coding: utf-8 -*-
##
## @author Edouard DUPIN
##
## @copyright 2012, Edouard DUPIN, all right reserved
##
## @license MPL v2.0 (see license file)
##
#pip install paho-mqtt --user
from realog import debug
import json
import os
import random
import copy
from dateutil import parser
import datetime
import db
def file_read_data(path):
if not os.path.isfile(path):
return ""
file = open(path, "r")
data_file = file.read()
file.close()
return data_file
def transfert_db(data_mapping, type_mapping):
out = {}
out[str(None)] = None
connection = db.connect_bdd();
debug.info("Load old BDD: ")
data = file_read_data('bdd_group.json')
my_old_bdd = json.loads(data)
debug.info("create the table:")
c = connection.cursor()
debug.info("insert elements: ")
iii = 0;
for elem in my_old_bdd:
iii+=1;
debug.info("[" + str(iii) + "/" + str(len(my_old_bdd)) + "] send new element " + str(elem["id"]))
id = elem["id"]
name = elem["name"]
if "description" not in elem.keys():
description = None
else:
description = elem["description"]
if "covers" not in elem.keys():
covers = []
else:
covers = elem["covers"]
if covers == None:
covers = [];
request_insert = (name, description)
c.execute('INSERT INTO node (type, name, description) VALUES (\'serie\', %s,%s) RETURNING id', request_insert)
id_of_new_row = c.fetchone()[0]
debug.info("data transform: " + str(id) + " => " + str(id_of_new_row))
out[str(id)] = id_of_new_row
connection.commit()
for elem_cover in covers:
request_insert = (id_of_new_row, data_mapping[str(elem_cover)])
print(" insert cover " + str(request_insert))
c.execute('INSERT INTO cover_link (node_id, data_id) VALUES (%s,%s) RETURNING id', request_insert)
connection.commit()
# Save (commit) the changes
connection.commit()
# We can also close the connection if we are done with it.
# Just be sure any changes have been committed or they will be lost.
connection.close()
return out;

View File

@ -1,86 +0,0 @@
#!/usr/bin/python3
# -*- coding: utf-8 -*-
##
## @author Edouard DUPIN
##
## @copyright 2012, Edouard DUPIN, all right reserved
##
## @license MPL v2.0 (see license file)
##
#pip install paho-mqtt --user
from realog import debug
import json
import os
import random
import copy
from dateutil import parser
import datetime
import db
def file_read_data(path):
if not os.path.isfile(path):
return ""
file = open(path, "r")
data_file = file.read()
file.close()
return data_file
def transfert_db(data_mapping, type_mapping, group_mapping):
out = {}
out[str(None)] = None
connection = db.connect_bdd();
debug.info("Load old BDD: ")
data = file_read_data('bdd_saison.json')
my_old_bdd = json.loads(data)
debug.info("create the table:")
c = connection.cursor()
debug.info("insert elements: ")
iii = 0;
for elem in my_old_bdd:
iii+=1;
debug.info("[" + str(iii) + "/" + str(len(my_old_bdd)) + "] send new element " + str(elem["id"]))
id = elem["id"]
name = elem["number"]
if "group_id" not in elem.keys():
group_id = None
else:
group_id = elem["group_id"]
if "description" not in elem.keys():
description = None
else:
description = elem["description"]
if "covers" not in elem.keys():
covers = []
else:
covers = elem["covers"]
if covers == None:
covers = [];
request_insert = (name, description, group_mapping[str(group_id)])
c.execute('INSERT INTO node (type, name, description, parent_id) VALUES (\'saison\', %s,%s,%s) RETURNING id', request_insert)
id_of_new_row = c.fetchone()[0]
debug.info("data transform: " + str(id) + " => " + str(id_of_new_row))
out[str(id)] = id_of_new_row
connection.commit()
for elem_cover in covers:
request_insert = (id_of_new_row, data_mapping[str(elem_cover)])
print(" insert cover " + str(request_insert))
c.execute('INSERT INTO cover_link (node_id, data_id) VALUES (%s,%s) RETURNING id', request_insert)
connection.commit()
# Save (commit) the changes
connection.commit()
# We can also close the connection if we are done with it.
# Just be sure any changes have been committed or they will be lost.
connection.close()
return out

View File

@ -1,70 +0,0 @@
#!/usr/bin/python3
# -*- coding: utf-8 -*-
##
## @author Edouard DUPIN
##
## @copyright 2012, Edouard DUPIN, all right reserved
##
## @license MPL v2.0 (see license file)
##
#pip install paho-mqtt --user
from realog import debug
import json
import os
import random
import copy
from dateutil import parser
import datetime
import db
def file_read_data(path):
if not os.path.isfile(path):
return ""
file = open(path, "r")
data_file = file.read()
file.close()
return data_file
def transfert_db(data_mapping):
out = {}
out[str(None)] = None
connection = db.connect_bdd();
debug.info("Load old BDD: ")
data = file_read_data('bdd_type.json')
my_old_bdd = json.loads(data)
debug.info("create the table:")
c = connection.cursor()
debug.info("insert elements: ")
iii = 0;
for elem in my_old_bdd:
iii+=1;
debug.info("[" + str(iii) + "/" + str(len(my_old_bdd)) + "] ??? Get element " + str(elem["id"]) + " with name: '" + elem["name"] + "'")
id = elem["id"]
name = elem["name"]
if name == 'Short Films':
name = 'Short movie'
if name == 'tv show':
name = 'TV show'
if name == 'Anniation tv show':
name = 'Anniation TV show'
request_insert = (name,)
c.execute("SELECT id FROM node WHERE type = 'type' AND name = %s LIMIT 1", request_insert)
id_of_new_row = c.fetchone()[0]
debug.info("data transform: " + str(id) + " => " + str(id_of_new_row))
out[str(id)] = id_of_new_row
# Save (commit) the changes
connection.commit()
# We can also close the connection if we are done with it.
# Just be sure any changes have been committed or they will be lost.
connection.close()
return out

View File

@ -1,80 +0,0 @@
#!/usr/bin/python3
# -*- coding: utf-8 -*-
##
## @author Edouard DUPIN
##
## @copyright 2012, Edouard DUPIN, all right reserved
##
## @license MPL v2.0 (see license file)
##
#pip install paho-mqtt --user
from realog import debug
import json
import os
import random
import copy
from dateutil import parser
import datetime
import db
def file_read_data(path):
if not os.path.isfile(path):
return ""
file = open(path, "r")
data_file = file.read()
file.close()
return data_file
def transfert_db():
out = {}
out[str(None)] = None
connection = db.connect_bdd();
debug.info("Load old BDD: ")
data = file_read_data('bdd_univers.json')
my_old_bdd = json.loads(data)
debug.info("create the table:")
c = connection.cursor()
debug.info("insert elements: ")
iii = 0;
for elem in my_old_bdd:
iii+=1;
debug.info("[" + str(iii) + "/" + str(len(my_old_bdd)) + "] send new element " + str(elem["id"]))
id = elem["id"]
name = elem["name"]
if "description" not in elem.keys():
description = None
else:
description = elem["description"]
if "covers" not in elem.keys():
covers = []
else:
covers = elem["covers"]
if covers == None:
covers = [];
request_insert = (name, description)
c.execute('INSERT INTO node (type, name, description) VALUES (\'univers\', %s,%s) RETURNING id', request_insert)
id_of_new_row = c.fetchone()[0]
debug.info("data transform: " + str(id) + " => " + str(id_of_new_row))
out[str(id)] = id_of_new_row
connection.commit()
for elem_cover in covers:
request_insert = (id_of_new_row, data_mapping[str(elem_cover)])
print(" insert cover " + str(request_insert))
c.execute('INSERT INTO cover_link (node_id, data_id) VALUES (%s,%s) RETURNING id', request_insert)
connection.commit()
# Save (commit) the changes
connection.commit()
# We can also close the connection if we are done with it.
# Just be sure any changes have been committed or they will be lost.
connection.close()
return out

View File

@ -1,136 +0,0 @@
#!/usr/bin/python3
# -*- coding: utf-8 -*-
##
## @author Edouard DUPIN
##
## @copyright 2012, Edouard DUPIN, all right reserved
##
## @license MPL v2.0 (see license file)
##
#pip install paho-mqtt --user
from realog import debug
import json
import os
import random
import copy
from dateutil import parser
import datetime
import db
def force_number(s):
if s == None:
return None;
try:
return int(s)
except ValueError:
return None
def file_read_data(path):
if not os.path.isfile(path):
return ""
file = open(path, "r")
data_file = file.read()
file.close()
return data_file
def transfert_db(data_mapping, type_mapping, group_mapping, saison_mapping):
out = {}
out[str(None)] = None
connection = db.connect_bdd();
debug.info("Load old BDD: ")
data = file_read_data('bdd_video.json')
my_old_bdd = json.loads(data)
debug.info("create the table:")
c = connection.cursor()
debug.info("insert elements: ")
iii = 0;
for elem in my_old_bdd:
iii+=1;
debug.info("[" + str(iii) + "/" + str(len(my_old_bdd)) + "] send new element " + str(elem["id"]))
id = elem["id"]
time_create = elem["create_date"];
name = elem["name"]
if "description" not in elem.keys():
description = None
else:
description = elem["description"]
if "covers" not in elem.keys():
covers = []
else:
covers = elem["covers"]
if covers == None:
covers = [];
if "data_id" not in elem.keys():
data_id = None
else:
data_id = elem["data_id"]
if "type_id" not in elem.keys():
type_id = None
else:
type_id = elem["type_id"]
if "univers_id" not in elem.keys():
univers_id = None
else:
univers_id = elem["univers_id"]
if "group_id" not in elem.keys():
group_id = None
else:
group_id = elem["group_id"]
if "saison_id" not in elem.keys():
saison_id = None
else:
saison_id = elem["saison_id"]
if "date" not in elem.keys():
date = None
else:
date = elem["date"]
date = force_number(date)
if date != None and date < 1850:
date = None
if "episode" not in elem.keys():
episode = None
else:
episode = elem["episode"]
if "time" not in elem.keys():
time = None
else:
time = elem["time"]
request_insert = (time_create, name, description, data_mapping[str(data_id)], type_mapping[str(type_id)], group_mapping[str(group_id)], saison_mapping[str(saison_id)], force_number(date), force_number(episode), time)
c.execute('INSERT INTO media (type, create_date, name, description, data_id, type_id, serie_id, saison_id, date, episode, time) VALUES (\'media\',%s,%s,%s,%s,%s,%s,%s,%s,%s,%s) RETURNING id', request_insert)
id_of_new_row = c.fetchone()[0]
debug.info("data transform: " + str(id) + " => " + str(id_of_new_row))
out[str(id)] = id_of_new_row
connection.commit()
for elem_cover in covers:
request_insert = (id_of_new_row, data_mapping[str(elem_cover)])
print(" insert cover " + str(request_insert))
c.execute('INSERT INTO cover_link (node_id, data_id) VALUES (%s,%s) RETURNING id', request_insert)
connection.commit()
# Save (commit) the changes
connection.commit()
# def dict_factory(cursor, row):
# d = {}
# for idx, col in enumerate(cursor.description):
# d[col[0]] = row[idx]
# return d
# conn.row_factory = dict_factory
# c = conn.cursor()
# c.execute('SELECT * FROM video WHERE deleted=false')
# results = c.fetchall()
# print(results)
# We can also close the connection if we are done with it.
# Just be sure any changes have been committed or they will be lost.
connection.close()

View File

@ -1,33 +1,25 @@
version: "3.7"
# Use root/example as user/password credentials
version: '3.1'
services:
bdd_service:
db_service:
image: mysql:latest
container_name: mysql_db
restart: always
image: postgres:alpine
environment:
PGDATA: /var/lib/postgresql/data
POSTGRES_DB: karideo
POSTGRES_USER: root
POSTGRES_PASSWORD: postgress_password
#this is for debug only
ports:
- 15032:5432
command: --default-authentication-plugin=mysql_native_password
env_file:
- ./config.env
#environment:
# MYSQL_ROOT_PASSWORD: changeme
# MYSQL_DATABASE: mybdd
volumes:
- /workspace/data/karideo/bdd:/var/lib/postgresql/data:rw
adminer:
image: adminer
- ./data:/var/lib/mysql
ports:
- 15306:3306
adminer_service:
image: adminer:latest
restart: always
ports:
- 15079:8080
- 8080:8080
links:
- bdd_service:db
pgadmin_service:
restart: always
image: dpage/pgadmin4
volumes:
- /workspace/data/karideo/pgadmin:/root/.pgadmin
ports:
- "15078:80"
links:
- bdd_service:db
- db_service:db

42
docker-compose.yaml Normal file
View File

@ -0,0 +1,42 @@
version: '3'
services:
karideo_db_service:
image: mysql:latest
restart: always
command: --default-authentication-plugin=mysql_native_password
env_file:
- ./config.env
volumes:
- /workspace/data/karideo/db:/var/lib/mysql
karideo_adminer_service:
image: adminer:latest
restart: always
ports:
- 18079:8080
links:
- karideo_db_service:db
karideo_back_service:
build: back/
restart: always
image: org.kar.video.back
ports:
- 18080:18080
env_file:
- ./config.env
links:
- karideo_db_service:db
volumes:
- /workspace/data/karideo/media:/application/data
karideo_front_service:
build: front/
restart: always
image: org.kar.video.front
container_name: karideo
ports:
#- 15081:4200
- 15081:80