Wednesday, September 24, 2008
Google, T-Mobile and HTC invent English
And its true. England, the US and Australia all want in. So they turn to HTC and T-Mobile to give us a platform to introduce English to the world.
They call together members of the press to announce their darling creation and what do they bring to the stage?
A half retarded, southerner with one leg named Andy. Sure he meets all the requirements; human, vocal cords, at least one eye, some type of self awareness. But something's off, he's not quite there. He talks with a drawl. He takes a bit too long to form sentences and has a slight stutter. He really can't remember all that much. He can sing but is off key unless you provide him with some other piece of equipment. He can't dance but is open to learning. Actually, he can't do much but is always open to learning as long as someone else teaches him. He "shur' as heck ain't gonna'" learn on his own. Oh, and to top it all off T-Mobile won't let him go any further than 1Km from his house without taking his other leg off. (But they'll reattach it at the beginning of the next billing cycle)
Andy, ambassador of English to the World! (I think the World might want to stick to the romantic languages)
This is what "The big G and the pink T" gave us yesterday. Some phone from 2005 with a flashy new interface. What is it about the G1/Dream that HTC needed so much time to develop? Sure the digital compass is new, but other than that it's a smart phone from before there was an iPhone. It seems that they didn't take any ideas from the iPhone at all. Why isn't the Touch HD the android phone? When you preemptively answer the "Why HTC" question in your press conference, you know things aren't going to go over well.
I'm sure the spin machines at those camps will try to say that "Oh, no this is better than the iPhone because it's open and unrestricted.." at first. Then when they get tired of saying that, they'll get angry and start with the "Well, this was never intended to be an iPhone killer."
Another underlying cause of concern for me is that Google didn't stop this train wreck. Either they seem to really be confident and are just treating this like another Google Beta or they don't care. Someone there had to know that this was not a good phone. No one voiced any concern? And to stand on stage, even with all the phone's shortcomings, and tout it as something so great in a post iPhone world is disheartening.
And T-Mobile, unless you have another android phone coming, I really think you've got yourself a Zune to At&t's iPod. Congratulations!
EDIT 9-24-08
T-Mobile has started taking steps in the right direction. They are reducing the 1Gb cap from a hard, fast rule to a reserved right for those that abuse the system. Also, phones after the first shipment will contain a 3.5mm headphone adapter.
Saturday, July 19, 2008
T-Mobile Address Manager export "Hack"
Edit: Thanks to yincrash for pointing out that they changed their namespace on this object to TMO.ABPORTAL.
My friend Candice got a 1st Gen iPhone on the cheap and needed to get her numbers from T-Mobile's new online Address Manager (TAB). It does syncing to and from a regular T-Mobile phone but the iPhone isn't a regular T-Mobile Phone. The app is new and they have a note about it not syncing changes made on the website to the phone yet and either by design or evil plotting there was no way to export the contacts.
My vocation to the rescue! They were using the prototype.js library to run the app and after some digging around I found the data store.TMO.ABPORTAL.ABIHM.ContactManager is the object that manages the contacts' actions and the _datas property is an array of contact javascript objects. So in the firebug console I wrote some code to get the contacts and wrote a csv file to an empty div. I then took that div into Wordpad to get the lines to break correctly on Windows and did an import into Windows Address Book. The rest is history!
Here's the code I used:
var data = ["firstname,lastname,name,homeMobile,homePhone1,homePhone2,workMobile,workPhone1,workPhone2"];
TMO.ABPORTAL.ABIHM.contactManager._datas.each(function(person) {
var a = [];
a.push(person.firstname);
a.push(person.lastname);
a.push(person.name);
a.push(person.homeMobile);
a.push(person.homePhone1);
a.push(person.homePhone2);
a.push(person.workMobile);
a.push(person.workPhone1);
a.push(person.workPhone2);
data.push(a.join(","));
});
$('L_footer_pane').update(data.join('\r\n'));
Tuesday, May 13, 2008
Playing with the Struts 2 Dispatcher
Due to the nature of our permission handling on a project at work I am in need of a way to pass URLs in to the Struts dispatcher and get back the class name and method of the action to invoke (possibly the results as well...). See we have our classes implement a "SecurityAware" interface that returns an array of [OR'd] permission names required to view a page. We also have a permission based menu system that sometimes requires different permissions than the page the menu item points to. I had run into a problem in trying to find all those needed permissions between the database and the source code which was a lot of manual work. So you can see why I'd want to just pass in the URLs from the menu and get the action, call the security method and display the needed permissions for the resulting page.
What I did was start taking a trip through the Struts 2 source and the test classes for an idea of what was going on. I started at the FilterDispatcher since that's the one class that I define and is the starting point of my (any?) Struts2 applications.
The filterDispatcher creates a Dispatcher object. This seems to be the core configuration beast of the system. This has an ActionMapper injected into it. This is where my problems begin.
How are things injected into the FilterDispatcher since I'm "creating" it in the web.xml? There's a ConfigurationManager that is created inside that loads the struts config files and I've had luck printing out parameters that I've set in my struts.xml so I think it's loading correctly. What I'm now having trouble with is the ActionMapper. I'm playing with this in jRuby and I have no idea how to deal with Java5 Generics (I guess I could Google it...) so I took the route of just injecting my created actionMapper.
actionMapper = DefaultActionMapper.new
dispatcher.configurationManager.configuration.container.inject(actionMapper)
This does have an effect in that I can set struts.enable.SlashesInActionNames to true and then call actionMapper.slashesInActionNames? and have the result be true (it defaults to false, so there is a change).
I should mention that I'm running this code in the struts blank example app's WEB-INF/classes directory. I can create a MockServletRequest and pass in URLs that should and shouldn't work. It errors out appropriately when the URL doesn't end with ".action" and I can get it to parse the namespace portion correctly, but I'm having no luck with the Method. For example /example/Login_input.action should result in an ActionMapping with:
- Name: Login_input
- Namespace: /example
- Method: input
Or at least that's what I'm expecting, but I never get anything for the method.
Here's my code so far.
require 'java'
import 'org.apache.struts2.dispatcher.Dispatcher'
import 'org.apache.struts2.dispatcher.FilterDispatcher'
import 'org.apache.struts2.dispatcher.mapper.DefaultActionMapper'
import 'org.springframework.mock.web.MockServletContext'
import 'org.springframework.mock.web.MockFilterConfig'
import 'org.springframework.mock.web.MockHttpServletRequest'
import 'org.springframework.mock.web.MockHttpServletResponse'
filterConfig = MockFilterConfig.new
servletContext = MockServletContext.new
dispatcher = Dispatcher.new(servletContext, {})
dispatcher.init
Dispatcher.instance = dispatcher
actionMapper = DefaultActionMapper.new
dispatcher.configurationManager.configuration.container.inject(actionMapper)
request = MockHttpServletRequest.new(servletContext, 'GET', '/example/other.action');
response = MockHttpServletResponse.new;
actionMapping = actionMapper.getMapping(request,dispatcher.configurationManager)
puts "Name: #{actionMapping.name}"
puts "Namespace: #{actionMapping.namespace}"
puts "Method: #{actionMapping.method}"
puts "Result: #{actionMapping.result}"
Wednesday, April 16, 2008
MythTV allowing schedules but showing none
Sunday, April 6, 2008
Maemo Mapper paths.db break down
When connected to GPS mapper has a track log in the paths.db file in /home/user/.maemo-mapper/. If you take a look at the file with the sqlite3 client you'll see a table named track_path. This is where the data points are stored but they're not in degrees. A .schema reveals that the columns are called unitx and unity.
A dig through the internet found me source that was using a function called unit2latlon. So I downloaded the source from the garage and grep'd for the definition of this function. It turns out to be a macro in defines.h.
Here's the macro converted to ruby for easy use. It only does long and lat. I still have to find what the altitude is in...
TILE_SIZE_P2 = 8
MAX_ZOOM = 20
WORLD_SIZE_UNITS = 2 << MAX_ZOOM + TILE_SIZE_P2
MERCATOR_SPAN = -6.28318377773622
MERCATOR_TOP = 3.14159188886811
def unit_2_lat_lon(unitx, unity)
lon = ((unitx) * (360.0 / WORLD_SIZE_UNITS)) - 180.0
lat = (360.0 * (Math.atan( Math.exp ((unity * (MERCATOR_SPAN / WORLD_SIZE_UNITS)) + MERCATOR_TOP)))) * (1.0 / Math::PI) - 90.0;
return lat,lon
end
It's line for line the same as the Maemo-Mapper team's code. There was a lot more in the defines.h file, but this is all that's needed to run the function. I ran the last point in the database and checked the output in Google maps (straight copy and paste!) and it is where it stopped logging!
irb(main):001:0> lat,lon = unit_2_lat_lon(157094175,199470581)
=> [41.9127500226541, -74.6601469069719]
Friday, April 4, 2008
Google Maps, Maemo Mapper, GPX, KML all get me to the rally!
It started out with just printing out the pdf's and the maps, but then I got a psp and I started downloading Google maps and drawing on them and loading them as pictures. Then I got the Nokia N800, suddenly there was no need for print outs (yay! I'm going green while driving > 300 miles to a fuel burning frenzy). The N800 can handle PDFs and with the help of Maemo Mapper can handle maps for me. That coupled with a bluetooth GPS receiver gives me a really great tool for navigating to the different points. Now I have an iPhone as well which has maps and PDF abilities (if it only had GPS!)
So what I did this year was plot everything on Google Maps:
View Larger Map
The cameras are spectator points. The orange lines are the closed road courses and the blue lines are the recommended approaches to the spectator areas. While editing a map you can download the kml file to view in Google Earth. This file just contains a link to the actual .kml file that has the lines and points in it. I tried putting this file on a server and hitting it in my iPhone's maps.app. But after getting a polite error about not being able to find anything matching the search I looked on the web and found that the only kml elements Google Maps for Mobile (which maps.app is based on I hear) is the point. So lines were out and my iPhone was out.
Next I looked up what format Maemo Mapper supported, which is GPX. I fired up gpsbabel and converted my real kml file to gpx only to have Maemo Mapper choke on it. It turns out that Mapper wants only one type of dataset at a time. The kml had lines and points which were converted to "trk"'s and waypoints. But I really only needed to store my spectator areas as Points of Interest (POI). Mapper stores it's POI in a sqlite3 database in /home/user/MyDocs/.documents/Maps/poi.db by default. By getting that file I was able to write a ruby script that took out the "Point" elements from the kml file and create sql insert statements. Putting that db back and fixing permissions (I was ssh'd in as root so the file became pwn'd) gave me the spectator points. Since they're the only things in there it makes for very easy viewing!
Then came the "approaches", I have them as line fragments on the google maps but Mapper only supports Routes and tracks. I don't know if tracks would have helped me as I think they're in a db called paths.db but the routes are stored in an xml file in gpx format. Gpsbable dropped the names and descriptions when it converted the lines so I created a new ruby script that took the LineStrings from kml and created trkpt's from them. Reloading the route file in Mapper gave me my route to the place plus the route fragments to the spectator areas. Since they were all in the same route file I could then download tiles around the routes and have everything internet free. I also added a description to some of the points in the line for turn directions/hints. You can count the bends in your google map to know which one to add it to and remember it goes at the beginning of a line not the end. So if you have a right turn between segment 2 and 3 add the turn description to segment 3.
Hopefully that'll be everything I need. I'm bringing my old phone just in case I need to tether (damn you iPhone and your lame bluetooth support) to the N800 for data. Now about that battery life...
Sunday, March 30, 2008
Building source on Ubuntu
sudo apt-get install build-essential before you start!./configure --enable-optimizedchecking for C compiler default output file name... configure: error: C compiler cannot create executables See 'config.log' for more details.
I knew there was some basic install stuff you needed before hand but I had to search for it. Once installed your configure step will work.
[update]
If you have to build ruby gems with native extensions then also add
sudo apt-get install ruby1.8-dev