RecentInfo-Manager
view release on metacpan or search on metacpan
blog/blog.markdown view on Meta::CPAN
:-( I'm looking to finally add "recently used files" support to my command line programs, to make attaching files to mails more convenient, but the XDG spec doesn't have a valid DTD
[XDG Desktop Bookmark Spec](https://www.freedesktop.org/wiki/Specifications/desktop-bookmark-spec/) - also used for the recently used files, but the DTD is not valid for `recently-used.xbel`
[XBEL homepage](https://pyxml.sourceforge.net/topics/xbel/) - some kind of XBEL, but not applicable for ingesting existing files
> \[Corion]: (and of course, manually editing the file results in either no change, or an empty recently-used list, without error messages to validate. And all things I find online are parsers, not writers)
> \[Corion]: I guess I have to dive into the ad-hoc generators and parsers, and generate a DTD from that :-(
[Some shell script that does the reverse](https://github.com/laodzu/gnome-recent)
Via Stackoverflow [some Python library](https://github.com/xenomachina/recently_used)
that points to [`Gtk.RecentManager`](https://docs.gtk.org/gtk3/class.RecentManager.html).
lib/RecentInfo/Entry.pm view on Meta::CPAN
);
sub to_native( $self ) {
my $href = $self->href;
return $href =~ m!^file:!
? URI->new( $href )->file
: $href
}
state $xpc = XML::LibXML::XPathContext->new();
$xpc->registerNs( bookmark => "http://www.freedesktop.org/standards/desktop-bookmarks");
$xpc->registerNs( mime => "http://www.freedesktop.org/standards/shared-mime-info" );
sub as_XML_fragment($self, $doc) {
my $bookmark = $doc->createElement('bookmark');
$bookmark->setAttribute( 'href' => $self->href );
# Validate that $modified, $visited etc. are proper DateTime strings
# We enforce here a Z timezone
for my $attr (qw(added modified visited )) {
my $at = $self->$attr;
lib/RecentInfo/Entry.pm view on Meta::CPAN
};
$bookmark->setAttribute( $attr => $self->$attr );
};
my $info = $bookmark->addNewChild( undef, 'info' );
my $metadata = $info->addNewChild( undef, 'metadata' );
#my $mime = $metadata->addNewChild( 'mime', 'mime-type' );
my $mime = $metadata->addNewChild( undef,'mime:mime-type' );
$mime->setAttribute( type => $self->mime_type );
#$mime->appendText( $self->mime_type );
$metadata->setAttribute('owner' => 'http://freedesktop.org' );
# Should we allow this to be empty, or should we leave it out completely then?!
if ($self->othermeta->@* ) {
my $parser = XML::LibXML->new();
for my $other ($self->othermeta->@* ) {
$info->addChild( $parser->parse_balanced_chunk( $other, 'UTF-8' )->firstChild);
}
};
if( $self->groups->@* ) {
lib/RecentInfo/Entry.pm view on Meta::CPAN
my $applications = $metadata->addNewChild( undef, "bookmark:applications" );
for my $application ($self->applications->@* ) {
$applications->addChild( $application->as_XML_fragment( $doc ));
};
return $bookmark;
}
sub from_XML_fragment( $class, $frag ) {
my $meta = $xpc->findnodes('./info[1]/metadata[@owner="http://freedesktop.org"]', $frag)->[0];
if(! $meta) {
warn $frag->toString;
croak "Invalid xml?! No <info>/<metadata> element found"
};
my $othermeta = $xpc->findnodes('./info[1]/metadata[@owner!="http://freedesktop.org"]', $frag);
my @othermeta = map { $_->toString } $othermeta->@*;
my %meta = (
mime_type => $xpc->find('./mime:mime-type/@type', $meta)->[0]->nodeValue,
);
my @applications = $xpc->find('./bookmark:applications/bookmark:application', $meta)->@*;
if( !@applications ) {
warn $meta->toString;
die "No applications found";
lib/RecentInfo/Manager/XBEL.pm view on Meta::CPAN
$self->entries->@* = sort { $a->visited cmp $b->visited } $self->entries->@*;
return $res
}
sub toString( $self ) {
my $doc = XML::LibXML::Document->new('1.0', 'UTF-8');
my $xbel = $doc->createElement('xbel');
$doc->setDocumentElement($xbel);
$xbel->setAttribute("version" => '1.0');
$xbel->setAttribute("xmlns:bookmark" => "http://www.freedesktop.org/standards/desktop-bookmarks");
$xbel->setAttribute("xmlns:mime" => "http://www.freedesktop.org/standards/shared-mime-info");
for my $bm ($self->entries->@*) {
$xbel->addChild($bm->as_XML_fragment( $doc ));
};
my $pp = XML::LibXML::PrettyPrint->new(
indent_string => ' ',
element => {
compact => [qw[ bookmark:group ]],
},
);
t/01-roundtrip.t view on Meta::CPAN
$bm = $reconstructed->fromString( $xml );
$reconstructed->entries->@* = $bm->@*;
is $xbel, $reconstructed, "The reconstructed data structure is identical to the first parse";
}
done_testing();
__DATA__
<?xml version="1.0" encoding="UTF-8"?>
<xbel xmlns:bookmark="http://www.freedesktop.org/standards/desktop-bookmarks"
xmlns:mime="http://www.freedesktop.org/standards/shared-mime-info"
version="1.0">
<bookmark href="file:///home/corion/Projekte/MIME-Detect/Changes" added="2024-06-06T15:59:35.484580Z" modified="2024-06-06T15:59:35.484583Z" visited="2024-06-06T15:59:35.484580Z">
<info>
<metadata owner="http://freedesktop.org">
<mime:mime-type type="text/plain"/>
<bookmark:groups>
<bookmark:group>geany</bookmark:group>
</bookmark:groups>
<bookmark:applications>
<bookmark:application name="geany" exec="'geany %u'" modified="2024-06-06T15:59:35.484582Z" count="1"/>
</bookmark:applications>
</metadata>
</info>
</bookmark>
</xbel>
---
<?xml version="1.0" encoding="UTF-8"?>
<xbel xmlns:bookmark="http://www.freedesktop.org/standards/desktop-bookmarks"
xmlns:mime="http://www.freedesktop.org/standards/shared-mime-info"
version="1.0"/>
---
<?xml version="1.0" encoding="UTF-8"?>
<xbel xmlns:bookmark="http://www.freedesktop.org/standards/desktop-bookmarks"
xmlns:mime="http://www.freedesktop.org/standards/shared-mime-info"
version="1.0">
<bookmark href="file:///home/corion/Projekte/MIME-Detect/Changes" added="2024-06-06T15:59:35.484580Z" modified="2024-06-06T15:59:35.484583Z" visited="2024-06-06T15:59:35.484580Z">
<info>
<metadata owner="http://freedesktop.org">
<mime:mime-type type="text/plain"/>
<bookmark:groups>
<bookmark:group>geany</bookmark:group>
<bookmark:group>Office</bookmark:group>
</bookmark:groups>
<bookmark:applications>
<bookmark:application name="geany" exec="'geany %u'" modified="2024-06-06T15:59:35.484582Z" count="1"/>
<bookmark:application name="geany2" exec="'geany %u'" modified="2024-06-06T15:59:35.484582Z" count="1"/>
</bookmark:applications>
</metadata>
</info>
</bookmark>
</xbel>
--- We (well, XSD) don't handle arbitrary metadata well
<?xml version="1.0" encoding="UTF-8"?>
<xbel xmlns:bookmark="http://www.freedesktop.org/standards/desktop-bookmarks"
xmlns:mime="http://www.freedesktop.org/standards/shared-mime-info"
version="1.0">
<bookmark href="file:///home/corion/Projekte/MIME-Detect/Changes" added="2024-06-06T15:59:35.484580Z" modified="2024-06-06T15:59:35.484583Z" visited="2024-06-06T15:59:35.484580Z">
<info>
<metadata owner="http://freedesktop.org">
<mime:mime-type type="text/plain"/>
<bookmark:groups>
<bookmark:group>geany</bookmark:group>
<bookmark:group>Office</bookmark:group>
</bookmark:groups>
<bookmark:applications>
<bookmark:application name="geany" exec="'geany %u'" modified="2024-06-06T15:59:35.484582Z" count="1"/>
<bookmark:application name="geany2" exec="'geany %u'" modified="2024-06-06T15:59:35.484582Z" count="1"/>
</bookmark:applications>
</metadata>
xsd/recently-used-xbel-internal.xsd view on Meta::CPAN
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:bookmark="http://www.freedesktop.org/standards/desktop-bookmarks"
xmlns:mime="http://www.freedesktop.org/standards/shared-mime-info"
targetNamespace="http://www.freedesktop.org/standards/desktop-bookmarks"
>
<xs:import
namespace="http://www.freedesktop.org/standards/shared-mime-info"
schemaLocation="shared-mime-info.xsd"
/>
<xs:complexType name="groupType">
<xs:simpleContent>
<xs:extension base="xs:string" />
</xs:simpleContent>
</xs:complexType>
<xs:complexType name="applicationType">
xsd/recently-used-xbel.xsd view on Meta::CPAN
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:bookmark="http://www.freedesktop.org/standards/desktop-bookmarks"
xmlns:mime="http://www.freedesktop.org/standards/shared-mime-info"
xmlns=""
xmlns:vc="http://www.w3.org/2007/XMLSchema-versioning"
vc:minVersion="1.1"
>
<xs:import
namespace="http://www.freedesktop.org/standards/shared-mime-info"
schemaLocation="shared-mime-info.xsd"
/>
<xs:import
namespace="http://www.freedesktop.org/standards/desktop-bookmarks"
schemaLocation="recently-used-xbel-internal.xsd"
/>
<xs:complexType name="groupType">
<xs:simpleContent>
<xs:extension base="xs:string" />
</xs:simpleContent>
</xs:complexType>
<xs:complexType name="applicationType">
xsd/recently-used-xbel.xsd view on Meta::CPAN
<xs:sequence>
<xs:element ref="mime:mime-type" maxOccurs="1" minOccurs="1" />
<xs:element name="icon" type="xs:string" maxOccurs="1" minOccurs="0" />
<xs:element ref="bookmark:groups" maxOccurs="1" minOccurs="0" />
<xs:element ref="bookmark:applications" maxOccurs="1" minOccurs="0" />
<xs:element name="private" type="xs:boolean" maxOccurs="1" minOccurs="0" />
</xs:sequence>
<xs:attribute name="owner" use="required">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:enumeration value="http://freedesktop.org"/>
</xs:restriction>
</xs:simpleType>
</xs:attribute>
</xs:complexType>
<!--
<xs:complexType name="metadataTypeOther">
<xs:sequence>
<xs:any processContents="skip"/>
</xs:sequence>
xsd/shared-mime-info.xsd view on Meta::CPAN
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns="http://www.freedesktop.org/standards/shared-mime-info"
targetNamespace="http://www.freedesktop.org/standards/shared-mime-info"
>
<xs:element name="mime-type" />
</xs:schema>
( run in 0.645 second using v1.01-cache-2.11-cpan-299005ec8e3 )