Profiles for users now saved when successfully creating a key, or if it doesn't exist already. Synced with profile on sever if available or use sane defaults if not. You can download the updated profile if changed on server /profiledown, or upload it if you make changes, /profileup, or let ttyverse smart sync changes, /syncprofile.
This commit is contained in:
+582
@@ -203,6 +203,7 @@ BEGIN {
|
||||
# user= # Username override
|
||||
# leader= # Command leader character
|
||||
|
||||
|
||||
# === EXTENSION SETTINGS ===
|
||||
# Extensions can be loaded with the -exts option
|
||||
# Extension preferences use the extpref_ prefix:
|
||||
@@ -220,6 +221,7 @@ EOF
|
||||
exit 0;
|
||||
}
|
||||
|
||||
|
||||
$space_pad = " " x 1024;
|
||||
$background_is_ready = 0;
|
||||
|
||||
@@ -2032,6 +2034,9 @@ if (length($credentials)) {
|
||||
|
||||
# Update server configuration (character limits, etc.)
|
||||
&update_server_config;
|
||||
|
||||
# Check and sync profile if enabled
|
||||
&check_and_sync_profile($keyfile);
|
||||
}
|
||||
|
||||
#### BOT/DAEMON MODE STARTUP ####
|
||||
@@ -4406,6 +4411,19 @@ EOF
|
||||
my $choices = $2;
|
||||
return &vote_on_poll($post_code, $choices);
|
||||
}
|
||||
# profile management commands
|
||||
if (m#^/syncprofile\s*$#i) {
|
||||
&cmd_syncprofile;
|
||||
return 0;
|
||||
}
|
||||
if (m#^/profileup\s*$#i) {
|
||||
&cmd_profileup;
|
||||
return 0;
|
||||
}
|
||||
if (m#^/profiledown\s*$#i) {
|
||||
&cmd_profiledown;
|
||||
return 0;
|
||||
}
|
||||
|
||||
# reply to all mentioned users
|
||||
if (m#^/(replyall|ra|replytoall)\s+([a-z]\d+)\s+(.+)$#i) {
|
||||
@@ -11266,4 +11284,568 @@ sub save_dm_seen_status {
|
||||
}
|
||||
}
|
||||
|
||||
#########################################################################
|
||||
# Profile Management System Functions
|
||||
#########################################################################
|
||||
|
||||
# Simple URL encoding for form data
|
||||
sub url_encode {
|
||||
my $str = shift;
|
||||
$str =~ s/([^A-Za-z0-9\-_\.~])/sprintf("%%%02X", ord($1))/ge;
|
||||
return $str;
|
||||
}
|
||||
|
||||
# Get the profile file path for a given keyfile
|
||||
sub get_profile_file_path {
|
||||
my $keyfile_path = shift;
|
||||
return "${keyfile_path}.profile";
|
||||
}
|
||||
|
||||
# Check if profile file exists for given keyfile
|
||||
sub profile_file_exists {
|
||||
my $keyfile_path = shift;
|
||||
my $profile_path = get_profile_file_path($keyfile_path);
|
||||
return -f $profile_path;
|
||||
}
|
||||
|
||||
# Parse profile file into structured hash
|
||||
sub parse_profile_file {
|
||||
my $profile_path = shift;
|
||||
my %profile = ();
|
||||
my @custom_fields = ();
|
||||
|
||||
unless (open(PROFILE, '<', $profile_path)) {
|
||||
print $stdout "-- Error: Cannot read profile file $profile_path: $!\n";
|
||||
return undef;
|
||||
}
|
||||
|
||||
print $stdout "-- DEBUG: Parsing profile file with multi-line support\n" if ($verbose);
|
||||
|
||||
my $current_field = '';
|
||||
my $current_value = '';
|
||||
|
||||
while (my $line = <PROFILE>) {
|
||||
chomp($line);
|
||||
|
||||
# Skip comments and empty lines
|
||||
next if ($line =~ /^\s*#/ || $line =~ /^\s*$/);
|
||||
|
||||
# Handle continuation lines (indented OR unindented for bio field)
|
||||
if ($line =~ /^\s+(.*)$/ && $current_field) {
|
||||
# Standard indented continuation
|
||||
$current_value .= "\n$1";
|
||||
next;
|
||||
} elsif ($current_field eq 'bio' && $line !~ /^\s*[^=]+\s*=/) {
|
||||
# Bio field continuation (non-indented lines that aren't new field definitions)
|
||||
$current_value .= "\n$line";
|
||||
next;
|
||||
}
|
||||
|
||||
# Finish previous field if we have one
|
||||
if ($current_field) {
|
||||
$current_value =~ s/^\s+|\s+$//g; # trim whitespace
|
||||
if ($current_field eq 'custom_field') {
|
||||
push @custom_fields, $current_value;
|
||||
} else {
|
||||
$profile{$current_field} = $current_value;
|
||||
}
|
||||
}
|
||||
|
||||
# Parse new field
|
||||
if ($line =~ /^\s*([^=]+?)\s*=\s*(.*)$/) {
|
||||
$current_field = $1;
|
||||
$current_value = $2;
|
||||
} else {
|
||||
$current_field = '';
|
||||
$current_value = '';
|
||||
}
|
||||
}
|
||||
|
||||
# Don't forget the last field
|
||||
if ($current_field) {
|
||||
$current_value =~ s/^\s+|\s+$//g;
|
||||
if ($current_field eq 'custom_field') {
|
||||
push @custom_fields, $current_value;
|
||||
} else {
|
||||
$profile{$current_field} = $current_value;
|
||||
}
|
||||
}
|
||||
|
||||
close(PROFILE);
|
||||
|
||||
$profile{'custom_fields'} = \@custom_fields;
|
||||
return \%profile;
|
||||
}
|
||||
|
||||
# Generate profile template file
|
||||
sub generate_profile_template {
|
||||
my $keyfile_path = shift;
|
||||
my $server_profile = shift || {};
|
||||
my $server_info = shift || {};
|
||||
|
||||
my $profile_path = get_profile_file_path($keyfile_path);
|
||||
|
||||
unless (open(TEMPLATE, '>', $profile_path)) {
|
||||
print $stdout "-- Error: Cannot create profile template $profile_path: $!\n";
|
||||
return 0;
|
||||
}
|
||||
|
||||
my $timestamp = scalar(localtime());
|
||||
my $server_name = $fediverseserver || 'your fediverse server';
|
||||
my $username = $server_profile->{'username'} || $server_profile->{'acct'} || 'your username';
|
||||
|
||||
# Clean HTML from bio for template
|
||||
my $clean_bio = $server_profile->{'note'} || 'Your bio/description here';
|
||||
$clean_bio =~ s/<br\s*\/?>/\n/gi; # Convert <br> tags to newlines
|
||||
$clean_bio =~ s/<\/p>\s*<p>/\n\n/gi; # Convert paragraph breaks to double newlines
|
||||
$clean_bio =~ s/<[^>]*>//g; # Remove remaining HTML tags
|
||||
$clean_bio =~ s/</</g; # Decode HTML entities
|
||||
$clean_bio =~ s/>/>/g;
|
||||
$clean_bio =~ s/&/&/g;
|
||||
$clean_bio =~ s/^\s+|\s+$//g; # Trim whitespace
|
||||
|
||||
print TEMPLATE <<EOF;
|
||||
# TTYverse Profile Template - Generated for $server_name
|
||||
# Change the following line to true to enable profile management
|
||||
use_profile = false
|
||||
|
||||
# Generated: $timestamp
|
||||
# Server: $server_name
|
||||
# Account: $username
|
||||
|
||||
# === Basic Profile Fields ===
|
||||
display_name = @{[$server_profile->{'display_name'} || 'Your Display Name']}
|
||||
bio = $clean_bio
|
||||
website = @{[$server_profile->{'url'} || 'https://example.com']}
|
||||
location = @{[$server_profile->{'location'} || 'Your Location']}
|
||||
|
||||
# === Custom Fields ===
|
||||
# Your server supports custom profile fields
|
||||
# Format: custom_field = Field Name = Field Value
|
||||
# Copy/paste this line for more custom fields
|
||||
EOF
|
||||
|
||||
# Add existing custom fields as examples
|
||||
if ($server_profile->{'fields'} && ref($server_profile->{'fields'}) eq 'ARRAY') {
|
||||
foreach my $field (@{$server_profile->{'fields'}}) {
|
||||
my $name = $field->{'name'} || '';
|
||||
my $value = $field->{'value'} || '';
|
||||
# Remove HTML tags from value for template
|
||||
$value =~ s/<[^>]*>//g;
|
||||
print TEMPLATE "custom_field = $name = $value\n";
|
||||
}
|
||||
}
|
||||
|
||||
# Always add commented examples for guidance
|
||||
print TEMPLATE "# \n";
|
||||
print TEMPLATE "# Examples (uncomment and edit to use):\n";
|
||||
print TEMPLATE "# custom_field = GitHub = yourusername\n";
|
||||
print TEMPLATE "# custom_field = Matrix = \@you:matrix.org\n";
|
||||
print TEMPLATE "# custom_field = Blog = https://myblog.com\n";
|
||||
print TEMPLATE "# custom_field = Website = https://yoursite.com\n";
|
||||
|
||||
close(TEMPLATE);
|
||||
chmod(0600, $profile_path); # Keep private
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
# Validate profile configuration
|
||||
sub validate_profile_config {
|
||||
my $profile = shift;
|
||||
my @errors = ();
|
||||
|
||||
# Check display_name length (varies by server, but 30 is common)
|
||||
if ($profile->{'display_name'} && length($profile->{'display_name'}) > 100) {
|
||||
push @errors, "Display name too long (max ~100 characters)";
|
||||
}
|
||||
|
||||
# Check bio length (varies by server, but 500 is common for Mastodon)
|
||||
if ($profile->{'bio'} && length($profile->{'bio'}) > 1000) {
|
||||
push @errors, "Bio too long (max ~500-1000 characters depending on server)";
|
||||
}
|
||||
|
||||
# Validate website URL format
|
||||
if ($profile->{'website'} && $profile->{'website'} !~ /^https?:\/\//) {
|
||||
push @errors, "Website must be a valid HTTP/HTTPS URL";
|
||||
}
|
||||
|
||||
# Validate custom fields format
|
||||
if ($profile->{'custom_fields'}) {
|
||||
foreach my $field (@{$profile->{'custom_fields'}}) {
|
||||
unless ($field =~ /^([^=]+)\s*=\s*(.+)$/) {
|
||||
push @errors, "Invalid custom field format: '$field' (should be 'Name = Value')";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return \@errors;
|
||||
}
|
||||
|
||||
# Fetch current user profile from server
|
||||
sub fetch_user_profile {
|
||||
print $stdout "-- Fetching current profile from server...\n" if ($verbose);
|
||||
|
||||
my $profile_data = &grabjson($credurl, 0, 0, 0, undef, 1);
|
||||
if (!$profile_data) {
|
||||
print $stdout "-- Error: Failed to fetch user profile from server\n";
|
||||
return undef;
|
||||
}
|
||||
|
||||
print $stdout "-- Profile fetched successfully\n" if ($verbose);
|
||||
return $profile_data;
|
||||
}
|
||||
|
||||
# Update server profile with changes
|
||||
sub update_server_profile {
|
||||
my $changes = shift;
|
||||
|
||||
unless (keys %$changes) {
|
||||
print $stdout "-- No profile changes to update\n" if ($verbose);
|
||||
return 1;
|
||||
}
|
||||
|
||||
print $stdout "-- Updating profile on server...\n" if ($verbose);
|
||||
|
||||
# Build direct curl command (bypass TTYverse backticks due to form data issues)
|
||||
my $update_url = "${apibase}/accounts/update_credentials";
|
||||
my $curl_cmd = "$baseagent";
|
||||
|
||||
# Add standard TTYverse curl options
|
||||
foreach my $arg (@wend) {
|
||||
$curl_cmd .= " '$arg'";
|
||||
}
|
||||
|
||||
# Add OAuth Bearer token authentication
|
||||
my $bearer_header = &signrequest($update_url, '');
|
||||
if ($bearer_header) {
|
||||
$curl_cmd .= " $bearer_header";
|
||||
}
|
||||
|
||||
# Add PATCH method
|
||||
$curl_cmd .= " -X PATCH";
|
||||
|
||||
# Add multipart form data fields
|
||||
$curl_cmd .= " -F 'display_name=" . $changes->{'display_name'} . "'" if defined($changes->{'display_name'});
|
||||
$curl_cmd .= " -F 'note=" . $changes->{'bio'} . "'" if defined($changes->{'bio'});
|
||||
|
||||
# Website is handled as a custom field, not direct 'url' parameter
|
||||
if (defined($changes->{'website'})) {
|
||||
# Find existing Website field or add as new field
|
||||
my $website_field_index = 0;
|
||||
$curl_cmd .= " -F 'fields_attributes[${website_field_index}][name]=Website'";
|
||||
$curl_cmd .= " -F 'fields_attributes[${website_field_index}][value]=" . $changes->{'website'} . "'";
|
||||
}
|
||||
|
||||
# Custom fields (Mastodon multipart format)
|
||||
if ($changes->{'custom_fields'}) {
|
||||
my $field_index = 0;
|
||||
foreach my $field_data (@{$changes->{'custom_fields'}}) {
|
||||
if ($field_data =~ /^([^=]+)\s*=\s*(.+)$/) {
|
||||
my ($name, $value) = ($1, $2);
|
||||
$name =~ s/^\s+|\s+$//g;
|
||||
$value =~ s/^\s+|\s+$//g;
|
||||
# Escape single quotes in field values
|
||||
$name =~ s/'/'\\''/g;
|
||||
$value =~ s/'/'\\''/g;
|
||||
$curl_cmd .= " -F 'fields_attributes[${field_index}][name]=$name'";
|
||||
$curl_cmd .= " -F 'fields_attributes[${field_index}][value]=$value'";
|
||||
$field_index++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# Add the URL
|
||||
$curl_cmd .= " '$update_url'";
|
||||
|
||||
print $stdout "-- DEBUG: Profile update command: $curl_cmd\n" if ($superverbose);
|
||||
|
||||
# Execute the request directly
|
||||
my $return = `$curl_cmd 2>&1`;
|
||||
my $exit_code = $?;
|
||||
|
||||
print $stdout "-- DEBUG: HTTP exit code: $exit_code\n" if ($verbose);
|
||||
print $stdout "-- DEBUG: API response length: " . length($return) . " bytes\n" if ($verbose);
|
||||
print $stdout "-- DEBUG: API response: $return\n" if ($superverbose);
|
||||
|
||||
# Check if update was successful - look for valid profile JSON response
|
||||
if ($return =~ /"id":\s*"[^"]+"/s && $return =~ /"username":\s*"[^"]+"/s) {
|
||||
print $stdout "-- Profile updated successfully\n";
|
||||
return 1;
|
||||
} elsif ($return =~ /"error":\s*"([^"]+)"/s) {
|
||||
print $stdout "-- Profile update failed: $1\n";
|
||||
return 0;
|
||||
} else {
|
||||
print $stdout "-- Profile update failed\n";
|
||||
print $stdout "-- Response: $return\n" if ($verbose);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
# Compare local profile config with server profile
|
||||
sub compare_profiles {
|
||||
my $local_config = shift;
|
||||
my $server_profile = shift;
|
||||
my %changes = ();
|
||||
|
||||
# Compare basic fields
|
||||
my %field_map = (
|
||||
'display_name' => 'display_name',
|
||||
'bio' => 'note',
|
||||
'website' => 'url'
|
||||
);
|
||||
|
||||
foreach my $local_field (keys %field_map) {
|
||||
my $server_field = $field_map{$local_field};
|
||||
my $local_value = $local_config->{$local_field} || '';
|
||||
my $server_value = $server_profile->{$server_field} || '';
|
||||
|
||||
# Clean server value (remove HTML tags from bio)
|
||||
if ($server_field eq 'note') {
|
||||
$server_value =~ s/<[^>]*>//g;
|
||||
$server_value =~ s/</</g;
|
||||
$server_value =~ s/>/>/g;
|
||||
$server_value =~ s/&/&/g;
|
||||
}
|
||||
|
||||
if ($local_value ne $server_value) {
|
||||
$changes{$local_field} = $local_value;
|
||||
print $stdout "-- Profile change detected in $local_field: '$server_value' -> '$local_value'\n" if ($verbose);
|
||||
}
|
||||
}
|
||||
|
||||
# Compare custom fields
|
||||
my @local_fields = @{$local_config->{'custom_fields'} || []};
|
||||
my @server_fields = @{$server_profile->{'fields'} || []};
|
||||
|
||||
# Convert server fields to same format as local fields
|
||||
my @server_field_strings = ();
|
||||
foreach my $server_field (@server_fields) {
|
||||
my $name = $server_field->{'name'} || '';
|
||||
my $value = $server_field->{'value'} || '';
|
||||
# Remove HTML tags
|
||||
$value =~ s/<[^>]*>//g;
|
||||
$value =~ s/</</g;
|
||||
$value =~ s/>/>/g;
|
||||
$value =~ s/&/&/g;
|
||||
push @server_field_strings, "$name = $value";
|
||||
}
|
||||
|
||||
# Check if custom fields have changed
|
||||
my $local_fields_str = join('||', sort @local_fields);
|
||||
my $server_fields_str = join('||', sort @server_field_strings);
|
||||
|
||||
if ($local_fields_str ne $server_fields_str) {
|
||||
$changes{'custom_fields'} = \@local_fields;
|
||||
print $stdout "-- Profile change detected in custom fields\n" if ($verbose);
|
||||
}
|
||||
|
||||
return \%changes;
|
||||
}
|
||||
|
||||
# Interactive profile sync command - smart bi-directional sync
|
||||
sub cmd_syncprofile {
|
||||
print $stdout "-- Manual profile sync requested\n";
|
||||
|
||||
my $profile_file = get_profile_file_path($keyfile);
|
||||
unless (profile_file_exists($keyfile)) {
|
||||
print $stdout "-- Error: No profile file found. Create one first by restarting TTYverse.\n";
|
||||
return;
|
||||
}
|
||||
|
||||
my $profile_config = parse_profile_file($profile_file);
|
||||
unless ($profile_config) {
|
||||
print $stdout "-- Error: Could not parse profile file\n";
|
||||
return;
|
||||
}
|
||||
|
||||
if ($profile_config->{'use_profile'} ne 'true') {
|
||||
print $stdout "-- Profile sync disabled. Set use_profile=true in $profile_file\n";
|
||||
return;
|
||||
}
|
||||
|
||||
# Validate and sync
|
||||
my $validation_errors = validate_profile_config($profile_config);
|
||||
if (@$validation_errors) {
|
||||
print $stdout "-- Profile validation errors:\n";
|
||||
foreach my $error (@$validation_errors) {
|
||||
print $stdout " $error\n";
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
my $server_profile = fetch_user_profile();
|
||||
unless ($server_profile) {
|
||||
print $stdout "-- Could not fetch server profile\n";
|
||||
return;
|
||||
}
|
||||
|
||||
my $changes = compare_profiles($profile_config, $server_profile);
|
||||
|
||||
if (keys %$changes) {
|
||||
print $stdout "-- Syncing profile changes: " . join(", ", keys %$changes) . "\n";
|
||||
my $success = update_server_profile($changes);
|
||||
if ($success) {
|
||||
print $stdout "-- Profile synced successfully\n";
|
||||
} else {
|
||||
print $stdout "-- Profile sync failed\n";
|
||||
}
|
||||
} else {
|
||||
print $stdout "-- Profile already up to date\n";
|
||||
}
|
||||
}
|
||||
|
||||
# Force upload local profile to server
|
||||
sub cmd_profileup {
|
||||
print $stdout "-- Forcing profile upload (local → server)\n";
|
||||
|
||||
my $profile_file = get_profile_file_path($keyfile);
|
||||
unless (profile_file_exists($keyfile)) {
|
||||
print $stdout "-- Error: No profile file found\n";
|
||||
return;
|
||||
}
|
||||
|
||||
my $profile_config = parse_profile_file($profile_file);
|
||||
unless ($profile_config) {
|
||||
print $stdout "-- Error: Could not parse profile file\n";
|
||||
return;
|
||||
}
|
||||
|
||||
if ($profile_config->{'use_profile'} ne 'true') {
|
||||
print $stdout "-- Profile sync disabled. Set use_profile=true in $profile_file\n";
|
||||
return;
|
||||
}
|
||||
|
||||
# Validate local config
|
||||
my $validation_errors = validate_profile_config($profile_config);
|
||||
if (@$validation_errors) {
|
||||
print $stdout "-- Profile validation errors:\n";
|
||||
foreach my $error (@$validation_errors) {
|
||||
print $stdout " $error\n";
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
# Force upload all local fields
|
||||
my %force_changes = ();
|
||||
$force_changes{'display_name'} = $profile_config->{'display_name'} if $profile_config->{'display_name'};
|
||||
$force_changes{'bio'} = $profile_config->{'bio'} if $profile_config->{'bio'};
|
||||
$force_changes{'website'} = $profile_config->{'website'} if $profile_config->{'website'};
|
||||
$force_changes{'custom_fields'} = $profile_config->{'custom_fields'} if $profile_config->{'custom_fields'};
|
||||
|
||||
if (keys %force_changes) {
|
||||
print $stdout "-- Uploading all profile fields to server\n";
|
||||
my $success = update_server_profile(\%force_changes);
|
||||
if ($success) {
|
||||
print $stdout "-- Profile uploaded successfully\n";
|
||||
} else {
|
||||
print $stdout "-- Profile upload failed\n";
|
||||
}
|
||||
} else {
|
||||
print $stdout "-- No profile data to upload\n";
|
||||
}
|
||||
}
|
||||
|
||||
# Force download server profile to local file
|
||||
sub cmd_profiledown {
|
||||
print $stdout "-- Forcing profile download (server → local)\n";
|
||||
|
||||
my $profile_file = get_profile_file_path($keyfile);
|
||||
|
||||
print $stdout "-- Fetching current server profile\n";
|
||||
my $server_profile = fetch_user_profile();
|
||||
unless ($server_profile) {
|
||||
print $stdout "-- Could not fetch server profile\n";
|
||||
return;
|
||||
}
|
||||
|
||||
print $stdout "-- Regenerating local profile file with server data\n";
|
||||
if (generate_profile_template($keyfile, $server_profile)) {
|
||||
print $stdout "-- Profile downloaded and saved to: $profile_file\n";
|
||||
print $stdout "-- Note: use_profile is set to false. Edit file and enable to use.\n";
|
||||
} else {
|
||||
print $stdout "-- Failed to download profile\n";
|
||||
}
|
||||
}
|
||||
|
||||
# Main profile sync function called during startup
|
||||
sub check_and_sync_profile {
|
||||
my $keyfile_path = shift;
|
||||
|
||||
return unless length($keyfile_path);
|
||||
|
||||
|
||||
my $profile_file = get_profile_file_path($keyfile_path);
|
||||
|
||||
# Check if profile file exists
|
||||
unless (profile_file_exists($keyfile_path)) {
|
||||
# Missing profile file - create template
|
||||
print $stdout "-- Profile template not found, creating: $profile_file\n";
|
||||
print $stdout "-- DEBUG: Fetching current server profile to populate template\n" if ($verbose);
|
||||
my $server_profile = fetch_user_profile();
|
||||
if (generate_profile_template($keyfile_path, $server_profile)) {
|
||||
print $stdout "-- Profile template created: $profile_file\n";
|
||||
print $stdout "-- Edit file and set use_profile=true to enable profile management\n";
|
||||
print $stdout "-- DEBUG: Template populated with server data: display_name='" .
|
||||
($server_profile->{'display_name'} || 'none') . "', custom_fields=" .
|
||||
scalar(@{$server_profile->{'fields'} || []}) . "\n" if ($verbose);
|
||||
} else {
|
||||
print $stdout "-- ERROR: Failed to create profile template\n";
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
# Parse existing profile file
|
||||
print $stdout "-- DEBUG: Parsing profile file: $profile_file\n" if ($verbose);
|
||||
my $profile_config = parse_profile_file($profile_file);
|
||||
unless ($profile_config) {
|
||||
print $stdout "-- Error: Could not parse profile file $profile_file\n";
|
||||
return;
|
||||
}
|
||||
|
||||
print $stdout "-- DEBUG: Profile config loaded - use_profile='" .
|
||||
($profile_config->{'use_profile'} || 'unset') . "', fields=" .
|
||||
scalar(keys %$profile_config) . "\n" if ($verbose);
|
||||
|
||||
# Check if profile management is enabled
|
||||
if ($profile_config->{'use_profile'} ne 'true') {
|
||||
print $stdout "-- Profile file found but disabled (use_profile=false)\n" if ($verbose);
|
||||
return;
|
||||
}
|
||||
|
||||
# Validate profile configuration
|
||||
my $validation_errors = validate_profile_config($profile_config);
|
||||
if (@$validation_errors) {
|
||||
print $stdout "-- Profile validation errors:\n";
|
||||
foreach my $error (@$validation_errors) {
|
||||
print $stdout " $error\n";
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
# Fetch current server profile and compare
|
||||
print $stdout "-- DEBUG: Fetching current server profile for comparison\n" if ($verbose);
|
||||
my $server_profile = fetch_user_profile();
|
||||
unless ($server_profile) {
|
||||
print $stdout "-- Could not fetch server profile for comparison\n";
|
||||
return;
|
||||
}
|
||||
|
||||
print $stdout "-- DEBUG: Comparing local config with server profile\n" if ($verbose);
|
||||
my $changes = compare_profiles($profile_config, $server_profile);
|
||||
|
||||
if (keys %$changes) {
|
||||
print $stdout "-- Updating profile: " . join(", ", keys %$changes) . "\n";
|
||||
print $stdout "-- DEBUG: Changes detected: " . scalar(keys %$changes) . " fields\n" if ($verbose);
|
||||
my $success = update_server_profile($changes);
|
||||
if ($success) {
|
||||
print $stdout "-- Profile updated successfully\n";
|
||||
} else {
|
||||
print $stdout "-- Profile update failed - check network and authentication\n";
|
||||
}
|
||||
} else {
|
||||
print $stdout "-- Profile up to date\n" if ($verbose);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user