Browse Source

+ initial

master
Alex 'AdUser' Z 5 years ago
commit
6c812dbf45
  1. 123
      qrss-export
  2. 44
      qrss-stats
  3. 116
      qrss.sql

123
qrss-export

@ -0,0 +1,123 @@
#!/usr/bin/env perl
use strict;
use warnings;
use utf8;
use Getopt::Std;
use IO::File;
use Date::Parse;
use DBIx::Simple;
use SQL::Abstract;
use Term::Prompt;
use YAML;
my $opts = { f => undef, F => undef };
getopts('f:F:', $opts)
or die "Usage: $0 [-f <qrss.db>] [-F <filter-by-url>]\n";
die "Usage: $0 [-f <qrss.db>]\n"
unless $opts->{f} and -f $opts->{f};
my $dbopts = { sqlite_unicode => 1, AutoCommit => 1, RaiseError => 1 };
my $dsn = sprintf 'dbi:SQLite:dbname=%s', $opts->{f};
my $db = DBIx::Simple->new($dsn, undef, undef, $dbopts);
sub list_feeds {
my $filter = $opts->{F}
? { xmlUrl => {-like => "%$opts->{F}%"} }
: { xmlUrl => {'!=' => ''} };
my @feeds = $db->select('feeds', [qw(id title text xmlUrl)], $filter, 'title')->hashes;
print " ID | Feed name (URL)\n";
print "-----+-----------------------------------------------------------\n";
foreach my $f (@feeds) {
printf " %3d | %s (%s)\n", $f->{id}, $f->{title} || $f->{text}, $f->{xmlurl};
}
print "\n";
}
sub export_feed {
my $fid = shift;
my $feed = $db->select('feeds', '*', {id => $fid})->hash
or return warn "no such feed: $fid\n";
my $fname = sprintf "%d - %s", $fid, substr($feed->{title} || $feed->{text}, 0, 128);
$fname =~ tr[/][]d;
$fname .= '.yml';
my $file = IO::File->new($fname, 'w');
my $yml = YAML::Dump({
type => 'feed',
url => $feed->{xmlurl} || $feed->{htmlurl},
name => $feed->{title} || $feed->{text},
note => $feed->{description},
});
if (utf8::is_utf8($yml)) { utf8::encode($yml); }
$file->print($yml);
my @news = $db->select('news', '*', {feedId => $fid})->hashes;
my $exported = 0;
print "exporting: ";
while (my $n = shift @news) {
$n->{flags} = '';
$n->{flags} .= ($n->{read}) ? 'u' : 'U';
$n->{flags} .= ($n->{starred}) ? 'S' : 's';
$n->{ctime} = str2time($n->{published} || $n->{modified});
if ($n->{description} and not $n->{content}) {
$n->{content} = $n->{description};
undef $n->{description};
}
foreach my $attr (qw(guid link_href)) {
next unless $n->{$attr} and index($n->{$attr}, '://') >= 0;
$n->{url} = $n->{$attr};
last;
}
$yml = YAML::Dump({
type => 'entry',
url => $n->{url},
ctime => $n->{ctime},
flags => $n->{flags},
author => $n->{author_name},
category => $n->{category},
title => $n->{title},
summary => $n->{description},
content => $n->{content},
});
if (utf8::is_utf8($yml)) { utf8::encode($yml); }
$file->print($yml);
$exported++;
if ($exported % 100 == 0) { print '.'; }
} # foreach @news
$file->close;
print "\n";
printf "exported: %s (%d entries)\n", $fname, $exported;
}
sub show_help {
print <<"HELP";
l\tList feeds
f\tSet list filter
e\tExport
h\tHelp
q\tQuit
HELP
}
binmode STDOUT => ':utf8';
$| = 1;
while (1) {
my $a = prompt('c', 'command', 'h for help', '', qw(l f e h q));
if ($a eq 'l') {
list_feeds();
} elsif ($a eq 'f') {
$opts->{F} = prompt('a', 'Filter by URL', '', 'example.com', '');
} elsif ($a eq 'e') {
my $fid = prompt('n', 'feed id:', '', '');
export_feed($fid);
} elsif ($a eq 'q') {
print "exiting...\n";
exit 0;
} else {
show_help();
}
}
exit 0;

44
qrss-stats

