Permalink
Browse files

Take two. I'm no longer a script. I'm a class now. I'm all growned up…

…. And I'm infinitely extensible -- I've got plugins now. I hope you like me.
  • Loading branch information...
1 parent dc99598 commit 86ed3b5e185ea9f1666ae3f4ab601f1b569b8dd7 @scottjacksonx committed Jun 17, 2010
View
@@ -12,11 +12,11 @@
-- *Annabel Scheme*, by Robin Sloan.
-HUGIN-19.LG.GRAILGRID.NET (a.k.a. Hu) is the narrator of Robin Sloan's *Annabel Scheme*. In the section above, we see the kinds of things that Hu, an AI Watson to Scheme's Holmes, is capable of doing and recording.
+HUGIN-19.LG.GRAILGRID.NET (a.k.a. Hu) is the narrator of Robin Sloan's *Annabel Scheme*. In the excerpt above, we see the kinds of things that Hu, an AI Watson to Scheme's Holmes, is capable of doing and recording.
-**I want to make Hu.** A rudimentary version of Hu, sure, but Hu nonetheless. Every ten minutes, I want my computer to take a snapshot of what's going on -- what time it is, what software I have open, what websites I'm looking at, how many unread emails I have, what music I've been listening to, which files are open, how long/big those files are (to track my work's progress), what the weather's like, what I've eaten (via services like Daytum), etc. From there, I can look at trends, graph things, measure things, and try to spot patterns.
+**I am making Hu.** A rudimentary version of Hu, sure, but Hu nonetheless. Every ten minutes, I want my computer to take a snapshot of what's going on -- what time it is, what software I have open, what websites I'm looking at, how many unread emails I have, what music I've been listening to, which files are open, how long/big those files are (to track my work's progress), what the weather's like, what I've eaten (via services like Daytum), etc. From there, I can look at trends, graph things, measure things, and try to spot patterns.
-What's more, I want this thing to have a plugin architecture -- after all:
+What's more, Hu has a plugin architecture -- after all:
> *I can interface with anything! I'm infinitely extensible...*
@@ -26,55 +26,34 @@ This is all wishlist stuff, though. Don't get your hopes up too high just yet.
# Using Hu #
-Hu is a little bit delicate at the moment. To use Hu, [download the source](http://github.com/scottjacksonx/hu/zipball/master), change your values at the top of `hu.py` and run `$ python hu.py`. That will run Hu once. To get Hu to run constantly, add `hu.py` to your `crontab`.
+Hu is a little bit delicate at the moment.
-btw, everything Hu captures will be stored in `hu-notes.txt`.
+To use Hu, first [download the source](http://github.com/scottjacksonx/hu/zipball/master). Then, change your values for the various plugins (your last.fm username for the `hu_lastfm` plugin, your location for the `hu_googleweather` plugin, etc.). Finally, run `$ python hu.py`. That will run Hu once.
-# The Potential #
-
-Once Hu has a bunch of information about you, here are the kinds of things you can start to ask:
-
-- What application do I spend the most time in? Find the most commonly occurring application on the "Current application" line.
-- What websites do I visit the most often? Get the most frequently-appearing domain.
-- How does the weather affect the kind of music I listen to? Compare the list of songs you listened to when the weather was "Cloudy" to the songs you listened to when the weather was "Fine."
-- What time of day do I listen to music most at? See how many songs I listened to between 6pm and 12am and compare that number with how many songs I listened to between 9am and 3pm.
-
-At the moment, you have to ask those questions at the command-line using your `sed`, `awk` and `grep` fu. I might make searching and querying Hu a bit easier later on, but until then, you'll have to speak bleep-blorp like a robot.
+# Plugins #
-# Progress #
+Hu has a plugin architecture. Here's how you write a plugin:
-So far, Hu records the following things:
+1. You come up with a name for your plugin. We'll call it `$PLUGIN`. When you see `$PLUGIN` from here on out, substitute your own plugin's name.
+2. You write a python script called `$PLUGIN`.py that contains a definition of a function called `getData()`. You can include other functions, classes or any other kind of code, but you _must_ define a function called `getData()`. `getData()` returns exactly what is recorded in Hu's entry, so it should be XML, complete with newlines (no newline necessary at the end). No tabs/spaces are necessary, since that's carried out from within `hu.py`.
+3. Put `$PLUGIN`.py inside a folder called `$PLUGIN`. The `$PLUGIN` folder lives inside the `hu` folder.
+4. Inside the `$PLUGIN` folder, have a file called `__init__.py`, which contains a single line of code: `import $PLUGIN`
+5. In `hu.py`, at the tippy-top where the plugin declarations are, add an import statement for your plugin similar to the import statements that are already there. It should look like:
-- the current time,
-- what the weather's like,
-- the currently-playing track in iTunes,
-- which application is currently active (i.e. front-most),
-- the name of the wireless network you're currently connected to,
-- recently played tracks on Last.fm,
-- currently opened tabs in Safari.
+ `import $PLUGIN.$PLUGIN`
+ `plugin_modules.append($PLUGIN.$PLUGIN)`
-I've only been working on Hu for a bit, so excuse the short feature list for now.
+That's all there is to it. If you're having any issues, look at how the default plugins (`hu_googleweather`, `hu_openapps`, etc.) work.
-Here's how Hu stores all this stuff, by the way:
-
-
->Wed, 26 May 2010 00:13:52
->Weather: Partly Cloudy, 17c
->Now Playing: The Postal Service - Such Great Heights
->Current Application: Safari
->Connected to: Simon
->
->Recently Played: The Replacements - Bastards of Young | listened at 1274796429
->
->Browser Tab: scottjacksonx's hu at master - GitHub [|] http://github.com/scottjacksonx/hu
->Browser Tab: Tumblr [|] http://www.tumblr.com/dashboard
->Browser Tab: Programming Like It’s 1995 « hackinghat.com [|] http://www.hackinghat.com/index.php/programming/programming-like-its-1995
-
-Just like that. All in a text file. Perfect for putting in, oh, I don't know, a [Dropbox](http://dropbox.com) folder.
+# The Potential #
-# The Future #
+Once Hu has a bunch of information about you, here are the kinds of things you can start to ask:
-I've got a few more things I want to get Hu to record -- the names of all of the open applications in the Dock, for example.
+- What application do I spend the most time in? Find the most commonly occurring frontmost application.
+- What websites do I visit the most often? Get the most frequently-appearing domain.
+- How does the weather affect the kind of music I listen to? Compare the list of songs you listened to when the weather was "Cloudy" to the songs you listened to when the weather was "Fine."
+- What time of day do I listen to music most at? See how many songs I listened to between 6pm and 12am and compare that number with how many songs I listened to between 9am and 3pm.
+At the moment, you have to ask those questions at the command-line using your `sed`, `awk` and `grep` fu. I plan on making searching and querying Hu a bit easier later on, but until then, you'll have to speak bleep-blorp like a robot.
View
170 hu.py
@@ -1,102 +1,82 @@
-import pywapi
-import time
-import datetime
-import pylast as lastfm
-import os
-import commands
+# Plugin declarations
-myLocation = "brisbane,australia"
-myLastFmUsername = "scottjacksonx"
+plugin_modules = []
+import hu_currentlyplaying.hu_currentlyplaying
+plugin_modules.append(hu_currentlyplaying.hu_currentlyplaying)
-def getWeather(location):
- """
- Gets the weather from Google.
- """
- googleWeather = pywapi.get_weather_from_google(location)
- condition = googleWeather['current_conditions']['condition']
- temp = googleWeather['current_conditions']['temp_c']
- return "Weather: " + condition + ", " + temp + "c"
-
-def getCurrentlyPlaying():
- """
- Gets the currently-playing track from iTunes.
- """
- return commands.getoutput("osascript scripts/currentlyPlaying.applescript")
-
-def getRecentTracks(username):
- """
- Gets recently-listened-to tracks from Last.fm
- """
- apiKey = "fd4197bb1bfc8521ced2ba81d70fd812"
- network = lastfm.get_lastfm_network(api_key = apiKey, username = username)
- user = lastfm.User(username, network)
- recentTracks = user.get_recent_tracks(20)
- tracksFromLastTenMinutes = []
- # get rid of any tracks with a play-time earlier than fifteen minutes ago.
-
- for track in recentTracks:
- now = time.time()
- if int(track[2]) + 600 > now: # track was played < 10 minutes (600 seconds) ago.
- tracksFromLastTenMinutes.append(track)
-
- return tracksFromLastTenMinutes
-
-def getOpenBrowserTabs():
- """
- Gets the title and URL of every tab open in the specified web browser.
- """
- return commands.getoutput("osascript scripts/urls.applescript")
-
-def getCurrentApp():
- """
- Gets the name of the front-most application.
- """
- return commands.getoutput("osascript scripts/frontApplication.applescript")
-
-def getCurrentNetworkName():
- """
- Gets the name of the wireless network the computer is currently coneected to.
- """
- return commands.getoutput("/System/Library/PrivateFrameworks/Apple80211.framework/Versions/A/Resources/airport -I|grep \" SSID: \"|cut -c 18-")
+import hu_lastfm.hu_lastfm
+plugin_modules.append(hu_lastfm.hu_lastfm)
-def takeSnapshot():
- """
- Makes a new file named after the timestamp it was created at and records everything that's going on.
+import hu_googleweather.hu_googleweather
+plugin_modules.append(hu_googleweather.hu_googleweather)
+
+import hu_ssidname.hu_ssidname
+plugin_modules.append(hu_ssidname.hu_ssidname)
+
+import hu_openbrowsertabs.hu_openbrowsertabs
+plugin_modules.append(hu_openbrowsertabs.hu_openbrowsertabs)
+
+import hu_openapps.hu_openapps
+plugin_modules.append(hu_openapps.hu_openapps)
+
+# End plugin declarations
+
+import datetime
+import time
+
+class hu:
"""
- # get current time.
- currentTime = int(time.time())
-
- # make and open new file for that time.
- newFile = open("hu-notes.txt", "a")
- newFile.write("\n")
-
- # put time in file
- snapshotTime = str(time.strftime("%a, %d %b %Y %H:%M:%S", time.localtime()))
- newFile.write(snapshotTime + "\n")
-
- # put weather in file.
- newFile.write(getWeather(myLocation) + "\n")
-
- # put current track in file.
- newFile.write("Now Playing: " + str(getCurrentlyPlaying()) + "\n")
+ i'm hu. i'm a big, important class. i watch you and i take notes.
- # put front app in file.
- newFile.write("Current Application: " + str(getCurrentApp()) + "\n")
-
- # put network in file.
- newFile.write("Connected to: " + str(getCurrentNetworkName()) + "\n\n")
+ i hope you like me.
+ """
- tracks = getRecentTracks(myLastFmUsername)
- for track in tracks:
- newFile.write("Recently Played: " + str(track[0]) + " | listened at " + str(track[2]) + "\n")
+ def takeSnapshot(self):
+ """
+ this is the part where i look at all of the things you want me to record.
- newFile.write("\n")
-
- # put current tabs in file.
- newFile.write(str(getOpenBrowserTabs()))
-
- newFile.write("----\n")
-
- newFile.close()
-
-takeSnapshot()
+ i look at the things, take a reading for each of them, and record them.
+
+ hopefully.
+ """
+ snapshot = "<entry time=\""
+ snapshotTime = str(time.strftime("%a, %d %b %Y %H:%M:%S", time.localtime()))
+ snapshot += snapshotTime + "\">\n"
+
+ for plugin in plugin_modules:
+ entryData = plugin.getData()
+ if entryData != "":
+ snapshot += str(entryData + "\n")
+ snapshot += "</entry>"
+ print snapshot
+ return snapshot
+
+
+ def writeSnapshotToLogFile(self, anEntry):
+ """
+ this is the bit where i write the things down in my big book.
+
+ if you want me to write down something secret, it's ok -- i won't tell.
+
+ promise.
+ """
+ try:
+ logFile = open("hu-notes.txt", "r")
+ currentLog = logFile.readlines()
+ logFile.close()
+ except:
+ currentLog = []
+ logFile = open("hu-notes.txt", "w")
+ logFile.write("<hu>\n")
+ for i in range(1, len(currentLog) - 1):
+ logFile.write(currentLog[i])
+ logFile.write(anEntry)
+ logFile.write("\n</hu>")
+ logFile.close()
+
+
+
+
+hu = hu()
+snapshot = hu.takeSnapshot()
+hu.writeSnapshotToLogFile(snapshot)
@@ -0,0 +1 @@
+import hu_currentlyplaying
@@ -0,0 +1,3 @@
+tell application "iTunes"
+ get "<currentlyplaying artist=\"" & artist of current track & "\" title=\"" & name of current track & "\" />"
+end tell
@@ -0,0 +1,10 @@
+import commands
+
+def getData():
+ """
+ gets the currently-playing track from iTunes.
+ """
+ track = commands.getoutput("osascript hu_currentlyplaying/currentlyPlaying.applescript")
+ if track[0:12] == "hu_currently":
+ return ""
+ return track
@@ -0,0 +1 @@
+import hu_googleweather
@@ -0,0 +1,16 @@
+location = "brisbane,australia"
+
+import pywapi
+
+def getData():
+ """
+ gets the weather at the specified location.
+ """
+
+ try:
+ googleWeather = pywapi.get_weather_from_google(location)
+ condition = googleWeather['current_conditions']['condition']
+ temp = googleWeather['current_conditions']['temp_c']
+ return "<weather location=\"" + location + "\" condition=\"" + condition + "\" temp=\"" + temp + "c" + "\"/>"
+ except:
+ return ""
Oops, something went wrong.

0 comments on commit 86ed3b5

Please sign in to comment.