~nova/todosrht-fuse

1dae3ae724bfd66d8e10446a81df22f07bd6b025 — Novalinium 2 years ago 4b8efcb
Adds initial support for reading files
1 files changed, 68 insertions(+), 33 deletions(-)

M main.pl
M main.pl => main.pl +68 -33
@@ 23,12 23,12 @@ my $TRACKER_NAME = "fletcher";
my $agent = WWW::Mechanize->new( agent => 'Yssaringintinka/1.0' );

my (%tracker_cache) = (
    '0' => {
    '.0' => {
        title => 'No tickets loaded',
        content => 'See title.',
        cont => 'See title.',
        labels => [],
        submitter => 'System',
		ctime => time()-$CACHE_TTL-1,
		atime => time()-$CACHE_TTL-1,
        status => 'OPEN',
		type => 0100,
		mode => 0755,


@@ 41,30 41,12 @@ my (%files) = (
		mode => 0755,
		ctime => time()-1000
	},
	a => {
		cont => "File 'a'.\n",
		type => 0100,
		mode => 0755,
		ctime => time()-2000
	},
	b => {
		cont => "This is file 'b'.\n",
		type => 0100,
		mode => 0644,
		ctime => time()-1000
	},
	me => {
		size => 45,
		type => 0100,
		mode => 0644,
		ctime => time()-1000
	},
);

sub refresh_tracker_cache() {
    if ((time() - $CACHE_TTL) > $tracker_cache{0}{ctime}) {
sub refresh_tracker_cache {
    if ((time() - $CACHE_TTL) > $tracker_cache{".0"}{atime}) {
        # refresh cache
        $tracker_cache{0}{ctime} = time();
        $tracker_cache{".0"}{atime} = time();
        foreach my $status (qw(open closed)) {
            my $page = 1;
            my $content;


@@ 75,7 57,9 @@ sub refresh_tracker_cache() {
                $content->find("div.ticket-list div.id")->each(sub {
                        my ($ticket, $offset) = @_;
                        my $ticket_id = substr($ticket->children->first->text, 1);
                        $tracker_cache{$ticket_id} = ();
                        if (!exists($tracker_cache{$ticket_id})) {
                            $tracker_cache{$ticket_id} = ();
                        }
                        $tracker_cache{$ticket_id}{title} = $ticket->following->[0]->text;
                        if ($ticket->following->[0]->children->first->children) {
                            $tracker_cache{$ticket_id}{labels} = $ticket->following->[0]->children->first->children->map('text')->each;


@@ 83,7 67,10 @@ sub refresh_tracker_cache() {
                            $tracker_cache{$ticket_id}{labels} = [];
                        }
                        $tracker_cache{$ticket_id}{mtime} = Time::Piece->strptime($ticket->following->[1]->children->first->attr->{title}, '%Y-%m-%d %H:%M:%S UTC')->epoch;
                        $tracker_cache{$ticket_id}{ctime} = $tracker_cache{$ticket_id}{mtime}; # TODO support mtime in e_getattr;
                        if (!exists($tracker_cache{$ticket_id}{ctime})) {
                            $tracker_cache{$ticket_id}{ctime} = $tracker_cache{$ticket_id}{mtime}; # TODO support mtime in e_getattr;
                            $tracker_cache{$ticket_id}{atime} = 0;
                        }
                        $tracker_cache{$ticket_id}{submitter} = $ticket->following->[2]->children->first->text;
                        $tracker_cache{$ticket_id}{submitter} =~ s/^\s+~(\S*)\s*$/$1/;
                        $tracker_cache{$ticket_id}{comments} = $ticket->following->[3]->text;


@@ 95,6 82,48 @@ sub refresh_tracker_cache() {
    }
    return \%tracker_cache;
}

sub refresh_ticket_cache {
    my ($ticket_id) = @_;
    if ((time() - $CACHE_TTL) > $tracker_cache{$ticket_id}{atime}) {
        # refresh cache
        $tracker_cache{$ticket_id}{atime} = time();
        my $page_url = sprintf("%s/~%s/%s/%d", $BASE_URL, $TRACKER_USER, $TRACKER_NAME, $ticket_id);
        $agent->get( $page_url );
        my $content = Mojo::DOM->new($agent->content());
        $tracker_cache{$ticket_id}{title} = $content->find('div.container-fluid h2 span')->last->text;
        $tracker_cache{$ticket_id}{description} = '';
        my $description_pointer = $content->at('div.header-tabbed ~ div.container div.row div.col-md-6')->children->first;
        if ($description_pointer->tag eq "style") {
            $description_pointer = $description_pointer->next_node;
            while ($description_pointer->tag ne "dl") {
                $tracker_cache{$ticket_id}{description} .= $description_pointer->all_text . "\n";
                $description_pointer = $description_pointer->next_node;
            }
        }
        $tracker_cache{$ticket_id}{status} = $description_pointer->at('strong.text-success')->text;
        $tracker_cache{$ticket_id}{status} =~ s/^\s+(\S*)\s*$/$1/ms;
        $tracker_cache{$ticket_id}{submitter} = $description_pointer->at('dd.col-md-9 > a')->text;
        $tracker_cache{$ticket_id}{submitter} =~ s/^\s+~(\S*)\s*$/$1/;
        # TODO Parse Assigned to: possibly use submitter as group and asignee as user or ACLs in future?
        $tracker_cache{$ticket_id}{ctime} = Time::Piece->strptime($description_pointer->find('dd > span:not([style])')->first->attr->{title}, '%Y-%m-%d %H:%M:%S UTC')->epoch;
        $tracker_cache{$ticket_id}{mtime} = Time::Piece->strptime($description_pointer->find('dd > span:not([style])')->last->attr->{title}, '%Y-%m-%d %H:%M:%S UTC')->epoch;
        $tracker_cache{$ticket_id}{labels} = [];
        if ($description_pointer->children->last->find('a')) {
            push @{$tracker_cache{$ticket_id}{labels}}, $description_pointer->children->last->find('a')->map('text')->each;
        }
        $tracker_cache{$ticket_id}{cont} = <<"EOF";
Name: $tracker_cache{$ticket_id}{title}
Description: $tracker_cache{$ticket_id}{description}
Status: $tracker_cache{$ticket_id}{status}
Submitter: ~$tracker_cache{$ticket_id}{submitter}
Created: $tracker_cache{$ticket_id}{ctime}
Modified: $tracker_cache{$ticket_id}{mtime}
Labels: @{$tracker_cache{$ticket_id}{labels}}
EOF
    }
}

sub filename_fixup {
	my ($file) = shift;
	$file =~ s,^/,,;


@@ 107,7 136,6 @@ sub e_getattr {
	$file =~ s,^/,,;
	$file = '.' unless length($file);
    print "getattr $file\n";
    refresh_tracker_cache();
    if (exists($files{$file})) {
        my ($size) = exists($files{$file}{cont}) ? length($files{$file}{cont}) : 0;
        $size = $files{$file}{size} if exists $files{$file}{size};


@@ 120,8 148,9 @@ sub e_getattr {
        #print(join(",",($dev,$ino,$modes,$nlink,$uid,$gid,$rdev,$size,$atime,$mtime,$ctime,$blksize,$blocks)),"\n");
        return ($dev,$ino,$modes,$nlink,$uid,$gid,$rdev,$size,$atime,$mtime,$ctime,$blksize,$blocks);
    } elsif (exists($tracker_cache{$file})) {
        # refresh_ticket_cache($file);
        my ($size) = exists($tracker_cache{$file}{cont}) ? length($tracker_cache{$file}{cont}) : 0;
        $size = $tracker_cache{$file}{comments} if exists $tracker_cache{$file}{comments};
        $size = $tracker_cache{$file}{comments} if $size == 0 && exists $tracker_cache{$file}{comments};
        my ($modes) = ($tracker_cache{$file}{type}<<9) + $tracker_cache{$file}{mode};
        my $submitter = $tracker_cache{$file}{submitter};
        print $submitter."\n";


@@ 151,6 180,9 @@ sub e_open {
	# VFS sanity check; it keeps all the necessary state, not much to do here.
    print "open @_\n";
    my $file = filename_fixup(shift);
    if (int($file)) {
        refresh_ticket_cache($file);
    }
    my ($flags, $fileinfo) = @_;
    print("open called $file, $flags, $fileinfo\n");
	return -ENOENT() unless exists($files{$file}) || exists($tracker_cache{$file});


@@ 166,18 198,21 @@ sub e_read {
	# return an error numeric, or binary/text string.  (note: 0 means EOF, "0" will
	# give a byte (ascii "0") to the reading program)
	my ($file) = filename_fixup(shift);
    if (int($file)) {
        refresh_ticket_cache($file);
    }
    my ($buf, $off, $fh) = @_;
    print "read from $file, $buf \@ $off\n";
    print "file handle:\n", Dumper($fh);
	return -ENOENT() unless exists($files{$file});
	if(!exists($files{$file}{cont})) {
	return -ENOENT() unless exists($tracker_cache{$file});
	if(!exists($tracker_cache{$file}{cont})) {
		return -EINVAL() if $off > 0;
		my $context = fuse_get_context();
		return sprintf("pid=0x%08x uid=0x%08x gid=0x%08x\n",@$context{'pid','uid','gid'});
	}
	return -EINVAL() if $off > length($files{$file}{cont});
	return 0 if $off == length($files{$file}{cont});
	return substr($files{$file}{cont},$off,$buf);
	return -EINVAL() if $off > length($tracker_cache{$file}{cont});
	return 0 if $off == length($tracker_cache{$file}{cont});
	return substr($tracker_cache{$file}{cont},$off,$buf);
}

sub e_statfs { return 255, 1, 1, 1, 1, 2 }