Skip to content

Commit

Permalink
Renamed to tiptop, and added a README.
Browse files Browse the repository at this point in the history
I don't know why re: tiptop. I just kind of like it, and I like that
it has "T" and "P" twice in it.
  • Loading branch information
Benjamin Trott committed Dec 9, 2009
1 parent 8de138f commit c0252fe
Show file tree
Hide file tree
Showing 9 changed files with 119 additions and 20 deletions.
2 changes: 1 addition & 1 deletion .gitignore
Expand Up @@ -4,6 +4,6 @@ inc/
pm_to_blib
blib/
TODO
dash.cfg
tiptop.cfg
sync-to-ec2
*~
4 changes: 2 additions & 2 deletions Makefile.PL
@@ -1,6 +1,6 @@
use inc::Module::Install;
name 'Dash';
all_from 'lib/Dash.pm';
name 'Tiptop';
all_from 'lib/Tiptop.pm';
requires 'CGI::Deurl::XS';
requires 'Config::Tiny';
requires 'DateTime';
Expand Down
99 changes: 99 additions & 0 deletions README.markdown
@@ -0,0 +1,99 @@
Tiptop
======

Tiptop is an alternate reader for the top content in your TypePad dashboard.
Rather than a stream of all of the events generated by people you follow
(posts, favorites, comments, &c), tiptop gives you a couple of views into that
content:

1. A list of posts, photos, videos, &c created by the people you follow
2. A leaderboard of the most-favorited posts, photos, videos, &c

And, in the future, maybe more. Its aim is to serve both as a reference
application for building upon the TypePad platform, as well as a genuinely
useful reader for the content you should be reading from people you follow.


Installing Tiptop
-----------------

Tiptop itself is pure Perl, but it has a number of dependencies beyond core
Perl. You can guarantee that those dependencies are installed by running the
`Makefile.PL`. Tiptop also requires a MySQL database to store post & user
content locally.


Configuring Tiptop
------------------

