I recently attended Miniconf in New York at which I decided to host a hackathon for my current hobby project, Mojo::Snoo - a Mojo wrapper for the reddit API.
Some hackathon attendees were nice enough to contribute code and give me some great ideas for future development. So, I’d like to briefly mention some changes introduced in the v0.10 release.
Firstly, let’s get one thing out of the way:
What the #$%! is Snoo?
Snoo is the name of reddit’s alien mascot. You know, the white alien at the top of reddit.com:
Not to be confused with “snu-snu” from Futurama.
According to reddit’s most recent license changes, reddit API wrappers cannot contain the word “reddit”.
Thus, Mojo::Snoo was born.
New features and changes
Moving on - I’d like to summarize some changes made recently and share some quick examples:
Firstly, I’d like to go ahead and mention the one-liner package, ojo::Snoo. ojo::Snoo was inspired by ojo, the Mojolicious one-liner module. This lets the user create quick one-liners via shortcut functions. Technically, these shortcut functions could accept OAuth details, but ojo::Snoo is intended to be used for non-auth reddit endpoints.
Quick example (see docs for more):
# print title of the first 5 “hot” submissions from /r/perl subreddit perl -Mojo::Snoo -E ‘sr(“perl”)->links(5)->each(sub { $_->title })’
In the example shown above, the function sr() is a shortcut to creating a Mojo::Snoo::Subreddit object.
Other shortcut functions include:
mr() -> Mojo::Snoo::Multireddit->new()
c() -> Mojo::Snoo::Comment->new()
l() -> Mojo::Snoo::Link->new()
u() -> Mojo::Snoo::User->new()
Before I explain this change, one must understand that reddit officially refers to certain entities within its site as “things”. For example, subreddits and comments are both classified as “things”. Subreddits have a type prefix of “t5”, while comments have “t1”. You can see all reddit “things” and more details here: http://www.reddit.com/dev/api#fullnames
One mistake I made originally was assuming subreddit link submissions were the *only* "thing" type.
So, in short, I’ve renamed Mojo::Snoo::Thing as Mojo::Snoo::Link, and Hunter McMillen contributed some initial work to revive Mojo::Snoo::Thing as a generic interface to creating “thing” objects.
examples:
# create new Mojo::Snoo::Link object from specific link ID Mojo::Snoo::Link->new(‘391jsz’);# do the same with the thing’s fullname via Mojo::Snoo::Thing
Mojo::Snoo::Thing->new(‘t3_391jsz’);
After a few releases, I quickly learned there have been some major changes to the monkey_patch function in Mojo::Util. Also, this function did not even exist at one point, which I think was the major point of failure. This change should help assure that more tests are passing.
What now?
write more tests
support more endpoints
improve documentation and examples
What’s the point?
Besides being a reddit API wrapper, I want Mojo::Snoo to be an attractive alternative to the Python reddit wrapper, PRAW. There are a *lot* of people on reddit wanting to learn how to write their own bots (see /r/redditdev), and most are guided towards PRAW. Furthermore, the Mojolicious suite is fast and its syntax is sexy.
]]>Long time no blog. I posted on reddit about my new module, Mojo::Snoo. I'm shooting for a funky Perl wrapper around the reddit API. Right now, I'm the only one using it (I think), but would like that to change.
So...feedback welcome! Install, break, complain, etc.
Oh, and I will be hosting a hackathon at Miniconf this weekend in NYC. So, feel free to say hi and help me with some development.
Links:
http://www.reddit.com/r/perl/comments/38eca1/feedback_welcome_mojosnoo/
https://github.com/aggrolite/Mojo-Snoo
https://metacpan.org/pod/Mojo::Snoo
First off, I'd like to compliment Yuji Shimada on his fantastic module WWW::YouTube::Download. I'm sure the module requires a lot of maintenance (as sites like YouTube can change their design quite a bit) and for that I'm grateful.
Now, the module worked perfectly for my downloading needs *except* that I could not fetch age-restricted videos. Instead I received a message that the module could not find any video URLs. The bright side to this problem was that Shimada's module made it *very* easy to come to a solution, thanks to the module's ua method which accepts a LWP::UserAgent object.
TL;DR - cookies
In my case, I was using Mechanize, so I passed the Mech object to the ua method, like so:
my $youtube = WWW::YouTube::Download->new;
my $mech = WWW::Mechanize->new( #
cookie_jar => {file => '~/.youtube.dat', autosave => 1},
);
$youtube->ua($mech);
Then from there I had to reproduce a browser login to YouTube:
sub login {
my $uri = URI->new('https://accounts.google.com/ServiceLogin');
$uri->query_form(
{ continue => 'http://www.youtube.com/signin',
service => 'youtube',
passive => 'true',
hl => 'en',
}
);
$mech->get($uri->as_string);
$mech->form_number(1); # lazy
$mech->field(Email => 'foobar@gmail.com');
$mech->field(Passwd => 'mylongpassword');
$mech->submit;
}
after login() subroutine is called, Mech will store cookies and we should be logged in the next time we view a video. So the next part is easy:
$youtube->download('4loJ5b102PU'); # video ID
Note:
Keep in mind that if the YouTube account you are using has never viewed an age-restricted video, you will need to click the Accept button (or something similar) once (and only once) before WWW::YouTube::Download can fetch these videos.
Creating a new object like this:
# only supports geo right now my $donuts = WWW::KrispyKreme::Hotlight->new(where => [34.170833,-118.25]);
and calling the locations method like this:
my $locations = $donuts->locations;
will return a structure like this:
[ { 'storeHours2' => '', 'locationId' => '993', 'hotLightOn' => '0', 'storeHours1' => '', 'phone' => '818-955-9015', 'zipcode' => '91504', 'state' => 'CA', 'city' => 'Burbank', 'geoLocation' => '34.190000,-118.330000', 'url' => 'http://kkre.me/oXMuQQ', 'title' => 'Burbank', 'address' => '1521 North Victory Place' }, { 'storeHours2' => '', 'locationId' => '985', 'hotLightOn' => '0', 'storeHours1' => '', 'phone' => '323-291-4133', 'zipcode' => '90008', 'state' => 'CA', 'city' => 'Los Angeles', 'geoLocation' => '34.010000,-118.340000', 'url' => 'http://kkre.me/pF3cuI', 'title' => 'Los Angeles', 'address' => '4034 Crenshaw Boulevard' }, ... ]
Notice there is a boolean value for 'hotLightOn' which can be handy for finding fresh donuts!
CPAN: https://metacpan.org/module/WWW::KrispyKreme::Hotlight
Github: https://github.com/aggrolite/WWW-KrispyKreme-HotLight
Yesterday I released another IRC plugin for POE::Component::IRC: POE::Component::IRC::Plugin::WWW::Reddit::TIL
The plugin simply fetches a random title and link from the front page of Reddit's TodayILearned subreddit.
I used WWW::Shorten::Simple to return bitly links, and Mojo::JSON to decode reddit's API.
example:
curtis: !TIL
ircbot: curtis: TIL that the fighter squadron with the highest number of kills in the Battle of Britain during WWII were actually from Poland, and showed up two months after the battle had begun. http://bit.ly/ZN0qdB
links:
]]>I have released my first module: POE::Component::IRC::Plugin::Vim::Tips, a plugin for the IRC client module POE::Component::IRC.
When a user types !vimtip (or !vimtips) in a channel that your bot has joined, my plugin will scrape the first page of tweets from the Vim Tips Twitter feed and reply back with a "random" tip from that list.
Example:
curtis !vimtip
vimbot curtis: ggguG will lower case the entire file (also known as the Jerry Yang treatment). http://is.gd/4xZW
A lesson learned from v0.01: Don't forget to list dependencies in Makefile.PL!
]]>Wow, I suspected concatenation was the key to getting a shorter line, but did not know how to implement it until now. Thanks all for the replies.
]]>Write a program that prints the numbers from 1 to 100. But for multiples of three print "Fizz" instead of the number and for the multiples of five print "Buzz". For numbers which are multiples of both three and five print "FizzBuzz".
I must have bookmarked the link while preparing for interviews before graduation. After skimming over the material I was curious to know the smallest amount of Perl code I could use to write a solution.
Here's my attempt:
Any shorter solutions? I suppose I could just use print if I wanted a one-liner...
]]>