use
5.008;
our
$VERSION
=
'0.206'
;
sub
new
{
my
$class
=
shift
;
my
$inuri
=
shift
;
my
$data
=
shift
;
my
$type
=
shift
||
'auto'
;
my
$model
;
if
(
ref
$data
and
$data
->isa(
'RDF::Trine::Model'
))
{
$model
=
$data
;
}
else
{
$model
= RDF::Trine::Model->new( RDF::Trine::Store->temporary_store );
unless
(
defined
$data
)
{
if
(
ref
$inuri
and
$inuri
->isa(
'URI::file'
))
{
$data
= slurp(
$inuri
->file );
}
elsif
(
$inuri
=~ /^(http|file|https|ftp):/i)
{
$data
= get(
$inuri
);
}
}
my
$fmt
=
shift
||
'turtle'
;
my
$parser
= RDF::Trine::Parser->new(
$fmt
);
$parser
->parse_into_model(
"$inuri"
,
$data
,
$model
);
}
if
(
lc
$type
eq
'auto'
)
{
my
$r
= RDF::Query->new(
->execute(
$model
);
if
(
$r
->get_boolean)
{
$type
=
'legacy'
;
}
else
{
$type
=
'current'
;
}
}
my
$self
= {
'model'
=>
$model
,
'type'
=>
$type
,
'uri'
=>
$inuri
} ;
bless
$self
,
$class
;
}
sub
is_legacy
{
my
$self
=
shift
;
return
(
lc
$self
->{
'type'
} eq
'legacy'
);
}
sub
is_current
{
my
$self
=
shift
;
return
!
$self
->is_legacy(
@_
);
}
sub
model
{
my
$self
=
shift
;
return
$self
->{
'model'
};
}
sub
uri
{
my
$self
=
shift
;
return
$self
->{
'uri'
} .
''
;
}
sub
to_string
{
my
$self
=
shift
;
my
$rv
=
''
;
$self
->_project_data;
my
$projects
=
$self
->{
'projects'
};
foreach
my
$project
(
sort
keys
%$projects
)
{
$rv
.=
$projects
->{
$project
}->{
'distname'
} .
"\n"
;
$rv
.= (
'='
x
length
$projects
->{
$project
}->{
'distname'
}) .
"\n\n"
;
$rv
.=
sprintf
(
"Created: %s\n"
,
$projects
->{
$project
}->{
'created'
})
if
$projects
->{
$project
}->{
'created'
};
foreach
my
$u
(
sort
keys
%{
$projects
->{
$project
}->{
'homepage'
} })
{
$rv
.=
sprintf
(
"Home page: <%s>\n"
,
$u
);
}
foreach
my
$u
(
sort
keys
%{
$projects
->{
$project
}->{
'bugdatabase'
} })
{
$rv
.=
sprintf
(
"Bug tracker: <%s>\n"
,
$u
);
}
foreach
my
$m
(
sort
keys
%{
$projects
->{
$project
}->{
'maint'
} })
{
my
@mboxes
=
sort
keys
%{
$projects
->{
$project
}->{
'maint'
}->{
$m
}->{
'mbox'
}};
my
$mbox
=
shift
@mboxes
;
if
(
defined
$mbox
) {
$rv
.=
sprintf
(
"Maintainer: %s <%s>\n"
,
$projects
->{
$project
}->{
'maint'
}->{
$m
}->{
'name'
},
$mbox
); }
else
{
$rv
.=
sprintf
(
"Maintainer: %s\n"
,
$projects
->{
$project
}->{
'maint'
}->{
$m
}->{
'name'
},
$mbox
); }
}
$rv
.=
"\n"
;
$self
->_release_data(
$project
);
my
@revisions
=
sort
{
if
(
exists
$b
->{
'issued'
} and
exists
$a
->{
'issued'
})
{
$b
->{
'issued'
} cmp
$a
->{
'issued'
} or Perl::Version->new(
$b
->{
'revision'
}) cmp Perl::Version->new(
$a
->{
'revision'
}); }
else
{ Perl::Version->new(
$b
->{
'revision'
}) cmp Perl::Version->new(
$a
->{
'revision'
}); }
}
values
%{
$projects
->{
$project
}->{
'v'
}};
foreach
my
$version
(
@revisions
)
{
$rv
.=
$version
->{
'revision'
};
$rv
.=
sprintf
(
' %s'
,
$version
->{
'issued'
} ?
$version
->{
'issued'
} :
'Unknown'
);
$rv
.=
sprintf
(
" %s"
,
$version
->{
'name'
})
if
$version
->{
'name'
};
$rv
.=
"\n\n"
;
my
@changes
=
map
{
my
$change
=
$_
;
my
$sigil
=
''
;
if
(
defined
$change
->{
'type'
} and
ref
(
$change
->{
'type'
}) eq
'ARRAY'
)
{
$sigil
=
join
' '
,
uniq
sort
map
{ m!doap.changeset.(.+)$!; $1; }
grep
{ m!doap.changeset.(.+)$! }
@{
$change
->{
'type'
} };
$sigil
=
"(${sigil}) "
if
length
$sigil
;
}
my
$ret
= wrap(
' - '
,
' '
,
sprintf
(
"%s%s"
,
$sigil
,
$change
->{
'label'
})) .
"\n"
;
for
(
sort
keys
%{
$change
->{issue} || {}})
{
? (
$ret
.=
sprintf
(
" Fixes RT#%s\n"
, $1)) :
m{^(?:tdb:.*)https://rt\.cpan\.org/Ticket/Display\.html\?id=([0-9]+)$}
? (
$ret
.=
sprintf
(
" Fixes RT#%s\n"
, $1)) :
? (
$ret
.=
sprintf
(
" Fixes GH#%s\n"
, $1)) :
();
}
my
%blame
= %{
$change
->{blame} || {}};
foreach
$b
(
values
%blame
)
{
if
(
defined
$b
->{nick})
{
$ret
.=
sprintf
(
" ++\$%s\n"
,
$b
->{nick}) }
elsif
(
defined
$b
->{name})
{
$ret
.=
sprintf
(
" ++\"%s\"\n"
,
$b
->{name}) }
elsif
(
defined
$b
->{uri})
{
$ret
.=
sprintf
(
" ++q<%s>\n"
,
$b
->{uri}) }
}
$ret
;
}
values
%{
$version
->{
'c'
}};
$rv
.=
join
q{}
,
sort
@changes
;
$rv
.=
"\n"
;
}
}
return
$rv
;
}
sub
to_file
{
my
$self
=
shift
;
my
$file
=
shift
;
open
OUT,
">$file"
;
print
OUT
$self
->to_string;
close
OUT;
}
sub
_project_data
{
my
$self
=
shift
;
my
$rv
;
if
(
$self
->is_legacy)
{
$rv
=
$self
->_project_data__legacy(
@_
);
}
else
{
$rv
=
$self
->_project_data__current(
@_
);
}
unless
(
length
$self
->{
'doctitle'
})
{
foreach
my
$project
(
sort
keys
%{
$self
->{
'projects'
}})
{
if
(
length
$self
->{
'doctitle'
} == 0
or
length
$self
->{
'doctitle'
} >
$self
->{
'projects'
}->{
$project
}->{
'distname'
})
{
$self
->{
'doctitle'
} =
$self
->{
'projects'
}->{
$project
}->{
'distname'
};
}
}
if
(
length
$self
->{
'doctitle'
})
{
$self
->{
'doctitle'
} =
"Changes for "
.
$self
->{
'doctitle'
};
}
else
{
$self
->{
'doctitle'
} =
"Changes"
;
}
}
return
$rv
;
}
sub
_project_data__current
{
my
$self
=
shift
;
my
$model
=
$self
->model;
my
$inuri
=
$self
->uri;
my
$sparql
= "
SELECT *
WHERE
{
?project a doap:Project .
OPTIONAL { <
$inuri
> dc:title ?title . }
OPTIONAL { <
$inuri
> rdfs:label ?title . }
OPTIONAL { ?project doap:name ?distname . }
OPTIONAL { ?project rdfs:label ?distname . }
OPTIONAL { ?project dc:title ?distname . }
OPTIONAL { ?project doap:created ?created . }
OPTIONAL { ?project doap:homepage ?homepage . }
OPTIONAL { ?project doap:bug-database ?bugdatabase . }
OPTIONAL
{
?project doap:maintainer ?maint .
?maint foaf:name ?maintname .
OPTIONAL { ?maint foaf:mbox ?maintmbox . }
}
}
";
my
$query
= RDF::Query->new(
$sparql
);
my
$results
=
$query
->execute(
$model
);
my
$projects
= {};
my
$doctitle
=
''
;
while
(
my
$row
=
$results
->
next
)
{
my
$p
=
$row
->{
'project'
}->as_ntriples;
$projects
->{
$p
}->{
'EXISTS'
}++;
$projects
->{
$p
}->{
'distname'
} =
$row
->{
'distname'
}->literal_value
if
UNIVERSAL::isa(
$row
->{
'distname'
},
'RDF::Trine::Node::Literal'
);
$projects
->{
$p
}->{
'created'
} =
$row
->{
'created'
}->literal_value
if
UNIVERSAL::isa(
$row
->{
'created'
},
'RDF::Trine::Node::Literal'
);
$projects
->{
$p
}->{
'homepage'
}->{
$row
->{
'homepage'
}->uri }++
if
UNIVERSAL::isa(
$row
->{
'homepage'
},
'RDF::Trine::Node::Resource'
);
$projects
->{
$p
}->{
'bugdatabase'
}->{
$row
->{
'bugdatabase'
}->uri }++
if
UNIVERSAL::isa(
$row
->{
'bugdatabase'
},
'RDF::Trine::Node::Resource'
);
$projects
->{
$p
}->{
'maint'
}->{
$row
->{
'maint'
}->as_ntriples }->{
'name'
} =
$row
->{
'maintname'
}->literal_value
if
UNIVERSAL::isa(
$row
->{
'maintname'
},
'RDF::Trine::Node::Literal'
);
$projects
->{
$p
}->{
'maint'
}->{
$row
->{
'maint'
}->as_ntriples }->{
'mbox'
}->{
$row
->{
'maintmbox'
}->uri }++
if
UNIVERSAL::isa(
$row
->{
'maintmbox'
},
'RDF::Trine::Node::Resource'
);
$doctitle
=
$row
->{
'title'
}->literal_value
if
UNIVERSAL::isa(
$row
->{
'title'
},
'RDF::Trine::Node::Literal'
);
}
foreach
my
$k
(
keys
%$projects
)
{
$projects
->{
$k
}->{
'distname'
} =
$k
unless
defined
$projects
->{
$k
}->{
'distname'
};
}
$self
->{
'projects'
} =
$projects
;
$self
->{
'doctitle'
} =
$doctitle
;
}
sub
_project_data__legacy
{
my
$self
=
shift
;
my
$model
=
$self
->model;
my
$inuri
=
$self
->uri;
my
$sparql
= "
SELECT *
WHERE
{
?project a doap:Project .
OPTIONAL { <
$inuri
> dc:title ?title . }
OPTIONAL { <
$inuri
> rdfs:label ?title . }
OPTIONAL { ?project doap:name ?distname . }
OPTIONAL { ?project rdfs:label ?distname . }
OPTIONAL { ?project dc:title ?distname . }
OPTIONAL { ?project doap:created ?created . }
OPTIONAL { ?project doap:homepage ?homepage . }
OPTIONAL { ?project doap:bug-database ?bugdatabase . }
OPTIONAL
{
?project doap:maintainer ?maint .
?maint foaf:name ?maintname .
OPTIONAL { ?maint foaf:mbox ?maintmbox . }
}
}
";
my
$query
= RDF::Query->new(
$sparql
);
my
$results
=
$query
->execute(
$model
);
my
$projects
= {};
my
$doctitle
=
''
;
while
(
my
$row
=
$results
->
next
)
{
my
$p
=
$row
->{
'project'
}->as_ntriples;
$projects
->{
$p
}->{
'EXISTS'
}++;
$projects
->{
$p
}->{
'distname'
} =
$row
->{
'distname'
}->literal_value
if
UNIVERSAL::isa(
$row
->{
'distname'
},
'RDF::Trine::Node::Literal'
);
$projects
->{
$p
}->{
'created'
} =
$row
->{
'created'
}->literal_value
if
UNIVERSAL::isa(
$row
->{
'created'
},
'RDF::Trine::Node::Literal'
);
$projects
->{
$p
}->{
'homepage'
}->{
$row
->{
'homepage'
}->uri }++
if
UNIVERSAL::isa(
$row
->{
'homepage'
},
'RDF::Trine::Node::Resource'
);
$projects
->{
$p
}->{
'bugdatabase'
}->{
$row
->{
'bugdatabase'
}->uri }++
if
UNIVERSAL::isa(
$row
->{
'bugdatabase'
},
'RDF::Trine::Node::Resource'
);
$projects
->{
$p
}->{
'maint'
}->{
$row
->{
'maint'
}->as_ntriples }->{
'name'
} =
$row
->{
'maintname'
}->literal_value
if
UNIVERSAL::isa(
$row
->{
'maintname'
},
'RDF::Trine::Node::Literal'
);
$projects
->{
$p
}->{
'maint'
}->{
$row
->{
'maint'
}->as_ntriples }->{
'mbox'
}->{
$row
->{
'maintmbox'
}->uri }++
if
UNIVERSAL::isa(
$row
->{
'maintmbox'
},
'RDF::Trine::Node::Resource'
);
$doctitle
=
$row
->{
'title'
}->literal_value
if
UNIVERSAL::isa(
$row
->{
'title'
},
'RDF::Trine::Node::Literal'
);
}
foreach
my
$k
(
keys
%$projects
)
{
$projects
->{
$k
}->{
'distname'
} =
$k
unless
defined
$projects
->{
$k
}->{
'distname'
};
}
$self
->{
'projects'
} =
$projects
;
$self
->{
'doctitle'
} =
$doctitle
;
}
sub
_release_data
{
my
$self
=
shift
;
if
(
$self
->is_legacy)
{
return
$self
->_release_data__legacy(
@_
);
}
else
{
return
$self
->_release_data__current(
@_
);
}
}
sub
_release_data__current
{
my
$self
=
shift
;
my
$model
=
$self
->model;
my
$p
=
shift
;
my
$projects
=
$self
->{
'projects'
};
my
$sparql
= "
SELECT *
WHERE
{
$p
doap:release ?version .
?version doap:revision ?revision .
OPTIONAL { ?version dc:issued ?issued . }
OPTIONAL { ?version rdfs:label ?vname . }
OPTIONAL
{
?version dcs:changeset [ dcs:item ?item ] .
OPTIONAL { ?item a ?itemtype . }
OPTIONAL { ?item rdfs:label ?itemlabel . }
OPTIONAL {
?item dcs:blame|dcs:thanks ?blame .
OPTIONAL { ?blame foaf:nick ?blamenick . }
OPTIONAL { ?blame foaf:name ?blamename . }
OPTIONAL { ?blame rdfs:label ?blamename . }
}
OPTIONAL { ?item dcs:fixes ?issue . }
}
}
";
my
$query
= RDF::Query->new(
$sparql
);
my
$results
=
$query
->execute(
$model
);
while
(
my
$row
=
$results
->
next
)
{
my
$v
=
$row
->{
'version'
}->as_ntriples;
$projects
->{
$p
}->{
'v'
}->{
$v
}->{
'EXISTS'
}++;
$projects
->{
$p
}->{
'v'
}->{
$v
}->{
'revision'
} =
$row
->{
'revision'
}->literal_value
if
UNIVERSAL::isa(
$row
->{
'revision'
},
'RDF::Trine::Node::Literal'
);
$projects
->{
$p
}->{
'v'
}->{
$v
}->{
'issued'
} =
$row
->{
'issued'
}->literal_value
if
UNIVERSAL::isa(
$row
->{
'issued'
},
'RDF::Trine::Node::Literal'
);
$projects
->{
$p
}->{
'v'
}->{
$v
}->{
'name'
} =
$row
->{
'vname'
}->literal_value
if
UNIVERSAL::isa(
$row
->{
'vname'
},
'RDF::Trine::Node::Literal'
);
if
(UNIVERSAL::isa(
$row
->{
'item'
},
'RDF::Trine::Node'
))
{
my
$c
=
$row
->{
'item'
}->as_ntriples;
$projects
->{
$p
}->{
'v'
}->{
$v
}->{
'c'
}->{
$c
}->{
'label'
} =
$row
->{
'itemlabel'
}->literal_value
if
UNIVERSAL::isa(
$row
->{
'itemlabel'
},
'RDF::Trine::Node::Literal'
);
push
@{
$projects
->{
$p
}->{
'v'
}->{
$v
}->{
'c'
}->{
$c
}->{
'type'
} },
$row
->{
'itemtype'
}->uri
if
UNIVERSAL::isa(
$row
->{
'itemtype'
},
'RDF::Trine::Node::Resource'
)
$projects
->{
$p
}->{
'v'
}->{
$v
}->{
'c'
}->{
$c
}->{
'blame'
} = {};
if
(UNIVERSAL::isa(
$row
->{
'issue'
},
'RDF::Trine::Node::Resource'
))
{
$projects
->{
$p
}->{
'v'
}->{
$v
}->{
'c'
}->{
$c
}->{
'issue'
}->{
$row
->{
'issue'
}->uri }++;
push
@{
$projects
->{
$p
}->{
'v'
}->{
$v
}->{
'c'
}->{
$c
}->{
'type'
} },
}
if
(UNIVERSAL::isa(
$row
->{
'blame'
},
'RDF::Trine::Node'
))
{
my
$b
=
$row
->{
'blame'
}->as_ntriples;
$projects
->{
$p
}->{
'v'
}->{
$v
}->{
'c'
}->{
$c
}->{
'blame'
}->{
$b
} = {
uri
=>
$row
->{
'blame'
}->is_resource ?
$row
->{
'blame'
}->uri :
undef
,
name
=>
$row
->{
'blamename'
}&
&$row
->{
'blamename'
}->is_literal ?
$row
->{
'blamename'
}->literal_value :
undef
,
nick
=>
$row
->{
'blamenick'
}&
&$row
->{
'blamenick'
}->is_literal ?
$row
->{
'blamenick'
}->literal_value :
undef
,
};
}
}
}
}
sub
_release_data__legacy
{
my
$self
=
shift
;
my
$model
=
$self
->model;
my
$p
=
shift
;
my
$projects
=
$self
->{
'projects'
};
my
$sparql
= "
SELECT *
WHERE
{
?version dc:isVersionOf
$p
.
?version doap:Version [ doap:revision ?revision ] .
OPTIONAL { ?version doap:Version [ doap:created ?issued ] . }
OPTIONAL { ?version rdfs:label ?vname . }
OPTIONAL { ?version asc:changes [ ?itemtype ?itemlabel ] . }
}
";
my
$query
= RDF::Query->new(
$sparql
);
my
$results
=
$query
->execute(
$model
);
while
(
my
$row
=
$results
->
next
)
{
my
$v
=
$row
->{
'version'
}->as_ntriples;
$projects
->{
$p
}->{
'v'
}->{
$v
}->{
'EXISTS'
}++;
$projects
->{
$p
}->{
'v'
}->{
$v
}->{
'revision'
} =
$row
->{
'revision'
}->literal_value
if
UNIVERSAL::isa(
$row
->{
'revision'
},
'RDF::Trine::Node::Literal'
);
$projects
->{
$p
}->{
'v'
}->{
$v
}->{
'issued'
} =
$row
->{
'issued'
}->literal_value
if
UNIVERSAL::isa(
$row
->{
'issued'
},
'RDF::Trine::Node::Literal'
);
$projects
->{
$p
}->{
'v'
}->{
$v
}->{
'name'
} =
$row
->{
'vname'
}->literal_value
if
UNIVERSAL::isa(
$row
->{
'vname'
},
'RDF::Trine::Node::Literal'
);
if
(UNIVERSAL::isa(
$row
->{
'itemlabel'
},
'RDF::Trine::Node'
))
{
my
$c
=
$row
->{
'itemlabel'
}->as_ntriples;
$projects
->{
$p
}->{
'v'
}->{
$v
}->{
'c'
}->{
$c
}->{
'label'
} =
$row
->{
'itemlabel'
}->literal_value
if
UNIVERSAL::isa(
$row
->{
'itemlabel'
},
'RDF::Trine::Node::Literal'
);
$projects
->{
$p
}->{
'v'
}->{
$v
}->{
'c'
}->{
$c
}->{
'blame'
} = {};
if
(UNIVERSAL::isa(
$row
->{
'itemtype'
},
'RDF::Trine::Node::Resource'
))
{
my
$u
=
$row
->{
'itemtype'
}->uri;
{
push
@{
$projects
->{
$p
}->{
'v'
}->{
$v
}->{
'c'
}->{
$c
}->{
'type'
} },
}
}
}
}
}
1;