Tiptop's configuration is stored in the `tiptop.cfg` file. At a minimum,
the database and user configuration (information about the user whose
followers you'd like to track, which is probably you) is required. Here's
a sample configuration file, which should live in `tiptop.cfg` in your
application root:

[database]
dsn=dbi:mysql:database=tiptop
username=username
password=password

[user]
xid=6p00d83455876069e2


Running Tiptop
--------------

Tiptop is composed of a couple of components:

1. Command-line tools (`load-events.pl`, `poll-favorited-by.pl`)
2. A PSGI-based web application

To test your configuration, you can first start up the web application:

bin/tiptop-web

Then navigate to the webserver in your browser (it runs on port 5000 by
default):

http://localhost:5000/

`tiptop-web` is simply a wrapper around the `plackup` tool, so you can use
any of the command-line options supported by that tool when running
`tiptop-web`, as well.

To load content into your database, run `load-events.pl`: this will poll
TypePad for new events created by your followers, and will create local copies
of the user and asset objects for fast access in the future:

perl tools/load-events.pl

This could take a little while the first time it runs, if you have a lot of
events in your dashboard history (the maximum number of events is 1,000); on
future invocations, though, `load-events.pl` will only look back through
your events until it finds events that it's previously processed, so it'll
be faster.

`load-events.pl` will only load favorites and assets by people that you
follow. You might also want to factor in favorites from users that you don't
follow when they happen to favorite assets from people you follow (or assets
favorited by people that you follow). To backfill favorites from all users
for the assets that `load-events.pl` has discovered, you can run
`poll-favorited-by.pl`:

perl tools/poll-favorited-by.pl

For each asset in your local database, this will query the list of favorites
for that asset and backfill them in your database, giving you a complete
list of users that have favorited each asset.


License
-------
Tiptop is free software; you can redistribute it and/or modify it under
the same terms as Perl itself.


Author
------
Benjamin Trott / ben@sixapart.com
6 changes: 3 additions & 3 deletions bin/app.psgi → bin/tiptop-app.psgi
Expand Up @@ -3,7 +3,7 @@ use strict;

use Find::Lib '../lib';

use Dash::Util;
use Tiptop::Util;
use DateTime;
use DateTime::Format::Mail;
use JSON;
Expand Down Expand Up @@ -36,7 +36,7 @@ my $error = sub {
sub load_assets_by {
my( $sql, @bind ) = @_;

my $dbh = Dash::Util->get_dbh;
my $dbh = Tiptop::Util->get_dbh;
my $sth = $dbh->prepare( <<SQL );
SELECT a.asset_id,
a.api_id,
Expand Down Expand Up @@ -74,7 +74,7 @@ SQL

# Calculate an excerpt, extract media, etc, and stuff it all
# into the "content" key.
$row->{content} = Dash::Util->get_content_data(
$row->{content} = Tiptop::Util->get_content_data(
$row->{type},
$row->{content},
decode_json( $row->{links_json} ),
Expand Down
2 changes: 1 addition & 1 deletion bin/dash-web → bin/tiptop-web
Expand Up @@ -6,6 +6,6 @@ use Path::Class;

my @args = @ARGV;
unshift @args,
'--app', file( $FindBin::Bin, 'app.psgi' );
'--app', file( $FindBin::Bin, 'tiptop-app.psgi' );

exec 'plackup', @args;
2 changes: 1 addition & 1 deletion lib/Dash.pm → lib/Tiptop.pm
@@ -1,4 +1,4 @@
package Dash;
package Tiptop;
use strict;
use 5.008_001;

Expand Down
4 changes: 2 additions & 2 deletions lib/Dash/Util.pm → lib/Tiptop/Util.pm
@@ -1,4 +1,4 @@
package Dash::Util;
package Tiptop::Util;
use strict;

use CGI::Deurl::XS ();
Expand All @@ -15,7 +15,7 @@ use JSON;
use List::Util qw( first min reduce );

our @EXPORT_OK = qw( debug );
our $Config = dirname( __FILE__ ) . "/../../dash.cfg";
our $Config = dirname( __FILE__ ) . "/../../tiptop.cfg";

GetOptions(
'config' => \$Config,
Expand Down
14 changes: 7 additions & 7 deletions tools/load-events.pl
Expand Up @@ -3,13 +3,13 @@

use Find::Lib '../lib';

use Dash::Util qw( debug );
use Tiptop::Util qw( debug );
use List::Util qw( first );
use WWW::TypePad;

my $tp = WWW::TypePad->new;
my $dbh = Dash::Util->get_dbh;
my $config = Dash::Util->config;
my $dbh = Tiptop::Util->get_dbh;
my $config = Tiptop::Util->config;

my $user_xid = $config->{user}{xid};
die "user.xid configuration is required; see README.markdown"
Expand All @@ -21,7 +21,7 @@

my $user = $tp->users->get( $user_xid )
or die "can't find user $user_xid on TypePad";
my $me_person = Dash::Util->find_or_create_person_from_api( $user );
my $me_person = Tiptop::Util->find_or_create_person_from_api( $user );
my $me_person_id = $me_person->{person_id};

my( $last_event_id ) = $dbh->selectrow_array( <<SQL );
Expand Down Expand Up @@ -131,7 +131,7 @@ sub process_asset {

# Convert the API objects into local objects, instantiating a local
# record if we hadn't seen this asset before.
my $asset = Dash::Util->find_or_create_asset_from_api( $event->{object} );
my $asset = Tiptop::Util->find_or_create_asset_from_api( $event->{object} );

$dbh->do( <<SQL, undef, $me_person_id, $asset->{asset_id} );
INSERT INTO stream (person_id, asset_id) VALUES (?, ?)
Expand All @@ -158,8 +158,8 @@ sub process_favorite {
# Convert the API objects into local objects, instantiating a local
# record if we hadn't seen this user/asset before.

my $person = Dash::Util->find_or_create_person_from_api( $event->{actor} );
my $asset = Dash::Util->find_or_create_asset_from_api( $event->{object} );
my $person = Tiptop::Util->find_or_create_person_from_api( $event->{actor} );
my $asset = Tiptop::Util->find_or_create_asset_from_api( $event->{object} );

$dbh->do( <<SQL, undef, $asset->{asset_id}, $person->{person_id}, $fave_id );
INSERT INTO favorited_by (asset_id, person_id, api_id) VALUES (?, ?, ?)
Expand Down
6 changes: 3 additions & 3 deletions tools/poll-favorited-by.pl
Expand Up @@ -3,11 +3,11 @@

use Find::Lib '../lib';

use Dash::Util qw( debug );
use Tiptop::Util qw( debug );
use WWW::TypePad;

my $tp = WWW::TypePad->new;
my $dbh = Dash::Util->get_dbh;
my $dbh = Tiptop::Util->get_dbh;

my $sth = $dbh->prepare( 'SELECT asset_id, api_id FROM asset' );
$sth->execute;
Expand All @@ -19,7 +19,7 @@
next unless defined $entry->{urlId};

my $person =
Dash::Util->find_or_create_person_from_api( $entry->{author} );
Tiptop::Util->find_or_create_person_from_api( $entry->{author} );

my $rv = $dbh->do( <<SQL, undef, $row->{asset_id}, $person->{person_id}, $entry->{urlId} );
INSERT IGNORE INTO favorited_by (asset_id, person_id, api_id) VALUES (?, ?, ?)
Expand Down

0 comments on commit c0252fe

Please sign in to comment.