AOT Builds
This commit is contained in:
commit
f7573e95e4
12
.config/dotnet-tools.json
Normal file
12
.config/dotnet-tools.json
Normal file
@ -0,0 +1,12 @@
|
||||
{
|
||||
"version": 1,
|
||||
"isRoot": true,
|
||||
"tools": {
|
||||
"deadcsharp": {
|
||||
"version": "2.0.0",
|
||||
"commands": [
|
||||
"dead-csharp"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
263
.editorconfig
Normal file
263
.editorconfig
Normal file
@ -0,0 +1,263 @@
|
||||
[*.md]
|
||||
end_of_line = crlf
|
||||
file_header_template = unset
|
||||
indent_size = 2
|
||||
indent_style = space
|
||||
insert_final_newline = false
|
||||
root = true
|
||||
tab_width = 2
|
||||
[*.cs]
|
||||
csharp_indent_block_contents = true
|
||||
csharp_indent_braces = false
|
||||
csharp_indent_case_contents = true
|
||||
csharp_indent_case_contents_when_block = true
|
||||
csharp_indent_labels = one_less_than_current
|
||||
csharp_indent_switch_labels = true
|
||||
csharp_new_line_before_catch = true
|
||||
csharp_new_line_before_else = true
|
||||
csharp_new_line_before_finally = true
|
||||
csharp_new_line_before_members_in_anonymous_types = true
|
||||
csharp_new_line_before_members_in_object_initializers = true
|
||||
csharp_new_line_before_open_brace = all
|
||||
csharp_new_line_between_query_expression_clauses = true
|
||||
csharp_prefer_braces = false
|
||||
csharp_prefer_qualified_reference = true:error
|
||||
csharp_prefer_simple_default_expression = true:warning
|
||||
csharp_prefer_simple_using_statement = true:warning
|
||||
csharp_prefer_static_local_function = true:warning
|
||||
csharp_preferred_modifier_order = public,private,protected,internal,static,extern,new,virtual,abstract,sealed,override,readonly,unsafe,volatile,async
|
||||
csharp_preserve_single_line_blocks = true
|
||||
csharp_preserve_single_line_statements = false
|
||||
csharp_space_after_cast = false
|
||||
csharp_space_after_colon_in_inheritance_clause = true
|
||||
csharp_space_after_comma = true
|
||||
csharp_space_after_dot = false
|
||||
csharp_space_after_keywords_in_control_flow_statements = true
|
||||
csharp_space_after_semicolon_in_for_statement = true
|
||||
csharp_space_around_binary_operators = before_and_after
|
||||
csharp_space_around_declaration_statements = false
|
||||
csharp_space_before_colon_in_inheritance_clause = true
|
||||
csharp_space_before_comma = false
|
||||
csharp_space_before_dot = false
|
||||
csharp_space_before_open_square_brackets = false
|
||||
csharp_space_before_semicolon_in_for_statement = false
|
||||
csharp_space_between_empty_square_brackets = false
|
||||
csharp_space_between_method_call_empty_parameter_list_parentheses = false
|
||||
csharp_space_between_method_call_name_and_opening_parenthesis = false
|
||||
csharp_space_between_method_call_parameter_list_parentheses = false
|
||||
csharp_space_between_method_declaration_empty_parameter_list_parentheses = false
|
||||
csharp_space_between_method_declaration_name_and_open_parenthesis = false
|
||||
csharp_space_between_method_declaration_parameter_list_parentheses = false
|
||||
csharp_space_between_parentheses = false
|
||||
csharp_space_between_square_brackets = false
|
||||
csharp_style_allow_blank_line_after_colon_in_constructor_initializer_experimental = true
|
||||
csharp_style_allow_blank_lines_between_consecutive_braces_experimental = true
|
||||
csharp_style_allow_embedded_statements_on_same_line_experimental = true
|
||||
csharp_style_conditional_delegate_call = true
|
||||
csharp_style_deconstructed_variable_declaration = false
|
||||
csharp_style_expression_bodied_accessors = when_on_single_line:warning
|
||||
csharp_style_expression_bodied_constructors = when_on_single_line:warning
|
||||
csharp_style_expression_bodied_indexers = when_on_single_line:warning
|
||||
csharp_style_expression_bodied_lambdas = when_on_single_line:warning
|
||||
csharp_style_expression_bodied_local_functions = when_on_single_line:warning
|
||||
csharp_style_expression_bodied_methods = when_on_single_line:warning
|
||||
csharp_style_expression_bodied_operators = when_on_single_line:warning
|
||||
csharp_style_expression_bodied_properties = when_on_single_line:warning
|
||||
csharp_style_implicit_object_creation_when_type_is_apparent = true:warning
|
||||
csharp_style_inlined_variable_declaration = false
|
||||
csharp_style_namespace_declarations = file_scoped:warning
|
||||
csharp_style_pattern_local_over_anonymous_function = true:warning
|
||||
csharp_style_pattern_matching_over_as_with_null_check = true:warning
|
||||
csharp_style_pattern_matching_over_is_with_cast_check = true:warning
|
||||
csharp_style_prefer_index_operator = true:warning
|
||||
csharp_style_prefer_not_pattern = true:warning
|
||||
csharp_style_prefer_null_check_over_type_check = true
|
||||
csharp_style_prefer_pattern_matching = true:warning
|
||||
csharp_style_prefer_range_operator = true:warning
|
||||
csharp_style_prefer_switch_expression = true:warning
|
||||
csharp_style_throw_expression = true
|
||||
csharp_style_unused_value_assignment_preference = discard_variable:warning
|
||||
csharp_style_unused_value_expression_statement_preference = discard_variable:warning
|
||||
csharp_style_var_elsewhere = false:warning
|
||||
csharp_style_var_for_built_in_types = false:warning
|
||||
csharp_style_var_when_type_is_apparent = false:warning
|
||||
csharp_using_directive_placement = outside_namespace
|
||||
dotnet_code_quality_unused_parameters = all
|
||||
dotnet_code_quality_unused_parameters = non_public # IDE0060: Remove unused parameter
|
||||
dotnet_code_quality.CAXXXX.api_surface = private, internal
|
||||
dotnet_diagnostic.CA1825.severity = warning # CA1823: Avoid zero-length array allocations
|
||||
dotnet_diagnostic.CA1829.severity = warning # CA1829: Use Length/Count property instead of Count() when available
|
||||
dotnet_diagnostic.CA1834.severity = warning # CA1834: Consider using 'StringBuilder.Append(char)' when applicable
|
||||
dotnet_diagnostic.CA1860.severity = error # CA1860: Prefer comparing 'Count' to 0 rather than using 'Any()', both for clarity and for performance
|
||||
dotnet_diagnostic.CA1869.severity = none # CA1869: Avoid creating a new 'JsonSerializerOptions' instance for every serialization operation. Cache and reuse instances instead.
|
||||
dotnet_diagnostic.CA2254.severity = none # CA2254: The logging message template should not vary between calls to 'LoggerExtensions.LogInformation(ILogger, string?, params object?[])'
|
||||
dotnet_diagnostic.IDE0001.severity = warning # IDE0001: Simplify name
|
||||
dotnet_diagnostic.IDE0002.severity = warning # Simplify (member access) - System.Version.Equals("1", "2"); Version.Equals("1", "2");
|
||||
dotnet_diagnostic.IDE0004.severity = warning # IDE0004: Cast is redundant.
|
||||
dotnet_diagnostic.IDE0005.severity = warning # Using directive is unnecessary
|
||||
dotnet_diagnostic.IDE0028.severity = error # IDE0028: Collection initialization can be simplified
|
||||
dotnet_diagnostic.IDE0031.severity = warning # Use null propagation (IDE0031)
|
||||
dotnet_diagnostic.IDE0047.severity = warning # IDE0047: Parentheses can be removed
|
||||
dotnet_diagnostic.IDE0049.severity = warning # Use language keywords instead of framework type names for type references (IDE0049)
|
||||
dotnet_diagnostic.IDE0060.severity = warning # IDE0060: Remove unused parameter
|
||||
dotnet_diagnostic.IDE0290.severity = none # Use primary constructor [Distance]csharp(IDE0290)
|
||||
dotnet_diagnostic.IDE0300.severity = error # IDE0300: Collection initialization can be simplified
|
||||
dotnet_diagnostic.IDE0301.severity = error #IDE0301: Collection initialization can be simplified
|
||||
dotnet_diagnostic.IDE0305.severity = none # IDE0305: Collection initialization can be simplified
|
||||
dotnet_naming_rule.abstract_method_should_be_pascal_case.severity = warning
|
||||
dotnet_naming_rule.abstract_method_should_be_pascal_case.style = pascal_case
|
||||
dotnet_naming_rule.abstract_method_should_be_pascal_case.symbols = abstract_method
|
||||
dotnet_naming_rule.class_should_be_pascal_case.severity = warning
|
||||
dotnet_naming_rule.class_should_be_pascal_case.style = pascal_case
|
||||
dotnet_naming_rule.class_should_be_pascal_case.symbols = class
|
||||
dotnet_naming_rule.delegate_should_be_pascal_case.severity = warning
|
||||
dotnet_naming_rule.delegate_should_be_pascal_case.style = pascal_case
|
||||
dotnet_naming_rule.delegate_should_be_pascal_case.symbols = delegate
|
||||
dotnet_naming_rule.enum_should_be_pascal_case.severity = warning
|
||||
dotnet_naming_rule.enum_should_be_pascal_case.style = pascal_case
|
||||
dotnet_naming_rule.enum_should_be_pascal_case.symbols = enum
|
||||
dotnet_naming_rule.event_should_be_pascal_case.severity = warning
|
||||
dotnet_naming_rule.event_should_be_pascal_case.style = pascal_case
|
||||
dotnet_naming_rule.event_should_be_pascal_case.symbols = event
|
||||
dotnet_naming_rule.interface_should_be_begins_with_i.severity = warning
|
||||
dotnet_naming_rule.interface_should_be_begins_with_i.style = begins_with_i
|
||||
dotnet_naming_rule.interface_should_be_begins_with_i.symbols = interface
|
||||
dotnet_naming_rule.method_should_be_pascal_case.severity = warning
|
||||
dotnet_naming_rule.method_should_be_pascal_case.style = pascal_case
|
||||
dotnet_naming_rule.method_should_be_pascal_case.symbols = method
|
||||
dotnet_naming_rule.non_field_members_should_be_pascal_case.severity = warning
|
||||
dotnet_naming_rule.non_field_members_should_be_pascal_case.style = pascal_case
|
||||
dotnet_naming_rule.non_field_members_should_be_pascal_case.symbols = non_field_members
|
||||
dotnet_naming_rule.private_method_should_be_pascal_case.severity = warning
|
||||
dotnet_naming_rule.private_method_should_be_pascal_case.style = pascal_case
|
||||
dotnet_naming_rule.private_method_should_be_pascal_case.symbols = private_method
|
||||
dotnet_naming_rule.private_or_internal_field_should_be_private_of_internal_field.severity = warning
|
||||
dotnet_naming_rule.private_or_internal_field_should_be_private_of_internal_field.style = private_of_internal_field
|
||||
dotnet_naming_rule.private_or_internal_field_should_be_private_of_internal_field.symbols = private_or_internal_field
|
||||
dotnet_naming_rule.private_or_internal_static_field_should_be_private_of_internal_field.severity = warning
|
||||
dotnet_naming_rule.private_or_internal_static_field_should_be_private_of_internal_field.style = private_of_internal_field
|
||||
dotnet_naming_rule.private_or_internal_static_field_should_be_private_of_internal_field.symbols = private_or_internal_static_field
|
||||
dotnet_naming_rule.property_should_be_pascal_case.severity = warning
|
||||
dotnet_naming_rule.property_should_be_pascal_case.style = pascal_case
|
||||
dotnet_naming_rule.property_should_be_pascal_case.symbols = property
|
||||
dotnet_naming_rule.public_or_protected_field_should_be_private_of_internal_field.severity = warning
|
||||
dotnet_naming_rule.public_or_protected_field_should_be_private_of_internal_field.style = private_of_internal_field
|
||||
dotnet_naming_rule.public_or_protected_field_should_be_private_of_internal_field.symbols = public_or_protected_field
|
||||
dotnet_naming_rule.static_field_should_be_pascal_case.severity = warning
|
||||
dotnet_naming_rule.static_field_should_be_pascal_case.style = pascal_case
|
||||
dotnet_naming_rule.static_field_should_be_pascal_case.symbols = static_field
|
||||
dotnet_naming_rule.static_method_should_be_pascal_case.severity = warning
|
||||
dotnet_naming_rule.static_method_should_be_pascal_case.style = pascal_case
|
||||
dotnet_naming_rule.static_method_should_be_pascal_case.symbols = static_method
|
||||
dotnet_naming_rule.struct_should_be_pascal_case.severity = warning
|
||||
dotnet_naming_rule.struct_should_be_pascal_case.style = pascal_case
|
||||
dotnet_naming_rule.struct_should_be_pascal_case.symbols = struct
|
||||
dotnet_naming_rule.types_should_be_pascal_case.severity = warning
|
||||
dotnet_naming_rule.types_should_be_pascal_case.style = pascal_case
|
||||
dotnet_naming_rule.types_should_be_pascal_case.symbols = types
|
||||
dotnet_naming_style.begins_with_i.capitalization = pascal_case
|
||||
dotnet_naming_style.begins_with_i.required_prefix = I
|
||||
dotnet_naming_style.begins_with_i.required_suffix =
|
||||
dotnet_naming_style.begins_with_i.word_separator =
|
||||
dotnet_naming_style.pascal_case.capitalization = pascal_case
|
||||
dotnet_naming_style.pascal_case.required_prefix =
|
||||
dotnet_naming_style.pascal_case.required_suffix =
|
||||
dotnet_naming_style.pascal_case.word_separator =
|
||||
dotnet_naming_style.private_of_internal_field.capitalization = pascal_case
|
||||
dotnet_naming_style.private_of_internal_field.required_prefix = _
|
||||
dotnet_naming_style.private_of_internal_field.required_suffix =
|
||||
dotnet_naming_style.private_of_internal_field.word_separator =
|
||||
dotnet_naming_symbols.abstract_method.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected
|
||||
dotnet_naming_symbols.abstract_method.applicable_kinds = method
|
||||
dotnet_naming_symbols.abstract_method.required_modifiers = abstract
|
||||
dotnet_naming_symbols.class.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected
|
||||
dotnet_naming_symbols.class.applicable_kinds = class
|
||||
dotnet_naming_symbols.class.required_modifiers =
|
||||
dotnet_naming_symbols.delegate.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected
|
||||
dotnet_naming_symbols.delegate.applicable_kinds = delegate
|
||||
dotnet_naming_symbols.delegate.required_modifiers =
|
||||
dotnet_naming_symbols.enum.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected
|
||||
dotnet_naming_symbols.enum.applicable_kinds = enum
|
||||
dotnet_naming_symbols.enum.required_modifiers =
|
||||
dotnet_naming_symbols.event.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected
|
||||
dotnet_naming_symbols.event.applicable_kinds = event
|
||||
dotnet_naming_symbols.event.required_modifiers =
|
||||
dotnet_naming_symbols.interface.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected
|
||||
dotnet_naming_symbols.interface.applicable_kinds = interface
|
||||
dotnet_naming_symbols.interface.required_modifiers =
|
||||
dotnet_naming_symbols.method.applicable_accessibilities = public
|
||||
dotnet_naming_symbols.method.applicable_kinds = method
|
||||
dotnet_naming_symbols.method.required_modifiers =
|
||||
dotnet_naming_symbols.non_field_members.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected
|
||||
dotnet_naming_symbols.non_field_members.applicable_kinds = property, event, method
|
||||
dotnet_naming_symbols.non_field_members.required_modifiers =
|
||||
dotnet_naming_symbols.private_method.applicable_accessibilities = private
|
||||
dotnet_naming_symbols.private_method.applicable_kinds = method
|
||||
dotnet_naming_symbols.private_method.required_modifiers =
|
||||
dotnet_naming_symbols.private_or_internal_field.applicable_accessibilities = internal, private, private_protected
|
||||
dotnet_naming_symbols.private_or_internal_field.applicable_kinds = field
|
||||
dotnet_naming_symbols.private_or_internal_field.required_modifiers =
|
||||
dotnet_naming_symbols.private_or_internal_static_field.applicable_accessibilities = internal, private, private_protected
|
||||
dotnet_naming_symbols.private_or_internal_static_field.applicable_kinds = field
|
||||
dotnet_naming_symbols.private_or_internal_static_field.required_modifiers = static
|
||||
dotnet_naming_symbols.property.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected
|
||||
dotnet_naming_symbols.property.applicable_kinds = property
|
||||
dotnet_naming_symbols.property.required_modifiers =
|
||||
dotnet_naming_symbols.public_or_protected_field.applicable_accessibilities = public, protected
|
||||
dotnet_naming_symbols.public_or_protected_field.applicable_kinds = field
|
||||
dotnet_naming_symbols.public_or_protected_field.required_modifiers =
|
||||
dotnet_naming_symbols.static_field.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected
|
||||
dotnet_naming_symbols.static_field.applicable_kinds = field
|
||||
dotnet_naming_symbols.static_field.required_modifiers = static
|
||||
dotnet_naming_symbols.static_method.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected
|
||||
dotnet_naming_symbols.static_method.applicable_kinds = method
|
||||
dotnet_naming_symbols.static_method.required_modifiers = static
|
||||
dotnet_naming_symbols.struct.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected
|
||||
dotnet_naming_symbols.struct.applicable_kinds = struct
|
||||
dotnet_naming_symbols.struct.required_modifiers =
|
||||
dotnet_naming_symbols.types.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected
|
||||
dotnet_naming_symbols.types.applicable_kinds = class, struct, interface, enum
|
||||
dotnet_naming_symbols.types.required_modifiers =
|
||||
dotnet_remove_unnecessary_suppression_exclusions = 0
|
||||
dotnet_separate_import_directive_groups = false
|
||||
dotnet_sort_system_directives_first = false
|
||||
dotnet_style_allow_multiple_blank_lines_experimental = false:warning
|
||||
dotnet_style_allow_statement_immediately_after_block_experimental = true
|
||||
dotnet_style_coalesce_expression = true
|
||||
dotnet_style_collection_initializer = true:warning
|
||||
dotnet_style_explicit_tuple_names = true:warning
|
||||
dotnet_style_namespace_match_folder = true
|
||||
dotnet_style_null_propagation = true:warning
|
||||
dotnet_style_object_initializer = true:warning
|
||||
dotnet_style_operator_placement_when_wrapping = beginning_of_line
|
||||
dotnet_style_parentheses_in_arithmetic_binary_operators = always_for_clarity
|
||||
dotnet_style_parentheses_in_other_binary_operators = always_for_clarity
|
||||
dotnet_style_parentheses_in_other_operators = never_if_unnecessary
|
||||
dotnet_style_parentheses_in_relational_binary_operators = always_for_clarity
|
||||
dotnet_style_predefined_type_for_locals_parameters_members = true
|
||||
dotnet_style_predefined_type_for_member_access = true:warning
|
||||
dotnet_style_prefer_auto_properties = true:warning
|
||||
dotnet_style_prefer_compound_assignment = true:warning
|
||||
dotnet_style_prefer_conditional_expression_over_assignment = false
|
||||
dotnet_style_prefer_conditional_expression_over_return = false
|
||||
dotnet_style_prefer_inferred_anonymous_type_member_names = true:warning
|
||||
dotnet_style_prefer_inferred_tuple_names = true:warning
|
||||
dotnet_style_prefer_is_null_check_over_reference_equality_method = true:warning
|
||||
dotnet_style_prefer_simplified_boolean_expressions = true:warning
|
||||
dotnet_style_prefer_simplified_interpolation = true
|
||||
dotnet_style_qualification_for_event = false:error
|
||||
dotnet_style_qualification_for_field = false
|
||||
dotnet_style_qualification_for_method = false:error
|
||||
dotnet_style_qualification_for_property = false:error
|
||||
dotnet_style_readonly_field = true:warning
|
||||
dotnet_style_require_accessibility_modifiers = for_non_interface_members
|
||||
end_of_line = crlf
|
||||
file_header_template = unset
|
||||
indent_size = 4
|
||||
indent_style = space
|
||||
insert_final_newline = false
|
||||
root = true
|
||||
tab_width = 4
|
||||
# https://docs.microsoft.com/en-us/dotnet/fundamentals/code-analysis/quality-rules/ca1822
|
||||
# https://github.com/dotnet/aspnetcore/blob/main/.editorconfig
|
||||
# https://github.com/dotnet/project-system/blob/main/.editorconfig
|
470
.gitignore
vendored
Normal file
470
.gitignore
vendored
Normal file
@ -0,0 +1,470 @@
|
||||
## Ignore Visual Studio temporary files, build results, and
|
||||
## files generated by popular Visual Studio add-ons.
|
||||
##
|
||||
## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore
|
||||
|
||||
# User-specific files
|
||||
*.rsuser
|
||||
*.suo
|
||||
*.user
|
||||
*.userosscache
|
||||
*.sln.docstates
|
||||
|
||||
# User-specific files (MonoDevelop/Xamarin Studio)
|
||||
*.userprefs
|
||||
|
||||
# Mono auto generated files
|
||||
mono_crash.*
|
||||
|
||||
# Build results
|
||||
[Dd]ebug/
|
||||
[Dd]ebugPublic/
|
||||
[Rr]elease/
|
||||
[Rr]eleases/
|
||||
x64/
|
||||
x86/
|
||||
[Ww][Ii][Nn]32/
|
||||
[Aa][Rr][Mm]/
|
||||
[Aa][Rr][Mm]64/
|
||||
bld/
|
||||
[Bb]in/
|
||||
[Oo]bj/
|
||||
[Ll]og/
|
||||
[Ll]ogs/
|
||||
|
||||
# Visual Studio 2015/2017 cache/options directory
|
||||
.vs/
|
||||
# Uncomment if you have tasks that create the project's static files in wwwroot
|
||||
#wwwroot/
|
||||
|
||||
# Visual Studio 2017 auto generated files
|
||||
Generated\ Files/
|
||||
|
||||
# MSTest test Results
|
||||
[Tt]est[Rr]esult*/
|
||||
[Bb]uild[Ll]og.*
|
||||
|
||||
# NUnit
|
||||
*.VisualState.xml
|
||||
TestResult.xml
|
||||
nunit-*.xml
|
||||
|
||||
# Build Results of an ATL Project
|
||||
[Dd]ebugPS/
|
||||
[Rr]eleasePS/
|
||||
dlldata.c
|
||||
|
||||
# Benchmark Results
|
||||
BenchmarkDotNet.Artifacts/
|
||||
|
||||
# .NET Core
|
||||
project.lock.json
|
||||
project.fragment.lock.json
|
||||
artifacts/
|
||||
|
||||
# Tye
|
||||
.tye/
|
||||
|
||||
# ASP.NET Scaffolding
|
||||
ScaffoldingReadMe.txt
|
||||
|
||||
# StyleCop
|
||||
StyleCopReport.xml
|
||||
|
||||
# Files built by Visual Studio
|
||||
*_i.c
|
||||
*_p.c
|
||||
*_h.h
|
||||
*.ilk
|
||||
*.meta
|
||||
*.obj
|
||||
*.iobj
|
||||
*.pch
|
||||
*.pdb
|
||||
*.ipdb
|
||||
*.pgc
|
||||
*.pgd
|
||||
*.rsp
|
||||
*.sbr
|
||||
*.tlb
|
||||
*.tli
|
||||
*.tlh
|
||||
*.tmp
|
||||
*.tmp_proj
|
||||
*_wpftmp.csproj
|
||||
*.log
|
||||
*.vspscc
|
||||
*.vssscc
|
||||
.builds
|
||||
*.pidb
|
||||
*.svclog
|
||||
*.scc
|
||||
|
||||
# Chutzpah Test files
|
||||
_Chutzpah*
|
||||
|
||||
# Visual C++ cache files
|
||||
ipch/
|
||||
*.aps
|
||||
*.ncb
|
||||
*.opendb
|
||||
*.opensdf
|
||||
*.sdf
|
||||
*.cachefile
|
||||
*.VC.db
|
||||
*.VC.VC.opendb
|
||||
|
||||
# Visual Studio profiler
|
||||
*.psess
|
||||
*.vsp
|
||||
*.vspx
|
||||
*.sap
|
||||
|
||||
# Visual Studio Trace Files
|
||||
*.e2e
|
||||
|
||||
# TFS 2012 Local Workspace
|
||||
$tf/
|
||||
|
||||
# Guidance Automation Toolkit
|
||||
*.gpState
|
||||
|
||||
# ReSharper is a .NET coding add-in
|
||||
_ReSharper*/
|
||||
*.[Rr]e[Ss]harper
|
||||
*.DotSettings.user
|
||||
|
||||
# TeamCity is a build add-in
|
||||
_TeamCity*
|
||||
|
||||
# DotCover is a Code Coverage Tool
|
||||
*.dotCover
|
||||
|
||||
# AxoCover is a Code Coverage Tool
|
||||
.axoCover/*
|
||||
!.axoCover/settings.json
|
||||
|
||||
# Coverlet is a free, cross platform Code Coverage Tool
|
||||
coverage*.json
|
||||
coverage*.xml
|
||||
coverage*.info
|
||||
|
||||
# Visual Studio code coverage results
|
||||
*.coverage
|
||||
*.coveragexml
|
||||
|
||||
# NCrunch
|
||||
_NCrunch_*
|
||||
.*crunch*.local.xml
|
||||
nCrunchTemp_*
|
||||
|
||||
# MightyMoose
|
||||
*.mm.*
|
||||
AutoTest.Net/
|
||||
|
||||
# Web workbench (sass)
|
||||
.sass-cache/
|
||||
|
||||
# Installshield output folder
|
||||
[Ee]xpress/
|
||||
|
||||
# DocProject is a documentation generator add-in
|
||||
DocProject/buildhelp/
|
||||
DocProject/Help/*.HxT
|
||||
DocProject/Help/*.HxC
|
||||
DocProject/Help/*.hhc
|
||||
DocProject/Help/*.hhk
|
||||
DocProject/Help/*.hhp
|
||||
DocProject/Help/Html2
|
||||
DocProject/Help/html
|
||||
|
||||
# Click-Once directory
|
||||
publish/
|
||||
|
||||
# Publish Web Output
|
||||
*.[Pp]ublish.xml
|
||||
*.azurePubxml
|
||||
# Note: Comment the next line if you want to checkin your web deploy settings,
|
||||
# but database connection strings (with potential passwords) will be unencrypted
|
||||
*.pubxml
|
||||
*.publishproj
|
||||
|
||||
# Microsoft Azure Web App publish settings. Comment the next line if you want to
|
||||
# checkin your Azure Web App publish settings, but sensitive information contained
|
||||
# in these scripts will be unencrypted
|
||||
PublishScripts/
|
||||
|
||||
# NuGet Packages
|
||||
*.nupkg
|
||||
# NuGet Symbol Packages
|
||||
*.snupkg
|
||||
# The packages folder can be ignored because of Package Restore
|
||||
**/[Pp]ackages/*
|
||||
# except build/, which is used as an MSBuild target.
|
||||
!**/[Pp]ackages/build/
|
||||
# Uncomment if necessary however generally it will be regenerated when needed
|
||||
#!**/[Pp]ackages/repositories.config
|
||||
# NuGet v3's project.json files produces more ignorable files
|
||||
*.nuget.props
|
||||
*.nuget.targets
|
||||
|
||||
# Microsoft Azure Build Output
|
||||
csx/
|
||||
*.build.csdef
|
||||
|
||||
# Microsoft Azure Emulator
|
||||
ecf/
|
||||
rcf/
|
||||
|
||||
# Windows Store app package directories and files
|
||||
AppPackages/
|
||||
BundleArtifacts/
|
||||
Package.StoreAssociation.xml
|
||||
_pkginfo.txt
|
||||
*.appx
|
||||
*.appxbundle
|
||||
*.appxupload
|
||||
|
||||
# Visual Studio cache files
|
||||
# files ending in .cache can be ignored
|
||||
*.[Cc]ache
|
||||
# but keep track of directories ending in .cache
|
||||
!?*.[Cc]ache/
|
||||
|
||||
# Others
|
||||
ClientBin/
|
||||
~$*
|
||||
*~
|
||||
*.dbmdl
|
||||
*.dbproj.schemaview
|
||||
*.jfm
|
||||
*.pfx
|
||||
*.publishsettings
|
||||
orleans.codegen.cs
|
||||
|
||||
# Including strong name files can present a security risk
|
||||
# (https://github.com/github/gitignore/pull/2483#issue-259490424)
|
||||
#*.snk
|
||||
|
||||
# Since there are multiple workflows, uncomment next line to ignore bower_components
|
||||
# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
|
||||
#bower_components/
|
||||
|
||||
# RIA/Silverlight projects
|
||||
Generated_Code/
|
||||
|
||||
# Backup & report files from converting an old project file
|
||||
# to a newer Visual Studio version. Backup files are not needed,
|
||||
# because we have git ;-)
|
||||
_UpgradeReport_Files/
|
||||
Backup*/
|
||||
UpgradeLog*.XML
|
||||
UpgradeLog*.htm
|
||||
ServiceFabricBackup/
|
||||
*.rptproj.bak
|
||||
|
||||
# SQL Server files
|
||||
*.mdf
|
||||
*.ldf
|
||||
*.ndf
|
||||
|
||||
# Business Intelligence projects
|
||||
*.rdl.data
|
||||
*.bim.layout
|
||||
*.bim_*.settings
|
||||
*.rptproj.rsuser
|
||||
*- [Bb]ackup.rdl
|
||||
*- [Bb]ackup ([0-9]).rdl
|
||||
*- [Bb]ackup ([0-9][0-9]).rdl
|
||||
|
||||
# Microsoft Fakes
|
||||
FakesAssemblies/
|
||||
|
||||
# GhostDoc plugin setting file
|
||||
*.GhostDoc.xml
|
||||
|
||||
# Node.js Tools for Visual Studio
|
||||
.ntvs_analysis.dat
|
||||
node_modules/
|
||||
|
||||
# Visual Studio 6 build log
|
||||
*.plg
|
||||
|
||||
# Visual Studio 6 workspace options file
|
||||
*.opt
|
||||
|
||||
# Visual Studio 6 auto-generated workspace file (contains which files were open etc.)
|
||||
*.vbw
|
||||
|
||||
# Visual Studio LightSwitch build output
|
||||
**/*.HTMLClient/GeneratedArtifacts
|
||||
**/*.DesktopClient/GeneratedArtifacts
|
||||
**/*.DesktopClient/ModelManifest.xml
|
||||
**/*.Server/GeneratedArtifacts
|
||||
**/*.Server/ModelManifest.xml
|
||||
_Pvt_Extensions
|
||||
|
||||
# Paket dependency manager
|
||||
.paket/paket.exe
|
||||
paket-files/
|
||||
|
||||
# FAKE - F# Make
|
||||
.fake/
|
||||
|
||||
# CodeRush personal settings
|
||||
.cr/personal
|
||||
|
||||
# Python Tools for Visual Studio (PTVS)
|
||||
__pycache__/
|
||||
*.pyc
|
||||
|
||||
# Cake - Uncomment if you are using it
|
||||
# tools/**
|
||||
# !tools/packages.config
|
||||
|
||||
# Tabs Studio
|
||||
*.tss
|
||||
|
||||
# Telerik's JustMock configuration file
|
||||
*.jmconfig
|
||||
|
||||
# BizTalk build output
|
||||
*.btp.cs
|
||||
*.btm.cs
|
||||
*.odx.cs
|
||||
*.xsd.cs
|
||||
|
||||
# OpenCover UI analysis results
|
||||
OpenCover/
|
||||
|
||||
# Azure Stream Analytics local run output
|
||||
ASALocalRun/
|
||||
|
||||
# MSBuild Binary and Structured Log
|
||||
*.binlog
|
||||
|
||||
# NVidia Nsight GPU debugger configuration file
|
||||
*.nvuser
|
||||
|
||||
# MFractors (Xamarin productivity tool) working folder
|
||||
.mfractor/
|
||||
|
||||
# Local History for Visual Studio
|
||||
.localhistory/
|
||||
|
||||
# BeatPulse healthcheck temp database
|
||||
healthchecksdb
|
||||
|
||||
# Backup folder for Package Reference Convert tool in Visual Studio 2017
|
||||
MigrationBackup/
|
||||
|
||||
# Ionide (cross platform F# VS Code tools) working folder
|
||||
.ionide/
|
||||
|
||||
# Fody - auto-generated XML schema
|
||||
FodyWeavers.xsd
|
||||
|
||||
##
|
||||
## Visual studio for Mac
|
||||
##
|
||||
|
||||
|
||||
# globs
|
||||
Makefile.in
|
||||
*.userprefs
|
||||
*.usertasks
|
||||
config.make
|
||||
config.status
|
||||
aclocal.m4
|
||||
install-sh
|
||||
autom4te.cache/
|
||||
*.tar.gz
|
||||
tarballs/
|
||||
test-results/
|
||||
|
||||
# Mac bundle stuff
|
||||
*.dmg
|
||||
*.app
|
||||
|
||||
# content below from: https://github.com/github/gitignore/blob/master/Global/macOS.gitignore
|
||||
# General
|
||||
.DS_Store
|
||||
.AppleDouble
|
||||
.LSOverride
|
||||
|
||||
# Icon must end with two \r
|
||||
Icon
|
||||
|
||||
|
||||
# Thumbnails
|
||||
._*
|
||||
|
||||
# Files that might appear in the root of a volume
|
||||
.DocumentRevisions-V100
|
||||
.fseventsd
|
||||
.Spotlight-V100
|
||||
.TemporaryItems
|
||||
.Trashes
|
||||
.VolumeIcon.icns
|
||||
.com.apple.timemachine.donotpresent
|
||||
|
||||
# Directories potentially created on remote AFP share
|
||||
.AppleDB
|
||||
.AppleDesktop
|
||||
Network Trash Folder
|
||||
Temporary Items
|
||||
.apdisk
|
||||
|
||||
# content below from: https://github.com/github/gitignore/blob/master/Global/Windows.gitignore
|
||||
# Windows thumbnail cache files
|
||||
Thumbs.db
|
||||
ehthumbs.db
|
||||
ehthumbs_vista.db
|
||||
|
||||
# Dump file
|
||||
*.stackdump
|
||||
|
||||
# Folder config file
|
||||
[Dd]esktop.ini
|
||||
|
||||
# Recycle Bin used on file shares
|
||||
$RECYCLE.BIN/
|
||||
|
||||
# Windows Installer files
|
||||
*.cab
|
||||
*.msi
|
||||
*.msix
|
||||
*.msm
|
||||
*.msp
|
||||
|
||||
# Windows shortcuts
|
||||
*.lnk
|
||||
|
||||
# JetBrains Rider
|
||||
.idea/
|
||||
*.sln.iml
|
||||
|
||||
##
|
||||
## Visual Studio Code
|
||||
##
|
||||
!.vscode/extensions.json
|
||||
!.vscode/launch.json
|
||||
!.vscode/settings.json
|
||||
!.vscode/tasks.json
|
||||
!Instance/.vscode/appsettings.example.json
|
||||
!Rename/.vscode/appsettings.example.json
|
||||
.vscode/helper/**
|
||||
.vscode/Docker/**
|
||||
Shared/.vscode/ged
|
||||
shared/.vscode/helper/**
|
||||
|
||||
#VSCode Settings => mklink /J "VSCode Settings" "C:\Users\phares\AppData\Roaming\Code\User"
|
||||
globalStorage/
|
||||
*workspaceStorage/
|
||||
|
||||
#Auto Gen Code from Code-Generator
|
||||
*.gen
|
||||
|
||||
[Ll]ib/
|
||||
|
||||
Shared/.kanbn
|
9
.prettierignore
Normal file
9
.prettierignore
Normal file
@ -0,0 +1,9 @@
|
||||
|
||||
**/.vscode/*
|
||||
|
||||
[Bb]in/
|
||||
[Oo]bj/
|
||||
|
||||
*.json
|
||||
|
||||
*.zip
|
1
.vscode/format-report.json
vendored
Normal file
1
.vscode/format-report.json
vendored
Normal file
@ -0,0 +1 @@
|
||||
[]
|
566
.vscode/launch.json
vendored
Normal file
566
.vscode/launch.json
vendored
Normal file
@ -0,0 +1,566 @@
|
||||
{
|
||||
"version": "0.2.0",
|
||||
"configurations": [
|
||||
{
|
||||
"name": ".NET Core Attach",
|
||||
"type": "coreclr",
|
||||
"request": "attach"
|
||||
},
|
||||
{
|
||||
"name": "Compare",
|
||||
"type": "coreclr",
|
||||
"request": "launch",
|
||||
"preLaunchTask": "build",
|
||||
"program": "${workspaceFolder}/Compare/bin/Debug/net8.0/win-x64/Compare.dll",
|
||||
"args": [
|
||||
"s"
|
||||
],
|
||||
"env": {
|
||||
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||
},
|
||||
"cwd": "${workspaceFolder}",
|
||||
"console": "integratedTerminal",
|
||||
"stopAtEntry": false,
|
||||
"requireExactSource": false
|
||||
},
|
||||
{
|
||||
"name": "Copy-Distinct",
|
||||
"type": "coreclr",
|
||||
"request": "launch",
|
||||
"preLaunchTask": "build",
|
||||
"program": "${workspaceFolder}/Copy-Distinct/bin/Debug/net8.0/win-x64/Copy-Distinct.dll",
|
||||
"args": [],
|
||||
"env": {
|
||||
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||
},
|
||||
"cwd": "${workspaceFolder}",
|
||||
"console": "integratedTerminal",
|
||||
"stopAtEntry": false,
|
||||
"requireExactSource": false
|
||||
},
|
||||
{
|
||||
"name": "Duplicate-Search",
|
||||
"type": "coreclr",
|
||||
"request": "launch",
|
||||
"preLaunchTask": "build",
|
||||
"program": "${workspaceFolder}/Duplicate-Search/bin/Debug/net8.0/win-x64/Duplicate-Search.dll",
|
||||
"args": [
|
||||
"s"
|
||||
],
|
||||
"env": {
|
||||
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||
},
|
||||
"cwd": "${workspaceFolder}",
|
||||
"console": "integratedTerminal",
|
||||
"stopAtEntry": false,
|
||||
"requireExactSource": false
|
||||
},
|
||||
{
|
||||
"name": "Date-Group",
|
||||
"type": "coreclr",
|
||||
"request": "launch",
|
||||
"preLaunchTask": "build",
|
||||
"program": "${workspaceFolder}/Date-Group/bin/Debug/net8.0/win-x64/Date-Group.dll",
|
||||
"args": [
|
||||
"s"
|
||||
],
|
||||
"env": {
|
||||
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||
},
|
||||
"cwd": "${workspaceFolder}",
|
||||
"console": "integratedTerminal",
|
||||
"stopAtEntry": false,
|
||||
"requireExactSource": false
|
||||
},
|
||||
{
|
||||
"name": "Delete-By-Distinct",
|
||||
"type": "coreclr",
|
||||
"request": "launch",
|
||||
"preLaunchTask": "build",
|
||||
"program": "${workspaceFolder}/Delete-By-Distinct/bin/Debug/net8.0/win-x64/Delete-By-Distinct.dll",
|
||||
"args": [
|
||||
"s"
|
||||
],
|
||||
"env": {
|
||||
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||
},
|
||||
"cwd": "${workspaceFolder}",
|
||||
"console": "integratedTerminal",
|
||||
"stopAtEntry": false,
|
||||
"requireExactSource": false
|
||||
},
|
||||
{
|
||||
"name": "Delete-By-Relative",
|
||||
"type": "coreclr",
|
||||
"request": "launch",
|
||||
"preLaunchTask": "build",
|
||||
"program": "${workspaceFolder}/Delete-By-Relative/bin/Debug/net8.0/win-x64/Delete-By-Relative.dll",
|
||||
"args": [
|
||||
"s"
|
||||
],
|
||||
"env": {
|
||||
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||
},
|
||||
"cwd": "${workspaceFolder}",
|
||||
"console": "integratedTerminal",
|
||||
"stopAtEntry": false,
|
||||
"requireExactSource": false
|
||||
},
|
||||
{
|
||||
"name": "Drag-Drop",
|
||||
"type": "coreclr",
|
||||
"request": "launch",
|
||||
"preLaunchTask": "build",
|
||||
"program": "${workspaceFolder}/Drag-Drop/bin/Debug/net8.0-windows/win-x64/Drag-Drop.dll",
|
||||
"args": [
|
||||
"s"
|
||||
],
|
||||
"env": {
|
||||
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||
},
|
||||
"cwd": "${workspaceFolder}",
|
||||
"console": "integratedTerminal",
|
||||
"stopAtEntry": false,
|
||||
"requireExactSource": false
|
||||
},
|
||||
{
|
||||
"name": "Drag-Drop-Explorer",
|
||||
"type": "coreclr",
|
||||
"request": "launch",
|
||||
"preLaunchTask": "build",
|
||||
"program": "${workspaceFolder}/Drag-Drop-Explorer/bin/Debug/net8.0-windows/win-x64/Drag-Drop-Explorer.dll",
|
||||
"args": [
|
||||
"s"
|
||||
],
|
||||
"env": {
|
||||
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||
},
|
||||
"cwd": "${workspaceFolder}",
|
||||
"console": "integratedTerminal",
|
||||
"stopAtEntry": false,
|
||||
"requireExactSource": false
|
||||
},
|
||||
{
|
||||
"name": "Drag-Drop-Move",
|
||||
"type": "coreclr",
|
||||
"request": "launch",
|
||||
"preLaunchTask": "build",
|
||||
"program": "${workspaceFolder}/Drag-Drop-Move/bin/Debug/net8.0-windows/win-x64/Drag-Drop-Move.dll",
|
||||
"args": [
|
||||
"s"
|
||||
],
|
||||
"env": {
|
||||
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||
},
|
||||
"cwd": "${workspaceFolder}",
|
||||
"console": "integratedTerminal",
|
||||
"stopAtEntry": false,
|
||||
"requireExactSource": false
|
||||
},
|
||||
{
|
||||
"name": "Drag-Drop-Set-Property-Item",
|
||||
"type": "coreclr",
|
||||
"request": "launch",
|
||||
"preLaunchTask": "build",
|
||||
"program": "${workspaceFolder}/Drag-Drop-Set-Property-Item/bin/Debug/net8.0-windows/win-x64/Drag-Drop-Set-Property-Item.dll",
|
||||
"args": [
|
||||
"s"
|
||||
],
|
||||
"env": {
|
||||
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||
},
|
||||
"cwd": "${workspaceFolder}",
|
||||
"console": "integratedTerminal",
|
||||
"stopAtEntry": false,
|
||||
"requireExactSource": false
|
||||
},
|
||||
{
|
||||
"name": "Instance",
|
||||
"type": "coreclr",
|
||||
"request": "launch",
|
||||
"preLaunchTask": "build",
|
||||
"program": "${workspaceFolder}/Instance/bin/Debug/net8.0/win-x64/Instance.dll",
|
||||
"args": [
|
||||
"s"
|
||||
],
|
||||
"env": {
|
||||
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||
},
|
||||
"cwd": "${workspaceFolder}",
|
||||
"console": "integratedTerminal",
|
||||
"stopAtEntry": false,
|
||||
"requireExactSource": false
|
||||
},
|
||||
{
|
||||
"name": "Mirror-Length",
|
||||
"type": "coreclr",
|
||||
"request": "launch",
|
||||
"preLaunchTask": "build",
|
||||
"program": "${workspaceFolder}/Mirror-Length/bin/Debug/net8.0/win-x64/Mirror-Length.dll",
|
||||
"args": [],
|
||||
"env": {
|
||||
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||
},
|
||||
"cwd": "${workspaceFolder}",
|
||||
"console": "integratedTerminal",
|
||||
"stopAtEntry": false,
|
||||
"requireExactSource": false
|
||||
},
|
||||
{
|
||||
"name": "Metadata-Query",
|
||||
"type": "coreclr",
|
||||
"request": "launch",
|
||||
"preLaunchTask": "build",
|
||||
"program": "${workspaceFolder}/Metadata-Query/bin/Debug/net8.0/win-x64/Metadata-Query.dll",
|
||||
"args": [
|
||||
"s"
|
||||
],
|
||||
"env": {
|
||||
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||
},
|
||||
"cwd": "${workspaceFolder}",
|
||||
"console": "integratedTerminal",
|
||||
"stopAtEntry": false,
|
||||
"requireExactSource": false
|
||||
},
|
||||
{
|
||||
"name": "Move-By-Id",
|
||||
"type": "coreclr",
|
||||
"request": "launch",
|
||||
"preLaunchTask": "build",
|
||||
"program": "${workspaceFolder}/Move-By-Id/bin/Debug/net8.0/win-x64/Move-By-Id.dll",
|
||||
"args": [
|
||||
"s"
|
||||
],
|
||||
"env": {
|
||||
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||
},
|
||||
"cwd": "${workspaceFolder}",
|
||||
"console": "integratedTerminal",
|
||||
"stopAtEntry": false,
|
||||
"requireExactSource": false
|
||||
},
|
||||
{
|
||||
"name": "Not-Copy-Copy",
|
||||
"type": "coreclr",
|
||||
"request": "launch",
|
||||
"preLaunchTask": "build",
|
||||
"program": "${workspaceFolder}/Not-Copy-Copy/bin/Debug/net8.0/win-x64/Not-Copy-Copy.dll",
|
||||
"args": [
|
||||
"s"
|
||||
],
|
||||
"env": {
|
||||
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||
},
|
||||
"cwd": "${workspaceFolder}",
|
||||
"console": "integratedTerminal",
|
||||
"stopAtEntry": false,
|
||||
"requireExactSource": false
|
||||
},
|
||||
{
|
||||
"name": "Offset-Date-Time-Original",
|
||||
"type": "coreclr",
|
||||
"request": "launch",
|
||||
"preLaunchTask": "build",
|
||||
"program": "${workspaceFolder}/Offset-Date-Time-Original/bin/Debug/net8.0/win-x64/Offset-Date-Time-Original.dll",
|
||||
"args": [
|
||||
"s"
|
||||
],
|
||||
"env": {
|
||||
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||
},
|
||||
"cwd": "${workspaceFolder}",
|
||||
"console": "integratedTerminal",
|
||||
"stopAtEntry": false,
|
||||
"requireExactSource": false
|
||||
},
|
||||
{
|
||||
"name": "PrepareForOld",
|
||||
"type": "coreclr",
|
||||
"request": "launch",
|
||||
"preLaunchTask": "build",
|
||||
"program": "${workspaceFolder}/PrepareForOld/bin/Debug/net8.0/win-x64/PrepareForOld.dll",
|
||||
"args": [
|
||||
"s"
|
||||
],
|
||||
"env": {
|
||||
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||
},
|
||||
"cwd": "${workspaceFolder}",
|
||||
"console": "integratedTerminal",
|
||||
"stopAtEntry": false,
|
||||
"requireExactSource": false
|
||||
},
|
||||
{
|
||||
"name": "Person",
|
||||
"type": "coreclr",
|
||||
"request": "launch",
|
||||
"preLaunchTask": "build",
|
||||
"program": "${workspaceFolder}/Person/bin/Debug/net8.0/Person.dll",
|
||||
"args": [
|
||||
"s"
|
||||
],
|
||||
"env": {
|
||||
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||
},
|
||||
"cwd": "${workspaceFolder}",
|
||||
"console": "integratedTerminal",
|
||||
"stopAtEntry": false,
|
||||
"requireExactSource": false
|
||||
},
|
||||
{
|
||||
"name": "Rename",
|
||||
"type": "coreclr",
|
||||
"request": "launch",
|
||||
"preLaunchTask": "build",
|
||||
"program": "${workspaceFolder}/Rename/bin/Debug/net8.0/win-x64/AA.Rename.dll",
|
||||
"args": [
|
||||
"s"
|
||||
],
|
||||
"env": {
|
||||
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||
},
|
||||
"cwd": "${workspaceFolder}",
|
||||
"console": "integratedTerminal",
|
||||
"stopAtEntry": false,
|
||||
"requireExactSource": false
|
||||
},
|
||||
{
|
||||
"name": "Set-Created-Date",
|
||||
"type": "coreclr",
|
||||
"request": "launch",
|
||||
"preLaunchTask": "build",
|
||||
"program": "${workspaceFolder}/Set-Created-Date/bin/Debug/net8.0/win-x64/Set-Created-Date.dll",
|
||||
"args": [
|
||||
"s"
|
||||
],
|
||||
"env": {
|
||||
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||
},
|
||||
"cwd": "${workspaceFolder}",
|
||||
"console": "integratedTerminal",
|
||||
"stopAtEntry": false,
|
||||
"requireExactSource": false
|
||||
}
|
||||
]
|
||||
}
|
||||
// https://www.amazon.com/photos/
|
||||
// "AmazonUsername": "phares36@gmail.com",
|
||||
// "AmazonPassword": "JlPhgtv@63",
|
||||
// Keep creating the .json file the same way
|
||||
// However load all .json files at the beginning
|
||||
// When looping through all files and file not in collection path&name or date is different from collection value
|
||||
// Get id in normal fashion
|
||||
// If id is in collection update collection to new path/name
|
||||
// If not save and add to collection
|
||||
// Nicéphore Niépce in 1826 or 182
|
||||
// https://dotnet.microsoft.com/en-us/download
|
||||
// https://git-scm.com/
|
||||
// https://code.visualstudio.com/
|
||||
// https://github.com/mikepharesjr/VS-Code-Settings
|
||||
// https://github.com/davisking/dlib-models
|
||||
// https://github.com/mikepharesjr/View-by-Distance-MKLink-Console
|
||||
// https://184.103.9.214/login?folder=/home/vscode/Notes&to=
|
||||
// Notes at 9/18/2022 10:29 PM
|
||||
// (637987913910140924) 9/14/2022 10:29 PM - 113 *.jpg && 109 *.json
|
||||
// (637989361172096980) 9/16/2022 02:41 PM - 094 *.jpg && 026 *.json
|
||||
// All including (637991052364021796) 9/18/2022 1:40 PM - 17435 *.jpg && 16237 *.json = 93.128763980499% with int match only
|
||||
// List of people with current person key formatted in tab form
|
||||
// Exclusion list for Robert
|
||||
// Person birthday allow #
|
||||
// Host face directory on Ubuntu
|
||||
// https://scontent-lax3-2.xx.fbcdn.net/v/t1.6435-9/49158951_2264915190186558_112485584324263936_n.jpg?_nc_cat=106&ccb=1-7&_nc_sid=84a396&_nc_ohc=Q78znguHVeMAX88OKg9&_nc_ht=scontent-lax3-2.xx&oh=00_AT_gJFk9xytYuXp9p5smDm0mMDXzsPnFS_EfKEbiL3KYqg&oe=63523F37
|
||||
// https://scontent-lax3-1.xx.fbcdn.net/v/t39.30808-6/290625560_10217841255422109_3297482250419620718_n.jpg?_nc_cat=104&ccb=1-7&_nc_sid=730e14&_nc_ohc=O3ybqwDLK9AAX_V0FGP&tn=D0unuoVdv--xjhpM&_nc_ht=scontent-lax3-1.xx&oh=00_AT-9rtBghXU7lAGkOy4KPHbV9Kyj8DGm-BGtUabWgQJbOg&oe=63335209
|
||||
// https://scontent-lax3-1.xx.fbcdn.net/v/t39.30808-6/243093116_10216723829287154_8982585928017225043_n.jpg?_nc_cat=104&ccb=1-7&_nc_sid=730e14&_nc_ohc=TW6UDC8v9egAX-_YcWf&_nc_ht=scontent-lax3-1.xx&oh=00_AT8rE2JOfkJINSsA5imGVBDbXNDvxx1_uZn0sLM-6ITDUw&oe=633238A9
|
||||
// https://scontent-lax3-1.xx.fbcdn.net/v/t1.18169-9/281249_1450445399251_3598212_n.jpg?_nc_cat=108&ccb=1-7&_nc_sid=cdbe9c&_nc_ohc=ihKT3xtvWXoAX-kiat-&tn=D0unuoVdv--xjhpM&_nc_ht=scontent-lax3-1.xx&oh=00_AT9cmbHu00fc0-aR-k6MP7T_cja6geiAkobbvU4pdfG6KQ&oe=63527F21
|
||||
// https://scontent-lax3-1.xx.fbcdn.net/v/t1.18169-9/62557_157063120990498_3918482_n.jpg?_nc_cat=110&ccb=1-7&_nc_sid=de6eea&_nc_ohc=lV8bmtAes-0AX8Uk9pG&_nc_ht=scontent-lax3-1.xx&oh=00_AT-ieBL8wIZ4gQmRWAvTWDu9wBzAsPV5s4c82MvOs6oU5g&oe=6355846B
|
||||
// https://scontent-lax3-1.xx.fbcdn.net/v/t1.18169-9/166577_1634651034600_6777460_n.jpg?_nc_cat=108&ccb=1-7&_nc_sid=cdbe9c&_nc_ohc=nEZ0RR0cqn4AX-wA-VH&_nc_ht=scontent-lax3-1.xx&oh=00_AT_ig2HUMDQl1fhXY0Inm0QWC3i2__rPUAWYF2Wqx-pkew&oe=635290D6
|
||||
// https://scontent-lax3-2.xx.fbcdn.net/v/t1.6435-9/97107804_10223189072017432_5088375698351980544_n.jpg?_nc_cat=101&ccb=1-7&_nc_sid=09cbfe&_nc_ohc=t0rqlgAAd_0AX-ANM1H&tn=D0unuoVdv--xjhpM&_nc_ht=scontent-lax3-2.xx&oh=00_AT_hqG2piNkASRB5z94qeY8q7hy90ku9Dka4enL4wsAnTg&oe=6354CD8A
|
||||
// https://scontent-lax3-2.xx.fbcdn.net/v/t1.6435-9/121491463_10159438417238072_1207001349879930424_n.jpg?_nc_cat=103&ccb=1-7&_nc_sid=8bfeb9&_nc_ohc=rZTiRaFTrCkAX_L4sVS&_nc_ht=scontent-lax3-2.xx&oh=00_AT_uKD2jeNUTwlyN5r6UXRK40aNNgRNCZrrJ9B-WW6tlag&oe=63522946
|
||||
// https://scontent-lax3-1.xx.fbcdn.net/v/t1.6435-9/96370874_10158521458082578_8748970895894118400_n.jpg?_nc_cat=108&ccb=1-7&_nc_sid=8bfeb9&_nc_ohc=qvIn4gTjvo0AX-dHnuq&_nc_ht=scontent-lax3-1.xx&oh=00_AT8R-D8AsjWKMlUxK-AimPNzxuNT06zQCS43ESdf1LEeoQ&oe=63562F54
|
||||
// https://scontent-lax3-2.xx.fbcdn.net/v/t1.6435-9/96681856_10157495047223435_2857053180632498176_n.jpg?_nc_cat=103&ccb=1-7&_nc_sid=8bfeb9&_nc_ohc=UwF0qUGoG9QAX-S1LcI&_nc_ht=scontent-lax3-2.xx&oh=00_AT-5j0EiZB6HOOc2jGqGOll2zFoNTdDLKLfJztq0HYWagg&oe=6355A2A9
|
||||
// https://scontent-lax3-1.xx.fbcdn.net/v/t31.18172-8/26850365_1810492538961485_3240264679723665015_o.jpg?_nc_cat=110&ccb=1-7&_nc_sid=0debeb&_nc_ohc=WrJYsgu1eS4AX8kIsyM&_nc_ht=scontent-lax3-1.xx&oh=00_AT-fzFN40kYFjF2-uYL6KcgKPxgFkDZ5BcyIUVFdCTf2tg&oe=635485B7
|
||||
// https://scontent-lax3-1.xx.fbcdn.net/v/t1.6435-9/67735718_10219770387799941_2254439277247070208_n.jpg?_nc_cat=108&ccb=1-7&_nc_sid=730e14&_nc_ohc=MD8haDYY7uIAX_dwTY4&_nc_ht=scontent-lax3-1.xx&oh=00_AT_zhJpjbWomrihWiSq35KFkmpBfEgbXCSNM68icaABxoA&oe=6355871D
|
||||
// https://scontent-lax3-2.xx.fbcdn.net/v/t1.6435-9/59983603_2215207855225638_2271200674882519040_n.jpg?_nc_cat=111&ccb=1-7&_nc_sid=8bfeb9&_nc_ohc=-2zmPWdcy9IAX8KXJ_t&_nc_ht=scontent-lax3-2.xx&oh=00_AT_7N0yufGym-cuQfeMK6iceBNI7eEyaScRm3m3_4njTIQ&oe=6354C2B6
|
||||
// https://scontent-lax3-1.xx.fbcdn.net/v/t1.6435-9/204501292_10222856568897395_8588510782161393042_n.jpg?_nc_cat=105&ccb=1-7&_nc_sid=8bfeb9&_nc_ohc=2gLdnkn19swAX_9mAG1&tn=D0unuoVdv--xjhpM&_nc_ht=scontent-lax3-1.xx&oh=00_AT_ha5ncAI7ykhbgFNT1_4NWCvPGFWQLgdq6q20nZSIVQA&oe=63537D09
|
||||
// https://scontent-lax3-1.xx.fbcdn.net/v/t1.6435-9/65945099_10217135244827869_3400689284598988800_n.jpg?_nc_cat=110&ccb=1-7&_nc_sid=8bfeb9&_nc_ohc=NHnhR9_7UTkAX8wpbxK&_nc_ht=scontent-lax3-1.xx&oh=00_AT_-Q-zUeDoD11B9TY_n_MWEimMiXCokB_5TojplmU6_Eg&oe=6355A2B8
|
||||
// https://scontent-lax3-2.xx.fbcdn.net/v/t1.18169-9/22055_581856018827_4131263_n.jpg?_nc_cat=107&ccb=1-7&_nc_sid=cdbe9c&_nc_ohc=zsqIe2xzpf0AX8lcyLV&tn=D0unuoVdv--xjhpM&_nc_ht=scontent-lax3-2.xx&oh=00_AT_DzvUir_30cauAjp8eaSlYKVADdanzWo1NAQK7_b3M-w&oe=63548E83
|
||||
// https://scontent-lax3-1.xx.fbcdn.net/v/t31.18172-8/14525108_10202312892739292_8313619716862825541_o.jpg?_nc_cat=102&ccb=1-7&_nc_sid=8bfeb9&_nc_ohc=lZ4MpT6i_MIAX-3d-nV&_nc_ht=scontent-lax3-1.xx&oh=00_AT_9JoZdMdlNV71PdrkU7AmvFkkwqllEg9sVTvcGyzoESw&oe=6353993A
|
||||
// https://scontent-lax3-2.xx.fbcdn.net/v/t1.6435-9/104325415_860091804515928_5960365004832843376_n.jpg?_nc_cat=106&ccb=1-7&_nc_sid=174925&_nc_ohc=y1AW-ld80OcAX_927wW&_nc_oc=AQluU8Pwuqxs9xBVYhQJ9ThWOh5vLIKvQdOQnCtZpN2-j-6d9PRMHWHR5aaFBkcJicA&tn=D0unuoVdv--xjhpM&_nc_ht=scontent-lax3-2.xx&oh=00_AT8vQwiLvz7cJU61FkIPLtcc8j8tlL2tC6zRlH1i20VUmQ&oe=6356EACE
|
||||
// https://scontent-lax3-1.xx.fbcdn.net/v/t1.6435-9/43565411_10217177505092918_6185540976904241152_n.jpg?_nc_cat=105&ccb=1-7&_nc_sid=730e14&_nc_ohc=yBls9BCXhdwAX_doX-2&_nc_ht=scontent-lax3-1.xx&oh=00_AT-PYyffphSxOeGM_3aC4oHSA4U9cEjm2OrappZ_jh6qIg&oe=6355895C
|
||||
// https://scontent-lax3-1.xx.fbcdn.net/v/t1.6435-9/48422692_10157144542022625_3324340889383337984_n.jpg?_nc_cat=108&ccb=1-7&_nc_sid=8bfeb9&_nc_ohc=h_gtXGa5nSAAX-CB2E1&_nc_ht=scontent-lax3-1.xx&oh=00_AT8x7vZA5VN27hfoMPcQ39So-1COUnuNjDj4iz8d-cw6wQ&oe=6354B370
|
||||
// https://scontent-lax3-2.xx.fbcdn.net/v/t1.6435-9/150153899_10208532293942419_1808101907825622971_n.jpg?_nc_cat=101&ccb=1-7&_nc_sid=8bfeb9&_nc_ohc=3NZWKCpJ0VYAX911uCo&_nc_ht=scontent-lax3-2.xx&oh=00_AT_NhKwagHEsPuQVSERZNQ2_6MOIG2UKG5r32c0fIPaeQA&oe=63552624
|
||||
// https://scontent-lax3-2.xx.fbcdn.net/v/t31.18172-8/13641143_10209202266801205_7525162492297688727_o.jpg?_nc_cat=106&ccb=1-7&_nc_sid=174925&_nc_ohc=AETs7fkfLacAX-q9cnO&_nc_ht=scontent-lax3-2.xx&oh=00_AT89DOYAP9GbNvEgmlI0z9VK9Z8uJttFQyuO-tfe5OGbFQ&oe=6355CF5D
|
||||
// https://scontent-lax3-2.xx.fbcdn.net/v/t1.18169-9/299875_2023116112081_1500929171_n.jpg?_nc_cat=103&ccb=1-7&_nc_sid=cdbe9c&_nc_ohc=bsY9uckSAQwAX-xxGaU&_nc_ht=scontent-lax3-2.xx&oh=00_AT8OStQmDU_7NLNrYLeNfoULcBA-onU1V3Z4bn35-ipzCQ&oe=63555339
|
||||
// https://scontent-lax3-2.xx.fbcdn.net/v/t1.18169-9/1544444_10203587296855592_4576811169900508598_n.jpg?_nc_cat=100&ccb=1-7&_nc_sid=730e14&_nc_ohc=pYUGNkoYGPcAX8X2gtw&_nc_ht=scontent-lax3-2.xx&oh=00_AT_thzQZyWPWDA8t1acXqEzifLMXxcPTUOgqWqmeuk3SfQ&oe=63566033
|
||||
// https://scontent-lax3-2.xx.fbcdn.net/v/t31.18172-8/10887668_10205175511939476_7644367668075304275_o.jpg?_nc_cat=100&ccb=1-7&_nc_sid=730e14&_nc_ohc=2T_utQvqkXYAX94o-WV&_nc_ht=scontent-lax3-2.xx&oh=00_AT8aSCQ4JVgRULd1RxRJ8DYqPtB9EyGY-May2QwwqKSqjQ&oe=6356B098
|
||||
// https://scontent-lax3-2.xx.fbcdn.net/v/t1.6435-9/78675669_10102984650797787_175454688261439488_n.jpg?_nc_cat=101&ccb=1-7&_nc_sid=8bfeb9&_nc_ohc=7Plv_RW77xoAX9PiH9G&_nc_ht=scontent-lax3-2.xx&oh=00_AT-npzVNkTzAdYgQ4D1ltfyl8llC_xqOHJ9Mi8Vmh2khlw&oe=63571251
|
||||
// https://scontent-lax3-2.xx.fbcdn.net/v/t1.6435-9/59569741_10214142910059142_9219208491263066112_n.jpg?_nc_cat=100&ccb=1-7&_nc_sid=730e14&_nc_ohc=F7GF2uCFljcAX8Skffr&_nc_ht=scontent-lax3-2.xx&oh=00_AT9e3f8x6hSmAcxQ5JDUvDPFEg0wcecKw175Qfj_WMwADQ&oe=635488AA
|
||||
// https://scontent-lax3-2.xx.fbcdn.net/v/t39.30808-6/290559432_10209959340897099_842876274165104077_n.jpg?_nc_cat=111&ccb=1-7&_nc_sid=8bfeb9&_nc_ohc=Vgxc93JsPBEAX8zrKaq&_nc_ht=scontent-lax3-2.xx&oh=00_AT-pPGd4o-t7kSeY4XKOTDeOzfg6wXOMBdY6rldQyrKQmw&oe=6335398E
|
||||
// https://scontent-lax3-1.xx.fbcdn.net/v/t39.30808-6/308587069_10210153867920153_6202104893656263114_n.jpg?stp=cp6_dst-jpg&_nc_cat=104&ccb=1-7&_nc_sid=8bfeb9&_nc_ohc=SKB2FSdXFQEAX_v1t5g&tn=D0unuoVdv--xjhpM&_nc_ht=scontent-lax3-1.xx&oh=00_AT_E1y9uQ27O5_FAyAeRJ0XotEyBEXytkM2iDCGvldSxLw&oe=633549B9
|
||||
// https://scontent-lax3-2.xx.fbcdn.net/v/t1.6435-9/67309987_10214298629206292_6820175905885782016_n.jpg?_nc_cat=106&ccb=1-7&_nc_sid=730e14&_nc_ohc=BTQEZF_dwRwAX-cxNEm&_nc_ht=scontent-lax3-2.xx&oh=00_AT8_z-JOBPmskVsJ0S9bOYgcYngpVrMjhVrfFk3r06Wj8Q&oe=635473AE
|
||||
// https://scontent-lax3-1.xx.fbcdn.net/v/t39.30808-6/263710427_1324163581376203_7502850514450466967_n.jpg?_nc_cat=110&ccb=1-7&_nc_sid=e3f864&_nc_ohc=2KB9VISs3y0AX-PiYUd&_nc_ht=scontent-lax3-1.xx&oh=00_AT_WaHBBSAR2-1dDEdpufugFf4eBttyGfIIflCwvCu_76g&oe=6334DBC3
|
||||
// https://scontent-lax3-2.xx.fbcdn.net/v/t1.6435-9/67181620_114720179834180_3651229536021905408_n.jpg?_nc_cat=101&ccb=1-7&_nc_sid=09cbfe&_nc_ohc=CYF8Qyy506MAX-GBXV_&_nc_ht=scontent-lax3-2.xx&oh=00_AT_dFZiY42lloSfdiqNgSBlDpS9eGIEu85hhG5KIQD7DwA&oe=6354B320
|
||||
// https://scontent-lax3-1.xx.fbcdn.net/v/t1.6435-9/68383564_10217654576270105_5209606295652401152_n.jpg?_nc_cat=109&ccb=1-7&_nc_sid=730e14&_nc_ohc=phqcunpNs5EAX-d33kB&_nc_ht=scontent-lax3-1.xx&oh=00_AT9n5kFQnIPSXUzNAMb19Wpue1YA-bHFpSCE-_tOXD8Gnw&oe=635615C2
|
||||
// https://scontent-lax3-2.xx.fbcdn.net/v/t39.30808-6/285466259_7423531907720135_1229107015631332741_n.jpg?_nc_cat=111&ccb=1-7&_nc_sid=09cbfe&_nc_ohc=z85uLRC706sAX_H3_Ht&_nc_ht=scontent-lax3-2.xx&oh=00_AT-_wJpeYhqcdivdF4SbBO3B6M082qGD3qdGAPDmVP6nAA&oe=6334B2ED
|
||||
// https://scontent-lax3-1.xx.fbcdn.net/v/t1.6435-9/32919393_10214483292069982_3789509822047584256_n.jpg?_nc_cat=105&ccb=1-7&_nc_sid=8bfeb9&_nc_ohc=oJzHahluIDYAX-5-UGl&tn=D0unuoVdv--xjhpM&_nc_ht=scontent-lax3-1.xx&oh=00_AT9e7dHUoseqwf6qF39NHEnPzal6NzQgyCwio6SvzUZTUQ&oe=63575682
|
||||
// https://scontent-lax3-1.xx.fbcdn.net/v/t31.18172-8/22256636_1931521070438917_6414682443902494017_o.jpg?_nc_cat=102&ccb=1-7&_nc_sid=cdbe9c&_nc_ohc=bf99qSpRJOQAX_stzg5&_nc_ht=scontent-lax3-1.xx&oh=00_AT-eoWkn2Gaqj8BGasgNOycRzf3AiQE2GqHtKC28_-vFug&oe=63586C84
|
||||
// https://scontent-lax3-1.xx.fbcdn.net/v/t1.18169-9/600876_10151927436713567_876993105_n.jpg?_nc_cat=110&ccb=1-7&_nc_sid=cdbe9c&_nc_ohc=dcNCC6RNOooAX985ENZ&_nc_ht=scontent-lax3-1.xx&oh=00_AT-9Q999B_sWiS-yPP48gVdrheH0bY-DAiOKmkExbnW5Rw&oe=6355ED8A
|
||||
// https://scontent-lax3-1.xx.fbcdn.net/v/t1.6435-9/35235266_10213962597433782_6655457381733892096_n.jpg?_nc_cat=110&ccb=1-7&_nc_sid=8bfeb9&_nc_ohc=uxfDliBhPHUAX_JXJNU&_nc_ht=scontent-lax3-1.xx&oh=00_AT9zGc-8QqaAHItoDqGzKAMEYOU0fEQz_ld1R_CGxPokug&oe=63565840
|
||||
// https://scontent-lax3-1.xx.fbcdn.net/v/t1.6435-9/161932468_10159007128985149_3980438021322511452_n.jpg?_nc_cat=104&ccb=1-7&_nc_sid=09cbfe&_nc_ohc=6dCTPFwvFPcAX8ogdv8&_nc_ht=scontent-lax3-1.xx&oh=00_AT8pspicXFXgj-MOKzkTyp_ZpuboruYwyM-MMNwro_m9JA&oe=63564482
|
||||
// https://scontent-lax3-1.xx.fbcdn.net/v/t1.6435-9/91250196_10215323899906785_1298078522899693568_n.jpg?_nc_cat=110&ccb=1-7&_nc_sid=730e14&_nc_ohc=CSXhKF_1hqsAX9qlbvP&tn=D0unuoVdv--xjhpM&_nc_ht=scontent-lax3-1.xx&oh=00_AT-JZSnju_3XqWV6w9rSSUmuo2oIaCig5pn7JmrvFbBfGw&oe=6354B339
|
||||
// https://scontent-lax3-1.xx.fbcdn.net/v/t1.18169-9/428510_490436967638912_1438526428_n.jpg?_nc_cat=108&ccb=1-7&_nc_sid=ba80b0&_nc_ohc=s0ZgvdtWwOsAX87AD-I&_nc_ht=scontent-lax3-1.xx&oh=00_AT-gv7QKuJhEjRPbmQr5hLG163-EQXcx6FJ8aHCcPTfEXw&oe=63563591
|
||||
// https://scontent-lax3-2.xx.fbcdn.net/v/t1.6435-9/50312617_10161338488075048_5525340242208358400_n.jpg?_nc_cat=101&ccb=1-7&_nc_sid=8bfeb9&_nc_ohc=NcQcK_z6t9kAX9-On7t&_nc_ht=scontent-lax3-2.xx&oh=00_AT_WYrFNqGwzuSssGPBRmhpqGlyf1k2ulbdKakrs4xAHBg&oe=635832DB
|
||||
// https://scontent-lax3-2.xx.fbcdn.net/v/t39.30808-6/247966826_10200232179385908_1907223790607385605_n.jpg?_nc_cat=106&ccb=1-7&_nc_sid=09cbfe&_nc_ohc=Xn0j5rxLaCQAX8OD7k4&_nc_ht=scontent-lax3-2.xx&oh=00_AT_bVVWAuaGYpIcBOCbAtn_xyS2Rqu--uKs06-FKOfjuzg&oe=633583B8
|
||||
// https://scontent-lax3-2.xx.fbcdn.net/v/t1.6435-9/57840024_10161651547530207_1744748790901899264_n.jpg?_nc_cat=107&ccb=1-7&_nc_sid=730e14&_nc_ohc=TKg3rTiXkYUAX-V8NO5&_nc_ht=scontent-lax3-2.xx&oh=00_AT-Mepp0iN8-mHhyKRHj-R5yBOu2wZGtQeApkSoZTzM3mg&oe=6356A1D2
|
||||
// https://scontent-lax3-2.xx.fbcdn.net/v/t39.30808-6/269876615_612483726673361_2182050585964176784_n.jpg?_nc_cat=106&ccb=1-7&_nc_sid=174925&_nc_ohc=9QJt0X_FDlEAX_Okew3&_nc_ht=scontent-lax3-2.xx&oh=00_AT_Yq8OflcYUA39JsmM__UxFYi8YASqsrRYx-T1Qn2NPSw&oe=6336391B
|
||||
// https://scontent-lax3-2.xx.fbcdn.net/v/t1.6435-9/126332086_10224303272989365_2242003924983097751_n.jpg?_nc_cat=111&ccb=1-7&_nc_sid=09cbfe&_nc_ohc=zpX0nadZ9XMAX8m1Kk1&tn=D0unuoVdv--xjhpM&_nc_ht=scontent-lax3-2.xx&oh=00_AT9c_dq-TLiNxgeqmp9Pwnqp9xjUIG3_ijxmiAW4MPYBKw&oe=63578DD6
|
||||
// https://scontent-lax3-2.xx.fbcdn.net/v/t1.6435-9/74624149_10215957575592842_7757392320252608512_n.jpg?_nc_cat=103&ccb=1-7&_nc_sid=8bfeb9&_nc_ohc=22WGGAPeTdAAX87greQ&_nc_ht=scontent-lax3-2.xx&oh=00_AT9J2qV9zBMEPuqsibA-87pjTBg3e3hVwHb211GO7lJicQ&oe=6355F050
|
||||
// https://scontent-lax3-1.xx.fbcdn.net/v/t31.18172-8/10649011_812346452173040_8035951943727654673_o.jpg?_nc_cat=104&ccb=1-7&_nc_sid=84a396&_nc_ohc=aDP-7N5XOgMAX9eflUn&_nc_ht=scontent-lax3-1.xx&oh=00_AT_mCAWB-OTJ32F1W90m-bPWu9GmjvFr-j1VdAQmkdNtXg&oe=63565628
|
||||
// https://scontent-lax3-2.xx.fbcdn.net/v/t39.30808-6/289655024_10228170790084748_4126077972169573791_n.jpg?_nc_cat=101&ccb=1-7&_nc_sid=8bfeb9&_nc_ohc=NeX9XD5pcwMAX9UBHLe&_nc_ht=scontent-lax3-2.xx&oh=00_AT-Qh77ATMIGL6JnKHr9rIim3Ui_UU7XH_S02S7-iu21qg&oe=633700F0
|
||||
// https://scontent-lax3-2.xx.fbcdn.net/v/t39.30808-6/266998682_10227151119593623_456420668145746211_n.jpg?_nc_cat=101&ccb=1-7&_nc_sid=8bfeb9&_nc_ohc=vjNb4pBYn5YAX_gWfIx&tn=D0unuoVdv--xjhpM&_nc_ht=scontent-lax3-2.xx&oh=00_AT_rv-lqoI2u7Y-FMU8G8Vfxo6QyA-tTEIMKRpRx9TxZPg&oe=63353CCC
|
||||
// https://scontent-lax3-1.xx.fbcdn.net/v/t1.6435-9/40093120_10217172129645111_2951374557987995648_n.jpg?_nc_cat=110&ccb=1-7&_nc_sid=8bfeb9&_nc_ohc=X1j0ykpT26oAX8kDzfQ&_nc_ht=scontent-lax3-1.xx&oh=00_AT-jst6eXb7F4NsSJRj4jOQvKqQOiiMP4K5iT8xq2t4dTg&oe=63588214
|
||||
// https://scontent-lax3-2.xx.fbcdn.net/v/t1.6435-9/31870362_10216285257993874_8330563136197230592_n.jpg?_nc_cat=103&ccb=1-7&_nc_sid=84a396&_nc_ohc=8kJ5pbwsKDMAX9hIVFA&tn=D0unuoVdv--xjhpM&_nc_ht=scontent-lax3-2.xx&oh=00_AT9vRjGUZdT7KasJ4Ndti2LHfrPaTcahl4ipT9BmdRZJeg&oe=6356737F
|
||||
// https://scontent-lax3-2.xx.fbcdn.net/v/t39.30808-6/230074448_10103880528811228_6909448863476427135_n.jpg?_nc_cat=103&ccb=1-7&_nc_sid=0debeb&_nc_ohc=cUpp1Y_DO8MAX92tN_t&tn=D0unuoVdv--xjhpM&_nc_ht=scontent-lax3-2.xx&oh=00_AT-K2_yEERUmvvjkjUKf7zwaV2Ofq1fHIQAtEkCt7I2Bhw&oe=63352B95
|
||||
// https://scontent-lax3-2.xx.fbcdn.net/v/t31.18172-8/13502600_10210212049485607_95598559411189791_o.jpg?_nc_cat=101&ccb=1-7&_nc_sid=cdbe9c&_nc_ohc=AEojM0a2X5cAX8kmHfZ&_nc_ht=scontent-lax3-2.xx&oh=00_AT-ZX7vIfwazh_zcDpFCLxwLgp90gERyBG2CtGxIClEnYA&oe=6355A9C7
|
||||
// https://scontent-lax3-2.xx.fbcdn.net/v/t31.18172-8/14195939_1314130471931770_9026437168267009241_o.jpg?_nc_cat=106&ccb=1-7&_nc_sid=730e14&_nc_ohc=f8owaBX7kMQAX8ioj3m&_nc_ht=scontent-lax3-2.xx&oh=00_AT8N8GR4GXmKa3w_dP952fl1_bx_s7CTz8qFtxaBK91S2w&oe=6355DBA1
|
||||
// https://scontent-lax3-1.xx.fbcdn.net/v/t1.6435-9/67428022_1287438048070254_7628190366730027008_n.jpg?_nc_cat=105&ccb=1-7&_nc_sid=b9115d&_nc_ohc=wO9dTzPDXjcAX85VZFY&_nc_ht=scontent-lax3-1.xx&oh=00_AT9ZDKZuwlVncwGAKb6fkty_AaqnBNmKj46n2L3V1Y_V5w&oe=63589442
|
||||
// https://scontent-lax3-2.xx.fbcdn.net/v/t1.6435-9/95959209_10221111135660559_6413640771529867264_n.jpg?_nc_cat=106&ccb=1-7&_nc_sid=730e14&_nc_ohc=tN-1cmyDpEsAX-GecHc&_nc_ht=scontent-lax3-2.xx&oh=00_AT9w87N6Gq277785G3f6iF5IhEtBtJ7FTZwxkK5dipNqOw&oe=63575F14
|
||||
// https://scontent-lax3-2.xx.fbcdn.net/v/t1.18169-9/207486_1959635958499_5198863_n.jpg?_nc_cat=111&ccb=1-7&_nc_sid=2c4854&_nc_ohc=Z2KnsIT4a60AX9wPnkk&_nc_ht=scontent-lax3-2.xx&oh=00_AT8Vxh2vW53SBZ4sH9cgZEofWKOUnpf8fpMjQRjZGCR6oQ&oe=6355FB36
|
||||
// https://scontent-lax3-1.xx.fbcdn.net/v/t1.6435-9/37219804_10213591073105306_9108104030982242304_n.jpg?_nc_cat=108&ccb=1-7&_nc_sid=8bfeb9&_nc_ohc=pngJAV_sIesAX8zSJG-&tn=D0unuoVdv--xjhpM&_nc_ht=scontent-lax3-1.xx&oh=00_AT8UXpCCDSQ8uOPtSrdzcty0tSpO6TCEKCL-K7q-BMb5CA&oe=6357898C
|
||||
// https://scontent-lax3-2.xx.fbcdn.net/v/t1.18169-9/427539_3441473049618_710901137_n.jpg?_nc_cat=101&ccb=1-7&_nc_sid=cdbe9c&_nc_ohc=3DPj0_PEbSsAX9ryGz1&_nc_ht=scontent-lax3-2.xx&oh=00_AT9t82wuMvW2xdHA8E1VokNBzIhHtgBbpH8fvrIxE_0rPQ&oe=6357DCF0
|
||||
// https://scontent-lax3-1.xx.fbcdn.net/v/t39.30808-6/241548211_237343028191419_6995991527624737723_n.jpg?_nc_cat=104&ccb=1-7&_nc_sid=09cbfe&_nc_ohc=nsC7CBQxaO8AX-De2g8&_nc_ht=scontent-lax3-1.xx&oh=00_AT_V2gvedewiVuhPIozJyq4ccKm6WoxBkXe0Ocm1fTZ3wA&oe=63365FAA
|
||||
// https://scontent-lax3-1.xx.fbcdn.net/v/t1.18169-9/10253934_10152334525164461_3158331570278601806_n.jpg?_nc_cat=104&ccb=1-7&_nc_sid=ba80b0&_nc_ohc=0A0Haq5W-IgAX8Y28oA&_nc_ht=scontent-lax3-1.xx&oh=00_AT-3tqlxtQj1n0D5t1jzVfQi22q3OMyQQrBcw2ZBrmYGaA&oe=6356ACAB
|
||||
// https://scontent-lax3-2.xx.fbcdn.net/v/t39.30808-6/308817118_10218508885627876_6441766117990882318_n.jpg?_nc_cat=106&ccb=1-7&_nc_sid=730e14&_nc_ohc=1kMU8trJLw4AX_R76M2&tn=D0unuoVdv--xjhpM&_nc_ht=scontent-lax3-2.xx&oh=00_AT9k53CcIY7KnW3CjRR4bbE8wjuAUVVi6D1an-kcbOaF2g&oe=63363C9E
|
||||
// https://scontent-lax3-1.xx.fbcdn.net/v/t1.6435-9/41038997_10156771390897533_9196241072043327488_n.jpg?_nc_cat=110&ccb=1-7&_nc_sid=174925&_nc_ohc=CK2PqvoqhVsAX9xGRSK&tn=D0unuoVdv--xjhpM&_nc_ht=scontent-lax3-1.xx&oh=00_AT8qHnIW7OsQMRb7htRwC7byyqcK4X5qAkdz8IM4caO_iA&oe=6357DA17
|
||||
// https://scontent-lax3-1.xx.fbcdn.net/v/t39.30808-6/279316302_4583494791751734_5208076832025426501_n.jpg?_nc_cat=109&ccb=1-7&_nc_sid=e3f864&_nc_ohc=Mt2sOGHVzbMAX-ghCmr&tn=D0unuoVdv--xjhpM&_nc_ht=scontent-lax3-1.xx&oh=00_AT_xdFzERKvZfApmuZ19H39uWsTz0vrJR7fivTuaLGiE1g&oe=63372D6C
|
||||
// https://scontent-lax3-2.xx.fbcdn.net/v/t39.30808-6/213757548_10222718701187533_9216326465615113019_n.jpg?_nc_cat=111&ccb=1-7&_nc_sid=8bfeb9&_nc_ohc=bMlCbM1DFccAX-UEjOE&_nc_oc=AQlwSf-Xrfqx-ldXQ8cz-gImrOZnTfVoNReVucU0i3C--RLTsfldVzKT8ij7sn7Jn3E&_nc_ht=scontent-lax3-2.xx&oh=00_AT-YAQ9scfYOoaPy5Kzb6yWcpe4t5MNTfE1pAP-RD3oBAA&oe=63379E32
|
||||
// https://scontent-lax3-1.xx.fbcdn.net/v/t1.18169-9/1005197_172610252919953_1797035311_n.jpg?_nc_cat=102&ccb=1-7&_nc_sid=cdbe9c&_nc_ohc=9wV_ZoGuDfQAX9ZQWRM&_nc_ht=scontent-lax3-1.xx&oh=00_AT_M3_rgENbCEjmouX8Ar_N_s-P5Tke0TvPzza0Mwx90dg&oe=635764FD
|
||||
// https://scontent-lax3-1.xx.fbcdn.net/v/t31.18172-8/24130218_2001836833160114_7527164989319060274_o.jpg?_nc_cat=104&ccb=1-7&_nc_sid=8bfeb9&_nc_ohc=ZxM5zjih3tYAX8IsXx9&_nc_ht=scontent-lax3-1.xx&oh=00_AT-G2-I-OXpcoq9TKqn_YT3gObzj8GMavpJe-KH7xj_5Lg&oe=6357091E
|
||||
// https://scontent-lax3-1.xx.fbcdn.net/v/t1.18169-9/11745695_10206235519080812_1953505210138379535_n.jpg?_nc_cat=109&ccb=1-7&_nc_sid=8bfeb9&_nc_ohc=RDqIQjOVB0AAX8Q90_Z&_nc_ht=scontent-lax3-1.xx&oh=00_AT_FogaOVWhgLcesEzaidYx--sKeBVCD6xDg2IWJdvcafA&oe=6356095A
|
||||
// https://scontent-lax3-2.xx.fbcdn.net/v/t39.30808-6/280118285_2094899397354077_5352291217200307805_n.jpg?_nc_cat=103&ccb=1-7&_nc_sid=8bfeb9&_nc_ohc=YQDlNI2xTrIAX-curq5&_nc_ht=scontent-lax3-2.xx&oh=00_AT8SuwF2W7tioXfAfCCun6zQsrIUjArOSr0ZlRb3F_Ej2Q&oe=63378827
|
||||
// https://scontent-lax3-2.xx.fbcdn.net/v/t1.18169-9/13233144_10101471840461827_9039193337970955304_n.jpg?_nc_cat=107&ccb=1-7&_nc_sid=cdbe9c&_nc_ohc=aiRRaotqsnYAX-slwLd&tn=D0unuoVdv--xjhpM&_nc_ht=scontent-lax3-2.xx&oh=00_AT_CxgSXV-0uNiiz_jLV_s3cPAk2vUyoro5MVsXsVyiEcg&oe=6358E40F
|
||||
// https://scontent-lax3-1.xx.fbcdn.net/v/t39.30808-6/305309404_10220461241674046_1323434462733520520_n.jpg?_nc_cat=108&ccb=1-7&_nc_sid=8bfeb9&_nc_ohc=NajFsslaLvcAX8-Kuz_&tn=D0unuoVdv--xjhpM&_nc_ht=scontent-lax3-1.xx&oh=00_AT89eIRz0st3qjPnhURiW9W7wXbaOV0usVykQiKRL_TRhg&oe=6337A145
|
||||
// https://scontent-lax3-2.xx.fbcdn.net/v/t1.6435-9/32481784_10216908834904287_1754862128918953984_n.jpg?_nc_cat=101&ccb=1-7&_nc_sid=8bfeb9&_nc_ohc=8mU2Cf_iAFwAX80s1xj&_nc_ht=scontent-lax3-2.xx&oh=00_AT8SXOmaqoNTZvBik5j4hE7YEenshkhPggwNgfLdIjIn4g&oe=6355E4D5
|
||||
// https://scontent-lax3-2.xx.fbcdn.net/v/t1.18169-9/22814020_10211731412395324_9169598565701382472_n.jpg?_nc_cat=101&ccb=1-7&_nc_sid=8bfeb9&_nc_ohc=UTLq0qx2PQwAX-Y9rIg&_nc_ht=scontent-lax3-2.xx&oh=00_AT_T9Bqd0LwRhuUkbMuUHQcCxcB7I3TAumrw7BR-UuEe3Q&oe=63563325
|
||||
// https://scontent-lax3-1.xx.fbcdn.net/v/t1.6435-9/94927050_10220780432954871_7311541287197343744_n.jpg?_nc_cat=105&ccb=1-7&_nc_sid=8bfeb9&_nc_ohc=qJofGIany9YAX_15Uhx&_nc_ht=scontent-lax3-1.xx&oh=00_AT_K9V-fQ-IOdVE3BtUQCtFvljScg3xdbjWK8LWh0fs3EQ&oe=6355F4D6
|
||||
// https://scontent-lax3-2.xx.fbcdn.net/v/t1.6435-9/47685020_2061588197234140_3115001451777097728_n.jpg?_nc_cat=103&ccb=1-7&_nc_sid=8bfeb9&_nc_ohc=g2_slmBopOEAX-kvLeT&_nc_ht=scontent-lax3-2.xx&oh=00_AT9CXSXrom34MSI2zgqXx7qdPKAn8fhKG8dBqGE3l1c_Nw&oe=63567CA6
|
||||
// https://scontent-lax3-2.xx.fbcdn.net/v/t1.6435-9/39221047_10156127305716865_6824896341232058368_n.jpg?_nc_cat=106&ccb=1-7&_nc_sid=8bfeb9&_nc_ohc=osdlvseA5vkAX9zsbYp&tn=D0unuoVdv--xjhpM&_nc_ht=scontent-lax3-2.xx&oh=00_AT96aJo9mM_AXgkaQau0AYQ6GgMk3m02z4fpuT1FwYvXtw&oe=6357B649
|
||||
// https://scontent-lax3-2.xx.fbcdn.net/v/t1.18169-9/11037634_10204752644508765_3331659968007967889_n.jpg?_nc_cat=107&ccb=1-7&_nc_sid=730e14&_nc_ohc=mjDY6IkATEoAX_WhE62&_nc_ht=scontent-lax3-2.xx&oh=00_AT8gl0GngVzWAynqGAC8zrgZUqAEgahMmzE5X41KpPnYxQ&oe=635825BA
|
||||
// https://scontent-lax3-1.xx.fbcdn.net/v/t1.6435-9/36371667_10213980051274137_6162910755566911488_n.jpg?_nc_cat=102&ccb=1-7&_nc_sid=8bfeb9&_nc_ohc=-j6ofEojPiIAX-yLrVV&_nc_ht=scontent-lax3-1.xx&oh=00_AT9ZvpazeIfHclhHr24SguNiu0m4WMAj2k5jm2I40JIv5w&oe=635612A1
|
||||
// https://scontent-lax3-2.xx.fbcdn.net/v/t1.18169-9/13938350_626048368466_6216870049337020892_n.jpg?_nc_cat=111&ccb=1-7&_nc_sid=8bfeb9&_nc_ohc=AbgIJkB2bH4AX-TuAoA&_nc_ht=scontent-lax3-2.xx&oh=00_AT-o0wi5Cz5vl1WDgcDm2BneTIBTuR-__qxxmR-3Fgyg_w&oe=63579473
|
||||
// https://scontent-lax3-1.xx.fbcdn.net/v/t39.30808-6/306356815_5223195104456342_2659949811667496237_n.jpg?_nc_cat=104&ccb=1-7&_nc_sid=730e14&_nc_ohc=NQdsObWTav0AX9EbW12&_nc_ht=scontent-lax3-1.xx&oh=00_AT8v-jsilYOUGKvQdlt7PXQmbdJRfZD0-GdycokWq-aNwg&oe=63365BAB
|
||||
// https://scontent-lax3-1.xx.fbcdn.net/v/t1.6435-9/44500772_10217404839095591_8903105516822069248_n.jpg?_nc_cat=105&ccb=1-7&_nc_sid=8bfeb9&_nc_ohc=RqwiyNoil04AX_Y4FGb&_nc_ht=scontent-lax3-1.xx&oh=00_AT85t0AjyzMXSj_UcUhKqWf7ZXdQOFAy12aFdeOO9cjBYg&oe=6356ED81
|
||||
// https://scontent-lax3-2.xx.fbcdn.net/v/t1.18169-9/23659202_10212567297792300_7982751930141302131_n.jpg?_nc_cat=101&ccb=1-7&_nc_sid=ad2b24&_nc_ohc=9vxjTRupUuAAX8fJ3Qa&_nc_ht=scontent-lax3-2.xx&oh=00_AT8wFIaUMmI2_kLSejxewgzzMK6g0ngEJVfhEQukM0zQdQ&oe=63596B35
|
||||
// https://scontent-lax3-1.xx.fbcdn.net/v/t1.6435-9/92554157_10158297246718523_986365937043111936_n.jpg?_nc_cat=105&ccb=1-7&_nc_sid=8bfeb9&_nc_ohc=lWhPQlbtKVoAX-4D9Ke&tn=D0unuoVdv--xjhpM&_nc_ht=scontent-lax3-1.xx&oh=00_AT_P1suJEkfnHlSL3rPoDoYW2exSg_gQyN--HoylQbt_JQ&oe=63567442
|
||||
// https://scontent-lax3-2.xx.fbcdn.net/v/t39.30808-6/280689051_10209840036394561_8737214584492733274_n.jpg?_nc_cat=101&ccb=1-7&_nc_sid=8bfeb9&_nc_ohc=iMAAHqNekCgAX8fvEAm&_nc_ht=scontent-lax3-2.xx&oh=00_AT8b7_ODsDN7lNgTKr7JZiUE65R7WWYxENl1vOUGeobpBw&oe=6336E678
|
||||
// https://scontent-lax3-1.xx.fbcdn.net/v/t1.18169-9/25110_107749419250772_1842086_n.jpg?_nc_cat=104&ccb=1-7&_nc_sid=09cbfe&_nc_ohc=xPyRCvImlaoAX9Z_UTs&_nc_ht=scontent-lax3-1.xx&oh=00_AT85xffhHDJlhzyFTBvWs8j3Gd4GyDCte_Pnd7hNM006sw&oe=635880C2
|
||||
// https://scontent-lax3-2.xx.fbcdn.net/v/t1.18169-9/10259940_10153561109653458_6837681277740526675_n.jpg?_nc_cat=100&ccb=1-7&_nc_sid=8bfeb9&_nc_ohc=T1v9Wfqz8rUAX8y6bxq&tn=D0unuoVdv--xjhpM&_nc_ht=scontent-lax3-2.xx&oh=00_AT9Y9j5s19n0EzgO_dZMom8tAweFYIrJLOEsrsr4HAWHkQ&oe=63588CAE
|
||||
// https://scontent-lax3-1.xx.fbcdn.net/v/t31.18172-8/17621858_10154253751886426_3939148233753829194_o.jpg?_nc_cat=104&ccb=1-7&_nc_sid=ad2b24&_nc_ohc=yMOqJQQBV80AX8Xlzr-&_nc_ht=scontent-lax3-1.xx&oh=00_AT_z0oeHJ0fqKhVA4WdgGE2cZSgL0bIKNXzPsY0zeLipAg&oe=6356AF4C
|
||||
// FileSizeChanged <F:\Tmp\Phares\Compare\Images-4d49b68\Kristy Google Photos from 2012\2012-10-19 12.00.31.jpg>
|
||||
// FileSizeChanged <F:\Tmp\Phares\Compare\Images-4d49b68\Kristy Google Photos from 2012\2012-10-20 15.41.37.jpg>
|
||||
// FileSizeChanged <F:\Tmp\Phares\Compare\Images-4d49b68\Kristy Google Photos from 2012\2012-10-23 09.57.51.jpg>
|
||||
// FileSizeChanged <F:\Tmp\Phares\Compare\Images-4d49b68\Kristy Google Photos from 2012\2012-10-25 13.46.09.jpg>
|
||||
// FileSizeChanged <F:\Tmp\Phares\Compare\Images-4d49b68\Kristy Google Photos from 2012\2012-10-30 21.47.53.jpg>
|
||||
// FileSizeChanged <F:\Tmp\Phares\Compare\Images-4d49b68\Kristy Google Photos from 2012\2012-10-31 11.33.13.jpg>
|
||||
// FileSizeChanged <F:\Tmp\Phares\Compare\Images-4d49b68\Kristy Google Photos from 2012\2012-11-05 10.28.25.jpg>
|
||||
// FileSizeChanged <F:\Tmp\Phares\Compare\Images-4d49b68\Kristy Google Photos from 2012\2012-11-11 19.57.27.jpg>
|
||||
// FileSizeChanged <F:\Tmp\Phares\Compare\Images-4d49b68\Kristy Google Photos from 2012\2012-11-12 14.15.39.jpg>
|
||||
// FileSizeChanged <F:\Tmp\Phares\Compare\Images-4d49b68\Kristy Google Photos from 2012\2012-11-13 09.49.09.jpg>
|
||||
// FileSizeChanged <F:\Tmp\Phares\Compare\Images-4d49b68\Kristy Google Photos from 2012\2012-11-15 08.55.19.jpg>
|
||||
// FileSizeChanged <F:\Tmp\Phares\Compare\Images-4d49b68\Kristy Google Photos from 2012\2012-12-01 18.03.13.jpg>
|
||||
// FileSizeChanged <F:\Tmp\Phares\Compare\Images-4d49b68\Kristy Google Photos from 2012\2012-12-04 08.44.23.jpg>
|
||||
// FileSizeChanged <F:\Tmp\Phares\Compare\Images-4d49b68\Kristy Google Photos from 2012\2012-12-10 21.20.31.jpg>
|
||||
// FileSizeChanged <F:\Tmp\Phares\Compare\Images-4d49b68\Kristy Google Photos from 2012\2012-12-16 18.17.53.jpg>
|
||||
// FileSizeChanged <F:\Tmp\Phares\Compare\Images-4d49b68\Kristy Google Photos from 2013\IMG_20130317_113053.jpg>
|
||||
// FileSizeChanged <F:\Tmp\Phares\Compare\Images-4d49b68\Kristy Google Photos from 2013\IMG_20130324_133916.jpg>
|
||||
// FileSizeChanged <F:\Tmp\Phares\Compare\Images-4d49b68\Kristy Google Photos from 2013\IMG_20130330_114757.jpg>
|
||||
// FileSizeChanged <F:\Tmp\Phares\Compare\Images-4d49b68\Kristy Google Photos from 2013\IMG_20130418_175845.jpg>
|
||||
// FileSizeChanged <F:\Tmp\Phares\Compare\Images-4d49b68\Kristy Google Photos from 2013\IMG_20130418_175934.jpg>
|
||||
// FileSizeChanged <F:\Tmp\Phares\Compare\Images-4d49b68\Kristy Google Photos from 2013\IMG_20130424_202523.jpg>
|
||||
// FileSizeChanged <F:\Tmp\Phares\Compare\Images-4d49b68\Kristy Google Photos from 2013\IMG_20130424_202634.jpg>
|
||||
// FileSizeChanged <F:\Tmp\Phares\Compare\Images-4d49b68\Kristy Google Photos from 2013\IMG_20130514_190936.jpg>
|
||||
// LastWriteTimeChanged <F:\Tmp\Phares\Compare\Images-4d49b68\Kristy Google Photos from 2013\IMG_20130516_104450.jpg>
|
||||
// LastWriteTimeChanged <F:\Tmp\Phares\Compare\Images-4d49b68\Kristy Google Photos from 2013\IMG_20130522_193539.jpg>
|
||||
// LastWriteTimeChanged <F:\Tmp\Phares\Compare\Images-4d49b68\Herman Family Reunion 2008\Herman Family Reunion (160).jpg>
|
||||
// LastWriteTimeChanged <F:\Tmp\Phares\Compare\Images-4d49b68\Herman Family Reunion 2008\Herman Family Reunion (213).jpg>
|
||||
// LastWriteTimeChanged <F:\Tmp\Phares\Compare\Images-4d49b68\Herman Family Reunion 2008\Herman Family Reunion (215).jpg>
|
||||
// LastWriteTimeChanged <F:\Tmp\Phares\Compare\Images-4d49b68\Herman Family Reunion 2008\Herman Family Reunion (218).jpg>
|
||||
// LastWriteTimeChanged <F:\Tmp\Phares\Compare\Images-4d49b68\Herman Family Reunion 2008\Herman Family Reunion (225).jpg>
|
||||
// LastWriteTimeChanged <F:\Tmp\Phares\Compare\Images-4d49b68\Herman Family Reunion 2008\Herman Family Reunion (226).jpg>
|
||||
// LastWriteTimeChanged <F:\Tmp\Phares\Compare\Images-4d49b68\Herman Family Reunion 2008\Herman Family Reunion (231).jpg>
|
||||
// LastWriteTimeChanged <F:\Tmp\Phares\Compare\Images-4d49b68\Herman Family Reunion 2008\Herman Family Reunion (232).jpg>
|
||||
// LastWriteTimeChanged <F:\Tmp\Phares\Compare\Images-4d49b68\Herman Family Reunion 2008\Herman Family Reunion (234).jpg>
|
||||
// - Device Videos 2_0_0_3 - Current - Kristy Google
|
||||
// - Device Videos 2_0_0_3 - Current - Mike Google
|
||||
// - Device Videos 2_0_0_3 - Current - Tracy
|
||||
// Chester & Linores ?Pearson?
|
||||
// Distance face files date time?
|
||||
// If not Hog and Original image size resize face
|
||||
// New json file with known locations at original image size
|
||||
// Add person to metadata when saving to SaveFilteredOriginalImagesFromJLinksForOutputResolutions maybe SaveMappedForOutputResolutions
|
||||
// GetFaceLocations
|
||||
// Stream stream;
|
||||
// FileType fileType;
|
||||
// const string abd = ".abd";
|
||||
// List<string> jsonGroupFiles = GetFileCollection(jsonGroupFileCollection);
|
||||
// foreach (string jsonGroupFile in jsonGroupFiles)
|
||||
// File.Move(jsonGroupFile, string.Concat(jsonGroupFile, abd));
|
||||
// stream = new FileStream(file, FileMode.Open, FileAccess.Read, FileShare.Read);
|
||||
// fileType = FileTypeDetector.DetectFileType(stream);
|
||||
// stream.Close();
|
||||
// stream.Dispose();
|
||||
// if (fileType == FileType.Unknown)
|
||||
// continue;
|
||||
// if (!isUniqueFileName || string.IsNullOrEmpty(resultAllInOneKey))
|
||||
// {
|
||||
// if (!isUniqueFileName && !string.IsNullOrEmpty(resultAllInOneKey))
|
||||
// File.Move(Path.Combine(resultAllInOneKey, fileName), Path.Combine(resultAllInOneKey, $"{fileName}.del"));
|
||||
// resultAllInOneKey = string.Concat(jsonGroupDirectory, directoryName[length..]);
|
||||
// }
|
||||
// if (!jsonGroupFileCollection.TryGetValue(resultAllInOneKey, out keyValuePairs) || !keyValuePairs.TryGetValue(fileName, out collection))
|
||||
// fileAndJsonGroupFiles.Add(new FileAndJsonGroupFile(file, isUniqueFileName, Path.Combine(resultAllInOneKey, fileName), false));
|
||||
// else
|
||||
// {
|
||||
// foreach (string jsonGroupFile in collection)
|
||||
// // File.Move(string.Concat(jsonGroupFile, abd), jsonGroupFile);
|
||||
// fileAndJsonGroupFiles.Add(new FileAndJsonGroupFile(file, isUniqueFileName, jsonGroupFile, true));
|
||||
// }
|
||||
// C:\Program Files\ImageMagick-7.1.0-Q16-HDRI>identify -format '%Q' "D:\7-Question\- - - Images\Mike Goolgle Photos 2014\-1507651551.jpg"
|
||||
// '98'
|
||||
// C:\Program Files\ImageMagick-7.1.0-Q16-HDRI>identify -format '%Q' "D:\7) Question\- - - Images\Mike Goolgle Photos 2014\197616258.jpg"
|
||||
// '90'
|
||||
// dotnet dead-csharp --inputs "**/*.cs" --excludes "**/obj/**" "**/I*.cs" "**/UnitTest*.cs"
|
||||
// " - Shortcut (2)"
|
||||
// _ Manual Copy Successful
|
||||
// # Don't know full birthday
|
||||
// ] Match
|
||||
// ^ Know birthday
|
||||
// _ Import of Partial info
|
||||
// ` Want to find
|
||||
// ~ Approxomite age
|
||||
// + Approxomite age and have at least one image
|
||||
// XPAuthor = 40093 | [3-1] ("Picasa") <Verified in Windows>
|
||||
// Artist = 315 | [182-3] ("Picasa", "unknown", " ")
|
||||
// Kristy, Mike, Tracy, Mackenzie, Julie, Patrick, ...
|
||||
// XPKeywords = 40094 | Vulgar !9, Blurry !4, Duplicate !3, Irrelevant !2, Review !1, Slideshow [0]
|
||||
// XPSubject = 40095 | Family Pictures, Scanned [2-1] (" ")
|
||||
// XPComment = 40092 | [9-2] ("\uFFFD", " ")
|
||||
// Rating = 18246 | [52-1] ("0")
|
||||
// UserComment = 37510 | [3570-^^^]
|
||||
// XPTitle = 40091 | [24-24] ("Logan and his Doggie", ...) <Verified in Windows>
|
||||
// ImageDescription = 270 | [2135-5^] 4+37+82+1354+647+11 ("Camera 360", "OLYMPUS DIGITAL CAMERA ", "SAMSUNG ", " ", " ")
|
||||
// int artist = (int)IExif.Tags.Artist;
|
||||
// int fileSource = (int)IExif.Tags.FileSource;
|
||||
// int userComment = (int)IExif.Tags.UserComment;
|
||||
// 0x9c9b XPTitle int8u IFD0 (tags 0x9c9b-0x9c9f are used by Windows Explorer; special characters in these values are converted to UTF-8 by default, or Windows Latin1 with the -L option. XPTitle is ignored by Windows Explorer if ImageDescription exists)
|
||||
// 0x9c9c XPComment int8u IFD0
|
||||
// 0x9c9d XPAuthor int8u IFD0 (ignored by Windows Explorer if Artist exists)
|
||||
// 0x9c9e XPKeywords int8u IFD0
|
||||
// 0x9c9f XPSubject int8u IFD0
|
||||
// 0xa300 FileSource undef ExifIFD 1 = Film Scanner
|
||||
// 2 = Reflection Print Scanner
|
||||
// 3 = Digital Camera
|
||||
// "\x03\x00\x00\x00" = Sigma Digital Camera
|
||||
// 0x9286 UserComment undef ExifIFD
|
||||
// 0x013b Artist string IFD0 (becomes a list-type tag when the MWG module is loaded)
|
15
.vscode/mklink.md
vendored
Normal file
15
.vscode/mklink.md
vendored
Normal file
@ -0,0 +1,15 @@
|
||||
---
|
||||
type: "note"
|
||||
created: "2023-10-20T03:58:11.564Z"
|
||||
updated: "2023-10-20T03:59:01.765Z"
|
||||
---
|
||||
|
||||
# mklink
|
||||
|
||||
```bash
|
||||
mklink /J "L:\Git\AA\Shared\.kanbn" "D:\5-Other-Small\Kanban\View-by-Distance"
|
||||
```
|
||||
|
||||
```bash
|
||||
mklink /J "L:\Git\AA\Shared\.kanbn" "D:\5-Other-Small\Kanban\View-by-Distance"
|
||||
```
|
61
.vscode/settings.json
vendored
Normal file
61
.vscode/settings.json
vendored
Normal file
@ -0,0 +1,61 @@
|
||||
{
|
||||
"cSpell.words": [
|
||||
"appsettings",
|
||||
"Argb",
|
||||
"ASPNETCORE",
|
||||
"Barrick",
|
||||
"bcdfghjklmnpqrstvwxyz",
|
||||
"Bday",
|
||||
"Beichler",
|
||||
"Bohdi",
|
||||
"Cobertura",
|
||||
"cref",
|
||||
"CUDA",
|
||||
"Dlib",
|
||||
"DSCN",
|
||||
"Exif",
|
||||
"eyeα",
|
||||
"Getα",
|
||||
"Greyscale",
|
||||
"Hasher",
|
||||
"Hmmss",
|
||||
"Hmmssfff",
|
||||
"jfif",
|
||||
"JOSN",
|
||||
"mmod",
|
||||
"Nicéphore",
|
||||
"Niépce",
|
||||
"nosj",
|
||||
"paramref",
|
||||
"permille",
|
||||
"permyriad",
|
||||
"Phares",
|
||||
"Phgtv",
|
||||
"Photoshop",
|
||||
"RDHC",
|
||||
"recognise",
|
||||
"Rects",
|
||||
"resnet",
|
||||
"Serilog",
|
||||
"Subfile",
|
||||
"Subfiles",
|
||||
"Syncthing",
|
||||
"Unmanaged",
|
||||
"unrecognised",
|
||||
"Upsample",
|
||||
"Vericruz"
|
||||
],
|
||||
"files.watcherExclude": {
|
||||
"**/node_modules": true
|
||||
},
|
||||
"cSpell.enabled": true,
|
||||
"files.exclude": {
|
||||
"**/.git": false,
|
||||
"**/node_modules": true
|
||||
},
|
||||
"coverage-gutters.coverageBaseDir": "./.vscode/ReportGenerator/Cobertura/*",
|
||||
"extensions.ignoreRecommendations": true,
|
||||
"[markdown]": {
|
||||
"editor.wordWrap": "off"
|
||||
}
|
||||
}
|
75
.vscode/tasks.json
vendored
Normal file
75
.vscode/tasks.json
vendored
Normal file
@ -0,0 +1,75 @@
|
||||
{
|
||||
"version": "2.0.0",
|
||||
"tasks": [
|
||||
{
|
||||
"label": "User Secrets Init",
|
||||
"command": "dotnet",
|
||||
"type": "process",
|
||||
"args": [
|
||||
"user-secrets",
|
||||
"-p",
|
||||
"${workspaceFolder}/Rename/AA.Rename.csproj",
|
||||
"init"
|
||||
],
|
||||
"problemMatcher": "$msCompile"
|
||||
},
|
||||
{
|
||||
"label": "User Secrets Set",
|
||||
"command": "dotnet",
|
||||
"type": "process",
|
||||
"args": [
|
||||
"user-secrets",
|
||||
"-p",
|
||||
"${workspaceFolder}/Rename/AA.Rename.csproj",
|
||||
"set",
|
||||
"_Application",
|
||||
"Rename"
|
||||
],
|
||||
"problemMatcher": "$msCompile"
|
||||
},
|
||||
{
|
||||
"label": "Format",
|
||||
"command": "dotnet",
|
||||
"type": "process",
|
||||
"args": [
|
||||
"format",
|
||||
"--report",
|
||||
".vscode",
|
||||
"--verbosity",
|
||||
"detailed",
|
||||
"--severity",
|
||||
"warn"
|
||||
],
|
||||
"problemMatcher": "$msCompile"
|
||||
},
|
||||
{
|
||||
"label": "build",
|
||||
"command": "dotnet",
|
||||
"type": "process",
|
||||
"args": [
|
||||
"build",
|
||||
"${workspaceFolder}/AA.sln",
|
||||
"/property:GenerateFullPaths=true",
|
||||
"/consoleloggerparameters:NoSummary"
|
||||
],
|
||||
"problemMatcher": "$msCompile"
|
||||
},
|
||||
{
|
||||
"label": "Publish AOT",
|
||||
"command": "dotnet",
|
||||
"type": "process",
|
||||
"args": [
|
||||
"publish",
|
||||
"-r",
|
||||
"win-x64",
|
||||
"-c",
|
||||
"Release",
|
||||
"-p:PublishAot=true",
|
||||
"${workspaceFolder}/Rename/AA.Rename.csproj",
|
||||
"/property:GenerateFullPaths=true",
|
||||
"/consoleloggerparameters:NoSummary"
|
||||
],
|
||||
"problemMatcher": "$msCompile"
|
||||
}
|
||||
]
|
||||
}
|
34
AA.sln
Normal file
34
AA.sln
Normal file
@ -0,0 +1,34 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio Version 17
|
||||
VisualStudioVersion = 17.0.31903.59
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AA.Shared", "Shared\AA.Shared.csproj", "{74E6778C-FCBE-4959-AFED-7C528BC5F855}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AA.Metadata", "Metadata\AA.Metadata.csproj", "{9E1FE0DA-8A9C-49B4-82BC-67F68D42F49C}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AA.Rename", "Rename\AA.Rename.csproj", "{E80BF7A6-C892-426D-829C-910BD4700E69}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
Release|Any CPU = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{74E6778C-FCBE-4959-AFED-7C528BC5F855}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{74E6778C-FCBE-4959-AFED-7C528BC5F855}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{74E6778C-FCBE-4959-AFED-7C528BC5F855}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{74E6778C-FCBE-4959-AFED-7C528BC5F855}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{9E1FE0DA-8A9C-49B4-82BC-67F68D42F49C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{9E1FE0DA-8A9C-49B4-82BC-67F68D42F49C}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{9E1FE0DA-8A9C-49B4-82BC-67F68D42F49C}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{9E1FE0DA-8A9C-49B4-82BC-67F68D42F49C}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{E80BF7A6-C892-426D-829C-910BD4700E69}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{E80BF7A6-C892-426D-829C-910BD4700E69}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{E80BF7A6-C892-426D-829C-910BD4700E69}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{E80BF7A6-C892-426D-829C-910BD4700E69}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
EndGlobal
|
43
Metadata/AA.Metadata.csproj
Normal file
43
Metadata/AA.Metadata.csproj
Normal file
@ -0,0 +1,43 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
<OutputType>library</OutputType>
|
||||
<RuntimeIdentifier>win-x64</RuntimeIdentifier>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<PackageId>Phares.AA.Metadata</PackageId>
|
||||
<GeneratePackageOnBuild>false</GeneratePackageOnBuild>
|
||||
<Version>8.0.101.1</Version>
|
||||
<Authors>Mike Phares</Authors>
|
||||
<Company>Phares</Company>
|
||||
<IncludeSymbols>true</IncludeSymbols>
|
||||
<SymbolPackageFormat>snupkg</SymbolPackageFormat>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<IsWindows Condition="'$([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::Windows)))' == 'true'">true</IsWindows>
|
||||
<IsOSX Condition="'$([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::OSX)))' == 'true'">true</IsOSX>
|
||||
<IsLinux Condition="'$([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::Linux)))' == 'true'">true</IsLinux>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(IsWindows)'=='true'">
|
||||
<DefineConstants>Windows</DefineConstants>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(IsOSX)'=='true'">
|
||||
<DefineConstants>OSX</DefineConstants>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(IsLinux)'=='true'">
|
||||
<DefineConstants>Linux</DefineConstants>
|
||||
</PropertyGroup>
|
||||
<ItemGroup Condition="'$(RuntimeIdentifier)' == 'browser-wasm'">
|
||||
<SupportedPlatform Include="browser" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="MetadataExtractor" Version="2.8.1" />
|
||||
<PackageReference Include="System.Text.Json" Version="7.0.3" />
|
||||
<PackageReference Include="Microsoft.Extensions.Hosting" Version="7.0.1" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Shared\AA.Shared.csproj" />
|
||||
</ItemGroup>
|
||||
</Project>
|
98
Metadata/Models/A_Metadata.cs
Normal file
98
Metadata/Models/A_Metadata.cs
Normal file
@ -0,0 +1,98 @@
|
||||
using MetadataExtractor;
|
||||
using System.Text.Json;
|
||||
using View_by_Distance.Metadata.Models.Stateless;
|
||||
using View_by_Distance.Metadata.Models.Stateless.Methods;
|
||||
using View_by_Distance.Shared.Models;
|
||||
using View_by_Distance.Shared.Models.Properties;
|
||||
|
||||
namespace View_by_Distance.Metadata.Models;
|
||||
|
||||
public class A_Metadata
|
||||
{
|
||||
|
||||
private readonly IAAConfiguration _AAConfiguration;
|
||||
private readonly bool _PropertiesChangedForMetadata;
|
||||
private readonly bool _ForceMetadataLastWriteTimeToCreationTime;
|
||||
private readonly IReadOnlyDictionary<string, string[]> _FileGroups;
|
||||
|
||||
public A_Metadata(IAAConfiguration aAConfiguration, bool forceMetadataLastWriteTimeToCreationTime, bool propertiesChangedForMetadata)
|
||||
{
|
||||
_AAConfiguration = aAConfiguration;
|
||||
_PropertiesChangedForMetadata = propertiesChangedForMetadata;
|
||||
_ForceMetadataLastWriteTimeToCreationTime = forceMetadataLastWriteTimeToCreationTime;
|
||||
string bResultsFullGroupDirectory = Shared.Models.Stateless.Methods.IResult.GetResultsFullGroupDirectory(_AAConfiguration,
|
||||
nameof(A_Metadata),
|
||||
string.Empty,
|
||||
includeResizeGroup: false,
|
||||
includeModel: false,
|
||||
includePredictorModel: false);
|
||||
_FileGroups = Shared.Models.Stateless.Methods.IPath.GetKeyValuePairs(aAConfiguration, bResultsFullGroupDirectory, [aAConfiguration.ResultSingleton]);
|
||||
}
|
||||
|
||||
public ExifDirectory GetMetadataCollection(string file)
|
||||
{
|
||||
ExifDirectory? results;
|
||||
string fileName = Path.GetFileName(file);
|
||||
string fileExtensionLowered = Path.GetExtension(file).ToLower();
|
||||
string fileNameWithoutExtension = Path.GetFileNameWithoutExtension(file);
|
||||
(_, int directoryIndex) = Shared.Models.Stateless.Methods.IPath.GetDirectoryNameAndIndex(_AAConfiguration.ResultAllInOneSubdirectoryLength, fileName);
|
||||
FileInfo fileInfo = new(Path.Combine(_FileGroups[_AAConfiguration.ResultSingleton][directoryIndex], $"{fileNameWithoutExtension}{fileExtensionLowered}.json"));
|
||||
if (_ForceMetadataLastWriteTimeToCreationTime && !fileInfo.Exists && File.Exists(Path.ChangeExtension(fileInfo.FullName, ".delete")))
|
||||
{
|
||||
File.Move(Path.ChangeExtension(fileInfo.FullName, ".delete"), fileInfo.FullName);
|
||||
fileInfo.Refresh();
|
||||
}
|
||||
if (_ForceMetadataLastWriteTimeToCreationTime && fileInfo.Exists && fileInfo.LastWriteTime != fileInfo.CreationTime)
|
||||
{
|
||||
File.SetLastWriteTime(fileInfo.FullName, fileInfo.CreationTime);
|
||||
fileInfo.Refresh();
|
||||
}
|
||||
if (_PropertiesChangedForMetadata)
|
||||
results = null;
|
||||
else if (!fileInfo.Exists)
|
||||
results = null;
|
||||
else if (!fileInfo.FullName.EndsWith(".json") && !fileInfo.FullName.EndsWith(".old"))
|
||||
throw new ArgumentException("must be a *.json file");
|
||||
else
|
||||
{
|
||||
string json = File.ReadAllText(fileInfo.FullName);
|
||||
try
|
||||
{
|
||||
results = JsonSerializer.Deserialize(json, ExifDirectorySourceGenerationContext.Default.ExifDirectory);
|
||||
if (results is null)
|
||||
throw new Exception();
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
results = null;
|
||||
}
|
||||
}
|
||||
if (results is null)
|
||||
{
|
||||
System.Drawing.Size? size;
|
||||
try
|
||||
{ size = Dimensions.GetDimensions(file); }
|
||||
catch (Exception) { size = null; }
|
||||
IReadOnlyList<MetadataExtractor.Directory> directories = ImageMetadataReader.ReadMetadata(file);
|
||||
results = Exif.Covert(file, fileInfo, size, directories);
|
||||
string json = JsonSerializer.Serialize(results, ExifDirectorySourceGenerationContext.Default.ExifDirectory);
|
||||
if (Shared.Models.Stateless.Methods.IPath.WriteAllText(fileInfo.FullName, json, updateDateWhenMatches: false, compareBeforeWrite: true, updateToWhenMatches: null) && _ForceMetadataLastWriteTimeToCreationTime)
|
||||
{
|
||||
File.SetLastWriteTime(fileInfo.FullName, fileInfo.CreationTime);
|
||||
fileInfo.Refresh();
|
||||
}
|
||||
}
|
||||
return results;
|
||||
}
|
||||
|
||||
public static Action<string> GetResultCollection(A_Metadata metadata, List<ExifDirectory> exifDirectories, Action tick)
|
||||
{
|
||||
return file =>
|
||||
{
|
||||
tick.Invoke();
|
||||
lock (exifDirectories)
|
||||
exifDirectories.Add(metadata.GetMetadataCollection(file));
|
||||
};
|
||||
}
|
||||
|
||||
}
|
2
Metadata/Models/Binder/.editorconfig
Normal file
2
Metadata/Models/Binder/.editorconfig
Normal file
@ -0,0 +1,2 @@
|
||||
[*.cs]
|
||||
csharp_preserve_single_line_statements = true
|
119
Metadata/Models/Binder/Configuration.cs
Normal file
119
Metadata/Models/Binder/Configuration.cs
Normal file
@ -0,0 +1,119 @@
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using System.Text.Json;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace View_by_Distance.Metadata.Models.Binder;
|
||||
|
||||
public class Configuration
|
||||
{
|
||||
|
||||
public string? DateGroup { get; set; }
|
||||
public string? FileNameDirectorySeparator { get; set; }
|
||||
public bool? ForcePropertyLastWriteTimeToCreationTime { get; set; }
|
||||
public string[]? IgnoreExtensions { get; set; }
|
||||
public string[]? IgnoreRulesKeyWords { get; set; }
|
||||
public int? MaxImagesInDirectoryForTopLevelFirstPass { get; set; }
|
||||
public string? ModelName { init; get; }
|
||||
public int? NumberOfJitters { init; get; }
|
||||
public int? NumberOfTimesToUpsample { init; get; }
|
||||
public int? Offset { init; get; }
|
||||
public string? Pattern { get; set; }
|
||||
public string? PersonBirthdayFormat { get; set; }
|
||||
public bool? PopulatePropertyId { get; set; }
|
||||
public string? PredictorModelName { get; set; }
|
||||
public bool? PropertiesChangedForProperty { get; set; }
|
||||
public string[]? PropertyContentCollectionFiles { get; set; }
|
||||
public string? ResultAllInOne { get; set; }
|
||||
public int? ResultAllInOneSubdirectoryLength { get; set; }
|
||||
public string? ResultCollection { get; set; }
|
||||
public string? ResultContent { get; set; }
|
||||
public string? ResultSingleton { get; set; }
|
||||
public string? RootDirectory { get; set; }
|
||||
public string[]? ValidImageFormatExtensions { get; set; }
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
string result = JsonSerializer.Serialize(this, BinderMetadataConfigurationSourceGenerationContext.Default.Configuration);
|
||||
return result;
|
||||
}
|
||||
|
||||
private static MetadataConfiguration Get(Configuration? configuration)
|
||||
{
|
||||
MetadataConfiguration result;
|
||||
if (configuration is null) throw new NullReferenceException(nameof(configuration));
|
||||
if (configuration.DateGroup is null) throw new NullReferenceException(nameof(configuration.DateGroup));
|
||||
if (configuration.FileNameDirectorySeparator is null) throw new NullReferenceException(nameof(configuration.FileNameDirectorySeparator));
|
||||
if (configuration.ForcePropertyLastWriteTimeToCreationTime is null) throw new NullReferenceException(nameof(configuration.ForcePropertyLastWriteTimeToCreationTime));
|
||||
if (configuration.IgnoreExtensions is null) throw new NullReferenceException(nameof(configuration.IgnoreExtensions));
|
||||
if (configuration.IgnoreRulesKeyWords is null) throw new NullReferenceException(nameof(configuration.IgnoreRulesKeyWords));
|
||||
if (configuration.MaxImagesInDirectoryForTopLevelFirstPass is null) throw new NullReferenceException(nameof(configuration.MaxImagesInDirectoryForTopLevelFirstPass));
|
||||
// if (configuration.ModelName is null) throw new NullReferenceException(nameof(configuration.ModelName));
|
||||
// if (configuration.NumberOfJitters is null) throw new NullReferenceException(nameof(configuration.NumberOfJitters));
|
||||
// if (configuration.NumberOfTimesToUpsample is null) throw new NullReferenceException(nameof(configuration.NumberOfTimesToUpsample));
|
||||
if (configuration.Offset is null) throw new NullReferenceException(nameof(configuration.Offset)); ;
|
||||
if (configuration.Pattern is null) throw new NullReferenceException(nameof(configuration.Pattern));
|
||||
if (configuration.PersonBirthdayFormat is null) throw new NullReferenceException(nameof(configuration.PersonBirthdayFormat));
|
||||
if (configuration.PopulatePropertyId is null) throw new NullReferenceException(nameof(configuration.PopulatePropertyId));
|
||||
// if (configuration.PredictorModelName is null) throw new NullReferenceException(nameof(configuration.PredictorModelName));
|
||||
if (configuration.PropertiesChangedForProperty is null) throw new NullReferenceException(nameof(configuration.PropertiesChangedForProperty));
|
||||
// if (configuration.PropertyContentCollectionFiles is null) throw new NullReferenceException(nameof(configuration.PropertyContentCollectionFiles));
|
||||
if (configuration.ResultAllInOne is null) throw new NullReferenceException(nameof(configuration.ResultAllInOne));
|
||||
if (configuration.ResultAllInOneSubdirectoryLength is null) throw new NullReferenceException(nameof(configuration.ResultAllInOneSubdirectoryLength));
|
||||
if (configuration.ResultCollection is null) throw new NullReferenceException(nameof(configuration.ResultCollection));
|
||||
if (configuration.ResultContent is null) throw new NullReferenceException(nameof(configuration.ResultContent));
|
||||
if (configuration.ResultSingleton is null) throw new NullReferenceException(nameof(configuration.ResultSingleton));
|
||||
if (configuration.RootDirectory is null) throw new NullReferenceException(nameof(configuration.RootDirectory));
|
||||
if (configuration.ValidImageFormatExtensions is null) throw new NullReferenceException(nameof(configuration.ValidImageFormatExtensions));
|
||||
result = new(configuration.DateGroup,
|
||||
configuration.FileNameDirectorySeparator,
|
||||
configuration.ForcePropertyLastWriteTimeToCreationTime.Value,
|
||||
configuration.IgnoreExtensions,
|
||||
configuration.IgnoreRulesKeyWords,
|
||||
configuration.MaxImagesInDirectoryForTopLevelFirstPass.Value,
|
||||
configuration.ModelName,
|
||||
configuration.NumberOfJitters,
|
||||
configuration.NumberOfTimesToUpsample,
|
||||
configuration.Offset.Value,
|
||||
configuration.Pattern,
|
||||
configuration.PersonBirthdayFormat,
|
||||
configuration.PopulatePropertyId.Value,
|
||||
configuration.PredictorModelName,
|
||||
configuration.PropertiesChangedForProperty.Value,
|
||||
configuration.PropertyContentCollectionFiles ?? [],
|
||||
configuration.ResultAllInOne,
|
||||
configuration.ResultAllInOneSubdirectoryLength.Value,
|
||||
configuration.ResultCollection,
|
||||
configuration.ResultContent,
|
||||
configuration.ResultSingleton,
|
||||
Path.GetFullPath(configuration.RootDirectory),
|
||||
configuration.ValidImageFormatExtensions);
|
||||
return result;
|
||||
}
|
||||
|
||||
public static MetadataConfiguration Get(IConfigurationRoot configurationRoot)
|
||||
{
|
||||
MetadataConfiguration result;
|
||||
#if Linux
|
||||
string environmentName = "Linux";
|
||||
#elif OSX
|
||||
string environmentName = "OSX";
|
||||
#elif Windows
|
||||
string environmentName = "Windows";
|
||||
#endif
|
||||
string section = string.Concat(environmentName, ":", nameof(Configuration));
|
||||
IConfigurationSection configurationSection = configurationRoot.GetSection(section);
|
||||
#pragma warning disable IL3050, IL2026
|
||||
Configuration? configuration = configurationSection.Get<Configuration>();
|
||||
#pragma warning restore IL3050, IL2026
|
||||
if (configuration is null) throw new NullReferenceException(nameof(configuration));
|
||||
result = Get(configuration);
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
[JsonSourceGenerationOptions(WriteIndented = true)]
|
||||
[JsonSerializable(typeof(Configuration))]
|
||||
internal partial class BinderMetadataConfigurationSourceGenerationContext : JsonSerializerContext
|
||||
{
|
||||
}
|
127
Metadata/Models/MetadataConfiguration.cs
Normal file
127
Metadata/Models/MetadataConfiguration.cs
Normal file
@ -0,0 +1,127 @@
|
||||
using System.Text.Json;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace View_by_Distance.Metadata.Models;
|
||||
|
||||
public class MetadataConfiguration : Shared.Models.Properties.IAAConfiguration
|
||||
{
|
||||
|
||||
protected string _RootDirectory;
|
||||
|
||||
public string RootDirectory => _RootDirectory;
|
||||
|
||||
public string DateGroup { init; get; }
|
||||
public string FileNameDirectorySeparator { init; get; }
|
||||
public bool ForcePropertyLastWriteTimeToCreationTime { init; get; }
|
||||
public string[] IgnoreExtensions { init; get; }
|
||||
public string[] IgnoreRulesKeyWords { init; get; }
|
||||
public int MaxImagesInDirectoryForTopLevelFirstPass { init; get; }
|
||||
public string? ModelName { init; get; }
|
||||
public int? NumberOfJitters { init; get; }
|
||||
public int? NumberOfTimesToUpsample { init; get; }
|
||||
public int Offset { init; get; }
|
||||
public string Pattern { init; get; }
|
||||
public string PersonBirthdayFormat { init; get; }
|
||||
public bool PopulatePropertyId { init; get; }
|
||||
public string? PredictorModelName { init; get; }
|
||||
public bool PropertiesChangedForProperty { init; get; }
|
||||
public string[] PropertyContentCollectionFiles { init; get; }
|
||||
public string ResultAllInOne { init; get; }
|
||||
public int ResultAllInOneSubdirectoryLength { init; get; }
|
||||
public string ResultCollection { init; get; }
|
||||
public string ResultContent { init; get; }
|
||||
public string ResultSingleton { init; get; }
|
||||
public string[] ValidImageFormatExtensions { init; get; }
|
||||
|
||||
[JsonConstructor]
|
||||
public MetadataConfiguration(string dateGroup,
|
||||
string fileNameDirectorySeparator,
|
||||
bool forcePropertyLastWriteTimeToCreationTime,
|
||||
string[] ignoreExtensions,
|
||||
string[] ignoreRulesKeyWords,
|
||||
int maxImagesInDirectoryForTopLevelFirstPass,
|
||||
string? modelName,
|
||||
int? numberOfJitters,
|
||||
int? numberOfTimesToUpsample,
|
||||
int offset,
|
||||
string pattern,
|
||||
string personBirthdayFormat,
|
||||
bool populatePropertyId,
|
||||
string? predictorModelName,
|
||||
bool propertiesChangedForProperty,
|
||||
string[] propertyContentCollectionFiles,
|
||||
string resultAllInOne,
|
||||
int resultAllInOneSubdirectoryLength,
|
||||
string resultCollection,
|
||||
string resultContent,
|
||||
string resultSingleton,
|
||||
string rootDirectory,
|
||||
string[] validImageFormatExtensions)
|
||||
{
|
||||
DateGroup = dateGroup;
|
||||
FileNameDirectorySeparator = fileNameDirectorySeparator;
|
||||
ForcePropertyLastWriteTimeToCreationTime = forcePropertyLastWriteTimeToCreationTime;
|
||||
IgnoreExtensions = ignoreExtensions;
|
||||
IgnoreRulesKeyWords = ignoreRulesKeyWords;
|
||||
MaxImagesInDirectoryForTopLevelFirstPass = maxImagesInDirectoryForTopLevelFirstPass;
|
||||
ModelName = modelName;
|
||||
NumberOfJitters = numberOfJitters;
|
||||
NumberOfTimesToUpsample = numberOfTimesToUpsample;
|
||||
Offset = offset;
|
||||
Pattern = pattern;
|
||||
PersonBirthdayFormat = personBirthdayFormat;
|
||||
PredictorModelName = predictorModelName;
|
||||
PopulatePropertyId = populatePropertyId;
|
||||
PropertiesChangedForProperty = propertiesChangedForProperty;
|
||||
PropertyContentCollectionFiles = propertyContentCollectionFiles;
|
||||
ResultAllInOne = resultAllInOne;
|
||||
ResultAllInOneSubdirectoryLength = resultAllInOneSubdirectoryLength;
|
||||
ResultCollection = resultCollection;
|
||||
ResultContent = resultContent;
|
||||
ResultSingleton = resultSingleton;
|
||||
_RootDirectory = rootDirectory;
|
||||
ValidImageFormatExtensions = validImageFormatExtensions;
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
string result = JsonSerializer.Serialize(this, MetadataConfigurationSourceGenerationContext.Default.MetadataConfiguration);
|
||||
return result;
|
||||
}
|
||||
|
||||
public void ChangeRootDirectory(string rootDirectory) =>
|
||||
_RootDirectory = Path.GetFullPath(rootDirectory);
|
||||
|
||||
public static void Verify(MetadataConfiguration propertyConfiguration, bool requireExist)
|
||||
{
|
||||
if (propertyConfiguration is null)
|
||||
throw new NullReferenceException(nameof(propertyConfiguration));
|
||||
if (propertyConfiguration.IgnoreExtensions is null || propertyConfiguration.IgnoreExtensions.Length == 0)
|
||||
throw new NullReferenceException(nameof(propertyConfiguration.IgnoreExtensions));
|
||||
if (propertyConfiguration.IgnoreRulesKeyWords is null || propertyConfiguration.IgnoreRulesKeyWords.Length == 0)
|
||||
throw new NullReferenceException(nameof(propertyConfiguration.IgnoreRulesKeyWords));
|
||||
if (propertyConfiguration.PropertyContentCollectionFiles is null)
|
||||
throw new NullReferenceException(nameof(propertyConfiguration.PropertyContentCollectionFiles));
|
||||
if (propertyConfiguration.ValidImageFormatExtensions is null || propertyConfiguration.ValidImageFormatExtensions.Length == 0)
|
||||
throw new NullReferenceException(nameof(propertyConfiguration.ValidImageFormatExtensions));
|
||||
if (propertyConfiguration is null)
|
||||
throw new NullReferenceException(nameof(propertyConfiguration));
|
||||
if (string.IsNullOrEmpty(propertyConfiguration.DateGroup))
|
||||
throw new NullReferenceException(nameof(propertyConfiguration.DateGroup));
|
||||
if (string.IsNullOrEmpty(propertyConfiguration.FileNameDirectorySeparator))
|
||||
throw new NullReferenceException(nameof(propertyConfiguration.FileNameDirectorySeparator));
|
||||
if (string.IsNullOrEmpty(propertyConfiguration.Pattern))
|
||||
throw new NullReferenceException(nameof(propertyConfiguration.Pattern));
|
||||
if (string.IsNullOrEmpty(propertyConfiguration.RootDirectory) || (requireExist && !Directory.Exists(propertyConfiguration.RootDirectory)))
|
||||
throw new NullReferenceException(nameof(propertyConfiguration.RootDirectory));
|
||||
if (propertyConfiguration.RootDirectory != Path.GetFullPath(propertyConfiguration.RootDirectory))
|
||||
throw new Exception();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
[JsonSourceGenerationOptions(WriteIndented = true)]
|
||||
[JsonSerializable(typeof(MetadataConfiguration))]
|
||||
internal partial class MetadataConfigurationSourceGenerationContext : JsonSerializerContext
|
||||
{
|
||||
}
|
173
Metadata/Models/Stateless/Dimensions.cs
Normal file
173
Metadata/Models/Stateless/Dimensions.cs
Normal file
@ -0,0 +1,173 @@
|
||||
using System.Drawing;
|
||||
|
||||
namespace View_by_Distance.Metadata.Models.Stateless.Methods;
|
||||
|
||||
internal static class Dimensions
|
||||
{
|
||||
|
||||
const string _ErrorMessage = "Could not recognize image format.";
|
||||
|
||||
#pragma warning disable IDE0230
|
||||
private static readonly Dictionary<byte[], Func<BinaryReader, Size>> _ImageFormatDecoders = new()
|
||||
{
|
||||
{ new byte[] { 0x42, 0x4D }, DecodeBitmap },
|
||||
{ new byte[] { 0x47, 0x49, 0x46, 0x38, 0x37, 0x61 }, DecodeGif },
|
||||
{ new byte[] { 0x47, 0x49, 0x46, 0x38, 0x39, 0x61 }, DecodeGif },
|
||||
{ new byte[] { 0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A }, DecodePng },
|
||||
{ new byte[] { 0xff, 0xd8 }, DecodeJfif },
|
||||
{ new byte[] { 0x52, 0x49, 0x46, 0x46 }, DecodeWebP },
|
||||
};
|
||||
#pragma warning restore IDE0230
|
||||
|
||||
private static bool StartsWith(byte[] thisBytes, byte[] thatBytes)
|
||||
{
|
||||
for (int i = 0; i < thatBytes.Length; i += 1)
|
||||
{
|
||||
if (thisBytes[i] != thatBytes[i])
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private static short ReadLittleEndianInt16(BinaryReader binaryReader)
|
||||
{
|
||||
byte[] bytes = new byte[sizeof(short)];
|
||||
for (int i = 0; i < sizeof(short); i += 1)
|
||||
{
|
||||
bytes[sizeof(short) - 1 - i] = binaryReader.ReadByte();
|
||||
}
|
||||
return BitConverter.ToInt16(bytes, 0);
|
||||
}
|
||||
|
||||
private static int ReadLittleEndianInt32(BinaryReader binaryReader)
|
||||
{
|
||||
byte[] bytes = new byte[sizeof(int)];
|
||||
for (int i = 0; i < sizeof(int); i += 1)
|
||||
{
|
||||
bytes[sizeof(int) - 1 - i] = binaryReader.ReadByte();
|
||||
}
|
||||
return BitConverter.ToInt32(bytes, 0);
|
||||
}
|
||||
|
||||
private static Size DecodeBitmap(BinaryReader binaryReader)
|
||||
{
|
||||
_ = binaryReader.ReadBytes(16);
|
||||
int width = binaryReader.ReadInt32();
|
||||
int height = binaryReader.ReadInt32();
|
||||
return new Size(width, height);
|
||||
}
|
||||
|
||||
private static Size DecodeGif(BinaryReader binaryReader)
|
||||
{
|
||||
int width = binaryReader.ReadInt16();
|
||||
int height = binaryReader.ReadInt16();
|
||||
return new Size(width, height);
|
||||
}
|
||||
|
||||
private static Size DecodePng(BinaryReader binaryReader)
|
||||
{
|
||||
_ = binaryReader.ReadBytes(8);
|
||||
int width = ReadLittleEndianInt32(binaryReader);
|
||||
int height = ReadLittleEndianInt32(binaryReader);
|
||||
return new Size(width, height);
|
||||
}
|
||||
|
||||
private static Size DecodeJfif(BinaryReader binaryReader)
|
||||
{
|
||||
while (binaryReader.ReadByte() == 0xff)
|
||||
{
|
||||
byte marker = binaryReader.ReadByte();
|
||||
short chunkLength = ReadLittleEndianInt16(binaryReader);
|
||||
|
||||
if (marker == 0xc0)
|
||||
{
|
||||
_ = binaryReader.ReadByte();
|
||||
|
||||
int height = ReadLittleEndianInt16(binaryReader);
|
||||
int width = ReadLittleEndianInt16(binaryReader);
|
||||
return new Size(width, height);
|
||||
}
|
||||
|
||||
if (chunkLength < 0)
|
||||
{
|
||||
ushort uChunkLength = (ushort)chunkLength;
|
||||
_ = binaryReader.ReadBytes(uChunkLength - 2);
|
||||
}
|
||||
else
|
||||
{
|
||||
_ = binaryReader.ReadBytes(chunkLength - 2);
|
||||
}
|
||||
}
|
||||
|
||||
throw new ArgumentException(_ErrorMessage);
|
||||
}
|
||||
|
||||
private static Size DecodeWebP(BinaryReader binaryReader)
|
||||
{
|
||||
_ = binaryReader.ReadUInt32(); // Size
|
||||
_ = binaryReader.ReadBytes(15); // WEBP, VP8 + more
|
||||
_ = binaryReader.ReadBytes(3); // SYNC
|
||||
|
||||
int width = binaryReader.ReadUInt16() & 0b00_11111111111111; // 14 bits width
|
||||
int height = binaryReader.ReadUInt16() & 0b00_11111111111111; // 14 bits height
|
||||
|
||||
return new Size(width, height);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the dimensions of an image.
|
||||
/// </summary>
|
||||
/// <param name="path">The path of the image to get the dimensions of.</param>
|
||||
/// <returns>The dimensions of the specified image.</returns>
|
||||
/// <exception cref="ArgumentException">The image was of an unrecognized format.</exception>
|
||||
public static Size GetDimensions(BinaryReader binaryReader)
|
||||
{
|
||||
int maxMagicBytesLength = _ImageFormatDecoders.Keys.OrderByDescending(x => x.Length).First().Length;
|
||||
|
||||
byte[] magicBytes = new byte[maxMagicBytesLength];
|
||||
|
||||
for (int i = 0; i < maxMagicBytesLength; i += 1)
|
||||
{
|
||||
magicBytes[i] = binaryReader.ReadByte();
|
||||
|
||||
foreach (KeyValuePair<byte[], Func<BinaryReader, Size>> kvPair in _ImageFormatDecoders)
|
||||
{
|
||||
if (StartsWith(magicBytes, kvPair.Key))
|
||||
{
|
||||
return kvPair.Value(binaryReader);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
throw new ArgumentException(_ErrorMessage, nameof(binaryReader));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the dimensions of an image.
|
||||
/// </summary>
|
||||
/// <param name="path">The path of the image to get the dimensions of.</param>
|
||||
/// <returns>The dimensions of the specified image.</returns>
|
||||
/// <exception cref="ArgumentException">The image was of an unrecognized format.</exception>
|
||||
public static Size GetDimensions(string path)
|
||||
{
|
||||
using BinaryReader binaryReader = new(File.OpenRead(path));
|
||||
try
|
||||
{
|
||||
return GetDimensions(binaryReader);
|
||||
}
|
||||
catch (ArgumentException e)
|
||||
{
|
||||
if (e.Message.StartsWith(_ErrorMessage))
|
||||
{
|
||||
throw new ArgumentException(_ErrorMessage, nameof(path), e);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
357
Metadata/Models/Stateless/Exif.cs
Normal file
357
Metadata/Models/Stateless/Exif.cs
Normal file
@ -0,0 +1,357 @@
|
||||
using MetadataExtractor;
|
||||
using MetadataExtractor.Formats.Exif;
|
||||
using System.Globalization;
|
||||
|
||||
namespace View_by_Distance.Metadata.Models.Stateless;
|
||||
|
||||
internal abstract class Exif
|
||||
{
|
||||
|
||||
private static DateTime? GetDateTime(string? value)
|
||||
{
|
||||
DateTime? result;
|
||||
string dateTimeFormat = "yyyy:MM:dd HH:mm:ss";
|
||||
string alternateFormat = "ddd MMM dd HH:mm:ss yyyy";
|
||||
if (value is not null && DateTime.TryParse(value, out DateTime dateTime))
|
||||
result = dateTime;
|
||||
else if (value is not null && value.Length == dateTimeFormat.Length && DateTime.TryParseExact(value, dateTimeFormat, CultureInfo.InvariantCulture, DateTimeStyles.None, out dateTime))
|
||||
result = dateTime;
|
||||
else if (value is not null && value.Length == alternateFormat.Length && DateTime.TryParseExact(value, alternateFormat, CultureInfo.InvariantCulture, DateTimeStyles.None, out dateTime))
|
||||
result = dateTime;
|
||||
else
|
||||
result = null;
|
||||
return result;
|
||||
}
|
||||
|
||||
private static Shared.Models.AviDirectory GetAviDirectory(IReadOnlyList<MetadataExtractor.Directory> directories)
|
||||
{
|
||||
Shared.Models.AviDirectory result;
|
||||
MetadataExtractor.Formats.Avi.AviDirectory? aviDirectory = directories.OfType<MetadataExtractor.Formats.Avi.AviDirectory>().FirstOrDefault();
|
||||
if (aviDirectory is null)
|
||||
result = new(null, null, null, null);
|
||||
else
|
||||
{
|
||||
DateTime? dateTimeOriginal;
|
||||
string? duration = aviDirectory.GetDescription(MetadataExtractor.Formats.Avi.AviDirectory.TagDuration);
|
||||
string? height = aviDirectory.GetDescription(MetadataExtractor.Formats.Avi.AviDirectory.TagHeight);
|
||||
string? width = aviDirectory.GetDescription(MetadataExtractor.Formats.Avi.AviDirectory.TagWidth);
|
||||
if (aviDirectory.TryGetDateTime(MetadataExtractor.Formats.Avi.AviDirectory.TagDateTimeOriginal, out DateTime checkDateTime))
|
||||
dateTimeOriginal = checkDateTime;
|
||||
else
|
||||
dateTimeOriginal = GetDateTime(aviDirectory.GetString(MetadataExtractor.Formats.Avi.AviDirectory.TagDateTimeOriginal));
|
||||
result = new(dateTimeOriginal, duration, height, width);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private static Shared.Models.ExifDirectoryBase GetExifDirectoryBase(IReadOnlyList<MetadataExtractor.Directory> directories)
|
||||
{
|
||||
Shared.Models.ExifDirectoryBase result;
|
||||
ExifDirectoryBase? exifDirectoryBase = directories.OfType<ExifDirectoryBase>().FirstOrDefault();
|
||||
if (exifDirectoryBase is null)
|
||||
result = new(null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null);
|
||||
else
|
||||
{
|
||||
DateTime? dateTime;
|
||||
DateTime checkDateTime;
|
||||
DateTime? dateTimeOriginal;
|
||||
DateTime? dateTimeDigitized;
|
||||
string? aperture = exifDirectoryBase.GetDescription(ExifDirectoryBase.TagAperture);
|
||||
string? applicationNotes = exifDirectoryBase.GetDescription(ExifDirectoryBase.TagApplicationNotes);
|
||||
string? artist = exifDirectoryBase.GetDescription(ExifDirectoryBase.TagArtist);
|
||||
string? bitsPerSample = exifDirectoryBase.GetDescription(ExifDirectoryBase.TagBitsPerSample);
|
||||
string? bodySerialNumber = exifDirectoryBase.GetDescription(ExifDirectoryBase.TagBodySerialNumber);
|
||||
string? cameraOwnerName = exifDirectoryBase.GetDescription(ExifDirectoryBase.TagCameraOwnerName);
|
||||
string? compressedAverageBitsPerPixel = exifDirectoryBase.GetDescription(ExifDirectoryBase.TagCompressedAverageBitsPerPixel);
|
||||
string? compression = exifDirectoryBase.GetDescription(ExifDirectoryBase.TagCompression);
|
||||
string? copyright = exifDirectoryBase.GetDescription(ExifDirectoryBase.TagCopyright);
|
||||
string? documentName = exifDirectoryBase.GetDescription(ExifDirectoryBase.TagDocumentName);
|
||||
string? exifVersion = exifDirectoryBase.GetDescription(ExifDirectoryBase.TagExifVersion);
|
||||
string? exposureTime = exifDirectoryBase.GetDescription(ExifDirectoryBase.TagExposureTime);
|
||||
string? fileSource = exifDirectoryBase.GetDescription(ExifDirectoryBase.TagFileSource);
|
||||
string? imageDescription = exifDirectoryBase.GetDescription(ExifDirectoryBase.TagImageDescription);
|
||||
string? imageHeight = exifDirectoryBase.GetDescription(ExifDirectoryBase.TagImageHeight);
|
||||
string? imageNumber = exifDirectoryBase.GetDescription(ExifDirectoryBase.TagImageNumber);
|
||||
string? imageUniqueId = exifDirectoryBase.GetDescription(ExifDirectoryBase.TagImageUniqueId);
|
||||
string? imageWidth = exifDirectoryBase.GetDescription(ExifDirectoryBase.TagImageWidth);
|
||||
string? isoSpeed = exifDirectoryBase.GetDescription(ExifDirectoryBase.TagIsoSpeed);
|
||||
string? lensMake = exifDirectoryBase.GetDescription(ExifDirectoryBase.TagLensMake);
|
||||
string? lensModel = exifDirectoryBase.GetDescription(ExifDirectoryBase.TagLensModel);
|
||||
string? lensSerialNumber = exifDirectoryBase.GetDescription(ExifDirectoryBase.TagLensSerialNumber);
|
||||
string? make = exifDirectoryBase.GetDescription(ExifDirectoryBase.TagMake);
|
||||
string? makerNote = exifDirectoryBase.GetDescription(ExifDirectoryBase.TagMakernote);
|
||||
string? model = exifDirectoryBase.GetDescription(ExifDirectoryBase.TagModel);
|
||||
string? orientation = exifDirectoryBase.GetDescription(ExifDirectoryBase.TagOrientation);
|
||||
int? orientationValue = orientation is null ? null : exifDirectoryBase.GetInt32(ExifDirectoryBase.TagOrientation);
|
||||
string? rating = exifDirectoryBase.GetDescription(ExifDirectoryBase.TagRating);
|
||||
string? ratingPercent = exifDirectoryBase.GetDescription(ExifDirectoryBase.TagRatingPercent);
|
||||
string? securityClassification = exifDirectoryBase.GetDescription(ExifDirectoryBase.TagSecurityClassification);
|
||||
string? shutterSpeed = exifDirectoryBase.GetDescription(ExifDirectoryBase.TagShutterSpeed);
|
||||
string? software = exifDirectoryBase.GetDescription(ExifDirectoryBase.TagSoftware);
|
||||
string? timeZone = exifDirectoryBase.GetDescription(ExifDirectoryBase.TagTimeZone);
|
||||
string? timeZoneDigitized = exifDirectoryBase.GetDescription(ExifDirectoryBase.TagTimeZoneDigitized);
|
||||
string? timeZoneOriginal = exifDirectoryBase.GetDescription(ExifDirectoryBase.TagTimeZoneOriginal);
|
||||
string? userComment = exifDirectoryBase.GetDescription(ExifDirectoryBase.TagUserComment);
|
||||
string? winAuthor = exifDirectoryBase.GetDescription(ExifDirectoryBase.TagWinAuthor);
|
||||
string? winComment = exifDirectoryBase.GetDescription(ExifDirectoryBase.TagWinComment);
|
||||
string? winKeywords = exifDirectoryBase.GetDescription(ExifDirectoryBase.TagWinKeywords);
|
||||
string? winSubject = exifDirectoryBase.GetDescription(ExifDirectoryBase.TagWinSubject);
|
||||
string? winTitle = exifDirectoryBase.GetDescription(ExifDirectoryBase.TagWinTitle);
|
||||
string? xResolution = exifDirectoryBase.GetDescription(ExifDirectoryBase.TagXResolution);
|
||||
string? yResolution = exifDirectoryBase.GetDescription(ExifDirectoryBase.TagYResolution);
|
||||
if (exifDirectoryBase.TryGetDateTime(ExifDirectoryBase.TagDateTime, out checkDateTime))
|
||||
dateTime = checkDateTime;
|
||||
else
|
||||
dateTime = GetDateTime(exifDirectoryBase.GetString(ExifDirectoryBase.TagDateTime));
|
||||
if (exifDirectoryBase.TryGetDateTime(ExifDirectoryBase.TagDateTimeOriginal, out checkDateTime))
|
||||
dateTimeOriginal = checkDateTime;
|
||||
else
|
||||
dateTimeOriginal = GetDateTime(exifDirectoryBase.GetString(ExifDirectoryBase.TagDateTimeOriginal));
|
||||
if (exifDirectoryBase.TryGetDateTime(ExifDirectoryBase.TagDateTimeDigitized, out checkDateTime))
|
||||
dateTimeDigitized = checkDateTime;
|
||||
else
|
||||
dateTimeDigitized = GetDateTime(exifDirectoryBase.GetString(ExifDirectoryBase.TagDateTimeDigitized));
|
||||
result = new(aperture,
|
||||
applicationNotes,
|
||||
artist,
|
||||
bitsPerSample,
|
||||
bodySerialNumber,
|
||||
cameraOwnerName,
|
||||
compressedAverageBitsPerPixel,
|
||||
compression,
|
||||
copyright,
|
||||
dateTime,
|
||||
dateTimeDigitized,
|
||||
dateTimeOriginal,
|
||||
documentName,
|
||||
exifVersion,
|
||||
exposureTime,
|
||||
fileSource,
|
||||
imageDescription,
|
||||
imageHeight,
|
||||
imageNumber,
|
||||
imageUniqueId,
|
||||
imageWidth,
|
||||
isoSpeed,
|
||||
lensMake,
|
||||
lensModel,
|
||||
lensSerialNumber,
|
||||
make,
|
||||
makerNote,
|
||||
model,
|
||||
orientation,
|
||||
orientationValue,
|
||||
rating,
|
||||
ratingPercent,
|
||||
securityClassification,
|
||||
shutterSpeed,
|
||||
software,
|
||||
timeZone,
|
||||
timeZoneDigitized,
|
||||
timeZoneOriginal,
|
||||
userComment,
|
||||
winAuthor,
|
||||
winComment,
|
||||
winKeywords,
|
||||
winSubject,
|
||||
winTitle,
|
||||
xResolution,
|
||||
yResolution);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private static Shared.Models.FileMetadataDirectory GetFileMetadataDirectory(string file, IReadOnlyList<MetadataExtractor.Directory> directories)
|
||||
{
|
||||
Shared.Models.FileMetadataDirectory result;
|
||||
MetadataExtractor.Formats.FileSystem.FileMetadataDirectory? fileMetadataDirectory = directories.OfType<MetadataExtractor.Formats.FileSystem.FileMetadataDirectory>().FirstOrDefault();
|
||||
if (fileMetadataDirectory is null)
|
||||
result = new(null, null, null);
|
||||
else
|
||||
{
|
||||
DateTime? fileModifiedDate;
|
||||
string? fileName = fileMetadataDirectory.GetDescription(MetadataExtractor.Formats.FileSystem.FileMetadataDirectory.TagFileName);
|
||||
string? fileSize = fileMetadataDirectory.GetDescription(MetadataExtractor.Formats.FileSystem.FileMetadataDirectory.TagFileSize);
|
||||
if (fileMetadataDirectory.TryGetDateTime(MetadataExtractor.Formats.FileSystem.FileMetadataDirectory.TagFileModifiedDate, out DateTime checkDateTime))
|
||||
fileModifiedDate = checkDateTime;
|
||||
else
|
||||
fileModifiedDate = GetDateTime(fileMetadataDirectory.GetString(MetadataExtractor.Formats.FileSystem.FileMetadataDirectory.TagFileModifiedDate));
|
||||
if (fileName is null || !file.EndsWith(fileName))
|
||||
throw new NotSupportedException($"!{file}.EndsWith({fileName})");
|
||||
result = new(fileModifiedDate, fileName, fileSize);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private static Shared.Models.GifHeaderDirectory GetGifHeaderDirectory(IReadOnlyList<MetadataExtractor.Directory> directories)
|
||||
{
|
||||
Shared.Models.GifHeaderDirectory result;
|
||||
MetadataExtractor.Formats.Gif.GifHeaderDirectory? gifHeaderDirectory = directories.OfType<MetadataExtractor.Formats.Gif.GifHeaderDirectory>().FirstOrDefault();
|
||||
if (gifHeaderDirectory is null)
|
||||
result = new(null, null);
|
||||
else
|
||||
{
|
||||
string? imageHeight = gifHeaderDirectory.GetDescription(MetadataExtractor.Formats.Gif.GifHeaderDirectory.TagImageHeight);
|
||||
string? imageWidth = gifHeaderDirectory.GetDescription(MetadataExtractor.Formats.Gif.GifHeaderDirectory.TagImageWidth);
|
||||
result = new(imageHeight, imageWidth);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private static Shared.Models.PhotoshopDirectory GetPhotoshopDirectory(IReadOnlyList<MetadataExtractor.Directory> directories)
|
||||
{
|
||||
Shared.Models.PhotoshopDirectory result;
|
||||
MetadataExtractor.Formats.Photoshop.PhotoshopDirectory? PhotoshopDirectory = directories.OfType<MetadataExtractor.Formats.Photoshop.PhotoshopDirectory>().FirstOrDefault();
|
||||
if (PhotoshopDirectory is null)
|
||||
result = new(null, null);
|
||||
else
|
||||
{
|
||||
string? jpegQuality = PhotoshopDirectory.GetDescription(MetadataExtractor.Formats.Photoshop.PhotoshopDirectory.TagJpegQuality);
|
||||
string? url = PhotoshopDirectory.GetDescription(MetadataExtractor.Formats.Photoshop.PhotoshopDirectory.TagUrl);
|
||||
result = new(jpegQuality, url);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private static Shared.Models.GpsDirectory GetGpsDirectory(IReadOnlyList<MetadataExtractor.Directory> directories)
|
||||
{
|
||||
Shared.Models.GpsDirectory result;
|
||||
GpsDirectory? gpsDirectory = directories.OfType<GpsDirectory>().FirstOrDefault();
|
||||
if (gpsDirectory is null)
|
||||
result = new(null, null, null, null, null, null);
|
||||
else
|
||||
{
|
||||
DateTime? timeStamp;
|
||||
string? altitude = gpsDirectory.GetDescription(GpsDirectory.TagAltitude);
|
||||
string? latitude = gpsDirectory.GetDescription(GpsDirectory.TagLatitude);
|
||||
string? latitudeRef = gpsDirectory.GetDescription(GpsDirectory.TagLatitudeRef);
|
||||
string? longitude = gpsDirectory.GetDescription(GpsDirectory.TagLongitude);
|
||||
string? longitudeRef = gpsDirectory.GetDescription(GpsDirectory.TagLongitudeRef);
|
||||
if (gpsDirectory.TryGetDateTime(GpsDirectory.TagTimeStamp, out DateTime checkDateTime))
|
||||
timeStamp = checkDateTime;
|
||||
else
|
||||
timeStamp = GetDateTime(gpsDirectory.GetString(GpsDirectory.TagTimeStamp));
|
||||
result = new(altitude,
|
||||
latitude,
|
||||
latitudeRef,
|
||||
longitude,
|
||||
longitudeRef,
|
||||
timeStamp);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private static Shared.Models.JpegDirectory GetJpegDirectory(IReadOnlyList<MetadataExtractor.Directory> directories)
|
||||
{
|
||||
Shared.Models.JpegDirectory result;
|
||||
MetadataExtractor.Formats.Jpeg.JpegDirectory? jpegDirectory = directories.OfType<MetadataExtractor.Formats.Jpeg.JpegDirectory>().FirstOrDefault();
|
||||
if (jpegDirectory is null)
|
||||
result = new(null, null);
|
||||
else
|
||||
{
|
||||
string? imageHeight = jpegDirectory.GetDescription(MetadataExtractor.Formats.Jpeg.JpegDirectory.TagImageHeight);
|
||||
string? imageWidth = jpegDirectory.GetDescription(MetadataExtractor.Formats.Jpeg.JpegDirectory.TagImageWidth);
|
||||
result = new(imageHeight, imageWidth);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private static Shared.Models.PngDirectory GetPngDirectory(IReadOnlyList<MetadataExtractor.Directory> directories)
|
||||
{
|
||||
Shared.Models.PngDirectory result;
|
||||
MetadataExtractor.Formats.Png.PngDirectory? pngDirectory = directories.OfType<MetadataExtractor.Formats.Png.PngDirectory>().FirstOrDefault();
|
||||
if (pngDirectory is null)
|
||||
result = new(null, null);
|
||||
else
|
||||
{
|
||||
string? imageHeight = pngDirectory.GetDescription(MetadataExtractor.Formats.Png.PngDirectory.TagImageHeight);
|
||||
string? imageWidth = pngDirectory.GetDescription(MetadataExtractor.Formats.Png.PngDirectory.TagImageWidth);
|
||||
result = new(imageHeight, imageWidth);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private static Shared.Models.QuickTimeMovieHeaderDirectory GetQuickTimeMovieHeaderDirectoryDirectory(IReadOnlyList<MetadataExtractor.Directory> directories)
|
||||
{
|
||||
Shared.Models.QuickTimeMovieHeaderDirectory result;
|
||||
MetadataExtractor.Formats.QuickTime.QuickTimeMovieHeaderDirectory? aviDirectory = directories.OfType<MetadataExtractor.Formats.QuickTime.QuickTimeMovieHeaderDirectory>().FirstOrDefault();
|
||||
if (aviDirectory is null)
|
||||
result = new(null);
|
||||
else
|
||||
{
|
||||
DateTime? created;
|
||||
if (aviDirectory.TryGetDateTime(MetadataExtractor.Formats.QuickTime.QuickTimeMovieHeaderDirectory.TagCreated, out DateTime checkDateTime))
|
||||
created = checkDateTime;
|
||||
else
|
||||
created = GetDateTime(aviDirectory.GetString(MetadataExtractor.Formats.QuickTime.QuickTimeMovieHeaderDirectory.TagCreated));
|
||||
result = new(created);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private static Shared.Models.QuickTimeTrackHeaderDirectory GetQuickTimeTrackHeaderDirectoryDirectory(IReadOnlyList<MetadataExtractor.Directory> directories)
|
||||
{
|
||||
Shared.Models.QuickTimeTrackHeaderDirectory result;
|
||||
MetadataExtractor.Formats.QuickTime.QuickTimeTrackHeaderDirectory? aviDirectory = directories.OfType<MetadataExtractor.Formats.QuickTime.QuickTimeTrackHeaderDirectory>().FirstOrDefault();
|
||||
if (aviDirectory is null)
|
||||
result = new(null);
|
||||
else
|
||||
{
|
||||
DateTime? created;
|
||||
if (aviDirectory.TryGetDateTime(MetadataExtractor.Formats.QuickTime.QuickTimeTrackHeaderDirectory.TagCreated, out DateTime checkDateTime))
|
||||
created = checkDateTime;
|
||||
else
|
||||
created = GetDateTime(aviDirectory.GetString(MetadataExtractor.Formats.QuickTime.QuickTimeTrackHeaderDirectory.TagCreated));
|
||||
result = new(created);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private static Shared.Models.WebPDirectory GetWebPDirectory(IReadOnlyList<MetadataExtractor.Directory> directories)
|
||||
{
|
||||
Shared.Models.WebPDirectory result;
|
||||
MetadataExtractor.Formats.WebP.WebPDirectory? WebPDirectory = directories.OfType<MetadataExtractor.Formats.WebP.WebPDirectory>().FirstOrDefault();
|
||||
if (WebPDirectory is null)
|
||||
result = new(null, null);
|
||||
else
|
||||
{
|
||||
string? imageHeight = WebPDirectory.GetDescription(MetadataExtractor.Formats.WebP.WebPDirectory.TagImageHeight);
|
||||
string? imageWidth = WebPDirectory.GetDescription(MetadataExtractor.Formats.WebP.WebPDirectory.TagImageWidth);
|
||||
result = new(imageHeight, imageWidth);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
internal static Shared.Models.ExifDirectory Covert(string file, FileInfo fileInfo, System.Drawing.Size? size, IReadOnlyList<MetadataExtractor.Directory> directories)
|
||||
{
|
||||
Shared.Models.ExifDirectory results;
|
||||
Shared.Models.AviDirectory aviDirectory = GetAviDirectory(directories);
|
||||
Shared.Models.GpsDirectory gpsDirectory = GetGpsDirectory(directories);
|
||||
Shared.Models.PngDirectory pngDirectory = GetPngDirectory(directories);
|
||||
Shared.Models.JpegDirectory jpegDirectory = GetJpegDirectory(directories);
|
||||
Shared.Models.WebPDirectory webPDirectory = GetWebPDirectory(directories);
|
||||
Shared.Models.ExifDirectoryBase exifDirectoryBase = GetExifDirectoryBase(directories);
|
||||
Shared.Models.GifHeaderDirectory gifHeaderDirectory = GetGifHeaderDirectory(directories);
|
||||
Shared.Models.PhotoshopDirectory photoshopDirectory = GetPhotoshopDirectory(directories);
|
||||
Shared.Models.FileMetadataDirectory fileMetadataDirectory = GetFileMetadataDirectory(file, directories);
|
||||
Shared.Models.QuickTimeMovieHeaderDirectory quickTimeMovieHeaderDirectory = GetQuickTimeMovieHeaderDirectoryDirectory(directories);
|
||||
Shared.Models.QuickTimeTrackHeaderDirectory quickTimeTrackHeaderDirectory = GetQuickTimeTrackHeaderDirectoryDirectory(directories);
|
||||
results = new(aviDirectory,
|
||||
exifDirectoryBase,
|
||||
file,
|
||||
fileMetadataDirectory,
|
||||
gifHeaderDirectory,
|
||||
gpsDirectory,
|
||||
size?.Height,
|
||||
fileInfo.FullName,
|
||||
jpegDirectory,
|
||||
photoshopDirectory,
|
||||
pngDirectory,
|
||||
quickTimeMovieHeaderDirectory,
|
||||
quickTimeTrackHeaderDirectory,
|
||||
webPDirectory,
|
||||
size?.Width);
|
||||
return results;
|
||||
}
|
||||
|
||||
}
|
118
Metadata/Models/Stateless/GPS.cs
Normal file
118
Metadata/Models/Stateless/GPS.cs
Normal file
@ -0,0 +1,118 @@
|
||||
using View_by_Distance.Metadata.Models.Stateless.Methods;
|
||||
|
||||
namespace View_by_Distance.Metadata.Models.Stateless;
|
||||
|
||||
internal abstract class GPS
|
||||
{
|
||||
|
||||
private static bool CoordinateValidatorValidate(double latitude, double longitude)
|
||||
{
|
||||
if (latitude is < (-90) or > 90)
|
||||
return false;
|
||||
if (longitude is < (-180) or > 180)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private static double GetRadius(IMetadata.DistanceUnit distanceUnit)
|
||||
{
|
||||
return distanceUnit switch
|
||||
{
|
||||
IMetadata.DistanceUnit.Kilometers => 6371.0, // EarthRadiusInKilometers;
|
||||
IMetadata.DistanceUnit.Meters => 6371000.0, // EarthRadiusInMeters;
|
||||
IMetadata.DistanceUnit.NauticalMiles => 3440.0, // EarthRadiusInNauticalMiles;
|
||||
IMetadata.DistanceUnit.Miles => 3959.0, // EarthRadiusInMiles;
|
||||
_ => throw new NotSupportedException()
|
||||
};
|
||||
}
|
||||
|
||||
private static double ToRadian(double d) =>
|
||||
d * (Math.PI / 180);
|
||||
|
||||
private static double DiffRadian(double val1, double val2) =>
|
||||
ToRadian(val2) - ToRadian(val1);
|
||||
|
||||
internal static double GetDistance(double originLatitude, double originLongitude, double destinationLatitude, double destinationLongitude, int decimalPlaces = 1, IMetadata.DistanceUnit distanceUnit = IMetadata.DistanceUnit.Miles)
|
||||
{
|
||||
if (!CoordinateValidatorValidate(originLatitude, originLongitude))
|
||||
throw new ArgumentException("Invalid origin coordinates supplied.");
|
||||
if (!CoordinateValidatorValidate(destinationLatitude, destinationLongitude))
|
||||
throw new ArgumentException("Invalid destination coordinates supplied.");
|
||||
double radius = GetRadius(distanceUnit);
|
||||
return Math.Round(
|
||||
radius * 2 *
|
||||
Math.Asin(Math.Min(1,
|
||||
Math.Sqrt(
|
||||
Math.Pow(Math.Sin(DiffRadian(originLatitude, destinationLatitude) / 2.0), 2.0) +
|
||||
Math.Cos(ToRadian(originLatitude)) * Math.Cos(ToRadian(destinationLatitude)) *
|
||||
Math.Pow(Math.Sin(DiffRadian(originLongitude, destinationLongitude) / 2.0),
|
||||
2.0)))), decimalPlaces);
|
||||
}
|
||||
|
||||
private static double ParseValueFromDmsString(string value)
|
||||
{
|
||||
double result;
|
||||
if (string.IsNullOrEmpty(value))
|
||||
return double.MinValue;
|
||||
|
||||
double secondsValue;
|
||||
string[] degrees = value.Split('°');
|
||||
if (degrees.Length != 2)
|
||||
return double.MinValue;
|
||||
if (!double.TryParse(degrees[0], out double degreesValue))
|
||||
return double.MinValue;
|
||||
|
||||
string[] minutes = degrees[1].Split('\'');
|
||||
if (minutes.Length != 2)
|
||||
return double.MinValue;
|
||||
if (!double.TryParse(minutes[0], out double minutesValue))
|
||||
return double.MinValue;
|
||||
|
||||
string[] seconds = minutes[1].Split('"');
|
||||
if (seconds.Length != 2)
|
||||
secondsValue = 0;
|
||||
else
|
||||
{
|
||||
if (!double.TryParse(seconds[0], out secondsValue))
|
||||
return double.MinValue;
|
||||
}
|
||||
result = Math.Abs(degreesValue) + (minutesValue / 60) + (secondsValue / 3600);
|
||||
|
||||
if (degreesValue < 0)
|
||||
result *= -1;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// internal static GeoLocation? GeoLocation(ReadOnlyDictionary<string, MetadataExtractorDirectory> metadataExtractorDirectories)
|
||||
// {
|
||||
// GeoLocation? result;
|
||||
// if (!metadataExtractorDirectories.TryGetValue("GPS", out MetadataExtractorDirectory? metadataExtractorDirectory))
|
||||
// result = null;
|
||||
// else
|
||||
// {
|
||||
// MetadataExtractorTag? metadataExtractorTag;
|
||||
// if (!metadataExtractorDirectory.Tags.TryGetValue((int)Shared.Models.Stateless.IExif.Tags.GPSLatitude, out metadataExtractorTag) || string.IsNullOrEmpty(metadataExtractorTag.Description))
|
||||
// result = null;
|
||||
// else
|
||||
// {
|
||||
// string latitudeDMS = metadataExtractorTag.Description;
|
||||
// double latitude = ParseValueFromDmsString(latitudeDMS);
|
||||
// if (!metadataExtractorDirectory.Tags.TryGetValue((int)Shared.Models.Stateless.IExif.Tags.GPSLongitude, out metadataExtractorTag) || string.IsNullOrEmpty(metadataExtractorTag.Description))
|
||||
// result = null;
|
||||
// else
|
||||
// {
|
||||
// string longitudeDMS = metadataExtractorTag.Description;
|
||||
// double longitude = ParseValueFromDmsString(longitudeDMS);
|
||||
// result = new(latitude, longitude);
|
||||
// string dms = result.ToDmsString();
|
||||
// if ($"{latitudeDMS}, {longitudeDMS}" != dms)
|
||||
// result = null;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// return result;
|
||||
// }
|
||||
|
||||
}
|
24
Metadata/Models/Stateless/Methods/IMetadata.cs
Normal file
24
Metadata/Models/Stateless/Methods/IMetadata.cs
Normal file
@ -0,0 +1,24 @@
|
||||
namespace View_by_Distance.Metadata.Models.Stateless.Methods;
|
||||
|
||||
public interface IMetadata
|
||||
{
|
||||
|
||||
enum DistanceUnit
|
||||
{
|
||||
Miles,
|
||||
NauticalMiles,
|
||||
Kilometers,
|
||||
Meters
|
||||
}
|
||||
|
||||
Shared.Models.ExifDirectory TestStatic_Convert(string file, FileInfo fileInfo, System.Drawing.Size? size, IReadOnlyList<MetadataExtractor.Directory> directories) =>
|
||||
Convert(file, fileInfo, size, directories);
|
||||
static Shared.Models.ExifDirectory Convert(string file, FileInfo fileInfo, System.Drawing.Size? size, IReadOnlyList<MetadataExtractor.Directory> directories) =>
|
||||
Exif.Covert(file, fileInfo, size, directories);
|
||||
|
||||
double? TestStatic_GetDistance(double originLatitude, double originLongitude, double destinationLatitude, double destinationLongitude, int decimalPlaces = 1, DistanceUnit distanceUnit = DistanceUnit.Miles) =>
|
||||
GetDistance(originLatitude, originLongitude, destinationLatitude, destinationLongitude, decimalPlaces, distanceUnit);
|
||||
static double? GetDistance(double originLatitude, double originLongitude, double destinationLatitude, double destinationLongitude, int decimalPlaces = 1, DistanceUnit distanceUnit = DistanceUnit.Miles) =>
|
||||
GPS.GetDistance(originLatitude, originLongitude, destinationLatitude, destinationLongitude, decimalPlaces, distanceUnit);
|
||||
|
||||
}
|
47
Rename/AA.Rename.csproj
Normal file
47
Rename/AA.Rename.csproj
Normal file
@ -0,0 +1,47 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
<OutputType>Exe</OutputType>
|
||||
<RuntimeIdentifier>win-x64</RuntimeIdentifier>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<UserSecretsId>fa0fa59b-afe4-4960-9afc-18fcbc7fb41b</UserSecretsId>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<PackageId>Phares.View.by.Distance.Rename</PackageId>
|
||||
<GeneratePackageOnBuild>false</GeneratePackageOnBuild>
|
||||
<Version>8.0.101.1</Version>
|
||||
<Authors>Mike Phares</Authors>
|
||||
<Company>Phares</Company>
|
||||
<IncludeSymbols>true</IncludeSymbols>
|
||||
<SymbolPackageFormat>snupkg</SymbolPackageFormat>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<IsWindows Condition="'$([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::Windows)))' == 'true'">true</IsWindows>
|
||||
<IsOSX Condition="'$([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::OSX)))' == 'true'">true</IsOSX>
|
||||
<IsLinux Condition="'$([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::Linux)))' == 'true'">true</IsLinux>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(IsWindows)'=='true'">
|
||||
<DefineConstants>Windows</DefineConstants>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(IsOSX)'=='true'">
|
||||
<DefineConstants>OSX</DefineConstants>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(IsLinux)'=='true'">
|
||||
<DefineConstants>Linux</DefineConstants>
|
||||
</PropertyGroup>
|
||||
<ItemGroup Condition="'$(RuntimeIdentifier)' == 'browser-wasm'">
|
||||
<SupportedPlatform Include="browser" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="runtime.win-x64.Microsoft.DotNet.ILCompiler" Version="8.0.0-rc.2.23479.6" />
|
||||
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="7.0.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.Configuration.UserSecrets" Version="7.0.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.Hosting" Version="7.0.1" />
|
||||
<PackageReference Include="ShellProgressBar" Version="5.2.0" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Metadata\AA.Metadata.csproj" />
|
||||
<ProjectReference Include="..\Shared\AA.Shared.csproj" />
|
||||
</ItemGroup>
|
||||
</Project>
|
26
Rename/Models/AppSettings.cs
Normal file
26
Rename/Models/AppSettings.cs
Normal file
@ -0,0 +1,26 @@
|
||||
using System.Text.Json;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace View_by_Distance.Rename.Models;
|
||||
|
||||
public record AppSettings(string Company,
|
||||
string DefaultUnknownDirectoryName,
|
||||
bool ForceIdName,
|
||||
int MaxDegreeOfParallelism,
|
||||
int MaxMinutesDelta,
|
||||
bool RenameUndo)
|
||||
{
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
string result = JsonSerializer.Serialize(this, AppSettingsSourceGenerationContext.Default.AppSettings);
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
[JsonSourceGenerationOptions(WriteIndented = true)]
|
||||
[JsonSerializable(typeof(AppSettings))]
|
||||
internal partial class AppSettingsSourceGenerationContext : JsonSerializerContext
|
||||
{
|
||||
}
|
2
Rename/Models/Binder/.editorconfig
Normal file
2
Rename/Models/Binder/.editorconfig
Normal file
@ -0,0 +1,2 @@
|
||||
[*.cs]
|
||||
csharp_preserve_single_line_statements = true
|
72
Rename/Models/Binder/AppSettings.cs
Normal file
72
Rename/Models/Binder/AppSettings.cs
Normal file
@ -0,0 +1,72 @@
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using System.Text.Json;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace View_by_Distance.Rename.Models.Binder;
|
||||
|
||||
public class AppSettings
|
||||
{
|
||||
|
||||
public string? Company { get; set; }
|
||||
public string? DefaultUnknownDirectoryName { get; set; }
|
||||
public bool? ForceIdName { get; set; }
|
||||
public int? MaxDegreeOfParallelism { get; set; }
|
||||
public int? MaxMinutesDelta { get; set; }
|
||||
public bool? RenameUndo { get; set; }
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
string result = JsonSerializer.Serialize(this, BinderAppSettingsSourceGenerationContext.Default.AppSettings);
|
||||
return result;
|
||||
}
|
||||
|
||||
private static Models.AppSettings Get(AppSettings? appSettings)
|
||||
{
|
||||
Models.AppSettings result;
|
||||
if (appSettings?.Company is null) throw new NullReferenceException(nameof(appSettings.Company));
|
||||
if (appSettings?.DefaultUnknownDirectoryName is null) throw new NullReferenceException(nameof(appSettings.DefaultUnknownDirectoryName));
|
||||
if (appSettings?.ForceIdName is null) throw new NullReferenceException(nameof(appSettings.ForceIdName));
|
||||
if (appSettings?.MaxDegreeOfParallelism is null) throw new NullReferenceException(nameof(appSettings.MaxDegreeOfParallelism));
|
||||
if (appSettings?.MaxMinutesDelta is null) throw new NullReferenceException(nameof(appSettings.MaxMinutesDelta));
|
||||
if (appSettings?.RenameUndo is null) throw new NullReferenceException(nameof(appSettings.RenameUndo));
|
||||
result = new(
|
||||
appSettings.Company,
|
||||
appSettings.DefaultUnknownDirectoryName,
|
||||
appSettings.ForceIdName.Value,
|
||||
appSettings.MaxDegreeOfParallelism.Value,
|
||||
appSettings.MaxMinutesDelta.Value,
|
||||
appSettings.RenameUndo.Value
|
||||
);
|
||||
return result;
|
||||
}
|
||||
|
||||
public static Models.AppSettings Get(IConfigurationRoot configurationRoot)
|
||||
{
|
||||
Models.AppSettings result;
|
||||
#pragma warning disable IL3050, IL2026
|
||||
AppSettings? appSettings = configurationRoot.Get<AppSettings>();
|
||||
#pragma warning restore IL3050, IL2026
|
||||
if (appSettings?.Company is null)
|
||||
{
|
||||
foreach (IConfigurationProvider configurationProvider in configurationRoot.Providers)
|
||||
{
|
||||
if (configurationProvider is not Microsoft.Extensions.Configuration.Json.JsonConfigurationProvider jsonConfigurationProvider)
|
||||
continue;
|
||||
if (jsonConfigurationProvider.Source.FileProvider is not Microsoft.Extensions.FileProviders.PhysicalFileProvider physicalFileProvider)
|
||||
continue;
|
||||
if (!physicalFileProvider.Root.Contains("UserSecrets"))
|
||||
continue;
|
||||
throw new NotSupportedException(physicalFileProvider.Root);
|
||||
}
|
||||
}
|
||||
result = Get(appSettings);
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
[JsonSourceGenerationOptions(WriteIndented = true)]
|
||||
[JsonSerializable(typeof(AppSettings))]
|
||||
internal partial class BinderAppSettingsSourceGenerationContext : JsonSerializerContext
|
||||
{
|
||||
}
|
62
Rename/Models/Binder/Configuration.cs
Normal file
62
Rename/Models/Binder/Configuration.cs
Normal file
@ -0,0 +1,62 @@
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using System.Text.Json;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace View_by_Distance.Rename.Models.Binder;
|
||||
|
||||
public class Configuration
|
||||
{
|
||||
|
||||
public bool? ForceMetadataLastWriteTimeToCreationTime { get; set; }
|
||||
public string[]? IgnoreExtensions { get; set; }
|
||||
public string? PersonBirthdayFormat { get; set; }
|
||||
public bool? PropertiesChangedForMetadata { get; set; }
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
string result = JsonSerializer.Serialize(this, BinderConfigurationSourceGenerationContext.Default.Configuration);
|
||||
return result;
|
||||
}
|
||||
|
||||
private static Models.Configuration Get(Configuration? configuration, Metadata.Models.MetadataConfiguration metadataConfiguration)
|
||||
{
|
||||
Models.Configuration result;
|
||||
if (configuration is null) throw new NullReferenceException(nameof(configuration));
|
||||
if (configuration.ForceMetadataLastWriteTimeToCreationTime is null) throw new NullReferenceException(nameof(configuration.ForceMetadataLastWriteTimeToCreationTime));
|
||||
if (configuration.IgnoreExtensions is null) throw new NullReferenceException(nameof(configuration.IgnoreExtensions));
|
||||
if (configuration.PersonBirthdayFormat is null) throw new NullReferenceException(nameof(configuration.PersonBirthdayFormat));
|
||||
if (configuration.PropertiesChangedForMetadata is null) throw new NullReferenceException(nameof(configuration.PropertiesChangedForMetadata));
|
||||
result = new(metadataConfiguration,
|
||||
configuration.ForceMetadataLastWriteTimeToCreationTime.Value,
|
||||
configuration.IgnoreExtensions,
|
||||
configuration.PersonBirthdayFormat,
|
||||
configuration.PropertiesChangedForMetadata.Value);
|
||||
return result;
|
||||
}
|
||||
|
||||
public static Models.Configuration Get(IConfigurationRoot configurationRoot, Metadata.Models.MetadataConfiguration metadataConfiguration)
|
||||
{
|
||||
Models.Configuration result;
|
||||
#if Linux
|
||||
string environmentName = "Linux";
|
||||
#elif OSX
|
||||
string environmentName = "OSX";
|
||||
#elif Windows
|
||||
string environmentName = "Windows";
|
||||
#endif
|
||||
string section = string.Concat(environmentName, ":", nameof(Configuration));
|
||||
IConfigurationSection configurationSection = configurationRoot.GetSection(section);
|
||||
#pragma warning disable IL3050, IL2026
|
||||
Configuration? configuration = configurationSection.Get<Configuration>();
|
||||
#pragma warning restore IL3050, IL2026
|
||||
result = Get(configuration, metadataConfiguration);
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
[JsonSourceGenerationOptions(WriteIndented = true)]
|
||||
[JsonSerializable(typeof(Configuration))]
|
||||
internal partial class BinderConfigurationSourceGenerationContext : JsonSerializerContext
|
||||
{
|
||||
}
|
26
Rename/Models/Configuration.cs
Normal file
26
Rename/Models/Configuration.cs
Normal file
@ -0,0 +1,26 @@
|
||||
|
||||
using System.Text.Json;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace View_by_Distance.Rename.Models;
|
||||
|
||||
public record Configuration(Metadata.Models.MetadataConfiguration MetadataConfiguration,
|
||||
bool ForceMetadataLastWriteTimeToCreationTime,
|
||||
string[] IgnoreExtensions,
|
||||
string PersonBirthdayFormat,
|
||||
bool PropertiesChangedForMetadata)
|
||||
{
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
string result = JsonSerializer.Serialize(this, ConfigurationSourceGenerationContext.Default.Configuration);
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
[JsonSourceGenerationOptions(WriteIndented = true)]
|
||||
[JsonSerializable(typeof(Configuration))]
|
||||
internal partial class ConfigurationSourceGenerationContext : JsonSerializerContext
|
||||
{
|
||||
}
|
57
Rename/Program.cs
Normal file
57
Rename/Program.cs
Normal file
@ -0,0 +1,57 @@
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Hosting;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using View_by_Distance.Rename.Models;
|
||||
|
||||
namespace View_by_Distance.Rename;
|
||||
|
||||
public class Program
|
||||
{
|
||||
|
||||
public static void Secondary(ILogger<Program> logger, List<string> args)
|
||||
{
|
||||
IConfigurationBuilder configurationBuilder = new ConfigurationBuilder()
|
||||
.AddEnvironmentVariables()
|
||||
.AddUserSecrets<Program>();
|
||||
IConfigurationRoot configurationRoot = configurationBuilder.Build();
|
||||
AppSettings appSettings = Models.Binder.AppSettings.Get(configurationRoot);
|
||||
if (appSettings.MaxDegreeOfParallelism > Environment.ProcessorCount)
|
||||
throw new Exception("MaxDegreeOfParallelism must be =< Environment.ProcessorCount!");
|
||||
if (string.IsNullOrEmpty(appSettings.Company))
|
||||
throw new Exception("Company must have a value!");
|
||||
int silentIndex = args.IndexOf("s");
|
||||
if (silentIndex > -1)
|
||||
args.RemoveAt(silentIndex);
|
||||
try
|
||||
{
|
||||
if (args is null)
|
||||
throw new Exception("args is null!");
|
||||
Shared.Models.Console console = new();
|
||||
_ = new Rename(args, logger, configurationRoot, appSettings, silentIndex > -1, console);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
logger?.LogError(ex, "Error!");
|
||||
}
|
||||
if (silentIndex > -1)
|
||||
logger?.LogDebug("Done. Bye");
|
||||
else
|
||||
{
|
||||
logger?.LogDebug("Done. Press 'Enter' to end");
|
||||
_ = Console.ReadLine();
|
||||
}
|
||||
}
|
||||
|
||||
public static void Main(string[] args)
|
||||
{
|
||||
#pragma warning disable IL3050
|
||||
ILogger<Program>? logger = Host.CreateDefaultBuilder(args).Build().Services.GetRequiredService<ILogger<Program>>();
|
||||
#pragma warning restore IL3050
|
||||
if (args is not null)
|
||||
Secondary(logger, args.ToList());
|
||||
else
|
||||
Secondary(logger, []);
|
||||
}
|
||||
|
||||
}
|
71
Rename/Rename.cs
Normal file
71
Rename/Rename.cs
Normal file
@ -0,0 +1,71 @@
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using ShellProgressBar;
|
||||
using View_by_Distance.Metadata.Models;
|
||||
using View_by_Distance.Rename.Models;
|
||||
using View_by_Distance.Shared.Models;
|
||||
using View_by_Distance.Shared.Models.Stateless.Methods;
|
||||
|
||||
namespace View_by_Distance.Rename;
|
||||
|
||||
public class Rename
|
||||
{
|
||||
|
||||
private readonly AppSettings _AppSettings;
|
||||
private readonly Configuration _Configuration;
|
||||
private readonly IConfigurationRoot _ConfigurationRoot;
|
||||
private readonly MetadataConfiguration _MetadataConfiguration;
|
||||
|
||||
public Rename(List<string> args, ILogger<Program>? logger, IConfigurationRoot configurationRoot, AppSettings appSettings, bool isSilent, IConsole console)
|
||||
{
|
||||
if (isSilent)
|
||||
{ }
|
||||
if (args is null)
|
||||
throw new NullReferenceException(nameof(args));
|
||||
if (console is null)
|
||||
throw new NullReferenceException(nameof(console));
|
||||
_AppSettings = appSettings;
|
||||
_ConfigurationRoot = configurationRoot;
|
||||
MetadataConfiguration metadataConfiguration = Metadata.Models.Binder.Configuration.Get(configurationRoot);
|
||||
Configuration configuration = Models.Binder.Configuration.Get(configurationRoot, metadataConfiguration);
|
||||
_MetadataConfiguration = metadataConfiguration;
|
||||
_Configuration = configuration;
|
||||
logger?.LogInformation("{RootDirectory}", metadataConfiguration.RootDirectory);
|
||||
MetadataConfiguration.Verify(metadataConfiguration, requireExist: false);
|
||||
Verify();
|
||||
List<string> linesB = RenameFilesInDirectories(logger);
|
||||
if (linesB.Count != 0)
|
||||
{
|
||||
File.WriteAllLines($"D:/Tmp/Phares/{DateTime.Now.Ticks}.tsv", linesB);
|
||||
_ = IPath.DeleteEmptyDirectories(metadataConfiguration.RootDirectory);
|
||||
}
|
||||
}
|
||||
|
||||
private void Verify()
|
||||
{
|
||||
if (_AppSettings is null)
|
||||
throw new NullReferenceException(nameof(_AppSettings));
|
||||
if (_Configuration is null)
|
||||
throw new NullReferenceException(nameof(_Configuration));
|
||||
if (_ConfigurationRoot is null)
|
||||
throw new NullReferenceException(nameof(_ConfigurationRoot));
|
||||
if (_MetadataConfiguration is null)
|
||||
throw new NullReferenceException(nameof(_MetadataConfiguration));
|
||||
}
|
||||
|
||||
private List<string> RenameFilesInDirectories(ILogger? logger)
|
||||
{
|
||||
List<string> old = [];
|
||||
List<ExifDirectory> exifDirectories = [];
|
||||
string rootDirectoryFullPath = Path.GetFullPath(_MetadataConfiguration.RootDirectory);
|
||||
ParallelOptions parallelOptions = new() { MaxDegreeOfParallelism = _AppSettings.MaxDegreeOfParallelism };
|
||||
IEnumerable<string> files = Directory.EnumerateFiles(rootDirectoryFullPath, "*", SearchOption.AllDirectories);
|
||||
A_Metadata metadata = new(_MetadataConfiguration, _Configuration.ForceMetadataLastWriteTimeToCreationTime, _Configuration.PropertiesChangedForMetadata);
|
||||
ProgressBar progressBar = new(123000, "EnumerateFiles load", new ProgressBarOptions() { ProgressCharacter = '─', ProgressBarOnBottom = true, DisableBottomPercentage = true });
|
||||
files.AsParallel().ForAll(A_Metadata.GetResultCollection(metadata, exifDirectories, () => progressBar.Tick()));
|
||||
if (progressBar.CurrentTick != exifDirectories.Count)
|
||||
throw new NotSupportedException();
|
||||
return old;
|
||||
}
|
||||
|
||||
}
|
15
Shared/.vscode/mklink.md
vendored
Normal file
15
Shared/.vscode/mklink.md
vendored
Normal file
@ -0,0 +1,15 @@
|
||||
---
|
||||
type: "note"
|
||||
created: "2023-10-20T03:58:11.564Z"
|
||||
updated: "2023-10-20T03:59:01.765Z"
|
||||
---
|
||||
|
||||
# mklink
|
||||
|
||||
```bash
|
||||
mklink /J "L:\Git\AA\Shared\.kanbn" "D:\5-Other-Small\Kanban\View-by-Distance"
|
||||
```
|
||||
|
||||
```bash
|
||||
mklink /J "L:\Git\AA\Shared\.kanbn" "D:\5-Other-Small\Kanban\View-by-Distance"
|
||||
```
|
61
Shared/.vscode/settings.json
vendored
Normal file
61
Shared/.vscode/settings.json
vendored
Normal file
@ -0,0 +1,61 @@
|
||||
{
|
||||
"cSpell.words": [
|
||||
"appsettings",
|
||||
"Argb",
|
||||
"ASPNETCORE",
|
||||
"Barrick",
|
||||
"bcdfghjklmnpqrstvwxyz",
|
||||
"Bday",
|
||||
"Beichler",
|
||||
"Bohdi",
|
||||
"Cobertura",
|
||||
"cref",
|
||||
"CUDA",
|
||||
"Dlib",
|
||||
"DSCN",
|
||||
"Exif",
|
||||
"eyeα",
|
||||
"Getα",
|
||||
"Greyscale",
|
||||
"Hasher",
|
||||
"Hmmss",
|
||||
"Hmmssfff",
|
||||
"jfif",
|
||||
"JOSN",
|
||||
"mmod",
|
||||
"Nicéphore",
|
||||
"Niépce",
|
||||
"nosj",
|
||||
"paramref",
|
||||
"permille",
|
||||
"permyriad",
|
||||
"Phares",
|
||||
"Phgtv",
|
||||
"Photoshop",
|
||||
"RDHC",
|
||||
"recognise",
|
||||
"Rects",
|
||||
"resnet",
|
||||
"Serilog",
|
||||
"Subfile",
|
||||
"Subfiles",
|
||||
"Syncthing",
|
||||
"Unmanaged",
|
||||
"unrecognised",
|
||||
"Upsample",
|
||||
"Vericruz"
|
||||
],
|
||||
"files.watcherExclude": {
|
||||
"**/node_modules": true
|
||||
},
|
||||
"cSpell.enabled": true,
|
||||
"files.exclude": {
|
||||
"**/.git": false,
|
||||
"**/node_modules": true
|
||||
},
|
||||
"coverage-gutters.coverageBaseDir": "./.vscode/ReportGenerator/Cobertura/*",
|
||||
"extensions.ignoreRecommendations": true,
|
||||
"[markdown]": {
|
||||
"editor.wordWrap": "off"
|
||||
}
|
||||
}
|
38
Shared/AA.Shared.csproj
Normal file
38
Shared/AA.Shared.csproj
Normal file
@ -0,0 +1,38 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
<RuntimeIdentifiers>win-x64;linux-x64</RuntimeIdentifiers>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<PackageId>Phares.AA.Shared</PackageId>
|
||||
<GeneratePackageOnBuild>false</GeneratePackageOnBuild>
|
||||
<Version>8.0.101.1</Version>
|
||||
<Authors>Mike Phares</Authors>
|
||||
<Company>Phares</Company>
|
||||
<IncludeSymbols>true</IncludeSymbols>
|
||||
<SymbolPackageFormat>snupkg</SymbolPackageFormat>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<IsWindows Condition="'$([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::Windows)))' == 'true'">true</IsWindows>
|
||||
<IsOSX Condition="'$([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::OSX)))' == 'true'">true</IsOSX>
|
||||
<IsLinux Condition="'$([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::Linux)))' == 'true'">true</IsLinux>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(IsWindows)'=='true'">
|
||||
<DefineConstants>Windows</DefineConstants>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(IsOSX)'=='true'">
|
||||
<DefineConstants>OSX</DefineConstants>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(IsLinux)'=='true'">
|
||||
<DefineConstants>Linux</DefineConstants>
|
||||
</PropertyGroup>
|
||||
<ItemGroup Condition="'$(RuntimeIdentifier)' == 'browser-wasm'">
|
||||
<SupportedPlatform Include="browser" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="System.Drawing.Common" Version="7.0.0" />
|
||||
<PackageReference Include="System.Text.Json" Version="7.0.3" />
|
||||
</ItemGroup>
|
||||
</Project>
|
24
Shared/Models/AviDirectory.cs
Normal file
24
Shared/Models/AviDirectory.cs
Normal file
@ -0,0 +1,24 @@
|
||||
using System.Text.Json;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace View_by_Distance.Shared.Models;
|
||||
|
||||
public record AviDirectory(DateTime? DateTimeOriginal,
|
||||
string? Duration,
|
||||
string? Height,
|
||||
string? Width)
|
||||
{
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
string result = JsonSerializer.Serialize(this, AviDirectorySourceGenerationContext.Default.AviDirectory);
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
[JsonSourceGenerationOptions(WriteIndented = true)]
|
||||
[JsonSerializable(typeof(AviDirectory))]
|
||||
public partial class AviDirectorySourceGenerationContext : JsonSerializerContext
|
||||
{
|
||||
}
|
35
Shared/Models/ExifDirectory.cs
Normal file
35
Shared/Models/ExifDirectory.cs
Normal file
@ -0,0 +1,35 @@
|
||||
using System.Text.Json;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace View_by_Distance.Shared.Models;
|
||||
|
||||
public record ExifDirectory(AviDirectory AviDirectory,
|
||||
ExifDirectoryBase ExifDirectoryBase,
|
||||
string File,
|
||||
FileMetadataDirectory FileMetadataDirectory,
|
||||
GifHeaderDirectory GifHeaderDirectory,
|
||||
GpsDirectory GpsDirectory,
|
||||
int? Height,
|
||||
string JsonFile,
|
||||
JpegDirectory JpegDirectory,
|
||||
PhotoshopDirectory PhotoshopDirectory,
|
||||
PngDirectory PngDirectory,
|
||||
QuickTimeMovieHeaderDirectory QuickTimeMovieHeaderDirectory,
|
||||
QuickTimeTrackHeaderDirectory QuickTimeTrackHeaderDirectory,
|
||||
WebPDirectory WebPDirectory,
|
||||
int? Width)
|
||||
{
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
string result = JsonSerializer.Serialize(this, ExifDirectorySourceGenerationContext.Default.ExifDirectory);
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
[JsonSourceGenerationOptions(WriteIndented = true)]
|
||||
[JsonSerializable(typeof(ExifDirectory))]
|
||||
public partial class ExifDirectorySourceGenerationContext : JsonSerializerContext
|
||||
{
|
||||
}
|
66
Shared/Models/ExifDirectoryBase.cs
Normal file
66
Shared/Models/ExifDirectoryBase.cs
Normal file
@ -0,0 +1,66 @@
|
||||
using System.Text.Json;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace View_by_Distance.Shared.Models;
|
||||
|
||||
public record ExifDirectoryBase(string? Aperture,
|
||||
string? ApplicationNotes,
|
||||
string? Artist,
|
||||
string? BitsPerSample,
|
||||
string? BodySerialNumber,
|
||||
string? CameraOwnerName,
|
||||
string? CompressedAverageBitsPerPixel,
|
||||
string? Compression,
|
||||
string? Copyright,
|
||||
DateTime? DateTime,
|
||||
DateTime? DateTimeDigitized,
|
||||
DateTime? DateTimeOriginal,
|
||||
string? DocumentName,
|
||||
string? ExifVersion,
|
||||
string? ExposureTime,
|
||||
string? FileSource,
|
||||
string? ImageDescription,
|
||||
string? ImageHeight,
|
||||
string? ImageNumber,
|
||||
string? ImageUniqueId,
|
||||
string? ImageWidth,
|
||||
string? IsoSpeed,
|
||||
string? LensMake,
|
||||
string? LensModel,
|
||||
string? LensSerialNumber,
|
||||
string? Make,
|
||||
string? MakerNote,
|
||||
string? Model,
|
||||
string? Orientation,
|
||||
int? OrientationValue,
|
||||
string? Rating,
|
||||
string? RatingPercent,
|
||||
string? SecurityClassification,
|
||||
string? ShutterSpeed,
|
||||
string? Software,
|
||||
string? TimeZone,
|
||||
string? TimeZoneDigitized,
|
||||
string? TimeZoneOriginal,
|
||||
string? UserComment,
|
||||
string? WinAuthor,
|
||||
string? WinComment,
|
||||
string? WinKeywords,
|
||||
string? WinSubject,
|
||||
string? WinTitle,
|
||||
string? XResolution,
|
||||
string? YResolution)
|
||||
{
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
string result = JsonSerializer.Serialize(this, ExifDirectoryBaseSourceGenerationContext.Default.ExifDirectoryBase);
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
[JsonSourceGenerationOptions(WriteIndented = true)]
|
||||
[JsonSerializable(typeof(ExifDirectoryBase))]
|
||||
public partial class ExifDirectoryBaseSourceGenerationContext : JsonSerializerContext
|
||||
{
|
||||
}
|
82
Shared/Models/FileHolder.cs
Normal file
82
Shared/Models/FileHolder.cs
Normal file
@ -0,0 +1,82 @@
|
||||
using System.Text.Json;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace View_by_Distance.Shared.Models;
|
||||
|
||||
public class FileHolder
|
||||
{
|
||||
|
||||
protected readonly DateTime? _CreationTime;
|
||||
protected readonly string? _DirectoryName;
|
||||
protected readonly bool _Exists;
|
||||
protected readonly string _ExtensionLowered;
|
||||
protected readonly string _FullName;
|
||||
protected readonly int? _Id;
|
||||
protected readonly DateTime? _LastWriteTime;
|
||||
protected readonly long? _Length;
|
||||
protected readonly string _Name;
|
||||
protected readonly string _NameWithoutExtension;
|
||||
public DateTime? CreationTime => _CreationTime;
|
||||
public string? DirectoryName => _DirectoryName;
|
||||
public bool Exists => _Exists;
|
||||
public string ExtensionLowered => _ExtensionLowered;
|
||||
public string FullName => _FullName;
|
||||
public int? Id => _Id;
|
||||
public DateTime? LastWriteTime => _LastWriteTime;
|
||||
public long? Length => _Length;
|
||||
public string Name => _Name;
|
||||
public string NameWithoutExtension => _NameWithoutExtension;
|
||||
|
||||
public FileHolder(DateTime? creationTime, string? directoryName, bool exists, string extensionLowered, string fullName, int? id, DateTime? lastWriteTime, long? length, string name, string nameWithoutExtension)
|
||||
{
|
||||
_CreationTime = creationTime;
|
||||
_DirectoryName = directoryName;
|
||||
_Exists = exists;
|
||||
_ExtensionLowered = extensionLowered;
|
||||
_FullName = fullName;
|
||||
_Id = id;
|
||||
_LastWriteTime = lastWriteTime;
|
||||
_Length = length;
|
||||
_Name = name;
|
||||
_NameWithoutExtension = nameWithoutExtension;
|
||||
}
|
||||
|
||||
public FileHolder(FileInfo fileInfo, int? id)
|
||||
{
|
||||
if (fileInfo.Exists)
|
||||
{
|
||||
_CreationTime = fileInfo.CreationTime;
|
||||
_CreationTime = fileInfo.CreationTime;
|
||||
_LastWriteTime = fileInfo.LastWriteTime;
|
||||
_Length = fileInfo.Length;
|
||||
}
|
||||
_DirectoryName = fileInfo.DirectoryName;
|
||||
_Exists = fileInfo.Exists;
|
||||
_ExtensionLowered = fileInfo.Extension.ToLower();
|
||||
_Id = id;
|
||||
_FullName = fileInfo.FullName;
|
||||
_Name = fileInfo.Name;
|
||||
_NameWithoutExtension = Path.GetFileNameWithoutExtension(fileInfo.FullName);
|
||||
}
|
||||
|
||||
public FileHolder(string fileName) :
|
||||
this(new FileInfo(fileName), null)
|
||||
{ }
|
||||
|
||||
public FileHolder(string fileName, int? id) :
|
||||
this(new FileInfo(fileName), id)
|
||||
{ }
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
string result = JsonSerializer.Serialize(this, FileHolderSourceGenerationContext.Default.FileHolder);
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
[JsonSourceGenerationOptions(WriteIndented = true)]
|
||||
[JsonSerializable(typeof(FileHolder))]
|
||||
internal partial class FileHolderSourceGenerationContext : JsonSerializerContext
|
||||
{
|
||||
}
|
23
Shared/Models/FileMetadataDirectory.cs
Normal file
23
Shared/Models/FileMetadataDirectory.cs
Normal file
@ -0,0 +1,23 @@
|
||||
using System.Text.Json;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace View_by_Distance.Shared.Models;
|
||||
|
||||
public record FileMetadataDirectory(DateTime? FileModifiedDate,
|
||||
string? FileName,
|
||||
string? FileSize)
|
||||
{
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
string result = JsonSerializer.Serialize(this, FileMetadataDirectorySourceGenerationContext.Default.FileMetadataDirectory);
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
[JsonSourceGenerationOptions(WriteIndented = true)]
|
||||
[JsonSerializable(typeof(FileMetadataDirectory))]
|
||||
public partial class FileMetadataDirectorySourceGenerationContext : JsonSerializerContext
|
||||
{
|
||||
}
|
22
Shared/Models/GifHeaderDirectory.cs
Normal file
22
Shared/Models/GifHeaderDirectory.cs
Normal file
@ -0,0 +1,22 @@
|
||||
using System.Text.Json;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace View_by_Distance.Shared.Models;
|
||||
|
||||
public record GifHeaderDirectory(string? ImageHeight,
|
||||
string? ImageWidth)
|
||||
{
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
string result = JsonSerializer.Serialize(this, GifHeaderDirectorySourceGenerationContext.Default.GifHeaderDirectory);
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
[JsonSourceGenerationOptions(WriteIndented = true)]
|
||||
[JsonSerializable(typeof(GifHeaderDirectory))]
|
||||
public partial class GifHeaderDirectorySourceGenerationContext : JsonSerializerContext
|
||||
{
|
||||
}
|
26
Shared/Models/GpsDirectory.cs
Normal file
26
Shared/Models/GpsDirectory.cs
Normal file
@ -0,0 +1,26 @@
|
||||
using System.Text.Json;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace View_by_Distance.Shared.Models;
|
||||
|
||||
public record GpsDirectory(string? Altitude,
|
||||
string? Latitude,
|
||||
string? LatitudeRef,
|
||||
string? Longitude,
|
||||
string? LongitudeRef,
|
||||
DateTime? TimeStamp)
|
||||
{
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
string result = JsonSerializer.Serialize(this, GpsDirectorySourceGenerationContext.Default.GpsDirectory);
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
[JsonSourceGenerationOptions(WriteIndented = true)]
|
||||
[JsonSerializable(typeof(GpsDirectory))]
|
||||
public partial class GpsDirectorySourceGenerationContext : JsonSerializerContext
|
||||
{
|
||||
}
|
22
Shared/Models/JpegDirectory.cs
Normal file
22
Shared/Models/JpegDirectory.cs
Normal file
@ -0,0 +1,22 @@
|
||||
using System.Text.Json;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace View_by_Distance.Shared.Models;
|
||||
|
||||
public record JpegDirectory(string? ImageHeight,
|
||||
string? ImageWidth)
|
||||
{
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
string result = JsonSerializer.Serialize(this, JpegDirectorySourceGenerationContext.Default.JpegDirectory);
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
[JsonSourceGenerationOptions(WriteIndented = true)]
|
||||
[JsonSerializable(typeof(JpegDirectory))]
|
||||
public partial class JpegDirectorySourceGenerationContext : JsonSerializerContext
|
||||
{
|
||||
}
|
22
Shared/Models/PhotoshopDirectory.cs
Normal file
22
Shared/Models/PhotoshopDirectory.cs
Normal file
@ -0,0 +1,22 @@
|
||||
using System.Text.Json;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace View_by_Distance.Shared.Models;
|
||||
|
||||
public record PhotoshopDirectory(string? JpegQuality,
|
||||
string? Url)
|
||||
{
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
string result = JsonSerializer.Serialize(this, PhotoshopDirectorySourceGenerationContext.Default.PhotoshopDirectory);
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
[JsonSourceGenerationOptions(WriteIndented = true)]
|
||||
[JsonSerializable(typeof(PhotoshopDirectory))]
|
||||
public partial class PhotoshopDirectorySourceGenerationContext : JsonSerializerContext
|
||||
{
|
||||
}
|
22
Shared/Models/PngDirectory.cs
Normal file
22
Shared/Models/PngDirectory.cs
Normal file
@ -0,0 +1,22 @@
|
||||
using System.Text.Json;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace View_by_Distance.Shared.Models;
|
||||
|
||||
public record PngDirectory(string? ImageHeight,
|
||||
string? ImageWidth)
|
||||
{
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
string result = JsonSerializer.Serialize(this, PngDirectorySourceGenerationContext.Default.PngDirectory);
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
[JsonSourceGenerationOptions(WriteIndented = true)]
|
||||
[JsonSerializable(typeof(PngDirectory))]
|
||||
public partial class PngDirectorySourceGenerationContext : JsonSerializerContext
|
||||
{
|
||||
}
|
25
Shared/Models/Properties/IAAConfiguration.cs
Normal file
25
Shared/Models/Properties/IAAConfiguration.cs
Normal file
@ -0,0 +1,25 @@
|
||||
namespace View_by_Distance.Shared.Models.Properties;
|
||||
|
||||
public interface IAAConfiguration
|
||||
{
|
||||
|
||||
public string DateGroup { init; get; }
|
||||
public string[] IgnoreExtensions { init; get; }
|
||||
public string[] IgnoreRulesKeyWords { init; get; }
|
||||
public string PersonBirthdayFormat { init; get; }
|
||||
public bool PropertiesChangedForProperty { init; get; }
|
||||
public string[] PropertyContentCollectionFiles { init; get; }
|
||||
public string ResultAllInOne { init; get; }
|
||||
public int ResultAllInOneSubdirectoryLength { init; get; }
|
||||
public string ResultCollection { init; get; }
|
||||
public string ResultContent { init; get; }
|
||||
public string ResultSingleton { init; get; }
|
||||
public string[] ValidImageFormatExtensions { init; get; }
|
||||
public string? ModelName { get; }
|
||||
public int? NumberOfJitters { get; }
|
||||
public int? NumberOfTimesToUpsample { get; }
|
||||
public int Offset { init; get; }
|
||||
public string? PredictorModelName { get; }
|
||||
public string RootDirectory { get; }
|
||||
|
||||
}
|
21
Shared/Models/QuickTimeMovieHeaderDirectory.cs
Normal file
21
Shared/Models/QuickTimeMovieHeaderDirectory.cs
Normal file
@ -0,0 +1,21 @@
|
||||
using System.Text.Json;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace View_by_Distance.Shared.Models;
|
||||
|
||||
public record QuickTimeMovieHeaderDirectory(DateTime? Created)
|
||||
{
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
string result = JsonSerializer.Serialize(this, QuickTimeMovieHeaderDirectorySourceGenerationContext.Default.QuickTimeMovieHeaderDirectory);
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
[JsonSourceGenerationOptions(WriteIndented = true)]
|
||||
[JsonSerializable(typeof(QuickTimeMovieHeaderDirectory))]
|
||||
public partial class QuickTimeMovieHeaderDirectorySourceGenerationContext : JsonSerializerContext
|
||||
{
|
||||
}
|
21
Shared/Models/QuickTimeTrackHeaderDirectory.cs
Normal file
21
Shared/Models/QuickTimeTrackHeaderDirectory.cs
Normal file
@ -0,0 +1,21 @@
|
||||
using System.Text.Json;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace View_by_Distance.Shared.Models;
|
||||
|
||||
public record QuickTimeTrackHeaderDirectory(DateTime? Created)
|
||||
{
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
string result = JsonSerializer.Serialize(this, QuickTimeTrackHeaderDirectorySourceGenerationContext.Default.QuickTimeTrackHeaderDirectory);
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
[JsonSourceGenerationOptions(WriteIndented = true)]
|
||||
[JsonSerializable(typeof(QuickTimeTrackHeaderDirectory))]
|
||||
public partial class QuickTimeTrackHeaderDirectorySourceGenerationContext : JsonSerializerContext
|
||||
{
|
||||
}
|
20
Shared/Models/Stateless/Console.cs
Normal file
20
Shared/Models/Stateless/Console.cs
Normal file
@ -0,0 +1,20 @@
|
||||
using View_by_Distance.Shared.Models.Stateless.Methods;
|
||||
|
||||
namespace View_by_Distance.Shared.Models;
|
||||
|
||||
public class Console : IConsole
|
||||
{
|
||||
|
||||
ConsoleKey IConsole.ReadKey()
|
||||
{
|
||||
ConsoleKey result = System.Console.ReadKey().Key;
|
||||
return result;
|
||||
}
|
||||
|
||||
string? IConsole.ReadLine()
|
||||
{
|
||||
string? result = System.Console.ReadLine();
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
20
Shared/Models/Stateless/Id.cs
Normal file
20
Shared/Models/Stateless/Id.cs
Normal file
@ -0,0 +1,20 @@
|
||||
namespace View_by_Distance.Shared.Models.Stateless;
|
||||
|
||||
internal abstract class Id
|
||||
{
|
||||
|
||||
internal static bool NameWithoutExtensionIsIdFormat(string fileNameWithoutExtension)
|
||||
{
|
||||
bool result;
|
||||
int intMinValueLength = int.MinValue.ToString().Length;
|
||||
if (fileNameWithoutExtension.Length < 5 || fileNameWithoutExtension.Length > intMinValueLength)
|
||||
result = false;
|
||||
else
|
||||
{
|
||||
bool skipOneAllAreNumbers = fileNameWithoutExtension[1..].All(l => char.IsNumber(l));
|
||||
result = (skipOneAllAreNumbers && fileNameWithoutExtension[0] == '-') || (skipOneAllAreNumbers && char.IsNumber(fileNameWithoutExtension[0]));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
9
Shared/Models/Stateless/Methods/IConsole.cs
Normal file
9
Shared/Models/Stateless/Methods/IConsole.cs
Normal file
@ -0,0 +1,9 @@
|
||||
namespace View_by_Distance.Shared.Models.Stateless.Methods;
|
||||
|
||||
public interface IConsole
|
||||
{
|
||||
|
||||
string? ReadLine();
|
||||
ConsoleKey ReadKey();
|
||||
|
||||
}
|
16
Shared/Models/Stateless/Methods/IDate.cs
Normal file
16
Shared/Models/Stateless/Methods/IDate.cs
Normal file
@ -0,0 +1,16 @@
|
||||
namespace View_by_Distance.Shared.Models.Stateless.Methods;
|
||||
|
||||
public interface IDate
|
||||
{
|
||||
|
||||
(bool?, string[]) TestStatic_IsWrongYear(string[] segments, string year) =>
|
||||
IsWrongYear(segments, year);
|
||||
static (bool?, string[]) IsWrongYear(string[] segments, string year) =>
|
||||
XDate.IsWrongYear(segments, year);
|
||||
|
||||
(int Season, string seasonName) TestStatic_GetSeason(int dayOfYear) =>
|
||||
GetSeason(dayOfYear);
|
||||
static (int Season, string seasonName) GetSeason(int dayOfYear) =>
|
||||
XDate.GetSeason(dayOfYear);
|
||||
|
||||
}
|
39
Shared/Models/Stateless/Methods/IId.cs
Normal file
39
Shared/Models/Stateless/Methods/IId.cs
Normal file
@ -0,0 +1,39 @@
|
||||
namespace View_by_Distance.Shared.Models.Stateless.Methods;
|
||||
|
||||
public interface IId
|
||||
{
|
||||
|
||||
bool TestStatic_NameWithoutExtensionIsIdFormat(string fileNameWithoutExtension) =>
|
||||
NameWithoutExtensionIsIdFormat(fileNameWithoutExtension);
|
||||
static bool NameWithoutExtensionIsIdFormat(string fileNameWithoutExtension) =>
|
||||
Id.NameWithoutExtensionIsIdFormat(fileNameWithoutExtension);
|
||||
|
||||
bool TestStatic_NameWithoutExtensionIsIdFormat(FileHolder fileHolder) =>
|
||||
NameWithoutExtensionIsIdFormat(fileHolder);
|
||||
static bool NameWithoutExtensionIsIdFormat(FileHolder fileHolder) =>
|
||||
NameWithoutExtensionIsIdFormat(fileHolder.NameWithoutExtension);
|
||||
|
||||
string TestStatic_GetPaddedId(int intMinValueLength, int index, int id) =>
|
||||
GetPaddedId(intMinValueLength, index, id);
|
||||
static string GetPaddedId(int intMinValueLength, int index, int id) =>
|
||||
id > -1 ? $"{index}070{id.ToString().PadLeft(intMinValueLength, '0')}" : $"{index}030{id.ToString()[1..].PadLeft(intMinValueLength, '0')}";
|
||||
|
||||
bool TestStatic_NameWithoutExtensionIsPaddedIdFormat(string fileNameWithoutExtension, int sortOrderOnlyLengthIndex) =>
|
||||
NameWithoutExtensionIsPaddedIdFormat(fileNameWithoutExtension, sortOrderOnlyLengthIndex);
|
||||
static bool NameWithoutExtensionIsPaddedIdFormat(string fileNameWithoutExtension, int sortOrderOnlyLengthIndex) =>
|
||||
fileNameWithoutExtension.Length > sortOrderOnlyLengthIndex
|
||||
&& fileNameWithoutExtension[sortOrderOnlyLengthIndex] == '0'
|
||||
&& fileNameWithoutExtension[sortOrderOnlyLengthIndex - 3] == '0'
|
||||
&& fileNameWithoutExtension.All(l => char.IsNumber(l));
|
||||
|
||||
short TestStatic_GetSortOrderOnlyLengthIndex(int offset) =>
|
||||
GetSortOrderOnlyLengthIndex(offset);
|
||||
static short GetSortOrderOnlyLengthIndex(int offset) =>
|
||||
(short)(offset.ToString().Length + 3);
|
||||
|
||||
bool TestStatic_NameWithoutExtensionIsPaddedIdFormat(FileHolder fileHolder, int sortOrderOnlyLengthIndex) =>
|
||||
NameWithoutExtensionIsPaddedIdFormat(fileHolder, sortOrderOnlyLengthIndex);
|
||||
static bool NameWithoutExtensionIsPaddedIdFormat(FileHolder fileHolder, int sortOrderOnlyLengthIndex) =>
|
||||
NameWithoutExtensionIsPaddedIdFormat(fileHolder.NameWithoutExtension, sortOrderOnlyLengthIndex);
|
||||
|
||||
}
|
74
Shared/Models/Stateless/Methods/IPath.cs
Normal file
74
Shared/Models/Stateless/Methods/IPath.cs
Normal file
@ -0,0 +1,74 @@
|
||||
using View_by_Distance.Shared.Models.Properties;
|
||||
|
||||
namespace View_by_Distance.Shared.Models.Stateless.Methods;
|
||||
|
||||
public interface IPath
|
||||
{ // ...
|
||||
|
||||
string TestStatic_GetRelativePath(string path, int length) =>
|
||||
GetRelativePath(path, length);
|
||||
static string GetRelativePath(string path, int length) =>
|
||||
XPath.GetRelativePath(path, length, forceExtensionToLower: false);
|
||||
|
||||
bool TestStatic_DeleteEmptyDirectories(string rootDirectory) =>
|
||||
DeleteEmptyDirectories(rootDirectory);
|
||||
static bool DeleteEmptyDirectories(string rootDirectory) =>
|
||||
XPath.DeleteEmptyDirectories(rootDirectory);
|
||||
|
||||
void TestStatic_ChangeDateForEmptyDirectories(string rootDirectory, long ticks) =>
|
||||
ChangeDateForEmptyDirectories(rootDirectory, ticks);
|
||||
static void ChangeDateForEmptyDirectories(string rootDirectory, long ticks) =>
|
||||
XPath.ChangeDateForEmptyDirectories(rootDirectory, ticks);
|
||||
|
||||
void TestStatic_MakeHiddenIfAllItemsAreHidden(string rootDirectory) =>
|
||||
MakeHiddenIfAllItemsAreHidden(rootDirectory);
|
||||
static void MakeHiddenIfAllItemsAreHidden(string rootDirectory) =>
|
||||
XPath.MakeHiddenIfAllItemsAreHidden(rootDirectory);
|
||||
|
||||
void TestStatic_DeleteEmptyDirectories(string rootDirectory, List<string> deletedDirectories) =>
|
||||
DeleteEmptyDirectories(rootDirectory, deletedDirectories);
|
||||
static void DeleteEmptyDirectories(string rootDirectory, List<string> deletedDirectories) =>
|
||||
XPath.DeleteEmptyDirectories(rootDirectory, deletedDirectories);
|
||||
// $dirs = gci "" -directory -recurse | Where { (gci $_.fullName).count -eq 0 } | select -expandproperty FullName $dirs | Foreach-Object { Remove-Item $_ }
|
||||
|
||||
string[] TestStatic_GetDirectoryNames(string directory) =>
|
||||
GetDirectoryNames(directory);
|
||||
static string[] GetDirectoryNames(string directory) =>
|
||||
XPath.GetDirectoryNames(directory).ToArray();
|
||||
|
||||
string[] TestStatic_GetDirectories(string directory) =>
|
||||
GetDirectories(directory);
|
||||
static string[] GetDirectories(string directory) =>
|
||||
XPath.GetDirectories(directory).ToArray();
|
||||
|
||||
string TestStatic_GetRelativePath(string path, int length, bool forceExtensionToLower) =>
|
||||
GetRelativePath(path, length, forceExtensionToLower);
|
||||
static string GetRelativePath(string path, int length, bool forceExtensionToLower) =>
|
||||
XPath.GetRelativePath(path, length, forceExtensionToLower);
|
||||
|
||||
bool TestStatic_WriteAllText(string path, string contents, bool updateDateWhenMatches, bool compareBeforeWrite, DateTime? updateToWhenMatches = null) =>
|
||||
WriteAllText(path, contents, updateDateWhenMatches, compareBeforeWrite, updateToWhenMatches);
|
||||
static bool WriteAllText(string path, string contents, bool updateDateWhenMatches, bool compareBeforeWrite, DateTime? updateToWhenMatches = null) =>
|
||||
XPath.WriteAllText(path, contents, updateDateWhenMatches, compareBeforeWrite, updateToWhenMatches);
|
||||
|
||||
(int level, List<string> directories) TestStatic_Get(string rootDirectory, string sourceDirectory) =>
|
||||
Get(rootDirectory, sourceDirectory);
|
||||
static (int level, List<string> directories) Get(string rootDirectory, string sourceDirectory) =>
|
||||
XPath.Get(rootDirectory, sourceDirectory);
|
||||
|
||||
string TestStatic_GetDirectory(string sourceDirectory, int level, string directoryName) =>
|
||||
GetDirectory(sourceDirectory, level, directoryName);
|
||||
static string GetDirectory(string sourceDirectory, int level, string directoryName) =>
|
||||
XPath.GetDirectory(sourceDirectory, level, directoryName);
|
||||
|
||||
(string, int) TestStatic_GetDirectoryNameAndIndex(int resultAllInOneSubdirectoryLength, string fileName) =>
|
||||
GetDirectoryNameAndIndex(resultAllInOneSubdirectoryLength, fileName);
|
||||
static (string, int) GetDirectoryNameAndIndex(int resultAllInOneSubdirectoryLength, string fileName) =>
|
||||
XPath.GetDirectoryNameAndIndex(resultAllInOneSubdirectoryLength, fileName);
|
||||
|
||||
Dictionary<string, string[]> TestStatic_GetKeyValuePairs(IAAConfiguration aAConfiguration, string? resultsFullGroupDirectory, string[]? directories) =>
|
||||
GetKeyValuePairs(aAConfiguration, resultsFullGroupDirectory, directories);
|
||||
static Dictionary<string, string[]> GetKeyValuePairs(IAAConfiguration propertyConfiguration, string? resultsFullGroupDirectory, string[]? directories) =>
|
||||
XPath.GetKeyValuePairs(propertyConfiguration, resultsFullGroupDirectory, directories);
|
||||
|
||||
}
|
48
Shared/Models/Stateless/Methods/IResult.cs
Normal file
48
Shared/Models/Stateless/Methods/IResult.cs
Normal file
@ -0,0 +1,48 @@
|
||||
using View_by_Distance.Shared.Models.Properties;
|
||||
|
||||
namespace View_by_Distance.Shared.Models.Stateless.Methods;
|
||||
|
||||
public interface IResult
|
||||
{
|
||||
|
||||
string TestStatic_GetRelativePath(IAAConfiguration aAConfiguration, string path) =>
|
||||
GetRelativePath(aAConfiguration, path);
|
||||
static string GetRelativePath(IAAConfiguration aAConfiguration, string path) =>
|
||||
XResult.GetRelativePath(aAConfiguration, path);
|
||||
|
||||
string TestStatic_GetResultsGroupDirectory(IAAConfiguration aAConfiguration, string description, bool create) =>
|
||||
GetResultsGroupDirectory(aAConfiguration, description, create);
|
||||
static string GetResultsGroupDirectory(IAAConfiguration aAConfiguration, string description, bool create) =>
|
||||
XResult.GetResultsGroupDirectory(aAConfiguration, description, create);
|
||||
|
||||
string TestStatic_GetResultsGroupDirectory(IAAConfiguration aAConfiguration, string description) =>
|
||||
GetResultsGroupDirectory(aAConfiguration, description);
|
||||
static string GetResultsGroupDirectory(IAAConfiguration aAConfiguration, string description) =>
|
||||
XResult.GetResultsGroupDirectory(aAConfiguration, description, create: true);
|
||||
|
||||
string TestStatic_GetResultsDateGroupDirectory(IAAConfiguration aAConfiguration, string description) =>
|
||||
GetResultsDateGroupDirectory(aAConfiguration, description);
|
||||
static string GetResultsDateGroupDirectory(IAAConfiguration aAConfiguration, string description) =>
|
||||
XResult.GetResultsDateGroupDirectory(aAConfiguration, description);
|
||||
|
||||
string TestStatic_GetResultsDateGroupDirectory(IAAConfiguration aAConfiguration, string description, string jsonGroup) =>
|
||||
GetResultsDateGroupDirectory(aAConfiguration, description, jsonGroup);
|
||||
static string GetResultsDateGroupDirectory(IAAConfiguration aAConfiguration, string description, string jsonGroup) =>
|
||||
XResult.GetResultsDateGroupDirectory(aAConfiguration, description, jsonGroup);
|
||||
|
||||
List<string> TestStatic_GetDirectoryInfoCollection(IAAConfiguration aAConfiguration, string sourceDirectory, string dateGroupDirectory, string contentDescription, string singletonDescription, string collectionDescription, bool converted) =>
|
||||
GetDirectoryInfoCollection(aAConfiguration, sourceDirectory, dateGroupDirectory, contentDescription, singletonDescription, collectionDescription, converted);
|
||||
static List<string> GetDirectoryInfoCollection(IAAConfiguration aAConfiguration, string sourceDirectory, string dateGroupDirectory, string contentDescription, string singletonDescription, string collectionDescription, bool converted) =>
|
||||
XResult.GetDirectoryInfoCollection(aAConfiguration, sourceDirectory, dateGroupDirectory, contentDescription, singletonDescription, collectionDescription, converted);
|
||||
|
||||
string TestStatic_GetResultsFullGroupDirectory(IAAConfiguration aAConfiguration, string description, string outputResolution, bool includeResizeGroup, bool includeModel, bool includePredictorModel) =>
|
||||
GetResultsFullGroupDirectory(aAConfiguration, description, outputResolution, includeResizeGroup, includeModel, includePredictorModel);
|
||||
static string GetResultsFullGroupDirectory(IAAConfiguration aAConfiguration, string description, string outputResolution, bool includeResizeGroup, bool includeModel, bool includePredictorModel) =>
|
||||
XResult.GetResultsFullGroupDirectory(aAConfiguration, description, outputResolution, includeResizeGroup, includeModel, includePredictorModel);
|
||||
|
||||
List<string> TestStatic_GetDirectoryInfoCollection(IAAConfiguration aAConfiguration, string sourceDirectory, string description, string outputResolution, bool includeResizeGroup, bool includeModel, bool includePredictorModel, string contentDescription, string singletonDescription, string collectionDescription) =>
|
||||
GetDirectoryInfoCollection(aAConfiguration, sourceDirectory, description, outputResolution, includeResizeGroup, includeModel, includePredictorModel, contentDescription, singletonDescription, collectionDescription);
|
||||
static List<string> GetDirectoryInfoCollection(IAAConfiguration aAConfiguration, string sourceDirectory, string description, string outputResolution, bool includeResizeGroup, bool includeModel, bool includePredictorModel, string contentDescription, string singletonDescription, string collectionDescription) =>
|
||||
XResult.GetDirectoryInfoCollection(aAConfiguration, sourceDirectory, description, outputResolution, includeResizeGroup, includeModel, includePredictorModel, contentDescription, singletonDescription, collectionDescription);
|
||||
|
||||
}
|
24
Shared/Models/Stateless/Model.cs
Normal file
24
Shared/Models/Stateless/Model.cs
Normal file
@ -0,0 +1,24 @@
|
||||
namespace View_by_Distance.Shared.Models.Stateless;
|
||||
|
||||
/// <summary>
|
||||
/// Specifies the model of face detector.
|
||||
/// </summary>
|
||||
public enum Model
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// Specifies that the model is HOG (Histograms of Oriented Gradients) based face detector.
|
||||
/// </summary>
|
||||
Hog,
|
||||
|
||||
/// <summary>
|
||||
/// Specifies that the model is CNN (Convolutional Neural Network) based face detector.
|
||||
/// </summary>
|
||||
Cnn,
|
||||
|
||||
/// <summary>
|
||||
/// Specifies that the custom face detector.
|
||||
/// </summary>
|
||||
Custom
|
||||
|
||||
}
|
24
Shared/Models/Stateless/PredictorModel.cs
Normal file
24
Shared/Models/Stateless/PredictorModel.cs
Normal file
@ -0,0 +1,24 @@
|
||||
namespace View_by_Distance.Shared.Models.Stateless;
|
||||
|
||||
/// <summary>
|
||||
/// Specifies the dimension of vector which be returned from detector.
|
||||
/// </summary>
|
||||
public enum PredictorModel
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// Specifies that the large scale detector. The detector returns 68 points for represent face.
|
||||
/// </summary>
|
||||
Large,
|
||||
|
||||
/// <summary>
|
||||
/// Specifies that the small scale detector. The detector returns 5 points for represent face.
|
||||
/// </summary>
|
||||
Small,
|
||||
|
||||
/// <summary>
|
||||
/// Specifies that the custom detector.
|
||||
/// </summary>
|
||||
Custom
|
||||
|
||||
}
|
50
Shared/Models/Stateless/XDate.cs
Normal file
50
Shared/Models/Stateless/XDate.cs
Normal file
@ -0,0 +1,50 @@
|
||||
namespace View_by_Distance.Shared.Models.Stateless;
|
||||
|
||||
internal abstract class XDate
|
||||
{
|
||||
|
||||
internal static (int Season, string seasonName) GetSeason(int dayOfYear)
|
||||
{
|
||||
(int Season, string seasonName) result = dayOfYear switch
|
||||
{
|
||||
< 78 => new(0, "Winter"),
|
||||
< 171 => new(1, "Spring"),
|
||||
< 264 => new(2, "Summer"),
|
||||
< 354 => new(3, "Fall"),
|
||||
_ => new(4, "Winter")
|
||||
};
|
||||
return result;
|
||||
}
|
||||
|
||||
internal static (bool?, string[]) IsWrongYear(string[] segments, string year)
|
||||
{
|
||||
bool? result;
|
||||
string[] results = (
|
||||
from l
|
||||
in segments
|
||||
where l?.Length > 2
|
||||
&& (
|
||||
l[..2] is "18" or "19" or "20"
|
||||
|| (l.Length == 5 && l.Substring(1, 2) is "18" or "19" or "20" && (l[0] is '~' or '=' or '-' or '^' or '#'))
|
||||
|| (l.Length == 6 && l[..2] is "18" or "19" or "20" && l[4] == '.')
|
||||
|| (l.Length == 7 && l.Substring(1, 2) is "18" or "19" or "20" && l[5] == '.')
|
||||
)
|
||||
select l
|
||||
).ToArray();
|
||||
string[] matches = (
|
||||
from l
|
||||
in results
|
||||
where l == year
|
||||
|| (l.Length == 5 && l.Substring(1, 4) == year && (l[0] is '~' or '=' or '-' or '^' or '#'))
|
||||
|| (l.Length == 6 && l[..4] == year && l[4] == '.')
|
||||
|| (l.Length == 7 && l.Substring(1, 4) == year && l[5] == '.')
|
||||
select l
|
||||
).ToArray();
|
||||
if (results.Length == 0)
|
||||
result = null;
|
||||
else
|
||||
result = matches.Length == 0;
|
||||
return new(result, results);
|
||||
}
|
||||
|
||||
}
|
331
Shared/Models/Stateless/XPath.cs
Normal file
331
Shared/Models/Stateless/XPath.cs
Normal file
@ -0,0 +1,331 @@
|
||||
using View_by_Distance.Shared.Models.Properties;
|
||||
|
||||
namespace View_by_Distance.Shared.Models.Stateless;
|
||||
|
||||
internal abstract class XPath
|
||||
{
|
||||
|
||||
internal static string GetRelativePath(string path, int length, bool forceExtensionToLower)
|
||||
{
|
||||
string result;
|
||||
if (forceExtensionToLower)
|
||||
{
|
||||
string extension = Path.GetExtension(path);
|
||||
string extensionLowered = Path.GetExtension(path).ToLower();
|
||||
if (extension != extensionLowered)
|
||||
{
|
||||
string? directoryName = Path.GetDirectoryName(path);
|
||||
if (string.IsNullOrEmpty(directoryName))
|
||||
throw new NullReferenceException(directoryName);
|
||||
string fileNameWithoutExtension = Path.GetFileNameWithoutExtension(path);
|
||||
if (string.IsNullOrEmpty(fileNameWithoutExtension))
|
||||
throw new NullReferenceException(fileNameWithoutExtension);
|
||||
path = Path.Combine(directoryName, $"{fileNameWithoutExtension}{extensionLowered}");
|
||||
}
|
||||
}
|
||||
result = path[length..].Replace(@"\", "/");
|
||||
return result;
|
||||
}
|
||||
|
||||
internal static bool DeleteEmptyDirectories(string rootDirectory)
|
||||
{
|
||||
bool result;
|
||||
List<string> results = [];
|
||||
DeleteEmptyDirectories(rootDirectory, results);
|
||||
result = results.Count > 0;
|
||||
return result;
|
||||
}
|
||||
|
||||
internal static void DeleteEmptyDirectories(string rootDirectory, List<string> deletedDirectories)
|
||||
{
|
||||
if (Directory.Exists(rootDirectory))
|
||||
{
|
||||
string[] files;
|
||||
string[] directories = Directory.GetDirectories(rootDirectory, "*", SearchOption.TopDirectoryOnly);
|
||||
if (directories.Length > 0)
|
||||
files = [];
|
||||
else
|
||||
files = Directory.GetFiles(rootDirectory, "*", SearchOption.AllDirectories);
|
||||
if (directories.Length == 0 && files.Length == 0)
|
||||
{
|
||||
deletedDirectories.Add(rootDirectory);
|
||||
try
|
||||
{ Directory.Delete(rootDirectory); }
|
||||
catch (UnauthorizedAccessException)
|
||||
{
|
||||
new DirectoryInfo(rootDirectory).Attributes = FileAttributes.Normal;
|
||||
Directory.Delete(rootDirectory);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
List<string> check = [];
|
||||
foreach (string directory in directories)
|
||||
{
|
||||
DeleteEmptyDirectories(directory, check);
|
||||
deletedDirectories.AddRange(check);
|
||||
if (check.Count > 0)
|
||||
DeleteEmptyDirectories(directory, deletedDirectories);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal static bool WriteAllText(string path, string contents, bool updateDateWhenMatches, bool compareBeforeWrite, DateTime? updateToWhenMatches)
|
||||
{
|
||||
bool result;
|
||||
string text;
|
||||
if (!compareBeforeWrite)
|
||||
result = true;
|
||||
else
|
||||
{
|
||||
if (!File.Exists(path))
|
||||
text = string.Empty;
|
||||
else
|
||||
text = File.ReadAllText(path);
|
||||
result = text != contents;
|
||||
if (!result && updateDateWhenMatches)
|
||||
{
|
||||
if (updateToWhenMatches is null)
|
||||
File.SetLastWriteTime(path, DateTime.Now);
|
||||
else
|
||||
File.SetLastWriteTime(path, updateToWhenMatches.Value);
|
||||
}
|
||||
}
|
||||
if (result)
|
||||
{
|
||||
if (path.Contains("()"))
|
||||
File.WriteAllText(path, contents);
|
||||
else if (path.Contains("{}") && !path.EndsWith(".json"))
|
||||
File.WriteAllText(path, contents);
|
||||
else if (path.Contains("[]") && !path.EndsWith(".json"))
|
||||
File.WriteAllText(path, contents);
|
||||
else if (path.Contains("{}") && path.EndsWith(".json") && contents[0] == '{')
|
||||
File.WriteAllText(path, contents);
|
||||
else if (path.Contains("[]") && path.EndsWith(".json") && contents[0] == '[')
|
||||
File.WriteAllText(path, contents);
|
||||
else
|
||||
File.WriteAllText(path, contents);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
internal static List<string> GetDirectoryNames(string directory)
|
||||
{
|
||||
List<string> results = [];
|
||||
string? fileName;
|
||||
string? checkDirectory = directory;
|
||||
string? pathRoot = Path.GetPathRoot(directory);
|
||||
string extension = Path.GetExtension(directory);
|
||||
if (string.IsNullOrEmpty(pathRoot))
|
||||
throw new NullReferenceException(nameof(pathRoot));
|
||||
if (Directory.Exists(directory))
|
||||
{
|
||||
fileName = Path.GetFileName(directory);
|
||||
if (!string.IsNullOrEmpty(fileName))
|
||||
results.Add(fileName);
|
||||
}
|
||||
else if ((string.IsNullOrEmpty(extension) || extension.Length > 3) && !File.Exists(directory))
|
||||
{
|
||||
fileName = Path.GetFileName(directory);
|
||||
if (!string.IsNullOrEmpty(fileName))
|
||||
results.Add(fileName);
|
||||
}
|
||||
for (int i = 0; i < int.MaxValue; i++)
|
||||
{
|
||||
checkDirectory = Path.GetDirectoryName(checkDirectory);
|
||||
if (string.IsNullOrEmpty(checkDirectory) || checkDirectory == pathRoot)
|
||||
break;
|
||||
fileName = Path.GetFileName(checkDirectory);
|
||||
if (string.IsNullOrEmpty(fileName))
|
||||
continue;
|
||||
results.Add(fileName);
|
||||
}
|
||||
results.Add(pathRoot);
|
||||
results.Reverse();
|
||||
return results;
|
||||
}
|
||||
|
||||
internal static List<string> GetDirectories(string directory)
|
||||
{
|
||||
List<string> results = [];
|
||||
string? checkDirectory = directory;
|
||||
string? pathRoot = Path.GetPathRoot(directory);
|
||||
if (string.IsNullOrEmpty(pathRoot))
|
||||
throw new NullReferenceException(nameof(pathRoot));
|
||||
if (Directory.Exists(directory))
|
||||
results.Add(directory);
|
||||
for (int i = 0; i < int.MaxValue; i++)
|
||||
{
|
||||
checkDirectory = Path.GetDirectoryName(checkDirectory);
|
||||
if (string.IsNullOrEmpty(checkDirectory) || checkDirectory == pathRoot)
|
||||
break;
|
||||
results.Add(checkDirectory);
|
||||
}
|
||||
results.Add(pathRoot);
|
||||
results.Reverse();
|
||||
return results;
|
||||
}
|
||||
|
||||
internal static (int level, List<string> directories) Get(string rootDirectory, string sourceDirectory)
|
||||
{
|
||||
int result = 0;
|
||||
string? directory;
|
||||
string? checkDirectory;
|
||||
List<string> results = [];
|
||||
checkDirectory = sourceDirectory;
|
||||
for (int i = 0; i < int.MaxValue; i++)
|
||||
{
|
||||
result += 1;
|
||||
directory = Path.GetFileName(checkDirectory);
|
||||
if (string.IsNullOrEmpty(directory))
|
||||
break;
|
||||
results.Add(directory);
|
||||
checkDirectory = Path.GetDirectoryName(checkDirectory);
|
||||
if (checkDirectory == rootDirectory)
|
||||
break;
|
||||
}
|
||||
results.Reverse();
|
||||
return new(result, results);
|
||||
}
|
||||
|
||||
internal static string GetDirectory(string sourceDirectory, int level, string directoryName)
|
||||
{
|
||||
string result;
|
||||
string? checkDirectory;
|
||||
checkDirectory = Path.GetDirectoryName(sourceDirectory);
|
||||
for (int i = 0; i < level; i++)
|
||||
checkDirectory = Path.GetDirectoryName(checkDirectory);
|
||||
if (string.IsNullOrEmpty(checkDirectory))
|
||||
throw new Exception();
|
||||
checkDirectory = Path.Combine(checkDirectory, directoryName);
|
||||
if (!Directory.Exists(checkDirectory))
|
||||
_ = Directory.CreateDirectory(checkDirectory);
|
||||
result = checkDirectory;
|
||||
return result;
|
||||
}
|
||||
|
||||
internal static void ChangeDateForEmptyDirectories(string rootDirectory, long ticks)
|
||||
{
|
||||
DateTime dateTime = new(ticks);
|
||||
IEnumerable<string> fileSystemEntries;
|
||||
string[] directories;
|
||||
if (!Directory.Exists(rootDirectory))
|
||||
directories = [];
|
||||
else
|
||||
directories = Directory.GetDirectories(rootDirectory, "*", SearchOption.AllDirectories);
|
||||
foreach (string directory in directories)
|
||||
{
|
||||
fileSystemEntries = Directory.EnumerateFileSystemEntries(directory, "*", SearchOption.TopDirectoryOnly);
|
||||
if (fileSystemEntries.Any())
|
||||
continue;
|
||||
Directory.SetLastWriteTime(directory, dateTime);
|
||||
}
|
||||
}
|
||||
|
||||
internal static void MakeHiddenIfAllItemsAreHidden(string rootDirectory)
|
||||
{
|
||||
bool check;
|
||||
FileInfo fileInfo;
|
||||
IEnumerable<string> files;
|
||||
DirectoryInfo directoryInfo;
|
||||
IEnumerable<string> subDirectories;
|
||||
string[] directories = Directory.GetDirectories(rootDirectory, "*", SearchOption.AllDirectories);
|
||||
foreach (string directory in directories)
|
||||
{
|
||||
directoryInfo = new(directory);
|
||||
if (directoryInfo.Attributes.HasFlag(FileAttributes.Hidden))
|
||||
continue;
|
||||
check = true;
|
||||
subDirectories = Directory.EnumerateDirectories(directory, "*", SearchOption.TopDirectoryOnly);
|
||||
foreach (string subDirectory in subDirectories)
|
||||
{
|
||||
directoryInfo = new(subDirectory);
|
||||
if (!directoryInfo.Attributes.HasFlag(FileAttributes.Hidden))
|
||||
{
|
||||
check = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!check)
|
||||
continue;
|
||||
files = Directory.EnumerateFiles(directory, "*", SearchOption.TopDirectoryOnly);
|
||||
foreach (string file in files)
|
||||
{
|
||||
fileInfo = new(file);
|
||||
if (!fileInfo.Attributes.HasFlag(FileAttributes.Hidden))
|
||||
{
|
||||
check = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!check)
|
||||
continue;
|
||||
directoryInfo.Attributes |= FileAttributes.Hidden;
|
||||
}
|
||||
}
|
||||
|
||||
internal static (string, int) GetDirectoryNameAndIndex(int resultAllInOneSubdirectoryLength, string fileName)
|
||||
{
|
||||
int converted;
|
||||
string result;
|
||||
string check = fileName.Length < resultAllInOneSubdirectoryLength ? new('-', resultAllInOneSubdirectoryLength) : fileName.Split('.')[0][^resultAllInOneSubdirectoryLength..];
|
||||
if (check.Any(l => !char.IsNumber(l)))
|
||||
{
|
||||
result = new('-', resultAllInOneSubdirectoryLength);
|
||||
converted = int.Parse($"1{new string('0', resultAllInOneSubdirectoryLength)}");
|
||||
}
|
||||
else
|
||||
{
|
||||
result = check;
|
||||
converted = int.Parse(check);
|
||||
}
|
||||
return (result, converted);
|
||||
}
|
||||
|
||||
internal static Dictionary<string, string[]> GetKeyValuePairs(IAAConfiguration aAConfiguration, string? resultsFullGroupDirectory, string[]? directories)
|
||||
{
|
||||
Dictionary<string, string[]> results = [];
|
||||
string directory;
|
||||
string checkDirectory;
|
||||
int converted = int.Parse($"1{new string('0', aAConfiguration.ResultAllInOneSubdirectoryLength)}");
|
||||
int plusOne = converted + 1;
|
||||
List<string> collection = [];
|
||||
if (directories is not null)
|
||||
{
|
||||
foreach (string key in directories)
|
||||
{
|
||||
if (resultsFullGroupDirectory is null)
|
||||
continue;
|
||||
collection.Clear();
|
||||
for (int i = 0; i < plusOne; i++)
|
||||
{
|
||||
if (string.IsNullOrEmpty(key))
|
||||
{
|
||||
if (i == converted)
|
||||
checkDirectory = Path.GetFullPath(Path.Combine(resultsFullGroupDirectory, new('-', aAConfiguration.ResultAllInOneSubdirectoryLength)));
|
||||
else
|
||||
checkDirectory = Path.GetFullPath(Path.Combine(resultsFullGroupDirectory, i.ToString().PadLeft(aAConfiguration.ResultAllInOneSubdirectoryLength, '0')));
|
||||
}
|
||||
else
|
||||
{
|
||||
directory = Path.Combine(resultsFullGroupDirectory, key, aAConfiguration.ResultAllInOne);
|
||||
if (i == converted)
|
||||
checkDirectory = Path.GetFullPath(Path.Combine(directory, new('-', aAConfiguration.ResultAllInOneSubdirectoryLength)));
|
||||
else
|
||||
checkDirectory = Path.GetFullPath(Path.Combine(directory, i.ToString().PadLeft(aAConfiguration.ResultAllInOneSubdirectoryLength, '0')));
|
||||
}
|
||||
if (!Directory.Exists(checkDirectory))
|
||||
_ = Directory.CreateDirectory(checkDirectory);
|
||||
collection.Add(checkDirectory);
|
||||
}
|
||||
if (!string.IsNullOrEmpty(key))
|
||||
results.Add(key, collection.ToArray());
|
||||
else
|
||||
results.Add(aAConfiguration.ResultAllInOne, collection.ToArray());
|
||||
}
|
||||
}
|
||||
return results;
|
||||
}
|
||||
|
||||
}
|
138
Shared/Models/Stateless/XResult.cs
Normal file
138
Shared/Models/Stateless/XResult.cs
Normal file
@ -0,0 +1,138 @@
|
||||
using View_by_Distance.Shared.Models.Properties;
|
||||
|
||||
namespace View_by_Distance.Shared.Models.Stateless;
|
||||
|
||||
internal abstract class XResult
|
||||
{
|
||||
|
||||
internal static string GetResultsDateGroupDirectory(IAAConfiguration aAConfiguration, string description, string jsonGroup)
|
||||
{
|
||||
string result = Path.Combine(GetResultsDateGroupDirectory(aAConfiguration, description), jsonGroup);
|
||||
if (!Directory.Exists(result))
|
||||
_ = Directory.CreateDirectory(result);
|
||||
return result;
|
||||
}
|
||||
|
||||
internal static string GetResultsDateGroupDirectory(IAAConfiguration aAConfiguration, string description)
|
||||
{
|
||||
string result = Path.Combine(GetResultsGroupDirectory(aAConfiguration, description, create: true), aAConfiguration.DateGroup);
|
||||
if (!Directory.Exists(result))
|
||||
_ = Directory.CreateDirectory(result);
|
||||
return result;
|
||||
}
|
||||
|
||||
internal static string GetRelativePath(IAAConfiguration aAConfiguration, string path)
|
||||
{
|
||||
string result = Methods.IPath.GetRelativePath(path, aAConfiguration.RootDirectory.Length);
|
||||
return result;
|
||||
}
|
||||
|
||||
private static void CheckContent(IAAConfiguration aAConfiguration, string dateGroupDirectory, string contentDescription, string result)
|
||||
{
|
||||
string checkDirectory;
|
||||
checkDirectory = Path.Combine(dateGroupDirectory, aAConfiguration.ResultContent, aAConfiguration.ResultAllInOne);
|
||||
if (!Directory.Exists(checkDirectory))
|
||||
_ = Directory.CreateDirectory(checkDirectory);
|
||||
string contentDirectory = new(result.Replace("<>", aAConfiguration.ResultContent));
|
||||
if (!Directory.Exists(contentDirectory))
|
||||
_ = Directory.CreateDirectory(contentDirectory);
|
||||
checkDirectory = Path.Combine(dateGroupDirectory, string.Concat("() - ", contentDescription));
|
||||
if (!Directory.Exists(checkDirectory))
|
||||
_ = Directory.CreateDirectory(checkDirectory);
|
||||
}
|
||||
|
||||
private static void CheckSingleton(IAAConfiguration aAConfiguration, string dateGroupDirectory, string singletonDescription, bool converted, string result)
|
||||
{
|
||||
string checkDirectory;
|
||||
checkDirectory = Path.Combine(dateGroupDirectory, aAConfiguration.ResultSingleton, aAConfiguration.ResultAllInOne);
|
||||
if (!Directory.Exists(checkDirectory))
|
||||
_ = Directory.CreateDirectory(checkDirectory);
|
||||
if (!converted)
|
||||
{
|
||||
string singletonDirectory = new(result.Replace("<>", aAConfiguration.ResultSingleton));
|
||||
if (!Directory.Exists(singletonDirectory))
|
||||
_ = Directory.CreateDirectory(singletonDirectory);
|
||||
}
|
||||
checkDirectory = Path.Combine(dateGroupDirectory, string.Concat("{} - ", singletonDescription));
|
||||
if (!Directory.Exists(checkDirectory))
|
||||
_ = Directory.CreateDirectory(checkDirectory);
|
||||
}
|
||||
|
||||
private static void CheckCollection(IAAConfiguration aAConfiguration, string dateGroupDirectory, string collectionDescription, bool converted, string result)
|
||||
{
|
||||
string checkDirectory = Path.Combine(dateGroupDirectory, aAConfiguration.ResultCollection, aAConfiguration.ResultAllInOne);
|
||||
if (!Directory.Exists(checkDirectory))
|
||||
_ = Directory.CreateDirectory(checkDirectory);
|
||||
if (!converted)
|
||||
{
|
||||
string collectionDirectory = new(result.Replace("<>", aAConfiguration.ResultCollection));
|
||||
if (!Directory.Exists(collectionDirectory))
|
||||
_ = Directory.CreateDirectory(collectionDirectory);
|
||||
}
|
||||
checkDirectory = Path.Combine(dateGroupDirectory, string.Concat("[] - ", collectionDescription));
|
||||
if (!Directory.Exists(checkDirectory))
|
||||
_ = Directory.CreateDirectory(checkDirectory);
|
||||
}
|
||||
|
||||
internal static string GetResultsFullGroupDirectory(IAAConfiguration aAConfiguration, string description, string outputResolution, bool includeResizeGroup, bool includeModel, bool includePredictorModel)
|
||||
{
|
||||
string result = GetResultsDateGroupDirectory(aAConfiguration, description);
|
||||
if (includeResizeGroup)
|
||||
result = Path.Combine(result, outputResolution);
|
||||
if (includeModel && includePredictorModel)
|
||||
{
|
||||
string modelName;
|
||||
string predictorModelName;
|
||||
if (aAConfiguration.ModelName is null)
|
||||
modelName = Model.Hog.ToString();
|
||||
else
|
||||
modelName = aAConfiguration.ModelName;
|
||||
if (aAConfiguration.PredictorModelName is null)
|
||||
predictorModelName = PredictorModel.Large.ToString();
|
||||
else
|
||||
predictorModelName = aAConfiguration.PredictorModelName;
|
||||
string dateGroupDirectory = string.Concat(outputResolution.Replace(" ", string.Empty), "-", modelName, "-", predictorModelName, "-", aAConfiguration.NumberOfJitters, "-", aAConfiguration.NumberOfTimesToUpsample);
|
||||
result = Path.Combine(result, dateGroupDirectory);
|
||||
}
|
||||
else if (includeModel)
|
||||
throw new Exception();
|
||||
else if (includePredictorModel)
|
||||
throw new Exception();
|
||||
if (!Directory.Exists(result))
|
||||
_ = Directory.CreateDirectory(result);
|
||||
return result;
|
||||
}
|
||||
|
||||
internal static List<string> GetDirectoryInfoCollection(IAAConfiguration aAConfiguration, string sourceDirectory, string dateGroupDirectory, string contentDescription, string singletonDescription, string collectionDescription, bool converted)
|
||||
{
|
||||
List<string> results = [];
|
||||
string sourceDirectorySegment = GetRelativePath(aAConfiguration, sourceDirectory);
|
||||
string result = string.Concat(Path.Combine(dateGroupDirectory, "<>"), sourceDirectorySegment);
|
||||
if (!string.IsNullOrEmpty(contentDescription))
|
||||
CheckContent(aAConfiguration, dateGroupDirectory, contentDescription, result);
|
||||
if (!string.IsNullOrEmpty(singletonDescription))
|
||||
CheckSingleton(aAConfiguration, dateGroupDirectory, singletonDescription, converted, result);
|
||||
if (!string.IsNullOrEmpty(collectionDescription))
|
||||
CheckCollection(aAConfiguration, dateGroupDirectory, collectionDescription, converted, result);
|
||||
results.Add(result);
|
||||
return results;
|
||||
}
|
||||
|
||||
internal static string GetResultsGroupDirectory(IAAConfiguration aAConfiguration, string description, bool create)
|
||||
{
|
||||
string result = Path.Combine($"{aAConfiguration.RootDirectory}-Results", description.Replace('_', ')'));
|
||||
if (create && !Directory.Exists(result))
|
||||
_ = Directory.CreateDirectory(result);
|
||||
return result;
|
||||
}
|
||||
|
||||
internal static List<string> GetDirectoryInfoCollection(IAAConfiguration aAConfiguration, string sourceDirectory, string description, string outputResolution, bool includeResizeGroup, bool includeModel, bool includePredictorModel, string contentDescription, string singletonDescription, string collectionDescription)
|
||||
{
|
||||
List<string> results;
|
||||
bool converted = false;
|
||||
string dateGroupDirectory = GetResultsFullGroupDirectory(aAConfiguration, description, outputResolution, includeResizeGroup, includeModel, includePredictorModel);
|
||||
results = GetDirectoryInfoCollection(aAConfiguration, sourceDirectory, dateGroupDirectory, contentDescription, singletonDescription, collectionDescription, converted);
|
||||
return results;
|
||||
}
|
||||
|
||||
}
|
22
Shared/Models/WebPDirectory.cs
Normal file
22
Shared/Models/WebPDirectory.cs
Normal file
@ -0,0 +1,22 @@
|
||||
using System.Text.Json;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace View_by_Distance.Shared.Models;
|
||||
|
||||
public record WebPDirectory(string? ImageHeight,
|
||||
string? ImageWidth)
|
||||
{
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
string result = JsonSerializer.Serialize(this, WebPDirectorySourceGenerationContext.Default.WebPDirectory);
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
[JsonSourceGenerationOptions(WriteIndented = true)]
|
||||
[JsonSerializable(typeof(WebPDirectory))]
|
||||
public partial class WebPDirectorySourceGenerationContext : JsonSerializerContext
|
||||
{
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user