@ -0,0 +1,44 @@
#!/usr/bin/env perl
use strict;
use warnings;
use utf8;
use Getopt::Std;
use DBIx::Simple;
use SQL::Abstract;
my $opts = { f => undef };
getopts('f:', $opts)
or die "Usage: $0 [-f <qrss.db>]\n";
die "Usage: $0 [-f <qrss.db>]\n"
unless $opts->{f} and -f $opts->{f};
my $dbopts = { sqlite_unicode => 1, AutoCommit => 1, RaiseError => 1 };
my $dsn = sprintf 'dbi:SQLite:dbname=%s', $opts->{f};
my $db = DBIx::Simple->new($dsn, undef, undef, $dbopts);
my $query = 'SELECT f.id, f.title, COUNT(*) AS cnt, '
. ' SUM(LENGTH(n.description)) AS len1, SUM(LENGTH(n.content)) AS len2 FROM feeds f'
. ' JOIN news n ON (f.id = feedId) GROUP BY f.id ORDER BY cnt DESC';
my $stats = $db->query($query)->hashes;
printf " ID | News | Summary | Content | Title \n";
print "---------------" x 4, "\n";
my $total = { cnt => 0, len1 => 0, len2 => 0 };
foreach my $s (@{ $stats }) {
utf8::encode($s->{title});
$s->{len1} //= 0;
$s->{len2} //= 0;
printf " %4d | %6d | %8.1fK | %8.1fK | %s\n", $s->{id}, $s->{cnt},
$s->{len1} / 1024, $s->{len2} / 1024, $s->{title};
$total->{cnt} += $s->{cnt};
$total->{len1} += $s->{len1};
$total->{len2} += $s->{len2};
}
print "---------------" x 4, "\n";
printf "%5s | %6d | %8.1fK | %8.1fK | %s\n", 'Total', $total->{cnt},
$total->{len1} / 1024, $total->{len2} / 1024, '';
exit 0;

116
qrss.sql

@ -0,0 +1,116 @@
CREATE TABLE feeds (
id integer primary key,
text varchar,
title varchar,
description varchar,
xmlUrl varchar,
htmlUrl varchar,
language varchar,
copyrights varchar,
author_name varchar,
author_email varchar,
author_uri varchar,
webMaster varchar,
pubdate varchar,
lastBuildDate varchar,
category varchar,
contributor varchar,
generator varchar,
docs varchar,
cloud_domain varchar,
cloud_port varchar,
cloud_path varchar,
cloud_procedure varchar,
cloud_protocal varchar,
ttl integer,
skipHours varchar,
skipDays varchar,
image blob,
unread integer,
newCount integer,
currentNews integer,
label varchar,
undeleteCount integer,
tags varchar,
hasChildren integer default 0,
parentId integer default 0,
rowToParent integer,
updateIntervalEnable int,
updateInterval int,
updateIntervalType varchar,
updateOnStartup int,
displayOnStartup int,
markReadAfterSecondsEnable int,
markReadAfterSeconds int,
markReadInNewspaper int,
markDisplayedOnSwitchingFeed int,
markDisplayedOnClosingTab int,
markDisplayedOnMinimize int,
layout text,
filter text,
groupBy int,
displayNews int,
displayEmbeddedImages integer default 1,
loadTypes text,
openLinkOnEmptyContent int,
columns text,
sort text,
sortType int,
maximumToKeep int,
maximumToKeepEnable int,
maximumAgeOfNews int,
maximumAgoOfNewEnable int,
deleteReadNews int,
neverDeleteUnreadNews int,
neverDeleteStarredNews int,
neverDeleteLabeledNews int,
status text,
created text,
updated text,
lastDisplayed text,
f_Expanded integer default 1,
flags text,
authentication integer default 0,
duplicateNewsMode integer default 0,
typeFeed integer default 0,
showNotification integer default 0,
disableUpdate integer default 0,
javaScriptEnable integer default 1,
layoutDirection integer default 0
);
CREATE TABLE news (
id integer primary key,
feedId integer,
guid varchar,
guidislink varchar default 'true',
description varchar,
content varchar,
title varchar,
published varchar,
modified varchar,
received varchar,
author_name varchar,
author_uri varchar,
author_email varchar,
category varchar,
label varchar,
new integer default 1, -- actually "seen"
read integer default 0, -- read/unread
starred integer default 0,
deleted integer default 0,
attachment varchar,
comments varchar,
enclosure_length,
enclosure_type,
enclosure_url,
source varchar,
link_href varchar,
link_enclosure varchar,
link_related varchar,
link_alternate varchar,
contributor varchar,
rights varchar,
deleteDate varchar,
feedParentId integer default 0
);
Loading…
Cancel
Save