Skip to content
This repository has been archived by the owner on May 5, 2024. It is now read-only.

Commit

Permalink
Init.
Browse files Browse the repository at this point in the history
  • Loading branch information
plu committed Jul 22, 2011
0 parents commit b99dd18
Show file tree
Hide file tree
Showing 23 changed files with 476 additions and 0 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
/app/log/*.log
/app/Makefile
1 change: 1 addition & 0 deletions app/.llrc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
/Volumes/perlbrew/locallib/cpan-meets-github
12 changes: 12 additions & 0 deletions app/Makefile.PL
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#!/usr/bin/env perl
use ExtUtils::MakeMaker;

WriteMakefile(
PREREQ_PM => {
'LWP::UserAgent' => '6.02',
'Mojolicious' => '1.64',
'Mojolicious::Plugin::Mongodb' => '1.07',
'MongoDB' => '0.43',
'Pithub' => '0.01005',
}
);
2 changes: 2 additions & 0 deletions app/app.psgi
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
$ENV{MOJO_MODE} = 'production';
require 'script/app.pl';
27 changes: 27 additions & 0 deletions app/lib/GMC.pm
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package GMC;

use Mojo::Base 'Mojolicious';
use GMC::Util qw(mongodb_config);

# This method will run once at server start
sub startup {
my $self = shift;

$self->static->root( $self->home->rel_dir('static') );

$self->plugin(
mongodb => {
mongodb_config(),
database => 'db',
helper => 'db',
}
);

# setup routes
my $r = $self->routes;
$r->namespace('GMC::Controller');
$r->route('/')->to('root#list');
$r->route('/user/:user')->to('root#view');
}

1;
26 changes: 26 additions & 0 deletions app/lib/GMC/Controller/Root.pm
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package GMC::Controller::Root;

use Mojo::Base 'Mojolicious::Controller';

sub list {
my ($self) = @_;
my $users = $self->db->users->find->sort( { name => 1 } );
$self->stash( users => $users );
}

sub view {
my ($self) = @_;
my $pauseid = $self->match->captures->{user};
my $user = $self->db->users->find( { pauseid => $pauseid } )->next;
unless ($user) {
$self->render_not_found;
return;
}
my $repos = $self->db->repos->find( { _user_id => $user->{_id} } )->sort( { name => 1 } );
$self->stash(
repos => $repos,
user => $user,
);
}

1;
156 changes: 156 additions & 0 deletions app/lib/GMC/Cron/Update.pm
Original file line number Diff line number Diff line change
@@ -0,0 +1,156 @@
package GMC::Cron::Update;

use strict;
use warnings;
use GMC::Util qw(mongodb_config);
use JSON::Any;
use LWP::UserAgent;
use Mojo::Base -base;
use Mojo::Log;
use MongoDB;
use Pithub;

__PACKAGE__->attr( [qw(db json log lwp mcpan pithub)] );

sub new {
my ( $package, %args ) = @_;

my $mongo = MongoDB::Connection->new( mongodb_config() );

return bless {
db => $mongo->db,
json => JSON::Any->new,
log => Mojo::Log->new,
lwp => LWP::UserAgent->new,
pithub => Pithub->new( per_page => 100, auto_pagination => 1 ),
mcpan => 'http://api.metacpan.org/author/_search?q=profile.name:github&size=100000',
} => $package;
}

sub run {
my ($self) = @_;

my $users = $self->fetch_metacpan_users;

foreach my $user (@$users) {
$self->create_or_update_user($user);
$self->update_repos($user);
}

$self->log->info("FINISHED.");
}

sub update_repos {
my ( $self, $user ) = @_;

my $repos = $self->fetch_github_repos( $user->{github_user} );

my %languages = ();
foreach my $repo (@$repos) {
$repo->{_user_id} = $user->{_id};
$languages{ $repo->{language} }++ if $repo->{language};
}

my $cond = { _id => $user->{_id} };
$self->db->users->update( $cond, { '$set' => { languages => \%languages } } ) if %languages;

if (@$repos) {
$self->db->repos->remove( { _user_id => $user->{_id} } );
$self->db->repos->batch_insert($repos);
}
}

sub create_or_update_user {
my ( $self, $user ) = @_;

$user->{github_data} = $self->fetch_github_user( $user->{github_user} );

my $cond = { pauseid => $user->{pauseid} };

my $db_user = $self->db->users->find($cond);
if ( $db_user->count ) {
$self->db->users->update( $cond => { '$set' => $user } );
$user->{_id} = $db_user->next->{_id};
$self->log->info("Updating user $user->{pauseid}");
}
else {
my $id = $self->db->users->insert($user);
$user->{_id} = $id;
$self->log->info("Adding new user $user->{pauseid}");
}
}

sub fetch_github_user {
my ( $self, $github_user ) = @_;

my $result = $self->pithub->users->get( user => $github_user );
my $github_data = {};

if ( $result->success ) {
$github_data = $result->content;
$self->log->info("Successfully fetched user ${github_user} from Github");
}
else {
$self->log->warn("Could not fetch user ${github_user} from Github");
}

return $github_data;
}

sub fetch_github_repos {
my ( $self, $github_user ) = @_;

my $result = $self->pithub->repos->list( user => $github_user );
my $repos = [];

if ( $result->success ) {
while ( my $row = $result->next ) {
push @$repos, $row;
}
$self->log->info("Successfully fetched repos of user ${github_user} from Github");
}
else {
$self->log->warn("Could not fetch repos of user ${github_user} from Github");
}

return $repos;
}

sub fetch_metacpan_users {
my ($self) = @_;

$self->log->info("Fetching users from MetaCPAN ...");

my $response = $self->lwp->get( $self->mcpan );
die $response->status_line unless $response->is_success;

my $data = $self->json->decode( $response->content );

my @result = ();
foreach my $row ( @{ $data->{hits}{hits} } ) {
$row = $row->{_source};

my $github_user;
foreach my $profile ( @{ $row->{profile} || [] } ) {
if ( $profile->{name} eq 'github' ) {
$github_user = $profile->{id};
last;
}
}

push @result,
{
github_user => $github_user,
gravatar_url => $row->{gravatar_url},
name => $row->{name},
pauseid => $row->{pauseid},
metacpan_url => "https://metacpan.org/author/" . $row->{pauseid},
};
}

$self->log->info("DONE");

return \@result;
}

1;
47 changes: 47 additions & 0 deletions app/lib/GMC/Util.pm
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package GMC::Util;

use Mojo::Base 'Exporter';
use JSON::XS;
use File::Slurp qw(read_file);

our @EXPORT_OK = qw/environment mongodb_config/;
my $ENVIRONMENT;

sub mongodb_config {
my ($self) = @_;

my %config = (
host => environment()->{DOTCLOUD_DATA_MONGODB_HOST},
port => environment()->{DOTCLOUD_DATA_MONGODB_PORT},
);

my ( $user, $pass ) = @{ environment() }{qw(DOTCLOUD_DATA_MONGODB_LOGIN DOTCLOUD_DATA_MONGODB_PASSWORD)};

$config{password} = $pass if defined $pass;
$config{username} = $user if defined $user;

return %config;
}

sub environment {
my ($self) = @_;

return $ENVIRONMENT if $ENVIRONMENT;

my $file = "$ENV{HOME}/environment.json";

if ( -f $file ) {
my $env = read_file($file);
$ENVIRONMENT = JSON::XS->new->decode($env);
return $ENVIRONMENT;
}

$ENVIRONMENT = {
DOTCLOUD_DATA_MONGODB_HOST => 'localhost',
DOTCLOUD_DATA_MONGODB_PORT => 27017,
};

return $ENVIRONMENT;
}

1;
Empty file added app/log/.gitignore
Empty file.
3 changes: 3 additions & 0 deletions app/nginx.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
if ($host != 'www.github-meets-cpan.com' ) {
rewrite ^/(.*)$ http://www.github-meets-cpan.com/$1 permanent;
}
24 changes: 24 additions & 0 deletions app/script/app.pl
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
#!/usr/bin/env perl

use strict;
use warnings;

use File::Basename 'dirname';
use File::Spec;

use lib join '/', File::Spec->splitdir( dirname(__FILE__) ), 'lib';
use lib join '/', File::Spec->splitdir( dirname(__FILE__) ), '..', 'lib';

# Check if Mojo is installed
eval 'use Mojolicious::Commands';
die <<EOF if $@;
It looks like you don't have the Mojolicious Framework installed.
Please visit http://mojolicio.us for detailed installation instructions.
EOF

# Application
$ENV{MOJO_APP} ||= 'GMC';

# Start commands
Mojolicious::Commands->start;
7 changes: 7 additions & 0 deletions app/script/update.pl
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
#!/usr/bin/env perl
use strict;
use warnings;
use FindBin;
use lib "$FindBin::Bin/../lib";
use GMC::Cron::Update;
GMC::Cron::Update->new->run;
Binary file added app/static/cpan.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added app/static/github.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
71 changes: 71 additions & 0 deletions app/static/screen.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
{
margin: 0;
padding: 0;
}

body {
margin: 0 auto;
width: 800px;
font: 15px/22px Helvetica, Arial, sans-serif;
background: #f0f0f0;
}

h2 {
font-size: 28px;
line-height: 44px;
padding: 22px 0;
}

h3 {
font-size: 18px;
line-height: 22px;
margin: 0;
}

div.name h3 {
padding-left: 102px;
}

div.reponame h3 {
padding-left: 10px;
}

div.item {
padding: 21px;
background: #E3E3E3;
border: 1px solid #d7d7d7;
-moz-border-radius: 11px;
-webkit-border-radius: 11px;
width: 80%;
margin-bottom: 2em;
}

div.avatar {
clear: both;
padding: 8px;
background: #E3E3E3;
border: 1px solid #a7a7a7;
-moz-border-radius: 11px;
-webkit-border-radius: 11px;
width: 80px;
height: 80px;
float: left;
}

div.name {
margin-top:90px;
}

img.avatar {
width: 80px;
height: 80px;
}

span.heart {
font-size: 800%;
}

span.heart a {
text-decoration: none;
color: #000;
}
1 change: 1 addition & 0 deletions app/static/static
Loading

0 comments on commit b99dd18

Please sign in to comment.