App-MHFS

 view release on metacpan or  search on metacpan

lib/MHFS/Settings.pm  view on Meta::CPAN

}

sub calc_source_id {
    my ($source) = @_;
    if($source->{'type'} ne 'local') {
        say "only local sources supported right now";
        return undef;
    }
    return encode_base64url(md5('local:'.$source->{folder}));
}

sub add_source {
    my ($sources, $source) = @_;
    my $id = calc_source_id($source);
    my $len = 6;
    my $shortid = substr($id, 0, $len);
    if (exists $sources->{$shortid}) {
        my $oldid = calc_source_id($sources->{$shortid});
        while(1) {
            $len++;
            substr($oldid, 0, $len) eq substr($id, 0, $len) or last;
            length($id) > $len or die "matching hash";
        }
        $sources->{substr($oldid, 0, $len)} = $sources->{$shortid};
        delete $sources->{$shortid};
        $shortid = substr($id, 0, $len);
    }
    $sources->{$shortid} = $source;
    return $shortid;
}

sub load {
    my ($launchsettings) = @_;
    my $scriptpath = abs_path(__FILE__);

    # settings are loaded with the following precedence
    # $launchsettings (@ARGV) > settings.pl > General environment vars
    # Directory preference goes from declared to defaults and specific to general:
    # For example $CFGDIR > $XDG_CONFIG_HOME > $XDG_CONFIG_DIRS > $FALLBACK_DATA_ROOT

    # load in the launchsettings
    my ($CFGDIR, $APPDIR, $FALLBACK_DATA_ROOT);
    if(exists $launchsettings->{CFGDIR}) {
        make_path($launchsettings->{CFGDIR});
        $CFGDIR = $launchsettings->{CFGDIR};
    }
    if(exists $launchsettings->{APPDIR}) {
        -d $launchsettings->{APPDIR} or die("Bad APPDIR provided");
        $APPDIR = $launchsettings->{APPDIR};
    }
    if(exists $launchsettings->{FALLBACK_DATA_ROOT}) {
        make_path($launchsettings->{FALLBACK_DATA_ROOT});
        $FALLBACK_DATA_ROOT = $launchsettings->{FALLBACK_DATA_ROOT};
    }

    # determine the settings dir
    if(! $CFGDIR){
        my $cfg_fallback = $FALLBACK_DATA_ROOT // $ENV{'HOME'};
        $cfg_fallback //= ($ENV{APPDATA}.'/mhfs') if($ENV{APPDATA}); # Windows
        # set the settings dir to the first that exists of $XDG_CONFIG_HOME and $XDG_CONFIG_DIRS
        # https://specifications.freedesktop.org/basedir-spec/basedir-spec-latest.html
        my $XDG_CONFIG_HOME = $ENV{'XDG_CONFIG_HOME'};
        $XDG_CONFIG_HOME //= ($cfg_fallback . '/.config') if($cfg_fallback);
        my @configdirs;
        push @configdirs, $XDG_CONFIG_HOME if($XDG_CONFIG_HOME);
        my $XDG_CONFIG_DIRS = $ENV{'XDG_CONFIG_DIRS'} || '/etc/xdg';
        push @configdirs, split(':', $XDG_CONFIG_DIRS);
        foreach my $cfgdir (@configdirs) {
            if(-d "$cfgdir/mhfs") {
                $CFGDIR = "$cfgdir/mhfs";
                last;
            }
        }
        $CFGDIR //= ($XDG_CONFIG_HOME.'/mhfs') if($XDG_CONFIG_HOME);
        defined($CFGDIR) or die("Failed to find valid candidate for \$CFGDIR");
    }
    $CFGDIR = rel2abs($CFGDIR);

    # load from the settings file
    my $SETTINGS_FILE = rel2abs($CFGDIR . '/settings.pl');
    my $SETTINGS = do ($SETTINGS_FILE);
    if(! $SETTINGS) {
        die "Error parsing settingsfile: $@" if($@);
        die "Cannot read settingsfile: $!" if(-e $SETTINGS_FILE);
        warn("No settings file found, using default settings");
        $SETTINGS = {};
    }

    # load defaults for unset values
    $SETTINGS->{'HOST'} ||= "127.0.0.1";
    $SETTINGS->{'PORT'} ||= 8000;

    $SETTINGS->{'ALLOWED_REMOTEIP_HOSTS'} ||= [
        ['127.0.0.1'],
    ];

    # write the default settings
    if(! -f $SETTINGS_FILE) {
        write_settings_file($SETTINGS, $SETTINGS_FILE);
    }
    $SETTINGS->{'CFGDIR'} = $CFGDIR;
    $SETTINGS->{flush} = $launchsettings->{flush} if(exists $launchsettings->{flush});

    # locate files based on appdir
    $APPDIR ||= $SETTINGS->{'APPDIR'} || dist_dir('App-MHFS');
    $APPDIR = abs_path($APPDIR);
    say __PACKAGE__.": using APPDIR " . $APPDIR;
    $SETTINGS->{'APPDIR'} = $APPDIR;

    # determine the fallback data root
    $FALLBACK_DATA_ROOT ||= $SETTINGS->{'FALLBACK_DATA_ROOT'} || $ENV{'HOME'};
    $FALLBACK_DATA_ROOT ||= ($ENV{APPDATA}.'/mhfs') if($ENV{APPDATA}); # Windows
    if($FALLBACK_DATA_ROOT) {
        $FALLBACK_DATA_ROOT = abs_path($FALLBACK_DATA_ROOT);
    }
    # determine the allowed remoteip host combos. only ipv4 now sorry
    $SETTINGS->{'ARIPHOSTS_PARSED'} = [];
    foreach my $rule (@{$SETTINGS->{'ALLOWED_REMOTEIP_HOSTS'}}) {
        # parse IPv4 with optional CIDR
        $rule->[0] =~ /^([^\/]+)(?:\/(\d{1,2}))?$/ or die("Invalid rule: " . $rule->[0]);
        my $ipstr = $1; my $cidr = $2 // 32;



( run in 0.521 second using v1.01-cache-2.11-cpan-e1769b4cff6 )