--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+ <classpathentry kind="src" output="target/classes" path="src/main/java">
+ <attributes>
+ <attribute name="optional" value="true"/>
+ <attribute name="maven.pomderived" value="true"/>
+ </attributes>
+ </classpathentry>
+ <classpathentry excluding="**" kind="src" output="target/classes" path="src/main/resources">
+ <attributes>
+ <attribute name="maven.pomderived" value="true"/>
+ </attributes>
+ </classpathentry>
+ <classpathentry kind="con" path="org.maven.ide.eclipse.MAVEN2_CLASSPATH_CONTAINER"/>
+ <classpathentry kind="src" output="target/test-classes" path="src/test/java">
+ <attributes>
+ <attribute name="optional" value="true"/>
+ <attribute name="maven.pomderived" value="true"/>
+ </attributes>
+ </classpathentry>
+ <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6">
+ <attributes>
+ <attribute name="maven.pomderived" value="true"/>
+ </attributes>
+ </classpathentry>
+ <classpathentry kind="con" path="org.eclipse.m2e.MAVEN2_CLASSPATH_CONTAINER">
+ <attributes>
+ <attribute name="maven.pomderived" value="true"/>
+ </attributes>
+ </classpathentry>
+ <classpathentry kind="output" path="target/classes"/>
+</classpath>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>meviz</name>
+ <comment></comment>
+ <projects>
+ </projects>
+ <buildSpec>
+ <buildCommand>
+ <name>org.eclipse.jdt.core.javabuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.maven.ide.eclipse.maven2Builder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.m2e.core.maven2Builder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>org.eclipse.m2e.core.maven2Nature</nature>
+ <nature>org.eclipse.jdt.core.javanature</nature>
+ <nature>org.maven.ide.eclipse.maven2Nature</nature>
+ </natures>
+</projectDescription>
--- /dev/null
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6
+org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
+org.eclipse.jdt.core.compiler.compliance=1.6
+org.eclipse.jdt.core.compiler.debug.lineNumber=generate
+org.eclipse.jdt.core.compiler.debug.localVariable=generate
+org.eclipse.jdt.core.compiler.debug.sourceFile=generate
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning
+org.eclipse.jdt.core.compiler.source=1.6
+org.eclipse.jdt.core.formatter.align_type_members_on_columns=false
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression=16
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_annotation=0
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_enum_constant=16
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_explicit_constructor_call=16
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_method_invocation=16
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_qualified_allocation_expression=16
+org.eclipse.jdt.core.formatter.alignment_for_assignment=0
+org.eclipse.jdt.core.formatter.alignment_for_binary_expression=16
+org.eclipse.jdt.core.formatter.alignment_for_compact_if=16
+org.eclipse.jdt.core.formatter.alignment_for_conditional_expression=80
+org.eclipse.jdt.core.formatter.alignment_for_enum_constants=0
+org.eclipse.jdt.core.formatter.alignment_for_expressions_in_array_initializer=16
+org.eclipse.jdt.core.formatter.alignment_for_method_declaration=0
+org.eclipse.jdt.core.formatter.alignment_for_multiple_fields=16
+org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_resources_in_try=80
+org.eclipse.jdt.core.formatter.alignment_for_selector_in_method_invocation=16
+org.eclipse.jdt.core.formatter.alignment_for_superclass_in_type_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_enum_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_type_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_constructor_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_method_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_union_type_in_multicatch=16
+org.eclipse.jdt.core.formatter.blank_lines_after_imports=1
+org.eclipse.jdt.core.formatter.blank_lines_after_package=1
+org.eclipse.jdt.core.formatter.blank_lines_before_field=0
+org.eclipse.jdt.core.formatter.blank_lines_before_first_class_body_declaration=0
+org.eclipse.jdt.core.formatter.blank_lines_before_imports=1
+org.eclipse.jdt.core.formatter.blank_lines_before_member_type=1
+org.eclipse.jdt.core.formatter.blank_lines_before_method=1
+org.eclipse.jdt.core.formatter.blank_lines_before_new_chunk=1
+org.eclipse.jdt.core.formatter.blank_lines_before_package=0
+org.eclipse.jdt.core.formatter.blank_lines_between_import_groups=1
+org.eclipse.jdt.core.formatter.blank_lines_between_type_declarations=1
+org.eclipse.jdt.core.formatter.brace_position_for_annotation_type_declaration=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_anonymous_type_declaration=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_array_initializer=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_block=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_block_in_case=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_constructor_declaration=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_enum_constant=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_enum_declaration=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_method_declaration=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_switch=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_type_declaration=end_of_line
+org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_block_comment=false
+org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_javadoc_comment=false
+org.eclipse.jdt.core.formatter.comment.format_block_comments=true
+org.eclipse.jdt.core.formatter.comment.format_header=false
+org.eclipse.jdt.core.formatter.comment.format_html=true
+org.eclipse.jdt.core.formatter.comment.format_javadoc_comments=true
+org.eclipse.jdt.core.formatter.comment.format_line_comments=true
+org.eclipse.jdt.core.formatter.comment.format_source_code=true
+org.eclipse.jdt.core.formatter.comment.indent_parameter_description=true
+org.eclipse.jdt.core.formatter.comment.indent_root_tags=true
+org.eclipse.jdt.core.formatter.comment.insert_new_line_before_root_tags=insert
+org.eclipse.jdt.core.formatter.comment.insert_new_line_for_parameter=insert
+org.eclipse.jdt.core.formatter.comment.line_length=80
+org.eclipse.jdt.core.formatter.comment.new_lines_at_block_boundaries=true
+org.eclipse.jdt.core.formatter.comment.new_lines_at_javadoc_boundaries=true
+org.eclipse.jdt.core.formatter.comment.preserve_white_space_between_code_and_line_comments=false
+org.eclipse.jdt.core.formatter.compact_else_if=true
+org.eclipse.jdt.core.formatter.continuation_indentation=2
+org.eclipse.jdt.core.formatter.continuation_indentation_for_array_initializer=2
+org.eclipse.jdt.core.formatter.disabling_tag=@formatter\:off
+org.eclipse.jdt.core.formatter.enabling_tag=@formatter\:on
+org.eclipse.jdt.core.formatter.format_guardian_clause_on_one_line=false
+org.eclipse.jdt.core.formatter.format_line_comment_starting_on_first_column=true
+org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_annotation_declaration_header=true
+org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_constant_header=true
+org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_declaration_header=true
+org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_type_header=true
+org.eclipse.jdt.core.formatter.indent_breaks_compare_to_cases=true
+org.eclipse.jdt.core.formatter.indent_empty_lines=false
+org.eclipse.jdt.core.formatter.indent_statements_compare_to_block=true
+org.eclipse.jdt.core.formatter.indent_statements_compare_to_body=true
+org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_cases=true
+org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_switch=false
+org.eclipse.jdt.core.formatter.indentation.size=4
+org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_field=insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_local_variable=insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_method=insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_package=insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_parameter=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_type=insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_label=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_opening_brace_in_array_initializer=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_at_end_of_file_if_missing=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_before_catch_in_try_statement=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_before_closing_brace_in_array_initializer=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_before_else_in_if_statement=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_before_finally_in_try_statement=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_before_while_in_do_statement=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_annotation_declaration=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_anonymous_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_block=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_constant=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_declaration=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_method_body=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_after_and_in_type_parameter=insert
+org.eclipse.jdt.core.formatter.insert_space_after_assignment_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation_type_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_binary_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_arguments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_parameters=insert
+org.eclipse.jdt.core.formatter.insert_space_after_closing_brace_in_block=insert
+org.eclipse.jdt.core.formatter.insert_space_after_closing_paren_in_cast=insert
+org.eclipse.jdt.core.formatter.insert_space_after_colon_in_assert=insert
+org.eclipse.jdt.core.formatter.insert_space_after_colon_in_case=insert
+org.eclipse.jdt.core.formatter.insert_space_after_colon_in_conditional=insert
+org.eclipse.jdt.core.formatter.insert_space_after_colon_in_for=insert
+org.eclipse.jdt.core.formatter.insert_space_after_colon_in_labeled_statement=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_allocation_expression=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_annotation=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_array_initializer=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_parameters=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_throws=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_constant_arguments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_declarations=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_explicitconstructorcall_arguments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_increments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_inits=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_parameters=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_throws=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_invocation_arguments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_field_declarations=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_local_declarations=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_parameterized_type_reference=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_superinterfaces=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_arguments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_parameters=insert
+org.eclipse.jdt.core.formatter.insert_space_after_ellipsis=insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_parameterized_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_brace_in_array_initializer=insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_allocation_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_annotation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_cast=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_catch=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_constructor_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_enum_constant=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_for=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_if=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_invocation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_parenthesized_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_switch=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_synchronized=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_try=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_while=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_postfix_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_prefix_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_question_in_conditional=insert
+org.eclipse.jdt.core.formatter.insert_space_after_question_in_wildcard=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_for=insert
+org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_try_resources=insert
+org.eclipse.jdt.core.formatter.insert_space_after_unary_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_and_in_type_parameter=insert
+org.eclipse.jdt.core.formatter.insert_space_before_assignment_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_before_at_in_annotation_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_binary_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_parameterized_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_brace_in_array_initializer=insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_allocation_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_annotation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_cast=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_catch=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_constructor_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_enum_constant=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_for=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_if=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_invocation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_parenthesized_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_switch=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_synchronized=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_try=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_while=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_assert=insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_case=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_conditional=insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_default=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_for=insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_labeled_statement=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_allocation_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_annotation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_array_initializer=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_throws=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_constant_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_declarations=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_explicitconstructorcall_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_increments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_inits=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_throws=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_invocation_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_field_declarations=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_local_declarations=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_parameterized_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_superinterfaces=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_ellipsis=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_parameterized_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_annotation_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_anonymous_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_array_initializer=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_block=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_constructor_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_constant=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_method_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_switch=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_allocation_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation_type_member_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_catch=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_constructor_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_enum_constant=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_for=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_if=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_invocation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_parenthesized_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_switch=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_synchronized=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_try=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_while=insert
+org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_return=insert
+org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_throw=insert
+org.eclipse.jdt.core.formatter.insert_space_before_postfix_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_prefix_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_question_in_conditional=insert
+org.eclipse.jdt.core.formatter.insert_space_before_question_in_wildcard=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_semicolon=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_for=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_try_resources=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_unary_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_brackets_in_array_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_braces_in_array_initializer=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_brackets_in_array_allocation_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_annotation_type_member_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_constructor_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_enum_constant=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_invocation=do not insert
+org.eclipse.jdt.core.formatter.join_lines_in_comments=true
+org.eclipse.jdt.core.formatter.join_wrapped_lines=true
+org.eclipse.jdt.core.formatter.keep_else_statement_on_same_line=false
+org.eclipse.jdt.core.formatter.keep_empty_array_initializer_on_one_line=false
+org.eclipse.jdt.core.formatter.keep_imple_if_on_one_line=false
+org.eclipse.jdt.core.formatter.keep_then_statement_on_same_line=false
+org.eclipse.jdt.core.formatter.lineSplit=80
+org.eclipse.jdt.core.formatter.never_indent_block_comments_on_first_column=false
+org.eclipse.jdt.core.formatter.never_indent_line_comments_on_first_column=false
+org.eclipse.jdt.core.formatter.number_of_blank_lines_at_beginning_of_method_body=0
+org.eclipse.jdt.core.formatter.number_of_empty_lines_to_preserve=1
+org.eclipse.jdt.core.formatter.put_empty_statement_on_new_line=true
+org.eclipse.jdt.core.formatter.tabulation.char=tab
+org.eclipse.jdt.core.formatter.tabulation.size=4
+org.eclipse.jdt.core.formatter.use_on_off_tags=false
+org.eclipse.jdt.core.formatter.use_tabs_only_for_leading_indentations=false
+org.eclipse.jdt.core.formatter.wrap_before_binary_operator=true
+org.eclipse.jdt.core.formatter.wrap_before_or_operator_multicatch=true
+org.eclipse.jdt.core.formatter.wrap_outer_expressions_when_nested=true
--- /dev/null
+eclipse.preferences.version=1
+formatter_profile=org.eclipse.jdt.ui.default.eclipse_profile
+formatter_settings_version=12
--- /dev/null
+activeProfiles=
+eclipse.preferences.version=1
+resolveWorkspaceProjects=false
+version=1
--- /dev/null
+#Tue May 31 02:56:21 EEST 2011
+activeProfiles=
+eclipse.preferences.version=1
+fullBuildGoals=process-test-resources
+resolveWorkspaceProjects=true
+resourceFilterGoals=process-resources resources\:testResources
+skipCompilerPlugin=true
+version=1
--- /dev/null
+
+ GNU GENERAL PUBLIC LICENSE
+ Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+ 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users. This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it. (Some other Free Software Foundation software is covered by
+the GNU Library General Public License instead.) You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+ To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have. You must make sure that they, too, receive or can get the
+source code. And you must show them these terms so they know their
+rights.
+
+ We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+ Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software. If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+ Finally, any free program is threatened constantly by software
+patents. We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary. To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+\f
+ GNU GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License. The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language. (Hereinafter, translation is included without limitation in
+the term "modification".) Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+ 1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+ 2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) You must cause the modified files to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ b) You must cause any work that you distribute or publish, that in
+ whole or in part contains or is derived from the Program or any
+ part thereof, to be licensed as a whole at no charge to all third
+ parties under the terms of this License.
+
+ c) If the modified program normally reads commands interactively
+ when run, you must cause it, when started running for such
+ interactive use in the most ordinary way, to print or display an
+ announcement including an appropriate copyright notice and a
+ notice that there is no warranty (or else, saying that you provide
+ a warranty) and that users may redistribute the program under
+ these conditions, and telling the user how to view a copy of this
+ License. (Exception: if the Program itself is interactive but
+ does not normally print such an announcement, your work based on
+ the Program is not required to print an announcement.)
+\f
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+ a) Accompany it with the complete corresponding machine-readable
+ source code, which must be distributed under the terms of Sections
+ 1 and 2 above on a medium customarily used for software interchange; or,
+
+ b) Accompany it with a written offer, valid for at least three
+ years, to give any third party, for a charge no more than your
+ cost of physically performing source distribution, a complete
+ machine-readable copy of the corresponding source code, to be
+ distributed under the terms of Sections 1 and 2 above on a medium
+ customarily used for software interchange; or,
+
+ c) Accompany it with the information you received as to the offer
+ to distribute corresponding source code. (This alternative is
+ allowed only for noncommercial distribution and only if you
+ received the program in object code or executable form with such
+ an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it. For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable. However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+\f
+ 4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License. Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+ 5. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Program or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+ 6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+ 7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all. For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+\f
+ 8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded. In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+ 9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation. If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+ 10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission. For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this. Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+ NO WARRANTY
+
+ 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+ 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+\f
+ How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+ <one line to give the program's name and a brief idea of what it does.>
+ Copyright (C) <year> <name of author>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+ Gnomovision version 69, Copyright (C) year name of author
+ Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License. Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+ `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+ <signature of Ty Coon>, 1 April 1989
+ Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs. If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library. If this is what you want to do, use the GNU Library General
+Public License instead of this License.
--- /dev/null
+See "doc" directory for project documentation.
--- /dev/null
+TODO:
+
+* integrate:
+ jheora
+ jogg and jorbis from jcraft
+
+
+* possibility to delete original files after conversion
+* possibility to get rid of the terminal window when encoding videos
+* possibility to use parent directory name in the file renamer tool
+
+HTML generator:
+ * video thumbnails
+
+ * possibility to go back multiple levels
+
+ * sitemap generation
+
--- /dev/null
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+<meta
+ http-equiv="Content-Type"
+ content="text/html; charset=UTF-8">
+<title>MeWiz</title>
+</head>
+<body>
+ <h1>MeWiz - Media Wizard</h1>
+ <a href="http://php.svjatoslav.eu/gitweb/?p=meviz.git;a=snapshot;h=HEAD;sf=tgz">Download</a>
+
+ <a href="http://svjatoslav.eu/static/gitbrowse/meviz/doc/index.html">Online homepage</a>
+
+ <a href="http://svjatoslav.eu/programs.jsp">Other applications hosted on svjatoslav.eu</a>
+ <pre>
+<b>Program author:</b>
+ Svjatoslav Agejenko
+ Homepage: <a href="http://svjatoslav.eu">http://svjatoslav.eu</a>
+ Email: <a href="mailto:svjatoslav@svjatoslav.eu">svjatoslav@svjatoslav.eu</a>
+
+This software is distributed under <a href="http://www.gnu.org/licenses/gpl-2.0.html">GNU GENERAL PUBLIC LICENSE Version 2</a>.
+
+<h2>Introdution</h2>
+
+The idea is to have something like a Swiss army knife of various tools
+for audio, video, photo editing/conversion.
+
+
+Current functionality:
+
+ * Acts as unified frontend for linux commandline tools for
+ audio, video and photo conversion.
+
+ * Generates HTML listing for directory content with image thumbnails and embedded video player
+ for OGV video. <a href="http://svjatoslav.eu/static/events/index.html">Example generated listing.</a>
+
+ * Batch file rename.
+
+
+ </pre>
+</body>
+</html>
\ No newline at end of file
--- /dev/null
+#!/bin/bash
+
+sudo apt-get install "maven"
+sudo apt-get install "lame"
+sudo apt-get install "vorbis-tools"
+sudo apt-get install "imagemagick"
+sudo apt-get install "ffmpeg2theora"
+sudo apt-get install "libav-tools"
+
+# this provides "avconv" commandline universal media conversion utility
+sudo apt-get install "libav-tools"
+
+mvn clean
+mvn package
+
+sudo mkdir /opt/meviz
+sudo cp target/meviz-1.0-SNAPSHOT.jar /opt/meviz/
+sudo cp meviz /opt/meviz/
+sudo ln -s /opt/meviz/meviz /usr/bin/
+
+
+
--- /dev/null
+#!/bin/bash
+
+set -f
+
+java -Xmx4000m -XX:MaxPermSize=2024m -jar /opt/meviz/meviz-1.0-SNAPSHOT.jar $@
+
--- /dev/null
+<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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>eu.svjatoslav</groupId>
+ <artifactId>meviz</artifactId>
+ <version>1.0-SNAPSHOT</version>
+ <packaging>jar</packaging>
+ <name>meviz</name>
+ <description>media wizard</description>
+
+ <organization>
+ <name>svjatoslav.eu</name>
+ <url>http://svjatoslav.eu</url>
+ </organization>
+
+ <dependencies>
+ <dependency>
+ <groupId>eu.svjatoslav</groupId>
+ <artifactId>svjatoslavcommons</artifactId>
+ <version>1.0-SNAPSHOT</version>
+ </dependency>
+
+ <dependency>
+ <groupId>log4j</groupId>
+ <artifactId>log4j</artifactId>
+ <version>1.2.16</version>
+ </dependency>
+
+ </dependencies>
+
+ <build>
+ <plugins>
+ <plugin>
+ <artifactId>maven-assembly-plugin</artifactId>
+ <configuration>
+ <archive>
+ <manifest>
+ <mainClass>eu.svjatoslav.meviz.Main</mainClass>
+ </manifest>
+ </archive>
+ <descriptorRefs>
+ <descriptorRef>jar-with-dependencies</descriptorRef>
+ </descriptorRefs>
+ </configuration>
+
+ <executions>
+
+ <execution>
+ <id>package-jar-with-dependencies</id>
+ <phase>package</phase>
+ <goals>
+ <goal>single</goal>
+ </goals>
+ <configuration>
+ <appendAssemblyId>false</appendAssemblyId>
+ <descriptorRefs>
+ <descriptorRef>jar-with-dependencies</descriptorRef>
+ </descriptorRefs>
+ <archive>
+ <manifest>
+ <mainClass>eu.svjatoslav.meviz.Main</mainClass>
+ </manifest>
+ </archive>
+ </configuration>
+ </execution>
+
+ </executions>
+ </plugin>
+
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <version>2.3.2</version>
+ <configuration>
+ <source>1.6</source>
+ <target>1.6</target>
+ </configuration>
+ </plugin>
+
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-source-plugin</artifactId>
+ <version>2.2.1</version>
+ <executions>
+ <execution>
+ <id>attach-sources</id>
+ <goals>
+ <goal>jar</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-javadoc-plugin</artifactId>
+ <version>2.9</version>
+ <executions>
+ <execution>
+ <id>attach-javadocs</id>
+ <goals>
+ <goal>jar</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+
+ </plugins>
+
+ <extensions>
+ <extension>
+ <groupId>org.apache.maven.wagon</groupId>
+ <artifactId>wagon-ssh</artifactId>
+ <version>2.2</version>
+ </extension>
+ </extensions>
+
+ </build>
+
+ <distributionManagement>
+ <snapshotRepository>
+ <id>svjatoslav.eu</id>
+ <name>svjatoslav.eu</name>
+ <url>scp://svjatoslav.eu:7022/var/lib/tomcat6/_svjatoslav.eu/static/maven</url>
+ </snapshotRepository>
+ </distributionManagement>
+
+ <repositories>
+ <repository>
+ <id>svjatoslav.eu</id>
+ <name>Svjatoslav repository</name>
+ <url>http://svjatoslav.eu/static/maven/</url>
+ </repository>
+ </repositories>
+
+</project>
--- /dev/null
+/*
+ * Meviz - Various tools collection to work with multimedia.
+ * Copyright (C) 2012, Svjatoslav Agejenko, svjatoslav@svjatoslav.eu
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of version 2 of the GNU General Public License
+ * as published by the Free Software Foundation.
+ */
+
+package eu.svjatoslav.meviz;
+
+import java.util.ArrayList;
+
+import eu.svjatoslav.meviz.encoder.Encoder;
+
+public class Main {
+
+ public static ArrayList<Module> modules;
+
+ public static String[] getRemainingOptions(final String[] options) {
+ final String[] remainingOptions = new String[options.length - 1];
+
+ for (int i = 1; i < options.length; i++)
+ remainingOptions[i - 1] = options[i];
+
+ return remainingOptions;
+ };
+
+ public static void initModules() {
+ modules = new ArrayList<Module>();
+
+ modules.add(new Encoder());
+ modules.add(new eu.svjatoslav.meviz.htmlindexer.Main());
+ modules.add(new eu.svjatoslav.meviz.renamer.Main());
+ modules.add(new eu.svjatoslav.meviz.grabmemcard.Main());
+ modules.add(new eu.svjatoslav.meviz.textsplitter.Main());
+
+ }
+
+ public static void main(final String[] args) throws Exception {
+
+ initModules();
+
+ if (args.length < 1)
+ showHelp();
+ else if (args[0].equals("help")) {
+ if (args.length != 2)
+ showHelp();
+ else {
+
+ for (final Module module : modules)
+ if (args[1].equals(module.getModuleCommand())) {
+ module.showCommandlineHelp();
+ return;
+ }
+
+ System.out.println("Error: unrecognized module by name:"
+ + args[1] + "\n");
+ showHelp();
+
+ }
+ } else {
+
+ for (final Module module : modules)
+ if (args[0].equals(module.getModuleCommand())) {
+ module.run(getRemainingOptions(args));
+ return;
+ }
+
+ System.out.println("Error: unrecognized commandline option:"
+ + args[0] + "\n");
+ showHelp();
+ }
+
+ }
+
+ public static void showHelp() {
+ final StringBuffer buffer = new StringBuffer();
+
+ buffer.append("Commandline options: \n"
+ + "help\n show this help screen \n\n");
+
+ buffer.append("help <module>\n show module specific help screen\n\n");
+
+ buffer.append("Available modules:\n\n");
+
+ for (final Module module : modules) {
+ buffer.append(module.getModuleCommand() + "\n");
+ buffer.append(" " + module.getDescription() + "\n\n");
+ }
+
+ System.out.println(buffer.toString());
+ }
+}
--- /dev/null
+/*
+ * Meviz - Various tools collection to work with multimedia.
+ * Copyright (C) 2012, Svjatoslav Agejenko, svjatoslav@svjatoslav.eu
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of version 2 of the GNU General Public License
+ * as published by the Free Software Foundation.
+ */
+
+package eu.svjatoslav.meviz;
+
+public interface Module {
+
+ public String getDescription();
+
+ public String getModuleCommand();
+
+ public void run(String args[]) throws Exception;
+
+ public void showCommandlineHelp();
+
+}
--- /dev/null
+/*
+ * Meviz - Various tools collection to work with multimedia.
+ * Copyright (C) 2012, Svjatoslav Agejenko, svjatoslav@svjatoslav.eu
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of version 2 of the GNU General Public License
+ * as published by the Free Software Foundation.
+ */
+
+package eu.svjatoslav.meviz.encoder;
+
+import eu.svjatoslav.commons.commandline.parameterparser.Argument;
+
+public class Bitrate implements Argument {
+ @Override
+ public String describeFormat() {
+ return "Target bitrate [LOW / MEDIUM / HIGH]";
+ }
+
+ @Override
+ public boolean validate(final String value) {
+ try {
+ bitrate.valueOf(value);
+ } catch (final IllegalArgumentException exception) {
+ return false;
+ }
+
+ return true;
+ }
+
+ static public enum bitrate {
+ LOW, MEDIUM, HIGH
+ };
+
+}
--- /dev/null
+/*
+ * Meviz - Various tools collection to work with multimedia.
+ * Copyright (C) 2012, Svjatoslav Agejenko, svjatoslav@svjatoslav.eu
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of version 2 of the GNU General Public License
+ * as published by the Free Software Foundation.
+ */
+
+package eu.svjatoslav.meviz.encoder;
+
+import eu.svjatoslav.commons.commandline.parameterparser.Parameter;
+import eu.svjatoslav.commons.commandline.parameterparser.Parser;
+
+public class CommandlineHandler {
+
+ Parameter outputFormatParameter = new Parameter(true, true, true,
+ new eu.svjatoslav.commons.commandline.parameterparser.arguments.String(), "Encoding output format.", "-o",
+ "--output-format");
+
+ Parameter terminalParameter = new Parameter("Enable popup terminal.", "--terminal");
+
+ Parameter testParameter = new Parameter("Simulate file encoding.", "-t", "--test");
+
+ Parameter recursiveParameter = new Parameter("Enable recursive mode.", "-r", "--recursive");
+
+ Parameter inputPatternParameter = new Parameter(true, true, true,
+ new eu.svjatoslav.commons.commandline.parameterparser.arguments.String(), "File input pattern.", "-i",
+ "--input-pattern");
+
+ Parameter workingDirectoryParameter = new Parameter(false, true, true,
+ new eu.svjatoslav.commons.commandline.parameterparser.arguments.ExistingDirectory(), "Working directory.",
+ "-w", "--working-directory");
+
+ Parameter videoBitrateParameter = new Parameter(false, true, false, new Bitrate(), "Video bitrate.", "-v",
+ "--video-bitrate");
+
+ public Parser initParser() {
+ final Parser parser = new Parser();
+
+ parser.addParameter(recursiveParameter);
+
+ parser.addParameter(testParameter);
+
+ parser.addParameter(terminalParameter);
+
+ parser.addParameter(outputFormatParameter);
+
+ parser.addParameter(inputPatternParameter);
+
+ parser.addParameter(workingDirectoryParameter);
+
+ parser.addParameter(videoBitrateParameter);
+
+ return parser;
+ }
+
+ /**
+ * @return {@link EncodingOptions} if commandline arguments were
+ * successfully parsed, or <code>null</code> if parsing error
+ * occurred.
+ */
+ public EncodingOptions parseCommandlineArguments(final String[] args) {
+
+ final EncodingOptions options = new EncodingOptions();
+
+ final Parser parser = initParser();
+ parser.parse(args);
+
+ if (recursiveParameter.isParameterSpecified())
+ options.recursive = true;
+
+ if (terminalParameter.isParameterSpecified())
+ options.terminal = true;
+
+ if (testParameter.isParameterSpecified())
+ options.testOnly = true;
+
+ if (outputFormatParameter.isParameterSpecified()) {
+ options.outputFormats.addAll(outputFormatParameter.getArgumentsAsStrings());
+ }
+
+ if (workingDirectoryParameter.isParameterSpecified()) {
+ options.workingDirectory = workingDirectoryParameter.getArgumentsAsFiles().get(0);
+ }
+
+ if (inputPatternParameter.isParameterSpecified()) {
+ options.inputPatterns.addAll(inputPatternParameter.getArgumentsAsStrings());
+ }
+
+ if (videoBitrateParameter.isParameterSpecified()) {
+
+ try {
+ options.videoBitrate = Bitrate.bitrate.valueOf(videoBitrateParameter.getArgumentAsString()
+ .toUpperCase());
+ } catch (final Exception e) {
+ System.out.println("Invalid video bitrate. Valid values are: LOW, MEDIUM, HIGH.");
+ return null;
+ }
+ }
+
+ return options;
+ }
+}
--- /dev/null
+/*
+ * Meviz - Various tools collection to work with multimedia.
+ * Copyright (C) 2012, Svjatoslav Agejenko, svjatoslav@svjatoslav.eu
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of version 2 of the GNU General Public License
+ * as published by the Free Software Foundation.
+ */
+
+package eu.svjatoslav.meviz.encoder;
+
+import java.io.File;
+import java.util.List;
+
+import eu.svjatoslav.commons.file.FilePathParser;
+import eu.svjatoslav.commons.string.WildCardMatcher;
+import eu.svjatoslav.meviz.Module;
+import eu.svjatoslav.meviz.encoder.converters.Converter;
+
+public class Encoder implements Module {
+
+ public FormatsRegistry encoderRegistry = new FormatsRegistry();
+
+ public EncodingOptions encodingOptions;
+
+ public EncodingPlan encodingPlan;
+
+ CommandlineHandler commandlineHandler = new CommandlineHandler();
+
+ /**
+ * Generate encoding plan
+ *
+ * @param sourceFile
+ * Source directory of file
+ */
+ public void compileEncodingPlan(final File sourceFile) {
+ if (!sourceFile.exists()) {
+ System.out.println("Error: file \"" + sourceFile.getAbsolutePath()
+ + "\" does not exist.");
+ return;
+ }
+
+ if (sourceFile.isDirectory()) {
+ // handle directory
+ for (final File subFile : sourceFile.listFiles())
+ if (subFile.isDirectory()) {
+ if (encodingOptions.recursive)
+ compileEncodingPlan(subFile);
+ } else
+ compileEncodingPlan(subFile);
+ } else if (sourceFile.isFile())
+ if (fileMatchesInputPattern(sourceFile)) {
+
+ // System.out.println("Processing file: " +
+ // file.getAbsolutePath());
+
+ final String sourceFileExtension = FilePathParser
+ .getFileExtension(sourceFile);
+
+ // encode source file into every desired target format
+ for (final String targetFormat : encodingOptions.outputFormats) {
+
+ // construct target file
+ final File targetFile = getTargetFile(sourceFile,
+ targetFormat);
+
+ // System.out.println("target path: " +
+ // targetFilePath.toString());
+
+ if (!targetFile.exists()) {
+
+ final List<eu.svjatoslav.meviz.encoder.converters.Converter> formats = encoderRegistry
+ .getEncoders(sourceFileExtension, targetFormat);
+
+ if (formats.size() == 0)
+ System.out
+ .println("Error: no encoders found to convert file \""
+ + sourceFile.getAbsolutePath()
+ + "\" into "
+ + targetFormat
+ + " format.");
+ else if (formats.size() > 1)
+ System.out
+ .println("Error: Encoders piping not yet supported to convert file \""
+ + sourceFile.getAbsolutePath()
+ + "\" into "
+ + targetFormat
+ + " format.");
+ else {
+ final Converter chosenFormat = formats.get(0);
+ final EncodingTask encodingTask = new EncodingTask(
+ sourceFile, targetFile, chosenFormat);
+
+ if (encodingOptions.terminal
+ || chosenFormat.isTerminalMandatory())
+ encodingTask.setUseTerminal(true);
+ encodingPlan.scheduleTask(encodingTask);
+ }
+ }
+ }
+ }
+
+ }
+
+ /**
+ * @param file
+ * single file candidate to potentially be encoded
+ *
+ * @return <code>true</code> if file shall be encoded.
+ */
+ public boolean fileMatchesInputPattern(final File file) {
+ final String fileName = file.getName().toLowerCase();
+
+ for (final String inputPattern : encodingOptions.inputPatterns)
+ if (WildCardMatcher.match(fileName, inputPattern.toLowerCase()))
+ return true;
+
+ return false;
+ }
+
+ @Override
+ public String getDescription() {
+ return "Convert between various media formats.";
+ }
+
+ @Override
+ public String getModuleCommand() {
+ return "encode";
+ }
+
+ private File getTargetFile(final File sourceFile, final String targetFormat) {
+ final StringBuffer targetFilePath = new StringBuffer();
+ targetFilePath.append(sourceFile.getParent());
+ targetFilePath.append("/");
+ targetFilePath.append(FilePathParser
+ .getFileNameWithoutExtension(sourceFile));
+ targetFilePath.append(".");
+ targetFilePath.append(targetFormat);
+
+ return new File(targetFilePath.toString());
+ }
+
+ @Override
+ public void run(final String[] args) {
+
+ // parse incoming commandline arguments
+ encodingOptions = commandlineHandler.parseCommandlineArguments(args);
+
+ if (encodingOptions == null) {
+ showCommandlineHelp();
+ return;
+ }
+
+ encodingPlan = new EncodingPlan();
+
+ compileEncodingPlan(encodingOptions.workingDirectory);
+
+ if (!encodingOptions.testOnly)
+ try {
+ encodingPlan.execute(encodingOptions);
+ } catch (final Exception exception) {
+ exception.printStackTrace();
+ }
+
+ }
+
+ @Override
+ public void showCommandlineHelp() {
+ commandlineHandler.initParser().showHelp();
+ System.out.println("Example commands:");
+ System.out
+ .println(" Convert all MTS files in the current directory into MP4's.");
+ System.out.println(" meviz encode -o mp4 -i *.MTS");
+ }
+
+}
--- /dev/null
+/*
+ * Meviz - Various tools collection to work with multimedia.
+ * Copyright (C) 2012, Svjatoslav Agejenko, svjatoslav@svjatoslav.eu
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of version 2 of the GNU General Public License
+ * as published by the Free Software Foundation.
+ */
+
+package eu.svjatoslav.meviz.encoder;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.List;
+
+public class EncodingOptions {
+
+ public Bitrate.bitrate videoBitrate = Bitrate.bitrate.MEDIUM;
+
+ public Bitrate audioBitrate;
+
+ public boolean recursive;
+
+ public boolean terminal;
+
+ public boolean testOnly;
+
+ public File workingDirectory = new File(System.getProperty("user.dir"));
+
+ List<String> outputFormats = new ArrayList<String>();
+
+ List<String> inputPatterns = new ArrayList<String>();
+
+}
--- /dev/null
+/*
+ * Meviz - Various tools collection to work with multimedia.
+ * Copyright (C) 2012, Svjatoslav Agejenko, svjatoslav@svjatoslav.eu
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of version 2 of the GNU General Public License
+ * as published by the Free Software Foundation.
+ */
+
+package eu.svjatoslav.meviz.encoder;
+
+import java.io.IOException;
+import java.util.ArrayList;
+
+public class EncodingPlan {
+
+ public ArrayList<EncodingTask> encodingTasks = new ArrayList<EncodingTask>();
+
+ public void execute(final EncodingOptions encodingOptions) throws IOException {
+ for (final EncodingTask task : encodingTasks) {
+
+ try {
+ String command = task.getCommand(encodingOptions);
+
+ if (task.doUseTerminal()) {
+ command = "xterm -e '" + command + "'";
+ }
+
+ System.out.println("Executing command: " + command);
+
+ final Runtime run = Runtime.getRuntime();
+ Process pr;
+ pr = run.exec(new String[] { "/bin/bash", "-c", command });
+
+ pr.waitFor();
+
+ } catch (final Exception e) {
+ System.out.println(e.toString());
+ e.printStackTrace();
+ }
+
+ }
+
+ }
+
+ public void scheduleTask(final EncodingTask encodingTask) {
+ encodingTasks.add(encodingTask);
+ };
+
+}
--- /dev/null
+/*
+ * Meviz - Various tools collection to work with multimedia.
+ * Copyright (C) 2012, Svjatoslav Agejenko, svjatoslav@svjatoslav.eu
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of version 2 of the GNU General Public License
+ * as published by the Free Software Foundation.
+ */
+
+package eu.svjatoslav.meviz.encoder;
+
+import java.io.File;
+
+import eu.svjatoslav.meviz.encoder.converters.Converter;
+
+public class EncodingTask {
+
+ /**
+ * Source file to encode
+ */
+ private final File source;
+
+ /**
+ * Target file.
+ */
+ private final File target;
+
+ private final Converter converter;
+
+ private boolean useTerminal;
+
+ public EncodingTask(final File source, final File destination,
+ final eu.svjatoslav.meviz.encoder.converters.Converter converter) {
+
+ this.source = source;
+ target = destination;
+ this.converter = converter;
+
+ }
+
+ /**
+ * @return the useTerminal
+ */
+ public boolean doUseTerminal() {
+ return useTerminal;
+ }
+
+ public String getCommand(final EncodingOptions encodingOptions) {
+ return converter.getCommand(source, target, encodingOptions);
+ }
+
+ /**
+ * @param useTerminal
+ * the useTerminal to set
+ */
+ public void setUseTerminal(final boolean useTerminal) {
+ this.useTerminal = useTerminal;
+ }
+}
--- /dev/null
+/*
+ * Meviz - Various tools collection to work with multimedia.
+ * Copyright (C) 2012, Svjatoslav Agejenko, svjatoslav@svjatoslav.eu
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of version 2 of the GNU General Public License
+ * as published by the Free Software Foundation.
+ */
+
+package eu.svjatoslav.meviz.encoder;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import eu.svjatoslav.meviz.encoder.converters.Avi2Ogv;
+import eu.svjatoslav.meviz.encoder.converters.Converter;
+import eu.svjatoslav.meviz.encoder.converters.Jpeg2Png;
+import eu.svjatoslav.meviz.encoder.converters.Mp42Ogv;
+import eu.svjatoslav.meviz.encoder.converters.Mts2Mkv;
+import eu.svjatoslav.meviz.encoder.converters.Mts2Mp4;
+import eu.svjatoslav.meviz.encoder.converters.Ogg2Mp3;
+import eu.svjatoslav.meviz.encoder.converters.Ogg2Wav;
+import eu.svjatoslav.meviz.encoder.converters.Png2Tiff;
+import eu.svjatoslav.meviz.encoder.converters.Tiff2Png;
+import eu.svjatoslav.meviz.encoder.converters.Wav2mp3;
+
+public class FormatsRegistry {
+
+ public ArrayList<Converter> encoders = new ArrayList<Converter>();
+
+ public FormatsRegistry() {
+ // video conversion
+ registerEncoder(new Avi2Ogv());
+ registerEncoder(new Mp42Ogv());
+ registerEncoder(new Mts2Mp4());
+ registerEncoder(new Mts2Mkv());
+
+ // image conversion
+ registerEncoder(new Jpeg2Png());
+ registerEncoder(new Png2Tiff());
+ registerEncoder(new Tiff2Png());
+
+ // audio conversion
+ registerEncoder(new Ogg2Wav());
+ registerEncoder(new Wav2mp3());
+ registerEncoder(new Ogg2Mp3());
+ }
+
+ public List<Converter> getEncoders(final String sourceFormat, final String targetFormat) {
+
+ final String sourceFormatLowerCase = sourceFormat.toLowerCase();
+ final String targetFormatLowerCase = targetFormat.toLowerCase();
+
+ final ArrayList<Converter> encoders = new ArrayList<Converter>();
+
+ for (final Converter encoder : this.encoders) {
+ if (encoder.getSourceFileExtension().equals(sourceFormatLowerCase)) {
+ if (encoder.getTargetFileExtension().equals(targetFormatLowerCase)) {
+ encoders.add(encoder);
+ return encoders;
+ }
+ }
+ }
+
+ return encoders;
+ }
+
+ public void registerEncoder(final Converter encoder) {
+ encoders.add(encoder);
+ }
+
+}
--- /dev/null
+/*
+ * Meviz - Various tools collection to work with multimedia.
+ * Copyright (C) 2012, Svjatoslav Agejenko, svjatoslav@svjatoslav.eu
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of version 2 of the GNU General Public License
+ * as published by the Free Software Foundation.
+ */
+
+package eu.svjatoslav.meviz.encoder.converters;
+
+import java.io.File;
+
+import eu.svjatoslav.meviz.encoder.EncodingOptions;
+
+public class Avi2Ogv implements Converter {
+
+ @Override
+ public String getCommand(final File inputFile, final File targetFile,
+ final EncodingOptions options) {
+
+ return "ffmpeg2theora \"" + inputFile.getAbsolutePath() + "\" -o \""
+ + targetFile.getAbsolutePath()
+ + "\" --optimize --videobitrate 3000 --width 800";
+ }
+
+ @Override
+ public String getSourceFileExtension() {
+ return "avi";
+ }
+
+ @Override
+ public String getTargetFileExtension() {
+ return "ogv";
+ }
+
+ @Override
+ public boolean isTerminalMandatory() {
+
+ return false;
+ }
+
+}
--- /dev/null
+/*
+ * Meviz - Various tools collection to work with multimedia.
+ * Copyright (C) 2012, Svjatoslav Agejenko, svjatoslav@svjatoslav.eu
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of version 2 of the GNU General Public License
+ * as published by the Free Software Foundation.
+ */
+
+package eu.svjatoslav.meviz.encoder.converters;
+
+import java.io.File;
+
+import eu.svjatoslav.meviz.encoder.EncodingOptions;
+
+public interface Converter {
+
+ public String getCommand(File inputFile, File targetFile, EncodingOptions options);
+
+ public String getSourceFileExtension();
+
+ public String getTargetFileExtension();
+
+ /**
+ * For some reasons some encoders require terminal to run. Until this is
+ * resolved, encoder can request for terminal using this method.
+ */
+ public boolean isTerminalMandatory();
+}
--- /dev/null
+/*
+ * Meviz - Various tools collection to work with multimedia.
+ * Copyright (C) 2012, Svjatoslav Agejenko, svjatoslav@svjatoslav.eu
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of version 2 of the GNU General Public License
+ * as published by the Free Software Foundation.
+ */
+
+package eu.svjatoslav.meviz.encoder.converters;
+
+import java.io.File;
+
+import eu.svjatoslav.meviz.encoder.EncodingOptions;
+
+public class Jpeg2Png implements Converter {
+
+ @Override
+ public String getCommand(final File inputFile, final File targetFile, final EncodingOptions options) {
+ return "convert \"" + inputFile.getAbsolutePath() + "\" \""
+ + targetFile.getAbsolutePath() + "\"";
+ }
+
+ @Override
+ public String getSourceFileExtension() {
+ return "jpeg";
+ }
+
+ @Override
+ public String getTargetFileExtension() {
+ return "png";
+ }
+
+ @Override
+ public boolean isTerminalMandatory() {
+ return false;
+ }
+
+}
--- /dev/null
+/*
+ * Meviz - Various tools collection to work with multimedia.
+ * Copyright (C) 2012, Svjatoslav Agejenko, svjatoslav@svjatoslav.eu
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of version 2 of the GNU General Public License
+ * as published by the Free Software Foundation.
+ */
+
+package eu.svjatoslav.meviz.encoder.converters;
+
+import java.io.File;
+
+import eu.svjatoslav.meviz.encoder.EncodingOptions;
+
+public class Mp42Ogv implements Converter {
+
+ @Override
+ public String getCommand(final File inputFile, final File targetFile, final EncodingOptions options) {
+ return "ffmpeg2theora \"" + inputFile.getAbsolutePath() + "\" -o \"" + targetFile.getAbsolutePath()
+ + "\" --optimize --videobitrate 3000 --width 800";
+ }
+
+ @Override
+ public String getSourceFileExtension() {
+ return "mp4";
+ }
+
+ @Override
+ public String getTargetFileExtension() {
+ return "ogv";
+ }
+
+ @Override
+ public boolean isTerminalMandatory() {
+ return true;
+ }
+
+}
--- /dev/null
+/*
+ * Meviz - Various tools collection to work with multimedia.
+ * Copyright (C) 2012, Svjatoslav Agejenko, svjatoslav@svjatoslav.eu
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of version 2 of the GNU General Public License
+ * as published by the Free Software Foundation.
+ */
+
+package eu.svjatoslav.meviz.encoder.converters;
+
+import java.io.File;
+
+import eu.svjatoslav.meviz.encoder.EncodingOptions;
+
+public class Mts2Mkv implements Converter {
+
+ @Override
+ public String getCommand(final File inputFile, final File targetFile, final EncodingOptions options) {
+
+ return "ffmpeg -i \"" + inputFile.getAbsolutePath() + "\" -vcodec copy -acodec copy \""
+ + targetFile.getAbsolutePath() + "\"";
+ }
+
+ @Override
+ public String getSourceFileExtension() {
+ return "mts";
+ }
+
+ @Override
+ public String getTargetFileExtension() {
+ return "mkv";
+ }
+
+ @Override
+ public boolean isTerminalMandatory() {
+ return true;
+ }
+
+}
--- /dev/null
+/*
+ * Meviz - Various tools collection to work with multimedia.
+ * Copyright (C) 2012, Svjatoslav Agejenko, svjatoslav@svjatoslav.eu
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of version 2 of the GNU General Public License
+ * as published by the Free Software Foundation.
+ */
+
+package eu.svjatoslav.meviz.encoder.converters;
+
+import java.io.File;
+
+import eu.svjatoslav.meviz.encoder.EncodingOptions;
+
+public class Mts2Mp4 implements Converter {
+
+ @Override
+ public String getCommand(final File inputFile, final File targetFile,
+ final EncodingOptions options) {
+ //
+ // int videoBitrate;
+ //
+ // switch (options.videoBitrate) {
+ // case LOW:
+ // videoBitrate = 3000;
+ // break;
+ //
+ // case MEDIUM:
+ // videoBitrate = 7000;
+ // break;
+ //
+ // case HIGH:
+ // videoBitrate = 15000;
+ // break;
+ //
+ // default:
+ // throw new RuntimeException("Video bitrate: " + options.videoBitrate
+ // + " is not supported.");
+ // }
+
+ // convert
+ final String codecParams = "-acodec libmp3lame -vcodec libx264 -b 3500k -b:a 192k";
+
+ // pass through
+ // final String codecParams = "-acodec copy -vcodec copy";
+
+ return "avconv -i \"" + inputFile.getAbsolutePath() + "\" "
+ + codecParams + " \"" + targetFile.getAbsolutePath() + "\"";
+ }
+
+ @Override
+ public String getSourceFileExtension() {
+ return "mts";
+ }
+
+ @Override
+ public String getTargetFileExtension() {
+ return "mp4";
+ }
+
+ @Override
+ public boolean isTerminalMandatory() {
+ return true;
+ }
+
+}
--- /dev/null
+/*
+ * Meviz - Various tools collection to work with multimedia.
+ * Copyright (C) 2012, Svjatoslav Agejenko, svjatoslav@svjatoslav.eu
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of version 2 of the GNU General Public License
+ * as published by the Free Software Foundation.
+ */
+
+package eu.svjatoslav.meviz.encoder.converters;
+
+import java.io.File;
+
+import eu.svjatoslav.meviz.encoder.EncodingOptions;
+
+public class Ogg2Mp3 implements Converter {
+
+ @Override
+ public String getCommand(final File inputFile, final File targetFile, final EncodingOptions options) {
+ return "avconv -i \"" + inputFile.getAbsolutePath() + "\" \"" + targetFile.getAbsolutePath() + "\"";
+ }
+
+ @Override
+ public String getSourceFileExtension() {
+ return "ogg";
+ }
+
+ @Override
+ public String getTargetFileExtension() {
+ return "mp3";
+ }
+
+ @Override
+ public boolean isTerminalMandatory() {
+ return false;
+ }
+
+}
--- /dev/null
+/*
+ * Meviz - Various tools collection to work with multimedia.
+ * Copyright (C) 2012, Svjatoslav Agejenko, svjatoslav@svjatoslav.eu
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of version 2 of the GNU General Public License
+ * as published by the Free Software Foundation.
+ */
+
+package eu.svjatoslav.meviz.encoder.converters;
+
+import java.io.File;
+
+import eu.svjatoslav.meviz.encoder.EncodingOptions;
+
+public class Ogg2Wav implements Converter {
+
+ @Override
+ public String getCommand(final File inputFile, final File targetFile, final EncodingOptions options) {
+
+ return "oggdec \"" + inputFile.getAbsolutePath() + "\" -o \"" + targetFile.getAbsolutePath() + "\"";
+
+ }
+
+ @Override
+ public String getSourceFileExtension() {
+ return "ogg";
+ }
+
+ @Override
+ public String getTargetFileExtension() {
+ return "wav";
+ }
+
+ @Override
+ public boolean isTerminalMandatory() {
+ return true;
+ }
+
+}
--- /dev/null
+/*
+ * Meviz - Various tools collection to work with multimedia.
+ * Copyright (C) 2012, Svjatoslav Agejenko, svjatoslav@svjatoslav.eu
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of version 2 of the GNU General Public License
+ * as published by the Free Software Foundation.
+ */
+
+package eu.svjatoslav.meviz.encoder.converters;
+
+import java.io.File;
+
+import eu.svjatoslav.meviz.encoder.EncodingOptions;
+
+public class Png2Tiff implements Converter {
+
+
+ @Override
+ public String getCommand(final File inputFile, final File targetFile, final EncodingOptions options) {
+ return "convert \"" + inputFile.getAbsolutePath() + "\" \""
+ + targetFile.getAbsolutePath() + "\"";
+ }
+
+ @Override
+ public String getSourceFileExtension() {
+ return "tiff";
+ }
+
+ @Override
+ public String getTargetFileExtension() {
+ return "png";
+ }
+
+ @Override
+ public boolean isTerminalMandatory() {
+ return false;
+ }
+
+
+}
--- /dev/null
+/*
+ * Meviz - Various tools collection to work with multimedia.
+ * Copyright (C) 2012, Svjatoslav Agejenko, svjatoslav@svjatoslav.eu
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of version 2 of the GNU General Public License
+ * as published by the Free Software Foundation.
+ */
+
+package eu.svjatoslav.meviz.encoder.converters;
+
+import java.io.File;
+
+import eu.svjatoslav.meviz.encoder.EncodingOptions;
+
+public class Tiff2Png implements Converter {
+
+
+ @Override
+ public String getCommand(final File inputFile, final File targetFile, final EncodingOptions options) {
+ return "convert \"" + inputFile.getAbsolutePath() + "\" \""
+ + targetFile.getAbsolutePath() + "\"";
+ }
+
+ @Override
+ public String getSourceFileExtension() {
+ return "png";
+ }
+
+ @Override
+ public String getTargetFileExtension() {
+ return "tiff";
+ }
+
+ @Override
+ public boolean isTerminalMandatory() {
+ return false;
+ }
+
+
+}
--- /dev/null
+/*
+ * Meviz - Various tools collection to work with multimedia.
+ * Copyright (C) 2012, Svjatoslav Agejenko, svjatoslav@svjatoslav.eu
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of version 2 of the GNU General Public License
+ * as published by the Free Software Foundation.
+ */
+
+package eu.svjatoslav.meviz.encoder.converters;
+
+import java.io.File;
+
+import eu.svjatoslav.meviz.encoder.EncodingOptions;
+
+public class Wav2mp3 implements Converter {
+
+ @Override
+ public String getCommand(final File inputFile, final File targetFile,
+ final EncodingOptions options) {
+
+ final String codecParams = "-b:a 192k";
+
+ return "avconv -i \"" + inputFile.getAbsolutePath() + "\" "
+ + codecParams + " \"" + targetFile.getAbsolutePath() + "\"";
+ }
+
+ @Override
+ public String getSourceFileExtension() {
+ return "wav";
+ }
+
+ @Override
+ public String getTargetFileExtension() {
+ return "mp3";
+ }
+
+ @Override
+ public boolean isTerminalMandatory() {
+ return false;
+ }
+
+}
--- /dev/null
+/*
+ * Meviz - Various tools collection to work with multimedia.
+ * Copyright (C) 2012, Svjatoslav Agejenko, svjatoslav@svjatoslav.eu
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of version 2 of the GNU General Public License
+ * as published by the Free Software Foundation.
+ */
+
+package eu.svjatoslav.meviz.grabmemcard;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.Date;
+import java.util.GregorianCalendar;
+
+import eu.svjatoslav.commons.file.CommonPathResolver;
+import eu.svjatoslav.commons.file.FilePathParser;
+import eu.svjatoslav.meviz.Module;
+import eu.svjatoslav.meviz.encoder.EncodingOptions;
+import eu.svjatoslav.meviz.encoder.EncodingPlan;
+import eu.svjatoslav.meviz.encoder.EncodingTask;
+import eu.svjatoslav.meviz.encoder.converters.Converter;
+import eu.svjatoslav.meviz.encoder.converters.Mts2Mp4;
+
+public class Main implements Module {
+
+ @Override
+ public String getDescription() {
+ return "Convenience helper to retrieve contents of inserted memory card.";
+ }
+
+ public File[] getDiskVideos(final File file) {
+ final String videosPath = file.getAbsolutePath()
+ + "/AVCHD/BDMV/STREAM/";
+ final File videosDirectory = new File(videosPath);
+
+ if (!videosDirectory.exists())
+ return new File[0];
+
+ return videosDirectory.listFiles();
+ }
+
+ public String getDoubleDigit(final int value) {
+ String valueString = Integer.toString(value);
+ if (valueString.length() == 1)
+ valueString = "0" + valueString;
+ return valueString;
+ };
+
+ @Override
+ public String getModuleCommand() {
+ return "grabmemcard";
+ }
+
+ @SuppressWarnings("deprecation")
+ public File getTargetDirectory() {
+ final Date now = new Date();
+ final GregorianCalendar calendar = new GregorianCalendar();
+
+ final StringBuffer directoryName = new StringBuffer();
+ directoryName.append(calendar.get(GregorianCalendar.YEAR) + "."
+ + getDoubleDigit(calendar.get(GregorianCalendar.MONTH) + 1)
+ + "."
+ + getDoubleDigit(calendar.get(GregorianCalendar.DAY_OF_MONTH))
+ + " ");
+
+ directoryName.append(getDoubleDigit(now.getHours()) + ":"
+ + getDoubleDigit(now.getMinutes()) + ":"
+ + getDoubleDigit(now.getSeconds()));
+
+ final String targetDirectoryPath = CommonPathResolver
+ .getDesktopDirectory().getAbsolutePath()
+ + "/"
+ + directoryName.toString() + "/";
+
+ System.out.println("Target directory path: " + targetDirectoryPath);
+
+ return new File(targetDirectoryPath);
+ }
+
+ @Override
+ public void run(final String[] args) throws IOException {
+
+ final File targetDirectory = getTargetDirectory();
+ targetDirectory.mkdirs();
+
+ final Converter converter = new Mts2Mp4();
+ final EncodingPlan encodingPlan = new EncodingPlan();
+
+ final File file = new File("/media");
+
+ for (final File insertedDisk : file.listFiles()) {
+ final File[] diskVideos = getDiskVideos(insertedDisk);
+
+ for (final File sourceFile : diskVideos) {
+
+ // compute target file path
+ final StringBuffer targetFilePath = new StringBuffer();
+ targetFilePath.append(targetDirectory.getAbsolutePath());
+ targetFilePath.append("/");
+ targetFilePath.append(FilePathParser
+ .getFileNameWithoutExtension(sourceFile));
+ targetFilePath.append(".mp4");
+ final File targetFile = new File(targetFilePath.toString());
+
+ final EncodingTask encodingTask = new EncodingTask(sourceFile,
+ targetFile, converter);
+ encodingPlan.scheduleTask(encodingTask);
+ }
+ }
+
+ final EncodingOptions options = new EncodingOptions();
+
+ encodingPlan.execute(options);
+ }
+
+ @Override
+ public void showCommandlineHelp() {
+ System.out.println("memory card grabber has no commandline options");
+ }
+
+}
--- /dev/null
+package eu.svjatoslav.meviz.htmlindexer;
+
+import java.io.File;
+import java.io.UnsupportedEncodingException;
+
+import eu.svjatoslav.meviz.htmlindexer.metadata.Dimension;
+import eu.svjatoslav.meviz.htmlindexer.metadata.DirectoryMetadata;
+import eu.svjatoslav.meviz.htmlindexer.metadata.fileTypes.AbstractFile;
+import eu.svjatoslav.meviz.htmlindexer.metadata.fileTypes.DirectoryFile;
+import eu.svjatoslav.meviz.htmlindexer.metadata.fileTypes.GeneralFile;
+import eu.svjatoslav.meviz.htmlindexer.metadata.fileTypes.Picture;
+
+public abstract class AbstractIndexer {
+
+ public void compileHtml(final Layout layout,
+ final DirectoryMetadata directory)
+ throws UnsupportedEncodingException {
+
+ for (final AbstractFile file : directory.getFiles())
+ if (file instanceof GeneralFile) {
+ final String fileExtension = file.getFileExtension();
+
+ if ("ogv".equals(fileExtension))
+ layout.enlistOgv((GeneralFile) file);
+ else
+ layout.enlistFile(file);
+
+ } else if (file instanceof Picture)
+ layout.enlistImage(file);
+ else if (file instanceof DirectoryFile)
+ layout.enlistDirectory(file);
+
+ }
+
+ public abstract String getThumbnailPath(Picture picture,
+ final Dimension desiredDimension);
+
+ public static boolean isImage(final String fileExtension) {
+ for (final String ext : Constants.SUPPORTED_IMAGE_EXTENSIONS)
+ if (ext.equals(fileExtension))
+ return true;
+ return false;
+ }
+
+ public static boolean isOgv(final String fileExtension) {
+ return fileExtension.equalsIgnoreCase("ogv");
+ }
+
+ public static boolean shallFileBeIndexed(final File file) {
+
+ if (file.getName().startsWith("."))
+ return false;
+ if (file.getName().startsWith("index"))
+ if (file.getName().endsWith(".html"))
+ return false;
+
+ return true;
+ }
+
+}
--- /dev/null
+/*
+ * Meviz - Various tools collection to work with multimedia.
+ * Copyright (C) 2012, Svjatoslav Agejenko, svjatoslav@svjatoslav.eu
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of version 2 of the GNU General Public License
+ * as published by the Free Software Foundation.
+ */
+
+package eu.svjatoslav.meviz.htmlindexer;
+
+import java.io.File;
+
+import eu.svjatoslav.commons.commandline.parameterparser.Parameter;
+import eu.svjatoslav.commons.commandline.parameterparser.Parser;
+import eu.svjatoslav.meviz.encoder.EncodingOptions;
+
+public class CommandlineHandler {
+
+ Parameter galleryNameParameter = new Parameter(false, true, false,
+ new eu.svjatoslav.commons.commandline.parameterparser.arguments.String(), "Gallery title. (default is: "
+ + Constants.DEFAULT_GALLERY_TITLE + ").", "-t", "--gallery-title");
+
+ Parameter workingDirectoryParameter = new Parameter(false, true, true,
+ new eu.svjatoslav.commons.commandline.parameterparser.arguments.String(), "Working directory.", "-w",
+ "--working-directory");
+
+ public Parser initParser() {
+
+ final Parser parser = new Parser();
+ parser.addParameter(galleryNameParameter);
+ parser.addParameter(workingDirectoryParameter);
+
+ return parser;
+ }
+
+ /**
+ * @return {@link EncodingOptions} if commandline arguments were
+ * successfully parsed, or <code>null</code> if parsing error
+ * occurred.
+ */
+ public IndexingOptions parseCommandlineArguments(final String[] args) {
+
+ final IndexingOptions options = new IndexingOptions();
+
+ final Parser parser = initParser();
+ if (!parser.parse(args)) {
+ return null;
+ }
+
+ if (galleryNameParameter.isParameterSpecified()) {
+ options.galleryTitle = galleryNameParameter.getArgumentsAsStrings().get(0);
+ }
+
+ if (workingDirectoryParameter.isParameterSpecified()) {
+ options.workingDirectory = workingDirectoryParameter.getArgumentsAsFiles().get(0);
+ } else {
+ options.workingDirectory = new File(System.getProperty("user.dir"));
+ }
+
+ return options;
+ }
+}
--- /dev/null
+/*
+ * Meviz - Various tools collection to work with multimedia.
+ * Copyright (C) 2012, Svjatoslav Agejenko, svjatoslav@svjatoslav.eu
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of version 2 of the GNU General Public License
+ * as published by the Free Software Foundation.
+ */
+
+package eu.svjatoslav.meviz.htmlindexer;
+
+public class Constants {
+
+ public static final String DEFAULT_GALLERY_TITLE = "Gallery";
+
+ public static final String METADATA_FILE_NAME = "metadata_6.dat";
+
+ public static final String THUMBNAILS_DIRECTORY_NAME = ".thumbnails";
+
+ /**
+ * If this string is found within index.html then it is assumed that the
+ * file is generated by current utility and therefore is safe to overwrite
+ * with the newer version.
+ *
+ * TODO: possibility of multiple patterns shall be present, to allow easy
+ * migration
+ *
+ * TODO: a safer way shall be used for detection, like specific pattern also
+ * in specific place within a file
+ */
+ public static final String HTML_MAGIC_STRING = "DirListGen";
+
+ public static final String HTML_MEMO = "Directory Listing Generator by Svjatoslav Agejenko. E-mail: svjatoslav@svjatoslav.eu, homepage: http://svjatoslav.eu";
+
+ public static final String[] SUPPORTED_IMAGE_EXTENSIONS = { "jpg", "jpeg",
+ "png", "gif" };
+
+ public static final String THUMBNAIL_VERSION = "2";
+
+}
--- /dev/null
+package eu.svjatoslav.meviz.htmlindexer;
+
+import java.util.Comparator;
+
+import eu.svjatoslav.meviz.htmlindexer.metadata.fileTypes.AbstractFile;
+
+public class FileSortComparator implements Comparator<AbstractFile> {
+
+ @Override
+ public int compare(final AbstractFile o1, final AbstractFile o2) {
+ return o1.fileName.compareTo(o2.fileName);
+ }
+
+}
--- /dev/null
+/*
+ * Meviz - Various tools collection to work with multimedia.
+ * Copyright (C) 2012, Svjatoslav Agejenko, svjatoslav@svjatoslav.eu
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of version 2 of the GNU General Public License
+ * as published by the Free Software Foundation.
+ */
+
+package eu.svjatoslav.meviz.htmlindexer;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileReader;
+import java.io.IOException;
+import java.io.UnsupportedEncodingException;
+import java.util.HashSet;
+
+import org.apache.log4j.Logger;
+
+import eu.svjatoslav.commons.file.IOHelper;
+import eu.svjatoslav.meviz.htmlindexer.layouts.MixedLayout;
+import eu.svjatoslav.meviz.htmlindexer.metadata.Dimension;
+import eu.svjatoslav.meviz.htmlindexer.metadata.DirectoryMetadata;
+import eu.svjatoslav.meviz.htmlindexer.metadata.MetadadaHelper;
+import eu.svjatoslav.meviz.htmlindexer.metadata.fileTypes.AbstractFile;
+import eu.svjatoslav.meviz.htmlindexer.metadata.fileTypes.DirectoryFile;
+import eu.svjatoslav.meviz.htmlindexer.metadata.fileTypes.GeneralFile;
+import eu.svjatoslav.meviz.htmlindexer.metadata.fileTypes.Picture;
+
+/**
+ * Main class of HTML indexer.
+ */
+
+public class FilesystemIndexer extends AbstractIndexer {
+
+ public static final Logger logger = Logger
+ .getLogger(FilesystemIndexer.class);
+
+ private final HashSet<String> validMetadataFiles = new HashSet<String>();
+
+ private final File directoryToIndex;
+
+ private String thumbnailsPath;
+
+ private File metadataFile;
+
+ private DirectoryMetadata metadata;
+
+ private final IndexingOptions indexingOptions;
+
+ private final String[] pathElements;
+
+ private HashSet<Layout> layouts;
+
+ public FilesystemIndexer(final File directoryToIndex,
+ final IndexingOptions indexingOptions, final String[] pathElements)
+ throws IOException, ImageFormatError {
+
+ this.directoryToIndex = directoryToIndex;
+ this.indexingOptions = indexingOptions;
+ this.pathElements = pathElements;
+
+ if (!directoryToIndex.canRead())
+ return;
+
+ validMetadataFiles.add(Constants.METADATA_FILE_NAME);
+
+ initializeThumbnailsDirectory();
+ loadOrCreateMetadata();
+
+ initializeLayouts();
+
+ updateMetadata();
+
+ metadata.removeUnusedMetadataEntries();
+
+ generateHtmlFromMetadata(layouts);
+
+ removeUnusedThumbnailFiles();
+
+ // save directory metadata
+ if (metadata.changed)
+ MetadadaHelper.saveDirectoryMetadata(metadataFile, metadata);
+
+ }
+
+ public boolean canWriteIndexFile(final File indexFile)
+ throws FileNotFoundException, IOException {
+ boolean canWriteIndexFile = false;
+
+ if (indexFile.exists()) {
+ // if file already exists, make sure that we can overwrite
+ // it
+ final FileReader fileReader = new FileReader(indexFile);
+ final BufferedReader reader = new BufferedReader(fileReader);
+
+ parseFile: {
+ while (true) {
+ final String line = reader.readLine();
+
+ if (line == null)
+ break parseFile;
+
+ if (line.contains(Constants.HTML_MAGIC_STRING)) {
+ canWriteIndexFile = true;
+ break parseFile;
+ }
+ }
+ }
+
+ reader.close();
+ fileReader.close();
+ } else
+ canWriteIndexFile = true;
+ return canWriteIndexFile;
+ }
+
+ public void cleanupUnusedMetadataFiles() {
+ final File thumbnailsDirectory = new File(thumbnailsPath);
+
+ for (final File file : thumbnailsDirectory.listFiles())
+ if (!validMetadataFiles.contains(file.getName()))
+ file.delete();
+ }
+
+ public void generateHtmlFromMetadata(final HashSet<Layout> layouts) {
+ // Generate HTML from metadata
+ for (final Layout layout : layouts) {
+
+ final String indexFilePath = directoryToIndex.getAbsolutePath()
+ + "/index" + layout.getFileNameSuffix() + ".html";
+
+ try {
+
+ final File indexFile = new File(indexFilePath);
+ if (canWriteIndexFile(indexFile)) {
+
+ indexForLayout(layout);
+
+ IOHelper.overwriteFileIfContentDiffers(indexFile, layout
+ .getHtml().getBytes());
+ }
+ } catch (final Exception e) {
+ logger.error("Error writing index file to:" + indexFilePath, e);
+ }
+ }
+ }
+
+ public String[] getSubPath(final File file) {
+
+ final String[] subPath = new String[pathElements.length + 1];
+
+ for (int i = 0; i < pathElements.length; i++)
+ subPath[i] = pathElements[i];
+
+ subPath[pathElements.length] = file.getName();
+ return subPath;
+ }
+
+ @Override
+ public String getThumbnailPath(final Picture picture,
+ final Dimension desiredDimension) {
+
+ // in case thumbnail size was equal to original, then return original
+ // file path
+ if (picture.getDimensions().equals(desiredDimension))
+ return picture.fileName;
+
+ final String thumbnailFileName = picture
+ .getRelativeThumbnailFileName(desiredDimension);
+
+ validMetadataFiles.add(thumbnailFileName);
+ final File thumbnailFile = new File(thumbnailsPath + thumbnailFileName);
+
+ if (!thumbnailFile.exists()) {
+
+ final File originalFile = new File(
+ directoryToIndex.getAbsolutePath() + "/" + picture.fileName);
+
+ // generate new thumbnail
+ Picture.makeThumbnail(originalFile, thumbnailFile,
+ desiredDimension.getAwtDimension());
+ }
+ return Constants.THUMBNAILS_DIRECTORY_NAME + "/" + thumbnailFileName;
+ }
+
+ public void indexForLayout(final Layout layout)
+ throws UnsupportedEncodingException {
+
+ for (final AbstractFile abstractFile : metadata.getFiles())
+ if (abstractFile instanceof GeneralFile) {
+
+ if (isOgv(abstractFile.getFileExtension()))
+ layout.enlistOgv(abstractFile);
+ else
+ layout.enlistFile(abstractFile);
+
+ } else if (abstractFile instanceof Picture)
+ layout.enlistImage(abstractFile);
+ else if (abstractFile instanceof DirectoryFile)
+ layout.enlistDirectory(abstractFile);
+
+ }
+
+ public void initializeLayouts() {
+ layouts = new HashSet<Layout>();
+ layouts.add(new MixedLayout());
+
+ for (final Layout layout : layouts)
+ layout.init(indexingOptions.galleryTitle, pathElements, this);
+ }
+
+ public void initializeThumbnailsDirectory() {
+ // initialize thumbnails directory
+ thumbnailsPath = directoryToIndex.getAbsolutePath() + "/"
+ + Constants.THUMBNAILS_DIRECTORY_NAME + "/";
+
+ // ensure thumbnails directory exists
+ final File thumbnailsDirectory = new File(thumbnailsPath);
+ if (!thumbnailsDirectory.exists())
+ thumbnailsDirectory.mkdirs();
+ }
+
+ public void loadOrCreateMetadata() {
+ metadataFile = new File(thumbnailsPath + Constants.METADATA_FILE_NAME);
+
+ metadata = MetadadaHelper.initDirectoryMetadata(metadataFile);
+ }
+
+ private void removeUnusedThumbnailFiles() {
+
+ final File thumbnailsDirectory = new File(thumbnailsPath);
+
+ for (final File file : thumbnailsDirectory.listFiles())
+ if (!validMetadataFiles.contains(file.getName()))
+ file.delete();
+
+ }
+
+ public void updateMetadata() throws IOException, ImageFormatError {
+
+ final File[] directoryContent = directoryToIndex.listFiles();
+
+ for (final File file : directoryContent)
+ if (shallFileBeIndexed(file)) {
+
+ metadata.ensureFileMetainfoIsUpToDate(directoryToIndex, file);
+
+ if (file.isDirectory())
+ new FilesystemIndexer(file, indexingOptions,
+ getSubPath(file));
+ }
+ }
+}
--- /dev/null
+/*
+ * Meviz - Various tools collection to work with multimedia.
+ * Copyright (C) 2012, Svjatoslav Agejenko, svjatoslav@svjatoslav.eu
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of version 2 of the GNU General Public License
+ * as published by the Free Software Foundation.
+ */
+
+package eu.svjatoslav.meviz.htmlindexer;
+
+public class ImageFormatError extends Exception {
+
+ private static final long serialVersionUID = 4037233564457071385L;
+
+ public ImageFormatError(final String message) {
+ super(message);
+ }
+}
--- /dev/null
+/*
+ * Meviz - Various tools collection to work with multimedia.
+ * Copyright (C) 2012, Svjatoslav Agejenko, svjatoslav@svjatoslav.eu
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of version 2 of the GNU General Public License
+ * as published by the Free Software Foundation.
+ */
+
+package eu.svjatoslav.meviz.htmlindexer;
+
+import java.io.File;
+
+public class IndexingOptions {
+
+ File workingDirectory;
+
+ String galleryTitle = Constants.DEFAULT_GALLERY_TITLE;
+
+}
--- /dev/null
+/*
+ * Meviz - Various tools collection to work with multimedia.
+ * Copyright (C) 2012, Svjatoslav Agejenko, svjatoslav@svjatoslav.eu
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of version 2 of the GNU General Public License
+ * as published by the Free Software Foundation.
+ */
+
+package eu.svjatoslav.meviz.htmlindexer;
+
+import java.io.UnsupportedEncodingException;
+
+import eu.svjatoslav.meviz.htmlindexer.metadata.fileTypes.AbstractFile;
+
+/**
+ * In order to have possibility of several different layouts per directory.
+ * Universal interface is defined.
+ *
+ * Layout implementation is responsible for actual HTML generation.
+ */
+
+public interface Layout {
+
+ /**
+ * Enlist directory.
+ */
+ public void enlistDirectory(AbstractFile directory);
+
+ /**
+ * Enlist simple file.
+ */
+ public void enlistFile(AbstractFile file);
+
+ /**
+ * Enlist image file.
+ */
+ public void enlistImage(AbstractFile picture);
+
+ /**
+ * Enlist video in OGV format.
+ *
+ * @throws UnsupportedEncodingException
+ */
+ public void enlistOgv(AbstractFile file)
+ throws UnsupportedEncodingException;
+
+ /**
+ * Return layout specific suffix that will be appended between
+ * index(suffix).html of generated file. This way multiple layouts can
+ * coexist in the same directory, each residing in its own HTML file.
+ */
+ public String getFileNameSuffix();
+
+ /**
+ * After necessary files have been enlisted for particular directory, use
+ * this method to retrieve generated HTML result.
+ */
+ public String getHtml();
+
+ /**
+ * Initialize layout for particular directory.
+ */
+ public void init(String galleryTitle, String[] path,
+ final AbstractIndexer indexer);
+}
--- /dev/null
+package eu.svjatoslav.meviz.htmlindexer;
+
+import eu.svjatoslav.meviz.Module;
+
+public class Main implements Module {
+
+ CommandlineHandler commandlineHandler = new CommandlineHandler();
+
+ IndexingOptions indexingOptions;
+
+ /** {@inheritDoc} */
+ @Override
+ public String getDescription() {
+ return "Generate HTML listing of directories.";
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public String getModuleCommand() {
+ return "index";
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public void run(final String[] args) throws Exception {
+
+ indexingOptions = commandlineHandler.parseCommandlineArguments(args);
+
+ if (indexingOptions == null) {
+ showCommandlineHelp();
+ return;
+ }
+
+ new FilesystemIndexer(indexingOptions.workingDirectory,
+ indexingOptions, new String[] {});
+
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public void showCommandlineHelp() {
+ commandlineHandler.initParser().showHelp();
+ }
+
+ // public static void main(final String[] args) throws Exception {
+ //
+ // final Main main = new Main();
+ // main.run(new String[] { "-w", "/home/n0/Desktop/testGallery/" });
+ //
+ // }
+
+}
--- /dev/null
+/*
+ * Meviz - Various tools collection to work with multimedia.
+ * Copyright (C) 2012, Svjatoslav Agejenko, svjatoslav@svjatoslav.eu
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of version 2 of the GNU General Public License
+ * as published by the Free Software Foundation.
+ */
+
+package eu.svjatoslav.meviz.htmlindexer;
+
+import java.awt.image.BufferedImage;
+import java.io.File;
+import java.io.IOException;
+import java.util.zip.CRC32;
+
+import javax.imageio.ImageIO;
+
+public class Utils {
+
+ private static File lastLoadedFile;
+
+ private static BufferedImage lastLoadedBufferedImage;
+
+ /**
+ * Load image into {@link BufferedImage} and return it. Caches last loaded
+ * image to speed up subsequent loading attempts.
+ *
+ * @throws ImageFormatError
+ * @throws IOException
+ */
+ public static BufferedImage getBufferedImage(final File file) throws ImageFormatError, IOException {
+ if (file.equals(lastLoadedFile)) {
+ return lastLoadedBufferedImage;
+ }
+
+ System.out.println("Loading image: " + file.getPath());
+ lastLoadedBufferedImage = ImageIO.read(file);
+ lastLoadedFile = file;
+
+ if (lastLoadedBufferedImage == null)
+ throw new ImageFormatError("File: " + file + " is not a valid image.");
+
+ return lastLoadedBufferedImage;
+ }
+
+ public static String getStringCrcAsHex(final String input) {
+
+ // create a new CRC-calculating object
+ final CRC32 crc = new CRC32();
+
+ // loop, calculating CRC for each byte of the string
+ // There is no CRC16.update(byte[]) method.
+ for (final byte b : input.getBytes()) {
+ crc.update(b);
+ }
+
+ // note use crc.value, not crc.getValue()
+ final String hex = Integer.toHexString((int) crc.getValue()).toUpperCase();
+
+ // System.out.println("Input string: " + input);
+ // System.out.println("Result: " + hex);
+
+ return hex;
+ }
+
+}
--- /dev/null
+/*
+ * Meviz - Various tools collection to work with multimedia.
+ * Copyright (C) 2012, Svjatoslav Agejenko, svjatoslav@svjatoslav.eu
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of version 2 of the GNU General Public License
+ * as published by the Free Software Foundation.
+ */
+
+package eu.svjatoslav.meviz.htmlindexer.layouts;
+
+import java.io.UnsupportedEncodingException;
+import java.util.List;
+
+import org.apache.log4j.Logger;
+
+import eu.svjatoslav.commons.file.FilePathParser;
+import eu.svjatoslav.commons.network.UrlParamEncoder;
+import eu.svjatoslav.meviz.htmlindexer.AbstractIndexer;
+import eu.svjatoslav.meviz.htmlindexer.Constants;
+import eu.svjatoslav.meviz.htmlindexer.Layout;
+import eu.svjatoslav.meviz.htmlindexer.metadata.Dimension;
+import eu.svjatoslav.meviz.htmlindexer.metadata.fileTypes.AbstractFile;
+import eu.svjatoslav.meviz.htmlindexer.metadata.fileTypes.GeneralFile;
+import eu.svjatoslav.meviz.htmlindexer.metadata.fileTypes.Picture;
+
+public class MixedLayout implements Layout {
+
+ Logger logger = Logger.getLogger(MixedLayout.class);
+
+ StringBuffer dirHtml = new StringBuffer();
+
+ StringBuffer filesHtml = new StringBuffer();
+
+ String galleryTitle;
+
+ String[] path;
+
+ public static final String encoding = "UTF-8";
+
+ int currentColumn = 0;
+
+ int horizontalColumnsLimit = 2;
+
+ private AbstractIndexer indexer;
+
+ public void columnAdded() {
+ currentColumn++;
+ if (currentColumn > horizontalColumnsLimit) {
+
+ currentColumn = 0;
+
+ filesHtml.append("</TR>\n");
+ }
+ }
+
+ @Override
+ public void enlistDirectory(final AbstractFile directory) {
+ dirHtml.append("<TR>");
+ dirHtml.append("<TD><b><a href=\"" + directory.fileName
+ + "/index.html\"> ==> " + directory.fileName
+ + "</a></b></TD>");
+ dirHtml.append("</TR>\n");
+
+ }
+
+ @Override
+ public void enlistFile(final AbstractFile file) {
+ finishRow();
+
+ final String fullFileName = file.fileName;
+
+ filesHtml.append("<TR>\n");
+ filesHtml.append(" <TD colspan=\""
+ + String.valueOf(horizontalColumnsLimit) + "\"><a href=\""
+ + UrlParamEncoder.encode(fullFileName) + "\">" + fullFileName
+ + "</a>\n");
+ filesHtml.append(" ("
+ + FilePathParser.getFileSizeDescription(file.getFileLength())
+ + ")</TD>\n");
+ filesHtml.append("</TR>\n");
+
+ }
+
+ @Override
+ public void enlistImage(final AbstractFile abstractFile) {
+ try {
+
+ final Picture picture = (Picture) abstractFile;
+
+ final Dimension imageSize = picture.getDimensions();
+
+ final List<Dimension> recommendedDimensions = Picture
+ .getThumbnailDimensions(imageSize);
+
+ Dimension listingDimension = new Dimension(500, 500);
+
+ if (listingDimension.width > imageSize.width)
+ if (listingDimension.height > imageSize.height)
+ listingDimension = imageSize;
+
+ final String listingThumbnailPath = indexer.getThumbnailPath(
+ picture, listingDimension);
+
+ startcolumn();
+
+ filesHtml.append("<TD><center><a href=\""
+ + UrlParamEncoder.encode(picture.fileName) + "\">\n");
+
+ filesHtml.append("<img border=\"0\" src=\""
+ + UrlParamEncoder.encode(listingThumbnailPath)
+ + "\"/></a>\n");
+ filesHtml.append("<br/><b>"
+ + FilePathParser
+ .getFileNameWithoutExtension(picture.fileName)
+ + "</b><br/>(");
+
+ int count = 0;
+ for (final Dimension dimension : recommendedDimensions) {
+ count++;
+ if (count > 1)
+ filesHtml.append(", ");
+ filesHtml.append("<a href=\""
+ + UrlParamEncoder.encode(indexer.getThumbnailPath(
+ picture, dimension)) + "\">");
+ filesHtml.append(dimension.width + "x" + dimension.height);
+ filesHtml.append("</a>");
+ }
+
+ filesHtml.append(")</TD>\n");
+
+ columnAdded();
+
+ } catch (final Exception e) {
+ logger.error(
+ "Error generating thumbnails for image file: "
+ + e.toString()
+ + ", thumbnail generation skipped, enlisting as ordinary file instead.",
+ e);
+ enlistFile(abstractFile);
+ }
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public void enlistOgv(final AbstractFile abstractFile)
+ throws UnsupportedEncodingException {
+
+ final GeneralFile file = (GeneralFile) abstractFile;
+
+ finishRow();
+
+ filesHtml
+ .append("<TR style=\"background-color: #404040; text-align: center\">\n");
+ filesHtml.append("<TD style=\"text-align: center\" colspan=\""
+ + String.valueOf(horizontalColumnsLimit) + "\">\n");
+
+ filesHtml.append("<video controls=\"controls\" tabindex=\"0\">\n");
+ filesHtml
+ .append("<source type=\"video/ogg\" codecs=\"theora, vorbis\" src=\""
+ + UrlParamEncoder.encode(file.fileName) + "\">\n");
+ filesHtml.append("</source>\n");
+
+ // if browser cannot play video directry, fall back to java Applet
+ filesHtml
+ .append("<applet code=\"com.fluendo.player.Cortado.class\" archive=\"http://theora.org/cortado.jar\" width=\"800\" height=\"600\">\n");
+ filesHtml.append(" <param name=\"url\" value=\""
+ + UrlParamEncoder.encode(file.fileName) + "\"/>\n");
+ filesHtml.append(" <param name=\"keepAspect\" value=\"true\"/>\n");
+ filesHtml.append(" <param name=\"autoPlay\" value=\"false\"/>\n");
+ filesHtml.append("</applet>\n");
+
+ filesHtml.append("</video>\n");
+
+ filesHtml.append("<br/>\n");
+
+ filesHtml
+ .append("Video: <b>"
+ + FilePathParser
+ .getFileNameWithoutExtension(file.fileName)
+ + "<b/> ");
+ filesHtml.append("<a href=\"" + UrlParamEncoder.encode(file.fileName)
+ + "\">download as OGV</a>\n");
+
+ filesHtml.append("</TD></TR>\n");
+
+ }
+
+ public void finishRow() {
+
+ if (currentColumn == 0)
+ return;
+
+ while (currentColumn <= horizontalColumnsLimit) {
+ filesHtml.append("<TD></TD>");
+ currentColumn++;
+ }
+ filesHtml.append("</TR>\n");
+ currentColumn = 0;
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public String getFileNameSuffix() {
+ return "";
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public String getHtml() {
+
+ // assemble final page HTML
+ final StringBuffer finalHtml = new StringBuffer();
+
+ // page header
+ finalHtml.append("<HTML>\n");
+ finalHtml.append("<HEAD>\n");
+ finalHtml
+ .append(" <meta HTTP-EQUIV=\"Content-Type\" CONTENT=\"text/html; charset=UTF-8\"/>\n");
+ finalHtml.append("</HEAD>\n");
+ finalHtml
+ .append("<BODY bgcolor=\"#000000\" alink=\"#50ffff\" link=\"#50ffff\" vlink=\"#ff50ff\" text=\"#ffffff\">\n");
+ finalHtml.append("<!-- " + Constants.HTML_MAGIC_STRING + " -->\n");
+ finalHtml.append("<!-- " + Constants.HTML_MEMO + " -->\n");
+ finalHtml.append("<FONT color=\"#ffffff\">\n");
+ finalHtml.append("<CENTER><H1>" + galleryTitle + "</H1>\n");
+
+ finalHtml.append("<H2>");
+ for (final String p : path)
+ finalHtml.append(" / " + p);
+ finalHtml.append("</H2></CENTER>\n");
+
+ // append directory listing
+ finalHtml.append("<TABLE>\n");
+
+ if (path.length > 0) {
+ finalHtml.append("<TR>");
+ finalHtml
+ .append("<TD><b><a href=\"../index.html\"> <== ..</a></b></TD>");
+ finalHtml.append("</TR>\n");
+ }
+
+ finalHtml.append(dirHtml.toString());
+ finalHtml.append("\n<TR><TD><br></TD></TR>\n");
+ finalHtml.append("</TABLE>\n");
+
+ // append file listing
+
+ finishRow();
+ finalHtml.append("<TABLE width=\"1100\">\n");
+ finalHtml.append(filesHtml.toString());
+ finalHtml.append("\n</TABLE>\n");
+
+ finalHtml.append("</font></BODY></HTML>\n");
+
+ return finalHtml.toString();
+ }
+
+ @Override
+ public void init(final String galleryTitle, final String[] path,
+ final AbstractIndexer indexer) {
+ this.indexer = indexer;
+ this.galleryTitle = galleryTitle;
+ this.path = path;
+ }
+
+ public void startcolumn() {
+ if (currentColumn == 0) {
+ filesHtml.append("<TR>");
+ currentColumn = 1;
+ }
+ }
+
+}
--- /dev/null
+/*
+ * Meviz - Various tools collection to work with multimedia.
+ * Copyright (C) 2012, Svjatoslav Agejenko, svjatoslav@svjatoslav.eu
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of version 2 of the GNU General Public License
+ * as published by the Free Software Foundation.
+ */
+
+package eu.svjatoslav.meviz.htmlindexer.metadata;
+
+import java.io.Serializable;
+
+/**
+ * Corresponds to single image dimensions.
+ */
+
+public class Dimension implements Serializable, Comparable<Dimension> {
+
+ private static final long serialVersionUID = -1039288266937331829L;
+
+ public int width;
+ public int height;
+
+ public Dimension() {
+ width = 0;
+ height = 0;
+ }
+
+ public Dimension(final Dimension origial) {
+ width = origial.width;
+ height = origial.height;
+ }
+
+ public Dimension(final int width, final int height) {
+ this.width = width;
+ this.height = height;
+ }
+
+ @Override
+ public int compareTo(final Dimension anotherDimension) {
+ if (width < anotherDimension.width)
+ return -1;
+ if (width > anotherDimension.width)
+ return 1;
+
+ if (height < anotherDimension.height)
+ return -1;
+ if (height > anotherDimension.height)
+ return 1;
+
+ return 0;
+ }
+
+ public boolean equals(final Dimension anotherDimension) {
+ if (compareTo(anotherDimension) == 0)
+ return true;
+ return false;
+ }
+
+ public int getArea() {
+ return width * height;
+ }
+
+ public java.awt.Dimension getAwtDimension() {
+ return new java.awt.Dimension(width, height);
+ }
+
+ public Dimension getScaled(final double multiplicationFactor) {
+ final Dimension result = new Dimension();
+
+ result.width = (int) ((width) * multiplicationFactor);
+ result.height = (int) ((height) * multiplicationFactor);
+
+ return result;
+ }
+}
--- /dev/null
+/*
+ * Meviz - Various tools collection to work with multimedia.
+ * Copyright (C) 2012, Svjatoslav Agejenko, svjatoslav@svjatoslav.eu
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of version 2 of the GNU General Public License
+ * as published by the Free Software Foundation.
+ */
+
+package eu.svjatoslav.meviz.htmlindexer.metadata;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+
+import eu.svjatoslav.commons.file.FilePathParser;
+import eu.svjatoslav.meviz.htmlindexer.AbstractIndexer;
+import eu.svjatoslav.meviz.htmlindexer.FileSortComparator;
+import eu.svjatoslav.meviz.htmlindexer.ImageFormatError;
+import eu.svjatoslav.meviz.htmlindexer.metadata.fileTypes.AbstractFile;
+import eu.svjatoslav.meviz.htmlindexer.metadata.fileTypes.DirectoryFile;
+import eu.svjatoslav.meviz.htmlindexer.metadata.fileTypes.GeneralFile;
+import eu.svjatoslav.meviz.htmlindexer.metadata.fileTypes.Picture;
+
+/**
+ * Corresponds to single filesystem directory.
+ */
+public class DirectoryMetadata implements Serializable {
+
+ private static final long serialVersionUID = 3526489102725366334L;
+
+ private final HashMap<String, AbstractFile> fileNameToFileMap = new HashMap<String, AbstractFile>();
+
+ public transient boolean changed;
+
+ /**
+ * Performs cleanup of directory model. In particular removes metadata for
+ * images that no longer exist in the filesystem.
+ */
+ public void cleanup() {
+ final Iterator<AbstractFile> fileIterator = fileNameToFileMap.values()
+ .iterator();
+
+ while (fileIterator.hasNext()) {
+ final AbstractFile file = fileIterator.next();
+
+ if (!file.isMetaInfoVerified())
+ fileIterator.remove();
+ }
+ }
+
+ public void ensureFileMetainfoIsUpToDate(final File parentDirectory,
+ final File file) throws IOException, ImageFormatError {
+
+ final String fileName = file.getName();
+
+ if (fileNameToFileMap.containsKey(fileName)) {
+ final boolean metainfoUpdated = fileNameToFileMap.get(fileName)
+ .ensureFileMetainfoIsUpToDate(parentDirectory);
+
+ if (metainfoUpdated)
+ changed = true;
+ } else
+ registerFile(parentDirectory, file);
+
+ }
+
+ public AbstractFile getFile(final String fileName) throws IOException {
+ return fileNameToFileMap.get(fileName);
+ }
+
+ public Collection<AbstractFile> getFiles() {
+
+ final ArrayList<AbstractFile> files = new ArrayList<AbstractFile>(
+ fileNameToFileMap.values());
+
+ Collections.sort(files, new FileSortComparator());
+
+ return files;
+ }
+
+ public Dimension getImageDimensions(final String fileName)
+ throws IOException, ImageFormatError {
+
+ return ((Picture) getFile(fileName)).getDimensions();
+ }
+
+ public AbstractFile registerFile(final File parentDirectory, final File file)
+ throws IOException, ImageFormatError {
+
+ final String fileName = file.getName();
+
+ final AbstractFile abstractFile;
+
+ if (file.isDirectory())
+ abstractFile = new DirectoryFile(parentDirectory, fileName);
+ else {
+ final String fileExtension = FilePathParser.getFileExtension(
+ fileName).toLowerCase();
+
+ if (AbstractIndexer.isImage(fileExtension))
+ abstractFile = new Picture(parentDirectory, fileName);
+ else
+ abstractFile = new GeneralFile(parentDirectory, fileName);
+ }
+
+ fileNameToFileMap.put(fileName, abstractFile);
+
+ changed = true;
+
+ return abstractFile;
+ }
+
+ public void removeUnusedMetadataEntries() {
+
+ for (final String key : new HashSet<String>(fileNameToFileMap.keySet()))
+ if (!fileNameToFileMap.get(key).isMetaInfoVerified()) {
+ fileNameToFileMap.remove(key);
+ changed = true;
+ }
+
+ }
+}
--- /dev/null
+/*
+ * Meviz - Various tools collection to work with multimedia.
+ * Copyright (C) 2012, Svjatoslav Agejenko, svjatoslav@svjatoslav.eu
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of version 2 of the GNU General Public License
+ * as published by the Free Software Foundation.
+ */
+
+package eu.svjatoslav.meviz.htmlindexer.metadata;
+
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+
+import org.apache.log4j.Logger;
+
+import eu.svjatoslav.commons.file.IOHelper;
+
+public class MetadadaHelper {
+
+ public static final Logger logger = Logger.getLogger(MetadadaHelper.class);
+
+ /**
+ * Load previously generated or initialize new directory metadata.
+ */
+ public static DirectoryMetadata initDirectoryMetadata(
+ final File metadataFile) {
+
+ if (!metadataFile.exists())
+ return new DirectoryMetadata();
+ else
+ try {
+
+ final ObjectInputStream in = new ObjectInputStream(
+ new FileInputStream(metadataFile));
+ final DirectoryMetadata directory = (DirectoryMetadata) in
+ .readObject();
+ in.close();
+
+ return directory;
+
+ } catch (final Exception exception) {
+ logger.error("Cannot load existing directory metadata.",
+ exception);
+
+ return new DirectoryMetadata();
+ }
+ }
+
+ public static void saveDirectoryMetadata(final File persistanceFile,
+ final DirectoryMetadata directory) throws IOException {
+ // serialize directory metadata into byte array
+ final ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
+
+ final ObjectOutputStream out = new ObjectOutputStream(
+ byteArrayOutputStream);
+ out.writeObject(directory);
+ out.close();
+
+ // store byte array into file
+ IOHelper.saveToFile(persistanceFile,
+ byteArrayOutputStream.toByteArray());
+ }
+}
--- /dev/null
+package eu.svjatoslav.meviz.htmlindexer.metadata.fileTypes;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.Serializable;
+
+import eu.svjatoslav.commons.file.FilePathParser;
+
+public abstract class AbstractFile implements Serializable {
+
+ private static final long serialVersionUID = -2547388204667088033L;
+
+ /**
+ * File name relative to the immediate parent directory.
+ */
+ public final String fileName;
+
+ /**
+ * File length in bytes.
+ */
+ private long fileLength;
+
+ private transient boolean metaInfoVerified;
+
+ public AbstractFile(final File parentDirectory, final String fileName)
+ throws IOException {
+ this.fileName = fileName;
+ ensureFileMetainfoIsUpToDate(parentDirectory);
+ }
+
+ /**
+ * @return <code>true</code> if file metadata was updated.
+ */
+ public boolean ensureFileMetainfoIsUpToDate(final File parentDirectory)
+ throws IOException {
+ if (!isMetainfoUpToDate(parentDirectory)) {
+ fileLength = getFile(parentDirectory).length();
+ updateFileMetainfo(parentDirectory);
+ metaInfoVerified = true;
+ return true;
+ }
+ return false;
+ };
+
+ public boolean fileExists(final File parentDirectory) {
+ return getFile(parentDirectory).exists();
+ }
+
+ public File getFile(final File parentDirectory) {
+ return new File(parentDirectory.getAbsolutePath(), fileName);
+ }
+
+ public String getFileExtension() {
+ return FilePathParser.getFileExtension(fileName);
+ }
+
+ public long getFileLength() {
+ return fileLength;
+ }
+
+ private boolean isMetainfoUpToDate(final java.io.File parentDirectory)
+ throws IOException {
+
+ if (metaInfoVerified)
+ return true;
+
+ final File file = getFile(parentDirectory);
+
+ // first check that file exists at all
+ if (!file.exists()) {
+ System.out.println(file);
+ throw new RuntimeException("Picture file by name \"" + fileName
+ + "\" does not exist in the parent directory \""
+ + parentDirectory.getAbsolutePath() + "\"");
+ }
+
+ // check that file length is the same as before
+ if (file.length() != fileLength)
+ return false;
+
+ metaInfoVerified = true;
+ return true;
+ }
+
+ public boolean isMetaInfoVerified() {
+ return metaInfoVerified;
+ }
+
+ protected abstract void updateFileMetainfo(final File parentDirectory)
+ throws IOException;
+
+}
--- /dev/null
+package eu.svjatoslav.meviz.htmlindexer.metadata.fileTypes;
+
+import java.io.File;
+import java.io.IOException;
+
+public class DirectoryFile extends AbstractFile {
+
+ private static final long serialVersionUID = 2387153281300820532L;
+
+ public DirectoryFile(final File parentDirectory, final String fileName)
+ throws IOException {
+ super(parentDirectory, fileName);
+ }
+
+ @Override
+ protected void updateFileMetainfo(final File parentDirectory)
+ throws IOException {
+ }
+
+}
--- /dev/null
+package eu.svjatoslav.meviz.htmlindexer.metadata.fileTypes;
+
+import java.io.File;
+import java.io.IOException;
+
+public class GeneralFile extends AbstractFile {
+
+ private static final long serialVersionUID = -2373609481729401415L;
+
+ public GeneralFile(final File parentDirectory, final String fileName)
+ throws IOException {
+ super(parentDirectory, fileName);
+ }
+
+ @Override
+ protected void updateFileMetainfo(final File parentDirectory)
+ throws IOException {
+ }
+
+}
--- /dev/null
+/*
+ * Meviz - Various tools collection to work with multimedia.
+ * Copyright (C) 2012, Svjatoslav Agejenko, svjatoslav@svjatoslav.eu
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of version 2 of the GNU General Public License
+ * as published by the Free Software Foundation.
+ */
+
+package eu.svjatoslav.meviz.htmlindexer.metadata.fileTypes;
+
+import java.awt.Graphics2D;
+import java.awt.Image;
+import java.awt.Toolkit;
+import java.awt.image.BufferedImage;
+import java.awt.image.FilteredImageSource;
+import java.awt.image.ImageFilter;
+import java.awt.image.ImageProducer;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.imageio.ImageIO;
+import javax.swing.ImageIcon;
+
+import eu.svjatoslav.commons.file.FilePathParser;
+import eu.svjatoslav.meviz.htmlindexer.Constants;
+import eu.svjatoslav.meviz.htmlindexer.ImageFormatError;
+import eu.svjatoslav.meviz.htmlindexer.Utils;
+import eu.svjatoslav.meviz.htmlindexer.metadata.Dimension;
+
+public class Picture extends AbstractFile {
+
+ private static final long serialVersionUID = -4156533490858298387L;
+
+ /**
+ * Picture dimensions.
+ */
+ private Dimension dimensions;
+
+ public Picture(final File parentDirectory, final String fileName)
+ throws IOException, ImageFormatError {
+ super(parentDirectory, fileName);
+ }
+
+ private String computeThumbnailHash(final Dimension targetDimension) {
+
+ // compute new thumbnails hash number
+ final String forMagicHash = fileName + " "
+ + String.valueOf(targetDimension.width) + " "
+ + String.valueOf(targetDimension.height) + " "
+ + String.valueOf(getFileLength()) + " "
+ + Constants.THUMBNAIL_VERSION;
+
+ // System.out.println("Computing hash from: " + forMagicHash);
+ return Utils.getStringCrcAsHex(forMagicHash);
+ }
+
+ public Dimension getDimensions() {
+ return dimensions;
+ };
+
+ /**
+ * Get thumbnail file name for this image and desired thumbnail dimensions
+ * relative to designated thumbnails directory within parent directory.
+ */
+ public String getRelativeThumbnailFileName(final Dimension targetDimension) {
+ return FilePathParser.getFileNameWithoutExtension(fileName) + " ("
+ + computeThumbnailHash(targetDimension) + ").jpeg";
+ }
+
+ @Override
+ public void updateFileMetainfo(final File parentDirectory)
+ throws IOException {
+ BufferedImage image;
+ try {
+ image = Utils.getBufferedImage(getFile(parentDirectory));
+ } catch (final ImageFormatError e) {
+ throw new RuntimeException(e);
+ }
+ dimensions = new Dimension(image.getWidth(), image.getHeight());
+ }
+
+ /**
+ * Actual returned target thumbnail size will be adjusted from desired one
+ * by attempting to generate as large as possible thumbnail, while not
+ * exceeding provided thumbnail width and height, and preserving aspect
+ * ratio of original image.
+ */
+ public static java.awt.Dimension getTargetThumbnailDimension(
+ final java.awt.Dimension originalImageDimension,
+ final java.awt.Dimension desiredTargetDimension) {
+
+ final double thumbWidthToHeightRatio = (double) desiredTargetDimension.width
+ / (double) desiredTargetDimension.height;
+ final double inputImageWidthToHeightRatio = (double) originalImageDimension.width
+ / (double) originalImageDimension.height;
+
+ if (thumbWidthToHeightRatio < inputImageWidthToHeightRatio) {
+
+ final java.awt.Dimension result = new java.awt.Dimension(
+ desiredTargetDimension.width,
+ (int) (desiredTargetDimension.width / inputImageWidthToHeightRatio));
+
+ return result;
+ } else {
+
+ final java.awt.Dimension result = new java.awt.Dimension(
+ (int) (desiredTargetDimension.height * inputImageWidthToHeightRatio),
+ desiredTargetDimension.height);
+
+ return result;
+ }
+ }
+
+ /**
+ * Propose list of thumbnail dimensions.
+ */
+ public static List<Dimension> getThumbnailDimensions(Dimension current) {
+ final ArrayList<Dimension> result = new ArrayList<Dimension>();
+ result.add(current);
+
+ while (current.getArea() > 100000) {
+ current = current.getScaled(0.5d);
+ result.add(current);
+ }
+
+ return result;
+
+ }
+
+ public static void makeThumbnail(final File inputFile,
+ final File outputFile,
+ final java.awt.Dimension preferredTargetDimensions) {
+
+ try {
+
+ final BufferedImage inputImage = Utils.getBufferedImage(inputFile);
+
+ final java.awt.Dimension sourceImageDimension = new java.awt.Dimension(
+ inputImage.getWidth(), inputImage.getHeight());
+
+ final java.awt.Dimension targetDimensions = getTargetThumbnailDimension(
+ sourceImageDimension, preferredTargetDimensions);
+
+ final OutputStream out = new FileOutputStream(outputFile);
+
+ final Image scaledImage = scaleImage(inputImage,
+ targetDimensions.width, targetDimensions.height);
+
+ final BufferedImage bufferedImage = new BufferedImage(
+ scaledImage.getWidth(null), scaledImage.getHeight(null),
+ BufferedImage.TYPE_INT_RGB);
+
+ final Graphics2D g = bufferedImage.createGraphics();
+ g.drawImage(scaledImage, 0, 0, null);
+ g.dispose();
+
+ ImageIO.write(bufferedImage, "jpg", out);
+ out.close();
+
+ } catch (final Exception exception) {
+ System.out.println(exception.toString());
+ exception.printStackTrace();
+ }
+ }
+
+ /**
+ * @return new image scaled to desired dimensions
+ */
+ public static Image scaleImage(final Image srcImage, final int width,
+ final int height) {
+
+ ImageFilter filter;
+ filter = new java.awt.image.AreaAveragingScaleFilter(width, height);
+
+ final ImageProducer prod = new FilteredImageSource(
+ srcImage.getSource(), filter);
+
+ final Image newImage = Toolkit.getDefaultToolkit().createImage(prod);
+
+ final ImageIcon imageIcon = new ImageIcon(newImage);
+ return imageIcon.getImage();
+ }
+
+}
--- /dev/null
+/*
+ * Meviz - Various tools collection to work with multimedia.
+ * Copyright (C) 2012, Svjatoslav Agejenko, svjatoslav@svjatoslav.eu
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of version 2 of the GNU General Public License
+ * as published by the Free Software Foundation.
+ */
+
+package eu.svjatoslav.meviz.renamer;
+
+import java.io.File;
+
+import eu.svjatoslav.commons.commandline.parameterparser.Parameter;
+import eu.svjatoslav.commons.commandline.parameterparser.Parser;
+import eu.svjatoslav.meviz.encoder.EncodingOptions;
+
+public class CommandlineHandler {
+
+ Parameter recursiveParameter = new Parameter("Enable recursive mode.",
+ "-r", "--recursive");
+
+ Parameter testParameter = new Parameter(
+ "Simulate renaming (no changes will be actually done).", "-t",
+ "--test");
+
+ Parameter outputPatternParameter = new Parameter(
+ true,
+ true,
+ true,
+ new eu.svjatoslav.commons.commandline.parameterparser.arguments.String(),
+ "Output pattern.", "-o", "--output-pattern");
+
+ Parameter inputPatternParameter = new Parameter(
+ true,
+ true,
+ true,
+ new eu.svjatoslav.commons.commandline.parameterparser.arguments.String(),
+ "File input pattern.", "-i", "--input-pattern");
+
+ Parameter workingDirectoryParameter = new Parameter(
+ false,
+ true,
+ true,
+ new eu.svjatoslav.commons.commandline.parameterparser.arguments.ExistingDirectory(),
+ "Working directory.", "-w", "--working-directory");
+
+ public Parser initParser() {
+
+ final Parser parser = new Parser();
+ parser.addParameter(recursiveParameter);
+ parser.addParameter(testParameter);
+ parser.addParameter(outputPatternParameter);
+ parser.addParameter(inputPatternParameter);
+ parser.addParameter(workingDirectoryParameter);
+
+ return parser;
+ }
+
+ /**
+ * @return {@link EncodingOptions} if commandline arguments were
+ * successfully parsed, or <code>null</code> if parsing error
+ * occurred.
+ */
+ public RenamingOptions parseCommandlineArguments(final String[] args) {
+
+ final RenamingOptions options = new RenamingOptions();
+
+ final Parser parser = initParser();
+ if (!parser.parse(args))
+ return null;
+
+ if (testParameter.isParameterSpecified())
+ options.testOnly = true;
+
+ if (recursiveParameter.isParameterSpecified())
+ options.recursive = true;
+
+ if (outputPatternParameter.isParameterSpecified())
+ options.outputPattern = outputPatternParameter
+ .getArgumentsAsStrings().get(0);
+
+ if (workingDirectoryParameter.isParameterSpecified())
+ options.targetDirectory = workingDirectoryParameter
+ .getArgumentsAsFiles().get(0);
+ else
+ options.targetDirectory = new File(System.getProperty("user.dir"));
+
+ if (inputPatternParameter.isParameterSpecified())
+ options.inputPatterns.addAll(inputPatternParameter
+ .getArgumentsAsStrings());
+
+ return options;
+ }
+}
--- /dev/null
+/*
+ * Meviz - Various tools collection to work with multimedia.
+ * Copyright (C) 2012, Svjatoslav Agejenko, svjatoslav@svjatoslav.eu
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of version 2 of the GNU General Public License
+ * as published by the Free Software Foundation.
+ */
+
+package eu.svjatoslav.meviz.renamer;
+
+import java.io.File;
+
+import eu.svjatoslav.commons.string.WildCardMatcher;
+import eu.svjatoslav.meviz.Module;
+
+public class Main implements Module {
+
+ CommandlineHandler commandlineHandler = new CommandlineHandler();
+
+ public int processedFilesCount;
+
+ RenamingOptions options;
+
+ /**
+ * Verify that program has enough information to start executing
+ *
+ * @return true if all is ok, false if errors were found
+ */
+ public boolean checkThatThereIsEnoughDataToProceed() {
+ if (options.inputPatterns.size() == 0) {
+ System.out.println("Error: no input patterns given.");
+ return false;
+ }
+
+ if (options.outputPattern == null) {
+ System.out.println("Error: no output pattern given.");
+ return false;
+ }
+
+ return true;
+ }
+
+ public boolean fileMatchesInputPattern(final File file) {
+ final String fileName = file.getName();
+
+ for (final String inputPattern : options.inputPatterns)
+ if (WildCardMatcher.match(fileName, inputPattern))
+ return true;
+
+ return false;
+ }
+
+ @Override
+ public String getDescription() {
+ return "Mass rename files according to given pattern.";
+ }
+
+ @Override
+ public String getModuleCommand() {
+ return "rename";
+ };
+
+ public void handleFile(final File file) {
+ if (!file.exists()) {
+ System.out.println("Error: file \"" + file.getAbsolutePath()
+ + "\" does not exist.");
+ return;
+ }
+
+ if (file.isDirectory()) {
+ for (final File subFile : file.listFiles())
+ if (subFile.isDirectory()) {
+ if (options.recursive)
+ handleFile(subFile);
+ } else
+ handleFile(subFile);
+ } else if (file.isFile())
+ if (fileMatchesInputPattern(file)) {
+
+ final StringBuffer targetFilePath = new StringBuffer();
+
+ targetFilePath.append(file.getParent());
+ targetFilePath.append("/");
+
+ for (int i = 0; i < options.outputPattern.length(); i++) {
+
+ final char c = options.outputPattern.charAt(i);
+
+ if (c == '*')
+ targetFilePath.append(file.getName());
+ else if (c == '%') {
+
+ final String processedFileCountString = String
+ .valueOf(processedFilesCount);
+
+ for (int j = 0; j < (5 - processedFileCountString
+ .length()); j++)
+ targetFilePath.append(0);
+
+ targetFilePath.append(processedFileCountString);
+ processedFilesCount++;
+ } else if (c == '_')
+ targetFilePath.append(" ");
+ else
+ targetFilePath.append(c);
+ }
+
+ final File targetFile = new File(targetFilePath.toString());
+
+ if (!options.testOnly) {
+
+ if (targetFile.exists())
+ System.out
+ .println("Renaming aborted because target file: "
+ + targetFile.getAbsolutePath()
+ + " already exists.");
+ else
+ file.renameTo(targetFile);
+
+ } else {
+ System.out.println("About to rename file: "
+ + file.getAbsolutePath());
+ System.out.println("into: " + targetFile.getAbsolutePath());
+ }
+ }
+
+ }
+
+ public void rename() {
+ handleFile(options.targetDirectory);
+ }
+
+ @Override
+ public void run(final String[] args) {
+
+ options = commandlineHandler.parseCommandlineArguments(args);
+
+ if (options == null) {
+ showCommandlineHelp();
+ return;
+ }
+
+ if (checkThatThereIsEnoughDataToProceed()) {
+
+ System.out.println("Renaming using input patterns: ");
+ for (final String inputPattern : options.inputPatterns)
+ System.out.println(" " + inputPattern);
+
+ rename();
+ } else
+ showCommandlineHelp();
+ }
+
+ @Override
+ public void showCommandlineHelp() {
+ commandlineHandler.initParser().showHelp();
+ System.out.println("");
+ System.out.println("Output pattern special symbols:");
+ System.out.println(" % - file number");
+ System.out.println(" * - original file name");
+ }
+
+}
--- /dev/null
+/*
+ * Meviz - Various tools collection to work with multimedia.
+ * Copyright (C) 2012, Svjatoslav Agejenko, svjatoslav@svjatoslav.eu
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of version 2 of the GNU General Public License
+ * as published by the Free Software Foundation.
+ */
+
+package eu.svjatoslav.meviz.renamer;
+
+import java.io.File;
+import java.util.ArrayList;
+
+public class RenamingOptions {
+
+ public ArrayList<String> inputPatterns = new ArrayList<String>();
+
+ public boolean recursive = false;
+
+ public boolean testOnly = false;
+
+ public String outputPattern;
+
+ public File targetDirectory;
+
+}
--- /dev/null
+/*
+ * Meviz - Various tools collection to work with multimedia.
+ * Copyright (C) 2012, Svjatoslav Agejenko, svjatoslav@svjatoslav.eu
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of version 2 of the GNU General Public License
+ * as published by the Free Software Foundation.
+ */
+
+package eu.svjatoslav.meviz.textsplitter;
+
+import java.io.File;
+
+import eu.svjatoslav.commons.commandline.parameterparser.Parameter;
+import eu.svjatoslav.commons.commandline.parameterparser.Parser;
+
+public class CommandlineHandler {
+
+ Parameter recursiveParameter = new Parameter("Enable recursive mode.",
+ "-r", "--recursive");
+
+ Parameter inputPatternParameter = new Parameter(
+ true,
+ true,
+ true,
+ new eu.svjatoslav.commons.commandline.parameterparser.arguments.String(),
+ "File input pattern.", "-i", "--input-pattern");
+
+ Parameter workingDirectoryParameter = new Parameter(
+ false,
+ true,
+ true,
+ new eu.svjatoslav.commons.commandline.parameterparser.arguments.ExistingDirectory(),
+ "Working directory.", "-w", "--working-directory");
+
+ public Parser initParser() {
+
+ final Parser parser = new Parser();
+ parser.addParameter(recursiveParameter);
+ parser.addParameter(inputPatternParameter);
+ parser.addParameter(workingDirectoryParameter);
+
+ return parser;
+ }
+
+ public TextSplittingOptions parseCommandlineArguments(final String[] args) {
+
+ final TextSplittingOptions options = new TextSplittingOptions();
+
+ final Parser parser = initParser();
+ if (!parser.parse(args))
+ return null;
+
+ if (recursiveParameter.isParameterSpecified())
+ options.recursive = true;
+
+ if (workingDirectoryParameter.isParameterSpecified())
+ options.targetDirectory = workingDirectoryParameter
+ .getArgumentsAsFiles().get(0);
+ else
+ options.targetDirectory = new File(System.getProperty("user.dir"));
+
+ if (inputPatternParameter.isParameterSpecified())
+ options.inputPatterns.addAll(inputPatternParameter
+ .getArgumentsAsStrings());
+
+ return options;
+ }
+}
--- /dev/null
+/*
+ * Meviz - Various tools collection to work with multimedia.
+ * Copyright (C) 2012, Svjatoslav Agejenko, svjatoslav@svjatoslav.eu
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of version 2 of the GNU General Public License
+ * as published by the Free Software Foundation.
+ */
+
+package eu.svjatoslav.meviz.textsplitter;
+
+import java.io.BufferedReader;
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.FileReader;
+import java.io.FileWriter;
+import java.io.IOException;
+
+import eu.svjatoslav.commons.file.FilePathParser;
+import eu.svjatoslav.commons.string.CuttableString;
+import eu.svjatoslav.commons.string.WildCardMatcher;
+import eu.svjatoslav.meviz.Module;
+
+public class Main implements Module {
+
+ public static final int targetLineLength = 200;
+
+ public static final int maxSplittedLines = 3;
+
+ public static final String splitLinePrefix = " ";
+
+ CommandlineHandler commandlineHandler = new CommandlineHandler();
+
+ TextSplittingOptions options;
+
+ public boolean fileMatchesInputPattern(final File file) {
+ final String fileName = file.getName().toLowerCase();
+
+ for (final String inputPattern : options.inputPatterns)
+ if (WildCardMatcher.match(fileName, inputPattern.toLowerCase()))
+ return true;
+
+ return false;
+ }
+
+ @Override
+ public String getDescription() {
+ return "Split text with long lines into multiple shorter lines.";
+ }
+
+ @Override
+ public String getModuleCommand() {
+ return "splittext";
+ }
+
+ private File getTargetFile(final File sourceFile) {
+ final StringBuffer targetFilePath = new StringBuffer();
+ targetFilePath.append(sourceFile.getParent());
+ targetFilePath.append("/");
+ targetFilePath.append(FilePathParser
+ .getFileNameWithoutExtension(sourceFile));
+
+ targetFilePath.append(".fixedLengh");
+
+ // add file extension
+ {
+ final String fileExtension = FilePathParser
+ .getFileExtension(sourceFile);
+
+ if (fileExtension.length() > 0)
+ targetFilePath.append("." + fileExtension);
+ }
+ return new File(targetFilePath.toString());
+ }
+
+ public void processDirectory(final File directory) {
+
+ for (final File subFile : directory.listFiles())
+ if (subFile.isDirectory()) {
+ if (options.recursive)
+ processDirectory(subFile);
+ } else if (fileMatchesInputPattern(subFile))
+ try {
+ processFile(subFile);
+ } catch (final IOException exception) {
+ System.out.println("Error processing file: "
+ + subFile.getAbsolutePath());
+ System.out.println(" exception: "
+ + exception.getMessage());
+ }
+
+ }
+
+ public void processFile(final File file) throws IOException {
+ final File targetFile = getTargetFile(file);
+
+ final BufferedReader bufferedReader = new BufferedReader(
+ new FileReader(file));
+
+ final BufferedWriter bufferedWriter = new BufferedWriter(
+ new FileWriter(targetFile));
+
+ while (true) {
+ final String readLine = bufferedReader.readLine();
+ if (readLine == null)
+ break;
+
+ if (readLine.length() <= targetLineLength)
+ bufferedWriter.write(readLine + "\n");
+ else {
+
+ final CuttableString cuttableString = new CuttableString(
+ readLine);
+
+ bufferedWriter.write(cuttableString.cutLeft(targetLineLength)
+ + "\n");
+
+ int splittedLinesCount = 0;
+
+ while (!cuttableString.isEmpty()) {
+ splittedLinesCount++;
+ if (splittedLinesCount >= maxSplittedLines)
+ break;
+
+ bufferedWriter.write(splitLinePrefix
+ + cuttableString.cutLeft(targetLineLength
+ - splitLinePrefix.length()) + "\n");
+ }
+ }
+
+ }
+
+ bufferedReader.close();
+ bufferedWriter.close();
+ }
+
+ @Override
+ public void run(final String[] args) throws IOException {
+
+ options = commandlineHandler.parseCommandlineArguments(args);
+
+ if (options == null) {
+ showCommandlineHelp();
+ return;
+ }
+
+ processDirectory(options.targetDirectory);
+
+ }
+
+ @Override
+ public void showCommandlineHelp() {
+ commandlineHandler.initParser().showHelp();
+ }
+
+}
--- /dev/null
+/*
+ * Meviz - Various tools collection to work with multimedia.
+ * Copyright (C) 2012, Svjatoslav Agejenko, svjatoslav@svjatoslav.eu
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of version 2 of the GNU General Public License
+ * as published by the Free Software Foundation.
+ */
+
+package eu.svjatoslav.meviz.textsplitter;
+
+import java.io.File;
+import java.util.ArrayList;
+
+public class TextSplittingOptions {
+
+ public ArrayList<String> inputPatterns = new ArrayList<String>();
+
+ public boolean recursive = false;
+
+ public boolean testOnly = false;
+
+ public String outputPattern;
+
+ public File targetDirectory;
+
+}
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd" >
+<log4j:configuration>
+ <appender name="stdout" class="org.apache.log4j.ConsoleAppender">
+ <layout class="org.apache.log4j.PatternLayout">
+ <param name="ConversionPattern" value="%d{ABSOLUTE}
+ %5p %c{1}:%L - %m%n" />
+
+ </layout>
+ </appender>
+ <root>
+ <priority value="info"></priority>
+ <!-- <priority value="debug"></priority> -->
+ <appender-ref ref="stdout" />
+ </root>
+</log4j:configuration>
\ No newline at end of file