Import old blog posts
This commit is contained in:
parent
957243617b
commit
0e4aa53353
36
_posts/2013-04-02-blog-or-not-blog.md
Normal file
36
_posts/2013-04-02-blog-or-not-blog.md
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
---
|
||||||
|
title: To Blog or Not to Blog
|
||||||
|
layout: post
|
||||||
|
---
|
||||||
|
|
||||||
|
|
||||||
|
The original intention of this blog was to serve as a place where I could
|
||||||
|
showcase the programming work I have done and detail my process. However, as
|
||||||
|
you can tell, there hasn't been any posts since my first ["Hello,
|
||||||
|
World!"](/blog/hello-world/) post. Sure, I've been working on projects, but I
|
||||||
|
just haven't gotten to the point in any of those projects where I felt like I
|
||||||
|
could blog in detail about it.
|
||||||
|
|
||||||
|
Then I watched this great talk that [Brian
|
||||||
|
Jones](http://pyvideo.org/speaker/352/brian-k-jones) gave at
|
||||||
|
[PyCon](http://pycon.org) that my friend, [Daniel Bond](http://dbond.cc/),
|
||||||
|
pointed out to me:
|
||||||
|
|
||||||
|
<div class="flex-video widescreen"><iframe width="640" height="360"
|
||||||
|
src="http://www.youtube.com/embed/BBfW3m3TK0w?feature=player_embedded"
|
||||||
|
frameborder="0" allowfullscreen></iframe></div>
|
||||||
|
|
||||||
|
One point that he makes that really resonates with me is how I should write
|
||||||
|
even if I feel like I don't know what I'm talking about. The reluctance to show
|
||||||
|
my inexperience is essentially the reason this blog sat stale for so many
|
||||||
|
months after its inception.
|
||||||
|
|
||||||
|
I have decided I will take Brian's words to heart, and start blogging just for
|
||||||
|
the sake of writing. Henceforth, I will no longer hesitate to chronicle my
|
||||||
|
journey through programming, writing, and any other quest which may take a hold
|
||||||
|
of me as I continue to improve and broaden my skills. I'll be wrong, I'll ask
|
||||||
|
questions, and I may frankly look like a blundering idiot at times; but, I only
|
||||||
|
ask that you just bear with me and understand that I'm new at all this still,
|
||||||
|
and I appreciate any constructive criticism that anyone has for me.
|
||||||
|
|
||||||
|
Let's see how far I can go.
|
87
_posts/2013-04-09-visualizing-laundry-usage.md
Normal file
87
_posts/2013-04-09-visualizing-laundry-usage.md
Normal file
@ -0,0 +1,87 @@
|
|||||||
|
---
|
||||||
|
title: Visualizing Laundry Usage
|
||||||
|
layout: post
|
||||||
|
---
|
||||||
|
|
||||||
|
George Mason University uses a system called
|
||||||
|
[eSuds](http://www.usatech.com/esuds/) to control the laundry machine
|
||||||
|
transactions in the dorms. What makes eSuds really cool though, is that it
|
||||||
|
keeps track of the status of every machine and displays it on a
|
||||||
|
[website](http://gmu.esuds.net/) so students can check how full the machines
|
||||||
|
are before making the trek down to the laundry rooms. The system emails each
|
||||||
|
student when their laundry is finished as well.
|
||||||
|
|
||||||
|
The only problem is that their user interface is pretty atrocious. I wrote up a
|
||||||
|
[usability analysis](https://gist.github.com/thallada/5351114) of the site for
|
||||||
|
my *SWE 205: Software Usability Analysis and Design* class, but most people
|
||||||
|
agree it's a pretty painful interface to use ([just see for
|
||||||
|
yourself](http://gmu.esuds.net/)). The thing is, most of the information that's
|
||||||
|
on the website could be reduced to a few charts. I'm a big fan of simplifying
|
||||||
|
data, so I thought: why not?
|
||||||
|
|
||||||
|
I decided to create the visualizations with [pygal](http://pygal.org/), because
|
||||||
|
the charts it spits out are absolutely gorgeous and well... it's in python,
|
||||||
|
which made it easy for me to dive right in. I'll probably try out
|
||||||
|
[d3js](http://d3js.org/) for my next visualization project though, it looks a
|
||||||
|
whole lot more advanced.
|
||||||
|
|
||||||
|
###Current laundry usage charts###
|
||||||
|
|
||||||
|
I created an [app](/laundry) in [Django](https://www.djangoproject.com/) to
|
||||||
|
display current laundry machine usage charts for all of the laundry rooms on
|
||||||
|
George Mason's campus. All of the data is scraped from the eSuds site using
|
||||||
|
[Beautiful Soup](http://www.crummy.com/software/BeautifulSoup/) and updated
|
||||||
|
every time you refresh the page.
|
||||||
|
|
||||||
|
<div style="text-align: center"><a href="/laundry" alt="See it in action"><img
|
||||||
|
src="/static/img/laundry_preview.png" /></a></div>
|
||||||
|
|
||||||
|
The site will save which laundry room you select so when you come back you will
|
||||||
|
immediately see the chart for your laundry room.
|
||||||
|
|
||||||
|
You can see the code for this on my
|
||||||
|
[GitHub](https://github.com/thallada/personalsite/) (look in the "laundry"
|
||||||
|
folder).
|
||||||
|
|
||||||
|
The point was to make this as dead simple and easy to use as possible. Do you
|
||||||
|
think I succeeded?
|
||||||
|
|
||||||
|
###Weekly laundry usage chart###
|
||||||
|
|
||||||
|
Knowing the *current* laundry machine usage is nice for saving a wasted trip
|
||||||
|
down to the laundry room, but what if you wanted to plan ahead and do your
|
||||||
|
laundry when you know other people are less likely to do laundry? That's why I
|
||||||
|
recorded the laundry usage with a [cronjob](http://en.wikipedia.org/wiki/Cron)
|
||||||
|
every 15 minutes for an entire week: to get an idea of when there is a high
|
||||||
|
probability of open machines.
|
||||||
|
|
||||||
|
<embed type="image/svg+xml" src="/static/record.svg">
|
||||||
|
|
||||||
|
This one is a little interactive.
|
||||||
|
|
||||||
|
As you can see, the laundry usage jumps around all over the place very quickly.
|
||||||
|
This definitely provides evidence to some previous frustrations I've had when I
|
||||||
|
had checked eSuds, saw that most machines were open, and arrived in the laundry
|
||||||
|
room to suddenly find that no machines were open.
|
||||||
|
|
||||||
|
**So when is the best time to do laundry?**
|
||||||
|
|
||||||
|
After analyzing the data for a bit, I noticed that there still seemed to be
|
||||||
|
quite a bit of usage around midnight and 1 AM, which, I suppose, would be
|
||||||
|
expected of college students. However, after about 2 AM the laundry usage
|
||||||
|
consistently teeters off until about 10 AM. So I guess there's no way around
|
||||||
|
it; if you want to have the laundry room to yourself, you'll have to be the
|
||||||
|
early bird.
|
||||||
|
|
||||||
|
Also, I should note that this was during the week of spring break. I'm
|
||||||
|
currently working on recording data over a few normal weeks and then compiling
|
||||||
|
it into one average week in order to see the patterns more clearly. I'll post
|
||||||
|
again once I've done that.
|
||||||
|
|
||||||
|
This was a lot of fun and I expect to make more data visualizations in the
|
||||||
|
future.
|
||||||
|
|
||||||
|
**Let me know what you think!**
|
||||||
|
|
||||||
|
EDIT: Check out the [comments on
|
||||||
|
Reddit](http://www.reddit.com/r/gmu/comments/1c1ehg/i_dont_like_esuds/).
|
92
_posts/2013-04-18-how-download-rtmp-video.md
Normal file
92
_posts/2013-04-18-how-download-rtmp-video.md
Normal file
@ -0,0 +1,92 @@
|
|||||||
|
---
|
||||||
|
title: How to Download a RTMP Video
|
||||||
|
layout: post
|
||||||
|
---
|
||||||
|
|
||||||
|
[RTMP or Real Time Messaging
|
||||||
|
Protocol](http://en.wikipedia.org/wiki/Real_Time_Messaging_Protocol) is a
|
||||||
|
protocol developed by Adobe to stream Flash videos. It's currently in use by
|
||||||
|
sites like the New York Times, ABC, NBC, Hulu, and so on. Since the video is
|
||||||
|
streamed to the user's Flash player (in their browser) bit-by-bit, the full
|
||||||
|
video file is never given to the user for them to keep. This is desirable to a
|
||||||
|
lot of media companies because then they can force you to watch through ads to
|
||||||
|
see their content and can charge you to download the full video.
|
||||||
|
|
||||||
|
However, [RTMPDump](http://rtmpdump.mplayerhq.hu/), an open-source tool
|
||||||
|
designed to intercept RTMP streams, can download the full video.
|
||||||
|
|
||||||
|
Despite numerous “How to use RTMPDump” tutorials and forum posts coming up
|
||||||
|
with a brief Google search, I've found a large portion of them are either
|
||||||
|
completely incorrect or are far too complicated since they are not using the
|
||||||
|
full toolkit that RTMPDump provides. Since it took me so long to find a decent
|
||||||
|
procedure for downloading a RTMP video, I thought it would be worth sharing
|
||||||
|
here.
|
||||||
|
|
||||||
|
Since this is questionably legal, make sure you understand any Terms of
|
||||||
|
Services you accepted or laws in your locality regarding this before you follow
|
||||||
|
the steps below ;).
|
||||||
|
|
||||||
|
###Have Linux### Most of these instructions will assume you have Ubuntu, but
|
||||||
|
most distributions will work.
|
||||||
|
|
||||||
|
While RTMPDump works on a variety of operating systems, I've only researched
|
||||||
|
how to do this on Linux. Feel free to comment if you know how to do this in
|
||||||
|
Windows or OSX.
|
||||||
|
|
||||||
|
###Install RTMPDump### This open source goodness can be found at
|
||||||
|
[http://rtmpdump.mplayerhq.hu/](http://rtmpdump.mplayerhq.hu/) or you can just
|
||||||
|
intall it using your Linux distro's package manager. For Ubuntu, that would be
|
||||||
|
typing the following into your terminal:
|
||||||
|
|
||||||
|
sudo apt-get install rtmpdump
|
||||||
|
|
||||||
|
###Redirect ALL the RTMP!### Now we need to configure your firewall to redirect
|
||||||
|
all RTMP traffic to a local port on your computer (Note: this will screw up any
|
||||||
|
RTMP streaming video you try to watch on your computer, so make sure you run
|
||||||
|
the undo command in one of the later steps to return things to normal). Type
|
||||||
|
the following into your terminal, there should be no output from the command:
|
||||||
|
|
||||||
|
sudo iptables -t nat -A OUTPUT -p tcp --dport 1935 -j REDIRECT
|
||||||
|
|
||||||
|
###Run rtmpsrv### When you install `rtmpdump`, a program called `rtmpsrv`
|
||||||
|
should have been bundled with it and installed as well. We will want to run
|
||||||
|
this now by entering the following command in a terminal:
|
||||||
|
|
||||||
|
rtmpsrv
|
||||||
|
|
||||||
|
This should output something that looks like this:
|
||||||
|
|
||||||
|
RTMP Server v2.4 (c) 2010 Andrej Stepanchuk, Howard Chu; license: GPL
|
||||||
|
|
||||||
|
Streaming on rtmp://0.0.0.0:1935
|
||||||
|
|
||||||
|
###Feed rtmpsrv the Precious Video### Now go to your browser and open/refresh
|
||||||
|
the page with the desired video. Try playing the video. If nothing happens and
|
||||||
|
it just continues to give you a black screen, then you're on the right track:
|
||||||
|
rtmpsrv has intercepted the video.
|
||||||
|
|
||||||
|
If you look back at the terminal that's running rtmpsrv you should see that
|
||||||
|
some text was outputted. There is one line in this printout that we need; it
|
||||||
|
should be a command that starts with `rtmpdump`. Copy that entire command, we
|
||||||
|
will need it later.
|
||||||
|
|
||||||
|
You can CTRL+C out of rtmpsrv now that we have what we need.
|
||||||
|
|
||||||
|
###Undo the Redirection### You must undo the iptables redirection command we
|
||||||
|
performed earlier before you can do anything else, so run this in your
|
||||||
|
terminal:
|
||||||
|
|
||||||
|
sudo iptables -t nat -D OUTPUT -p tcp --dport 1935 -j REDIRECT
|
||||||
|
|
||||||
|
###Finally, Download the Precious Video### Now paste that command you copied
|
||||||
|
from the rtmpsrv output in the step before last into your terminal prompt and
|
||||||
|
hit enter. You should now see a torrent of `INFO` printout along with a
|
||||||
|
percentage as the video is being downloaded.
|
||||||
|
|
||||||
|
###Feast Eyes on Precious Video### Once downloaded, the video file, which has a
|
||||||
|
`flv` extension and was named by the `-o` parameter in the command you copied
|
||||||
|
and pasted, should be in your current directory (`ls | grep flv` can find it as
|
||||||
|
well). Any video player should be able to play it, but vlc is a nice video
|
||||||
|
player for Ubuntu.
|
||||||
|
|
||||||
|
You're welcome.
|
122
_posts/2013-04-26-hackers.md
Normal file
122
_posts/2013-04-26-hackers.md
Normal file
@ -0,0 +1,122 @@
|
|||||||
|
---
|
||||||
|
title: Hackers
|
||||||
|
layout: post
|
||||||
|
---
|
||||||
|
|
||||||
|
*The following is a non-fiction essay I wrote for my* ENGH 396: Intro to
|
||||||
|
Creative Writing *class. I decided to write about my experience with
|
||||||
|
discovering and getting involved with the eccentric community of hackers that I
|
||||||
|
met since the past two internships I've had at [Valti](https:/www.valti.com/)
|
||||||
|
and [Humbug](https://humbughq.com/) in Cambridge, Massachusetts. Seeing as it
|
||||||
|
encapsulated what I've learned culturally since then, I decided to post it here
|
||||||
|
as well.*
|
||||||
|
|
||||||
|
Hackers -- not your malicious meddling Hollywood-style speed-typists -- but the
|
||||||
|
type who sees a toaster and turns it into a computer capable of etching emails
|
||||||
|
into the crispy surface of toast. Those who would create a programming language
|
||||||
|
consisting exclusively of expletives and then use it to filter out offensive
|
||||||
|
words from websites just for the irony. They would never steal a password or
|
||||||
|
cause any harm -- unless, perhaps, you gave them a powerful rocket and a bad
|
||||||
|
idea. Their curiosity leaves them with a burning desire to break all
|
||||||
|
assumptions and to answer "what if" questions as if they were a challenge to
|
||||||
|
their very existence.
|
||||||
|
|
||||||
|
My personal foray within the realm of hackers began with Boston. I had snagged
|
||||||
|
an internship with a startup called Valti started by a couple of Harvard
|
||||||
|
students who wanted to create an online platform that enabled college students
|
||||||
|
to exchange dresses. Startup businesses are dime a dozen in the hacker culture.
|
||||||
|
With so many wild ideas going around, every once in a while a profitable one
|
||||||
|
comes by. Hackers despise cubicles and big corporations, so starting their own
|
||||||
|
company on their own rules is the usual course of action.
|
||||||
|
|
||||||
|
While Harvard's snobby atmosphere put me off, MIT seemed to call out to the
|
||||||
|
hacker within me. Now, MIT is arguably the birthplace of the hacker, so when I
|
||||||
|
say that I was thrown into the thick of the hacker culture all at once, it is
|
||||||
|
no over-exaggeration. This is the place where people would regularly discuss
|
||||||
|
mathematical and computer science theories over a casual lunch with each other.
|
||||||
|
Computer Science is the de facto "undecided" major at MIT. You would be
|
||||||
|
hard-pressed to find a student who didn’t know their way around a Linux
|
||||||
|
terminal. Now imagine the computer club of such a university.
|
||||||
|
|
||||||
|
The Student Information Processing Board, or SIPB for short, was at least one
|
||||||
|
such computer club of MIT that I began to get involved with. This club, which
|
||||||
|
was established in the 60s, packaged their own operating system and distributed
|
||||||
|
computing environment called Project Athena that was good enough that the
|
||||||
|
university installed it on all of their computers. The members were laughably
|
||||||
|
out of my league in terms of computer science experience; I would find myself
|
||||||
|
regularly searching Wikipedia for every other word they would mention while in
|
||||||
|
a heated discussion concerning some technology. But, what surprised me the most
|
||||||
|
was not the depth of their knowledge, but the breadth; each of them seemed to
|
||||||
|
have an unlimited capacity for various trivial tidbits of knowledge from the
|
||||||
|
etymology of words to the physics of the universe. Being around that kind of
|
||||||
|
intelligence was fascinating, while at the same time frustrating, since it was
|
||||||
|
often hard to follow.
|
||||||
|
|
||||||
|
Whenever I wasn't building the website for Valti, I was out in the city going
|
||||||
|
to various meetups to meet people and learn about new upcoming technologies.
|
||||||
|
This was a totally new world for me. Hackers didn't exist in high school, they
|
||||||
|
were just those weird nerds in the computer classes. And, even at George Mason,
|
||||||
|
there still wasn't the same atmosphere of ingenuity as in Boston that gave me
|
||||||
|
the motivation to want to change the world. I had the feeling most CS students
|
||||||
|
at Mason were only there for the degree just so they could go work at some
|
||||||
|
boring government contractor in DC when they graduated. After seeing the hacker
|
||||||
|
culture in Boston, that type of job seemed like death to me.
|
||||||
|
|
||||||
|
Hackers, a world-wide amorphous group of people who enjoy discussing (and
|
||||||
|
arguing) various topics, naturally congregate among sites like Slashdot,
|
||||||
|
Reddit, and Hacker News (often abbreviated to HN -- hackers, much like the
|
||||||
|
military, are fond of their abbreviations) to get quick syndicated news and to
|
||||||
|
have large in-depth discussions in the comments. Locally, there are groups that
|
||||||
|
meet to discuss certain technologies or set up spaces where hackers can easily
|
||||||
|
build prototypes (usually referred to as "hackerspaces"). Unsurprisingly, the
|
||||||
|
hubs for these local communities are usually centered around cities that are
|
||||||
|
hosts to major computer science universities: San Fransisco, Boston, New York,
|
||||||
|
etc.
|
||||||
|
|
||||||
|
Their awareness of the languages they use and their fondness of breaking beyond
|
||||||
|
the norm lends hackers a great affinity to the game of word play, and thus they
|
||||||
|
have created their own lexicon of slang that borrows much from the jargon of
|
||||||
|
computer science. "Foobar," "grok," "cruft," "distro," "kluge," "phreaking,"
|
||||||
|
the words that are common knowledge among those already within the society put
|
||||||
|
a barrier in front of those like me looking to understand the culture.
|
||||||
|
|
||||||
|
Many of the students I met at MIT use a chat protocol called Zephyr as cross
|
||||||
|
between email and instant messaging to communicate with each other. Zephyr was
|
||||||
|
created in the 80’s as one of the first instant-messaging systems (the other,
|
||||||
|
more popular protocol being IRC), and, because of the culture surrounding the
|
||||||
|
program, it is still widely used at the university. "Zephyrisms" have developed
|
||||||
|
over the years to aid in simplifying communication. For example, "==" is used
|
||||||
|
to indicate agreement and "++" is used by what would probably be the equivalent
|
||||||
|
to a "Like" on Facebook. Both can find their parallels as symbols used in many
|
||||||
|
programming languages, the former for equality and the later for incrementing
|
||||||
|
an integer by one. Other more obscure zephyrisms include "starking," or
|
||||||
|
reviving an old thread of conversation, "prnf" which stands for "Pseudo-Random
|
||||||
|
Neuron Firings", and "i, i" which would mean "I have no point here, I just like
|
||||||
|
saying" and would usually prefix some snarky comment in reply to an otherwise
|
||||||
|
serious thread of conversation (some people would just omit the "i, i" and put
|
||||||
|
quotes around said snarky comment instead). Even though these zephyrisms seemed
|
||||||
|
completely arbitrary to me when I first encountered them, after a while of use
|
||||||
|
they came to me naturally, and I would even accidentally use them outside
|
||||||
|
Zephyr to the confusion of my friends. It was easy to see how such conventions
|
||||||
|
of speech developed originally.
|
||||||
|
|
||||||
|
The Free Software Foundation (FSF), which advocates for free, open-source,
|
||||||
|
non-proprietary software (free as in "free speech," not "free beer"), is based
|
||||||
|
in Boston and is one of the focal points of the hacker culture. The president,
|
||||||
|
Richard Stallman (who is often referred to as RMS), a big, heavily bearded
|
||||||
|
fellow, is particularly legendary in the community. Being nearly militant about
|
||||||
|
the goals of FSF, he refuses to use software that contains any proprietary code
|
||||||
|
at all: no cellphone, only uses a laptop developed completely open-source,
|
||||||
|
doesn’t use a browser to view the internet, and even refuses to use a key card,
|
||||||
|
which makes it difficult for him to get into his office at MIT. Though often
|
||||||
|
painfully stubborn about his ideas, he is the ultimate activist for hackers:
|
||||||
|
making sure the government and big corporations do not misuse people's
|
||||||
|
information or kill off the hacker culture.
|
||||||
|
|
||||||
|
While nowadays I like to call myself an aspiring hacker, I’m not so sure I
|
||||||
|
could ever match the intelligence and indestructible curiosity of those that I
|
||||||
|
met in Boston. Perhaps it is their unique culture of constantly questioning the
|
||||||
|
norm and striving for knowledge of the world around them that allows them to
|
||||||
|
transcend into true hackerdom. Either way, I now know never to tell a hacker
|
||||||
|
that something is impossible, because they will surely find a way to prove me
|
||||||
|
wrong.
|
67
_posts/2013-05-19-gmu-bookstore-homepage-concept.md
Normal file
67
_posts/2013-05-19-gmu-bookstore-homepage-concept.md
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
---
|
||||||
|
title: GMU Bookstore Homepage Concept and Staw Dispensers
|
||||||
|
layout: post
|
||||||
|
---
|
||||||
|
|
||||||
|
I have finally finished my second year of college. Now that finals are over, I
|
||||||
|
can post about some of the things I have been working on. First, a front-end I
|
||||||
|
made with a group in my [*SWE 205 : Software Usability Analysis and
|
||||||
|
Design*](http://www.cs.gmu.edu/~offutt/classes/205/) class. The assignment was
|
||||||
|
to create a homepage for the University's bookstore website, applying all of the
|
||||||
|
usability principles we had learned over the semester. I ended up working on it
|
||||||
|
when I wanted to procrastinate on assignments in my other classes, so I put
|
||||||
|
quite a bit of effort into it.
|
||||||
|
|
||||||
|
See it here: [swe205.hallada.net](http://swe205.hallada.net)
|
||||||
|
<div style="text-align: center">
|
||||||
|
<a href="http://swe205.hallada.net" alt="See it in action">
|
||||||
|
<img src="/static/img/gmu_bookstore_preview.jpg">
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
<br>
|
||||||
|
|
||||||
|
You can see all the code for it [up on my
|
||||||
|
GitHub](https://github.com/thallada/gmu-bookstore-concept).
|
||||||
|
|
||||||
|
Our group researched other university bookstore websites to get some ideas and
|
||||||
|
we liked the layout of [Virginia Tech's](http://www.bookstore.vt.edu/) (but
|
||||||
|
hated the colors). We liked how everything needed was presented immediately
|
||||||
|
upfront in a Windows 8 metro-esque grid.
|
||||||
|
|
||||||
|
Since the main feature of the site was a grid and I was already familiar with it
|
||||||
|
I used [Twitter Bootstrap](http://twitter.github.io/bootstrap/) to help with the
|
||||||
|
CSS. Bootstrap also helped make the design responsive and look nice on mobile
|
||||||
|
phones (try resizing your window to see it in action). I also used the
|
||||||
|
[Bootstrap modal](http://twitter.github.io/bootstrap/javascript.html#modals) for
|
||||||
|
the "Contact Us" form which is activated by the link in the footer of the page.
|
||||||
|
However, I had to modify it quite a bit to make sure it was fully usable and
|
||||||
|
would prompt the user before they closed out of the modal with text entered.
|
||||||
|
|
||||||
|
Overall, this was a fun project to end off a very fun and interesting course. I
|
||||||
|
highly recommend any one at GMU to take this course with Prof. Offutt even if
|
||||||
|
they don't plan on being web designers. I have come away from the class with not
|
||||||
|
only the principles for making usable web interfaces but also a habit of
|
||||||
|
analyzing nearly any interface in the real-world.
|
||||||
|
|
||||||
|
For example, I noticed the other day while getting food in the [Johnson
|
||||||
|
Center](http://jcweb.gmu.edu/) that they had installed a [new paper-less straw
|
||||||
|
dispenser](http://i.imgur.com/s9olzcg.jpg). When I first encountered it, I
|
||||||
|
didn't know how to operate it (and at the time there was no sign to tell me
|
||||||
|
how). Since there seemed to be a chute at the bottom of the contraption, I
|
||||||
|
figured there must be a way to get a straw to drop down into it, but the
|
||||||
|
dispenser didn't give any hints to how to do that. The knobs on the side had
|
||||||
|
looked purely decorative to me. Giving up, I opened the top of the dispenser and
|
||||||
|
grabed a straw from the pile of them, cursing the whole thing for it's bad
|
||||||
|
usability.
|
||||||
|
|
||||||
|
The next day I came by for food again, and I noticed that it now had a sign
|
||||||
|
instructing everyone to not do exactly what I had done the other day: "Do Not
|
||||||
|
Open. Just turn knob". More people than just I must have been perplexed by this
|
||||||
|
dispenser. As Offutt had said countless times in class before: if a interface
|
||||||
|
requires a manual then it has failed.
|
||||||
|
|
||||||
|
It's the little things, like the straw dispensers that no one knows how to use,
|
||||||
|
that you begin to notice after taking SWE 205. It's both a blessing and curse.
|
||||||
|
Bad interfaces drive me insane, and to my frustration I notice them everywhere
|
||||||
|
now. But, at least know the most basic things to avoid in the interfaces I
|
||||||
|
design now.
|
90
_posts/2013-06-04-w3m-reddit.md
Normal file
90
_posts/2013-06-04-w3m-reddit.md
Normal file
@ -0,0 +1,90 @@
|
|||||||
|
---
|
||||||
|
title: w3m-reddit
|
||||||
|
layout: post
|
||||||
|
---
|
||||||
|
|
||||||
|
I've been moving a lot of my daily tasks to the command-line lately, and that
|
||||||
|
includes redditing. I probably spend far too much time on
|
||||||
|
[reddit](http://reddit.com) as it is, but I really wanted to find an efficient
|
||||||
|
way to view reddit through the command-line. [w3m](http://w3m.sourceforge.net/)
|
||||||
|
could render reddit okay, but I couldn't view my personal front-page because
|
||||||
|
that required me to login to my profile.
|
||||||
|
|
||||||
|
The solution was [cortex](http://cortex.glacicle.org/), a CLI app for viewing
|
||||||
|
reddit.
|
||||||
|
|
||||||
|
However, I kind of got tired of viewing reddit through w3m, the header alone is
|
||||||
|
a few pages long to scroll through, and the CSS for the comments doesn't load so
|
||||||
|
there isn't any sense of threading. But, then I discovered reddit's mobile
|
||||||
|
website: [http://m.reddit.com](http://m.reddit.com), and it looks absolutely
|
||||||
|
beautiful in w3m. In fact, I think I prefer it to the normal website in any
|
||||||
|
modern browser; there are no distractions, just pure content.
|
||||||
|
|
||||||
|
<a href="/static/img/w3m_mobile_reddit.png"><img src="/static/img/w3m_mobile_reddit.png" alt="m.reddit.com rendered in w3m"></a>
|
||||||
|
|
||||||
|
In order to get cortex to open the mobile version of reddit, I made a bash
|
||||||
|
script wrapper around w3m that takes urls and replaces `"http://reddit.com"` and
|
||||||
|
`"http://www.reddit.com"` with `"http://m.reddit.com"` before passing them to
|
||||||
|
w3m (as well as fixing a double forward slash error in the comment uri cortex
|
||||||
|
outputs that desktop reddit accepts but mobile reddit 404s on). The script:
|
||||||
|
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
args=()
|
||||||
|
until [ -z "$1" ]; do
|
||||||
|
case "$1" in
|
||||||
|
-t|--tmux) t=1; shift ;;
|
||||||
|
--) shift ; break ;;
|
||||||
|
-*) echo "invalid option $1" 1>&2 ; shift ;; # or, error and exit 1 just like getopt does
|
||||||
|
*) args+=("$1") ; shift ;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
args+=("$@")
|
||||||
|
for arg in "${args[@]}" ; do
|
||||||
|
# Switch to mobile reddit
|
||||||
|
url=${arg/http:\/\/reddit.com/http:\/\/m.reddit.com}
|
||||||
|
url=${url/http:\/\/www.reddit.com/http:\/\/m.reddit.com}
|
||||||
|
# Fix double backslash error in comment uri for mobile reddit
|
||||||
|
url=${url/\/\/comments/\/comments}
|
||||||
|
if [[ $t == "1" ]]; then
|
||||||
|
tmux new-window 'w3m "'${url}'"'
|
||||||
|
else
|
||||||
|
w3m "${url}"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
Since I regurally use [Tmux](http://tmux.sourceforge.net/) (with
|
||||||
|
[Byobu](http://byobu.co/)), I also added an optional `-t`/`--tmux` switch that
|
||||||
|
will open w3m in a temporary new tmux window that will close when w3m is closed.
|
||||||
|
|
||||||
|
I saved the script as `w3m-reddit` and made it an executable command. In Ubuntu
|
||||||
|
that's done with the following commands:
|
||||||
|
|
||||||
|
$ sudo mv w3m-reddit /usr/bin/
|
||||||
|
$ sudo chmod +x /usr/bin/w3m-reddit
|
||||||
|
|
||||||
|
Now cortex needs to be configured to use `w3m-reddit`, and that's done by
|
||||||
|
setting `browser-command` in the cortex config at `~/.cortex/config` to
|
||||||
|
`w3m-reddit`:
|
||||||
|
|
||||||
|
## Command to invoke the webbrowser
|
||||||
|
## If left empty will try to autodetect the system default browser
|
||||||
|
##browser-command=firefox '{0}'
|
||||||
|
browser-command=w3m-reddit '{0}'
|
||||||
|
|
||||||
|
The result is a distraction-free reddit experience right in the command-line
|
||||||
|
without having to edit cortex directly. I've found that I even prefer reddit
|
||||||
|
this way. Without image thumbnails (I need to explicitly select the image links
|
||||||
|
to view the image in w3m) I am more inclined to pay equal attention to every
|
||||||
|
post, not just mindlessly scrolling through meme-fests. Thus I'm more focused
|
||||||
|
and tend to not loose myself like I do in the infinite scrolling of [RES
|
||||||
|
reddit](http://redditenhancementsuite.com/) in a GUI browser.
|
||||||
|
|
||||||
|
There are still some improvements I could make to the w3m-reddit script. Namely,
|
||||||
|
it should pass along any arguments to itself to w3m underneath. I'm still a
|
||||||
|
newby at bash though, and I couldn't figure out an easy way to do that without
|
||||||
|
scrapping the whole thing and starting over in Python instead.
|
||||||
|
|
||||||
|
Stay tuned for more posts on how I view images and videos efficiently from the
|
||||||
|
command-line.
|
149
_posts/2013-07-10-quick-command-line-search-search-pane.md
Normal file
149
_posts/2013-07-10-quick-command-line-search-search-pane.md
Normal file
@ -0,0 +1,149 @@
|
|||||||
|
---
|
||||||
|
title: "Quick Command-line Search: search-pane"
|
||||||
|
layout: post
|
||||||
|
---
|
||||||
|
|
||||||
|
It's been a while since I last wrote, but I've still been busy. I began my
|
||||||
|
research position at the [MIT Media Lab](http://media.mit.edu) working with
|
||||||
|
[Fluid Interfaces](http://fluid.media.mit.edu). It feels like I'm designing the
|
||||||
|
future; I really couldn't ask for a better job right now. But, more on that
|
||||||
|
later.
|
||||||
|
|
||||||
|
I've still been continuously refining my workspace, and how I use my laptop. As
|
||||||
|
I mentioned in my [last blog post](/blog/w3m-reddit), I've been moving more and more towards the
|
||||||
|
command-line for day-to-day operations because of it's unparalleled level of
|
||||||
|
customizability and compatibility with other programs. There's nothing more
|
||||||
|
powerful than being able to whip up a small python or bash script that interacts
|
||||||
|
with a couple of other programs to achieve something instantly that optimizes my
|
||||||
|
work flow.
|
||||||
|
|
||||||
|
I use the [Awesome](http://awesome.naquadah.org/) window manager, which works
|
||||||
|
great for tiling up terminal windows right up next to browser windows. However,
|
||||||
|
I also use [Byobu](http://byobu.co/) (which uses
|
||||||
|
[tmux](http://tmux.sourceforge.net) as a backend), practically a tiling window
|
||||||
|
manager for terminals. While working with a whole bunch of terminals, I've found
|
||||||
|
that I actually prefer using byobu panes over separate terminal windows under
|
||||||
|
awesome.
|
||||||
|
|
||||||
|
I'm pretty sure I clock in somewhere at three to five Google searches a minute
|
||||||
|
when really focused on a programming task, especially when I'm working with
|
||||||
|
something I'm unfamiliar with. Historically, I've done this by switching tags in
|
||||||
|
awesome to my web browser and then searching in the Google Chrome omni-bar. It
|
||||||
|
required me to leave the context of my code and then flip back and forth between
|
||||||
|
code and browser if I needed to reference anything.
|
||||||
|
|
||||||
|
My new-found love of w3m's compact nature led me to design the perfect search
|
||||||
|
program for my setup. I dubbed it the generic name: search-pane, and it does the
|
||||||
|
following:
|
||||||
|
|
||||||
|
* Very light-weight interface for inputing a search query that is fed directly
|
||||||
|
to w3m in a Google search.
|
||||||
|
* Byobu/Tmux key bindings to open a new window for search that closes on quit.
|
||||||
|
* Byobu/Tmux bindings to open in a quick one-off vertical or horizontal pane.
|
||||||
|
* Search history. Just like the bash shell, press up to cycle through past
|
||||||
|
searches.
|
||||||
|
* Global history. When a search is performed on one computer using search-pane,
|
||||||
|
the search is added not only to that computer's history, but the history of
|
||||||
|
any computer listed in the other-hosts config file. I'm often sshed into many
|
||||||
|
different machines, so this feature was a big plus for me.
|
||||||
|
* Vim keybindings to open up the search for even quicker access.
|
||||||
|
|
||||||
|
This is how I got it setup (on any Ubuntu machine with sudo privileges):
|
||||||
|
|
||||||
|
Save the following python file in `/usr/bin/` as `search-pane` (no extension):
|
||||||
|
|
||||||
|
#!/usr/bin/python
|
||||||
|
from subprocess import call, check_output
|
||||||
|
from threading import Thread
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
import readline
|
||||||
|
|
||||||
|
home = os.path.expanduser("~")
|
||||||
|
histfile = os.path.join(home, ".search-pane/history")
|
||||||
|
|
||||||
|
# load history
|
||||||
|
readline.read_history_file(histfile)
|
||||||
|
|
||||||
|
os.system('cls' if os.name=='nt' else 'clear') # clear the terminal
|
||||||
|
|
||||||
|
url = ''
|
||||||
|
query = ''
|
||||||
|
if len(sys.argv) > 1:
|
||||||
|
url = "http://google.com/search?q=" + '+'.join(sys.argv[1:]) # google url
|
||||||
|
query = ' '.join(sys.argv[1:])
|
||||||
|
readline.add_history(query) # add query to history buffer
|
||||||
|
else:
|
||||||
|
try:
|
||||||
|
query = raw_input('Search: ') # get user's search
|
||||||
|
url = "http://google.com/search?q=" + '+'.join(query.split()) # google
|
||||||
|
except KeyboardInterrupt:
|
||||||
|
sys.exit(0)
|
||||||
|
|
||||||
|
readline.write_history_file(histfile) # write search to history file
|
||||||
|
|
||||||
|
def write_other_hosts():
|
||||||
|
# write to history files on other registered hosts
|
||||||
|
with open(os.devnull, 'w') as FNULL:
|
||||||
|
with open(os.path.join(home, ".search-pane/other-hosts"), "r") as f:
|
||||||
|
for line in f:
|
||||||
|
line = line.strip().split()
|
||||||
|
host = line[0]
|
||||||
|
path = line[1]
|
||||||
|
# make sure we don't write to local file again
|
||||||
|
client_names = check_output(['hostname', '-A']).split()
|
||||||
|
if (host.split('@')[-1] not in client_names):
|
||||||
|
call(['ssh', host, 'echo', '"' + query + '"', '>>', path],
|
||||||
|
stderr=FNULL)
|
||||||
|
|
||||||
|
# Spin off another thread for sshing so user doesn't have to wait for
|
||||||
|
# connection to complete before viewing w3m.
|
||||||
|
try:
|
||||||
|
Thread(target=write_other_hosts).start()
|
||||||
|
except Exception, errtxt:
|
||||||
|
print errtxt
|
||||||
|
|
||||||
|
call(['w3m', url]) # pass url off to w3m
|
||||||
|
|
||||||
|
Make the directory and file for search history:
|
||||||
|
|
||||||
|
mkdir ~/.search-pane
|
||||||
|
touch ~/.search-pane/history
|
||||||
|
|
||||||
|
Allow anyone to execute the python script (make it into a program):
|
||||||
|
|
||||||
|
chmod a+x /usr/bin/search-pane
|
||||||
|
|
||||||
|
To get quick access to the program from the command-line edit `~/.bashrc` to
|
||||||
|
add:
|
||||||
|
|
||||||
|
alias s='search-pane'
|
||||||
|
|
||||||
|
To add byobu key bindings edit `~/.byobu/keybindings.tmux` (or `/usr/share/byobu/keybindings/f-keys.tmux`):
|
||||||
|
|
||||||
|
# thallada's keybindings:
|
||||||
|
bind-key Enter new-window -n "search" "search-pane"
|
||||||
|
bind-key - split-window -v -p 20 "search-pane"
|
||||||
|
bind-key = split-window -h -p 30 "search-pane"
|
||||||
|
|
||||||
|
To add vim key bindings edit ~/.vimrc
|
||||||
|
|
||||||
|
"Open google search in a tmux split beneath vim
|
||||||
|
map <leader>g :silent !tmux split-window -v -p 20 "search-pane"<CR>
|
||||||
|
|
||||||
|
If you wish to add the functionality to other machines then follow the steps
|
||||||
|
above and, on every machine, add the other hosts and the paths to the
|
||||||
|
search-pane history files on each to the other-hosts file:
|
||||||
|
|
||||||
|
vi ~/.search-pane/other-hosts
|
||||||
|
|
||||||
|
The syntax is:
|
||||||
|
|
||||||
|
user@host /path/to/history
|
||||||
|
|
||||||
|
Host separated by path by a space.
|
||||||
|
|
||||||
|
So far it's been really useful, and since it doesn't screw up my focus as much
|
||||||
|
I'm searching more.
|
||||||
|
|
||||||
|
Also, wow python is a lot easier than bash for these sorts of things...
|
47
_posts/2013-08-24-on-chromebooks.md
Normal file
47
_posts/2013-08-24-on-chromebooks.md
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
---
|
||||||
|
title: On Chromebooks
|
||||||
|
layout: post
|
||||||
|
---
|
||||||
|
|
||||||
|
I like to think that if only I find The Perfect Text Editor I will somehow
|
||||||
|
write better and more often. Obviously this is only a tactic I use to delay
|
||||||
|
actually writing anything, but I did come across something that might actually
|
||||||
|
help. [Draft](https://draftin.com) is a writing app being developed by one guy,
|
||||||
|
[Nate Kontny](https://twitter.com/natekontny), that has a ton of nifty
|
||||||
|
features, one of its best being a version control system that allows you to
|
||||||
|
send a draft to other people and accept or reject any changes they suggest. It
|
||||||
|
also has a minamilistic iA Writer type interface, which focuses on the actual
|
||||||
|
writing and nothing more.
|
||||||
|
|
||||||
|
One of my most favorite features that I have just discovered, though, is that
|
||||||
|
it allows publishing any Draft document to any arbitrary
|
||||||
|
[WebHook](http://en.wikipedia.org/wiki/Webhook). Which basically means I can
|
||||||
|
click a button in the interface and that will send a POST request to a URL I
|
||||||
|
specify with all of the data for my Draft document in JSON format. I can just
|
||||||
|
write a bit of code to parse that data and then I instantly have a better
|
||||||
|
editor for my blog.
|
||||||
|
|
||||||
|
It was really easy to do too. For this Django website, all it took [was adding
|
||||||
|
a view that parsed a JSON object and made a blog entry out of
|
||||||
|
it](https://github.com/thallada/personalsite/commit/c4694a6669dbc7b79a5bff3fb818a682ecacffbb).
|
||||||
|
You can read the
|
||||||
|
[documentation](https://draftin.com/documents/69898?token=5fjKKlZ0-AeBzqj_RAftAGdzRzl9VBfBHj5wpSWm_gU)
|
||||||
|
for more info on how to make a WebHook for Draft.
|
||||||
|
|
||||||
|
Nate has also made a lot of other neat features, like a [Chrome extension that
|
||||||
|
turns any textarea on the web into a Draft
|
||||||
|
document](https://chrome.google.com/webstore/detail/draft/amlbbbgcijmiooecobhkjblcdkjldmdk).
|
||||||
|
Read about some of the other features in the [Lifehacker
|
||||||
|
article](http://lifehacker.com/5993339/draft-is-a-writing-app-with-serious-version-and-draft-control).
|
||||||
|
The app is still in development and new features are being added constantly.
|
||||||
|
|
||||||
|
I think the take-away here is that the Big Guys, with apps like Google Drive or
|
||||||
|
Evernote, don't always have the best solutions. I tried hacking Google Drive
|
||||||
|
into a more immersive writing experience with templates and so on, but nothing
|
||||||
|
came close to the experience of Draft, which was exactly what I wanted to begin
|
||||||
|
with. It's a wonder that more people don't know about Draft, but I guess that's
|
||||||
|
part of the magic. There's a real person, an innovative and driven hacker,
|
||||||
|
behind the product who might actually listen to what I have to say.
|
||||||
|
|
||||||
|
Now excuse me while I go waste more time scouring the web for more obscure but
|
||||||
|
brilliant apps.
|
47
_posts/2013-10-03-publishing-draft-docs-to-my-blog.md
Normal file
47
_posts/2013-10-03-publishing-draft-docs-to-my-blog.md
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
---
|
||||||
|
title: Publishing Draft Docs to my Blog
|
||||||
|
layout: post
|
||||||
|
---
|
||||||
|
|
||||||
|
I like to think that if only I find The Perfect Text Editor I will somehow
|
||||||
|
write better and more often. Obviously this is only a tactic I use to delay
|
||||||
|
actually writing anything, but I did come across something that might actually
|
||||||
|
help. [Draft](https://draftin.com) is a writing app being developed by one guy,
|
||||||
|
[Nate Kontny](https://twitter.com/natekontny), that has a ton of nifty
|
||||||
|
features, one of its best being a version control system that allows you to
|
||||||
|
send a draft to other people and accept or reject any changes they suggest. It
|
||||||
|
also has a minamilistic iA Writer type interface, which focuses on the actual
|
||||||
|
writing and nothing more.
|
||||||
|
|
||||||
|
One of my most favorite features that I have just discovered, though, is that
|
||||||
|
it allows publishing any Draft document to any arbitrary
|
||||||
|
[WebHook](http://en.wikipedia.org/wiki/Webhook). Which basically means I can
|
||||||
|
click a button in the interface and that will send a POST request to a URL I
|
||||||
|
specify with all of the data for my Draft document in JSON format. I can just
|
||||||
|
write a bit of code to parse that data and then I instantly have a better
|
||||||
|
editor for my blog.
|
||||||
|
|
||||||
|
It was really easy to do too. For this Django website, all it took [was adding
|
||||||
|
a view that parsed a JSON object and made a blog entry out of
|
||||||
|
it](https://github.com/thallada/personalsite/commit/c4694a6669dbc7b79a5bff3fb818a682ecacffbb).
|
||||||
|
You can read the
|
||||||
|
[documentation](https://draftin.com/documents/69898?token=5fjKKlZ0-AeBzqj_RAftAGdzRzl9VBfBHj5wpSWm_gU)
|
||||||
|
for more info on how to make a WebHook for Draft.
|
||||||
|
|
||||||
|
Nate has also made a lot of other neat features, like a [Chrome extension that
|
||||||
|
turns any textarea on the web into a Draft
|
||||||
|
document](https://chrome.google.com/webstore/detail/draft/amlbbbgcijmiooecobhkjblcdkjldmdk).
|
||||||
|
Read about some of the other features in the [Lifehacker
|
||||||
|
article](http://lifehacker.com/5993339/draft-is-a-writing-app-with-serious-version-and-draft-control).
|
||||||
|
The app is still in development and new features are being added constantly.
|
||||||
|
|
||||||
|
I think the take-away here is that the Big Guys, with apps like Google Drive or
|
||||||
|
Evernote, don't always have the best solutions. I tried hacking Google Drive
|
||||||
|
into a more immersive writing experience with templates and so on, but nothing
|
||||||
|
came close to the experience of Draft, which was exactly what I wanted to begin
|
||||||
|
with. It's a wonder that more people don't know about Draft, but I guess that's
|
||||||
|
part of the magic. There's a real person, an innovative and driven hacker,
|
||||||
|
behind the product who might actually listen to what I have to say.
|
||||||
|
|
||||||
|
Now excuse me while I go waste more time scouring the web for more obscure but
|
||||||
|
brilliant apps.
|
@ -1,24 +0,0 @@
|
|||||||
---
|
|
||||||
layout: post
|
|
||||||
title: "Welcome to Jekyll!"
|
|
||||||
date: 2014-04-24 18:53:43
|
|
||||||
categories: jekyll update
|
|
||||||
---
|
|
||||||
|
|
||||||
You'll find this post in your `_posts` directory - edit this post and re-build (or run with the `-w` switch) to see your changes!
|
|
||||||
To add new posts, simply add a file in the `_posts` directory that follows the convention: YYYY-MM-DD-name-of-post.ext.
|
|
||||||
|
|
||||||
Jekyll also offers powerful support for code snippets:
|
|
||||||
|
|
||||||
{% highlight ruby %}
|
|
||||||
def print_hi(name)
|
|
||||||
puts "Hi, #{name}"
|
|
||||||
end
|
|
||||||
print_hi('Tom')
|
|
||||||
#=> prints 'Hi, Tom' to STDOUT.
|
|
||||||
{% endhighlight %}
|
|
||||||
|
|
||||||
Check out the [Jekyll docs][jekyll] for more info on how to get the most out of Jekyll. File all bugs/feature requests at [Jekyll's GitHub repo][jekyll-gh].
|
|
||||||
|
|
||||||
[jekyll-gh]: https://github.com/mojombo/jekyll
|
|
||||||
[jekyll]: http://jekyllrb.com
|
|
Loading…
Reference in New Issue
Block a user