dannyman.toldme.com

This page features every post I write, and is dedicated to Andrew Ho.

November 15, 2013
Sundry, Technical, Technology, Testimonials

A Computer Telephone Without a Keyboard!?

Link: https://dannyman.toldme.com/2013/11/15/a-computer-telephone-without-a-keyboard/

At long last, I retired my old T-Mobile G2. It was the last in a long line of phones I have owned for the past decade with a physical keyboard. (I think I owned every Sidekick up to the 3 before going Android with the G1 and the G2.) I like the ability to thumb type into my phone, but the G2’s old keyboard had long ago gone creaky, and it had lacked a dedicated number row besides.

Obligatory picture recently taken with my new computer telephone.  Featuring a cat.

Obligatory picture recently taken with my new computer telephone. Featuring a cat.

They don’t make nice smart phones with keyboards any more. Market research seems to indicate that the only remaining markets for keyboard phones are horny teenagers who need a cheap, hip Android-based Sidekick, and those legions of high powered business people who will never abandon their ancient Blackberries.

Anyway, the new Nexus 5 is here. The on-screen keyboard is okay slow and inaccurate. Like moving from a really fantastic sports car to a hovercraft piloted by a drunken monkey. I mean,the monkey-piloted hovercraft is undeniably cool technology, and I can eventually get where I need to go, but . . . its not the same, you see?

So, lets explore Voice dictation! It works . . . well, about as well as the monkey hovercraft, but with the added benefit that you don’t have to keep jiggling your thumb across the screen. But how do you do new lines and paragraphs? Where’s the command reference?

I asked Google. Google: android voice dictation commands?

Yup. If there is a reference somewhere, Google doesn’t know about it. How sad.

There is one humorous and not overly annoying video demonstrating how to do voice dictation. Various forum posts have users saying they can’t find a reference, but simple punctuation seems to work, and sometimes you can say “new paragraph” and sometimes you can not.

I have to wonder, at times.

The other thing that excited me about the Nexus 5 was that on the home screen you can drag apps right up to “Uninstall” . . . unless they’re Google apps! “Way to not be evil,” I cried. Until a Google colleague pointed out that it was just a bit of UI funkiness on Google’s part, owing to the applications coming bolted into the UI, there is at least a method to disable them.

Anyway, this is useful knowledge that helped me to vanquish the Picasa sync thing that has been hiding images from the gallery for the past few years. I have another project where I’m testing out BitTorrent Sync to pull images off our phones and then sync a copy of the family photo archive back down to the phones. If that works out, I’ll write it up. I may pursue that further to see if I can’t replace Dropbox, which, unfortunately, does not (yet) offer any sort of a family plan. Also, if I can host my own data I needn’t share as much of it with the NSA.

Feedback Welcome

October 15, 2013
JIRA, Technology

Notes From Atlassian Summit 2013

Link: https://dannyman.toldme.com/2013/10/15/atlassian-summit/

Two weeks ago, I attended Atlassian Summit 2013 in San Francisco.  This is an opportunity to train, network, and absorb propaganda about Atlassian products (JIRA, Greenhopper, Confluence, &c.) and ecosystem partners.  I thought I would share a summary of some of the notes I took along the way, for anyone who might find interest:

At the Keynote, Atlassian launched some interesting products:

As time passes, the ticket gets crankier at you about the SLA in real time.

As time passes, the ticket gets crankier at you in real time about the SLA.

Jira Service Desk

Jira Service Desk is an extension to JIRA 6 oriented around IT needs.  The interesting features include:

The first thing helps people get their work done, and the second is manager catnip.

Confluence Knowledge Base

Confluence 5.3 features a shake-the-box Knowledge Base setup:

Other Stuff I looked into:

REST and Webhooks

There was a presentation on JIRA’s REST API, and mention of Webhooks.

REST is really easy to use.  For example, hit https://jira.atlassian.com/rest/api/latest/issue/JRA-9

There’s API docs here: https://docs.atlassian.com/jira/REST/

Another feature for tight integration is Webhooks: you can configure JIRA so that certain issue actions trigger a hit to a remote URL.  This is generally intended for building apps around JIRA.  We might use this to implement Nagios ACKs.

Atlassian Connect

I haven’t looked too deeply as this is a JIRA 6 feature, but Atlassian Connect promises to be a new method of building JIRA extensions that is lighter-weight than their traditional plugin method.  (Plugins want you to set up Eclipse and build a Java Dev environment in your workstation… Connect sounds like just build something in your own technology stack around REST and Webhooks)

Cultivating Content: Designing Wiki Solutions that Scale

Rebecca Glassman, a tech writer at Opower, gave a really engaging talk that addresses a problem that seems commonplace: how to tame the wiki jungle!  Her methodology went something like this:

As they better learned user needs and what sort of knowledge there was, they built “The BOOK” (Body of Opower Knowledge) based on a National Parks model:

(I have some more notes on how they built, launched, and promoted The BOOK.  The problem they tackled sounds all to familiar and her approach is what I have always imagined as the sort of way to go.)

Ad Hoc Canvas

The Ad Hoc Canvas plugin for Confluence caught my eye.  At first glance, it is like Trello, or Kanban, where you fill out little cards and drag them around to track things.  But it has options to organize the information in different ways depending on the task at hand: wherever you are using a spreadsheet to track knowledge or work, Ad Hoc Canvas might be a much better solution.  Just look at the videos and you get an idea . . .

The Dark Art of Performance Tuning

Adaptavist gave a presentation on performance analysis of JIRA and Confluence.  It was fairly high-level but the gist of this is that you want to monitor and trend the state of the JVM: memory, heap, garbage collection, filehandles, database connections, &c.  He had some cool graphs of stuff like garbage collection events versus latency that had helped them to analyze issues for clients.  One consideration is that each plugin and each code revision to a plugin brings a bunch of new code into the pool with its own potential for issues.  Ideally, you can set up a load testing environment for your staging system.  Short of that, the more system metrics that you can track, you can upgrade plugins one at a time and watch for any effects.  As an example, one plugin upgrade went from reserving 30 database connections to reserving 150 database connections, and that messed up performance because the rest of the system would become starved of available database connections.  (So, they figured that out and increased that resource..)

tl;dr: JIRA Performance Tuning is a variation of managing other JVM Applications

Collaboration For Executives

I popped in on this session near the end, but the takeaway for anyone who wants to deliver effective presentations to upper management are:

The presenter’s narrative was driven by an initial need to capture executive buy-in that their JIRA system was critical to business function and needed adequate resourcing.

Feedback Welcome

September 23, 2013
JIRA, Python, Technical

Jython: Timezone Manipulation and Meeting Invitations vs Outlook

Link: https://dannyman.toldme.com/2013/09/23/jython-timezone-manipulation-and-meeting-invitations-vs-outlook/

As part of a project at work I’ve built some Jython code that builds iCalendar attachments to include meeting invitations for scheduled maintenance sessions. Jython is Python-in-Java which takes some getting used to but is damned handy when you’re working with JIRA. I will share a few anecdotes:

1) For doing date and time calculations, specifically to determine locale offset from UTC, you’re a lot happier calling the Java SimpleDateFormat stuff than you are dealing with Python. Python is a beautiful language but I burned a lot of time in an earlier version of this code figuring out how to convert between different time objects for manipulation and whatnot. This is not what you would expect from an intuitive, weakly-typed language, and it is interesting to find that the more obtuse, strongly-typed language handles time zones and it just fricking works.

Here is some sample code:

from java.text import SimpleDateFormat
from com.atlassian.jira.timezone import TimeZoneManagerImpl
tzm = TimeZoneManagerImpl(ComponentManager.getInstance().getJiraAuthenticationContext(),
    ComponentManager.getInstance().getUserPreferencesManager(),
    ComponentManager.getInstance().getApplicationProperties())
# df_utc = DateFormat UTC
# df_assignee = DateFormat Assignee
df_utc = SimpleDateFormat("EEE yyyy-MM-dd HH:mm ZZZZZ (zzz)")
df_assignee = SimpleDateFormat("EEE yyyy-MM-dd HH:mm ZZZZZ (zzz)")
tz = df_utc.getTimeZone()
df_utc.setTimeZone(tz.getTimeZone("UTC"))
df_assignee.setTimeZone(tzm.getTimeZoneforUser(assignee))
issue_dict['Start_Time_text'] = df_utc.format(start_time.getTime())
issue_dict['Start_Time_html'] = df_utc.format(start_time.getTime())
if df_utc != df_assignee:
    issue_dict['Start_Time_text'] += "\r\n                   "
    issue_dict['Start_Time_text'] += df_assignee.format(start_time.getTime())
    issue_dict['Start_Time_html'] += "<br />"
    issue_dict['Start_Time_html'] += df_assignee.format(start_time.getTime())
# Get TimeZone of Assignee
# Start Time in Assignee TimeZone

Since our team is global I set up our announcement emails to render the time in UTC, and, if it is different, in the time zone of the person leading the change. For example:

Start Time: Mon 2013-09-23 23:00 +0000 (UTC)
Mon 2013-09-23 16:00 -0700 (PDT)

2) I was sending meeting invitations with the host set to the assignee of the maintenance event. This seemed reasonable to me, but when Mac Outlook saw that the host was set, it would not offer to add the event to the host’s calendar. After all, all meeting invitations come from Microsoft Outlook, right?! If I am the host it must already be on my calendar!!

I tried just not setting the host. This worked fine except now people would RSVP to the event and they would get an error stuck in their outboxes.

So . . . set the host to a bogus email address? My boss was like “just change the code to send two different invitations” which sounds easy enough for him but I know how creaky and fun to debug is my code. I came upon a better solution: I set the host address to user+calendar@domain.com. This way, Outlook is naive enough to believe the email address doesn’t match, but all our software which handles mail delivery knows the old ways of address extension . . . I can send one invitation, and have that much less messy code to maintain.

from icalendar import Calendar, Event, UTC, vText, vCalAddress
# [ . . . ]
event = Event()
# [ . . . ]
# THIS trick allows organizer to add event without breaking RSVP
# decline functionality.  (Outlook and its users suck.)
organizer_a = assignee.getEmailAddress().split('@')
organizer = vCalAddress('MAILTO:' + organizer_a[0]+ '+calendar@' +
    organizer_a[1])
organizer.params['CN'] = vText(assignee.getDisplayName() + ' (' + assignee.getName() + ')')
event['organizer'] = organizer

You can get an idea of what fun it is to build iCalendar invitations, yes? The thing with the parentheses concatenation on the CN line is to follow our organization’s convention of rendering email addresses as “user@organization.com (Full Name)”.

3) Okay, third anecdote. You see in my first code fragment that I’m building up text objects for HTML and plaintext. I feed them into templates and craft a beautiful mime multipart/alternative with HTML and nicely-formatted plaintext . . . however, if there’s a Calendar invite also attached then Microsoft Exchange blows all that away, mangles the HTML to RTF and back again to HTML, and then renders its own text version of the RTF. My effort to make a pretty text email for the users gets chewed up and spat out, and my HTML gets mangled up, too. (And, yes, I work with SysAdmins so some users actually do look at the plain text . . .) I hate you, Microsoft Exchange!

Feedback Welcome

September 6, 2013
News and Reaction, Politics

Syria vs US Credibility

Link: https://dannyman.toldme.com/2013/09/06/syria-vs-us-credibility/

One big deal is that when Hussein used chemical weapons against Iran, we knew it was happening, and instead of raising a stink, we gave him logistical support. Our credibility with regards to international law is heavily tarnished, and that undermines our claims in present day Syria.

What I would love to see is if Congress, in authorizing military action, also passed some kind of Whistle Blower Compulsion bill: if you see something, you must say something!! If you are aware that a war crime or a crime against humanity is being perpetrated, you have to tell everyone you can think of: your boss, your mom, your blog, the New York Times, hell, even tell that douchenozzle Julian Assange! Failure to disclose knowledge of such crimes should consequently open you to charges of criminal conspiracy once they are finally disclosed.

(. . . not like we would ever prosecute Americans for War Crimes, but a boy can dream . . .)

As far as the current situation in Syria goes, I am reminded of Serbia. After a few too many abuses Clinton sent in air power to disrupt their military command and control and mess up the power grid. We basically put our thumb on the scale to expedite our preferred outcome. From what I can tell, our short-term preferred outcome in Syria is a stalemate (brutal dictator vs Al Qaeda) so I don’t reckon we’ll spend much time with our thumb on the scale.

The long-term desired outcome, which is the real reason we need to take the idea of intervention seriously, is to discourage the future use of chemical weapons. “Remember when Assad looked like he might win the civil war in Syria but then he gassed civilians and the US started bombing him? Yeah, maybe we shouldn’t be too quick to reach for the chemical weapons.” This is what I hope will be an outcome of our bombing Syria.

Feedback Welcome

August 7, 2013
About Me, News and Reaction, Politics, Sundry, Testimonials

Skipping Ender’s Game

Link: https://dannyman.toldme.com/2013/08/07/skipping-enders-game/

As new parents, it is not as if we are getting out to the movies at all these days. All the same, when the Ender’s Game Movie page popped up in my Facebook I had to pay a visit, and share my opinion:

FWIW, Card has continued to advocate and advance his beliefs that homosexual people should have lesser rights than heterosexual people. If you see this movie then some of your ticket price goes to Card and will help in your own small way to advocate for discrimination. This reason alone turns me so far of the prospect of seeing this movie.

When I was younger, I loved the entire trilogy, and I would still encourage folks to borrow the books from the library, but the thought of giving another dime to Card fills me with revulsion.

Discrimination is not cool, and every dollar of revenue this movie fails to book is a dollar that has been better spent elsewhere.

Unsurprisingly, people who are planning not see go watch Ender’s Game aren’t spending much time on the movie’s Facebook page. So, comments like mine get a lot of pushback. Some guy in Netherlands reads what I said above and responds, “So you liked the books and then you learned about OSC’s beliefs and you didn’t like the books anymore?”

Which, no, that’s not quite what I said. So, I’ll try again:

Peter, I love the books. What I dislike is the idea of giving any money to a guy who uses it as a soapbox to preach that gay people should be discriminated against. I dislike the idea of giving my money to someone who preaches against the rights of homosexuals just as much as I dislike the idea of giving my money to someone preaching Racism or Sexism or Ultranationalism or Religious Extremism or any of the rest.

Fortunately, there are plenty of great books to be read, plenty of great movies to be watched, that aren’t asking me to support the cause of hateful people. There are plenty of great books I have not yet read, plenty of great movies I have yet to watch. Plenty of enjoyment to be had without giving money to those preaching a tired old hatred.

Ask yourself this: would the idealistic young kids portrayed in “Enders Game” be lining up to see a movie produced by someone preaching hate? There are surely any number of more valuable things that you could be spending your time and money on, neh?

At any rate, as I said, there’s only so much time I have to spend that I’m not going to blow too much of it debating kids on Facebook. I have done my little part, and Orson Scott Card is pretty small-fry compared to the kind of awful stuff that is happening in Russia.

Feedback Welcome

August 6, 2013
About Me, Free Style, Sundry, Technology

My Very Own Font

Link: https://dannyman.toldme.com/2013/08/06/dannyscript/

Thanks to a tip from kk.org, I recently had the fun of “building” a custom hand-written font, using PaintFont.com.

Four score and seven years ago, our fathers set forth upon this continent a new nation. One conceived in Liberty and dedicated to the proposition that All Men are Created Equal.

My regular handwriting is pretty awful. But this font is somewhat more readable. The process is you pick out the characters you’ll want in your alphabet, download and print some templates, write in the squares on the templates, scan and upload and boom, you’ve got your font. Kind of fun.

Of course, nothing’s ever quite simple. I wrestled at first with the limitations of MyScriptFont.com and a ball-point pen. That first site doesn’t do “double-quotes”. To get the font as far as I have, I also needed to use a felt pen, which is weird for me, and then review the scanned pages in a paint program to eliminate stray marks and cut the bottom tail off my capital I.

I’m pretty pleased with the results thus far. I have to use a larger size for legibility. One nice feature about the PaintFont site is that you can later add characters to your existing font file. If I ever have occasion to employ this font for a “serious” endeavor, I may try to re-render some of the characters for better legibility.

In testing a handwritten font, I find that writing out a few addresses seems to be a good test. Not only do they have a good mixture of letter casing and numbers, but that’s pretty much all I have occasion to handwrite any more anyway:

Jake & Elwood Blues
1060 W Addison St.
Chicago, IL 60613

President Obama
1600 Pennsylvania Ave NW
Washington, DC 20500

The Honorable Mike Honda
2001 Gateway Place
Suite 670W
San Jose, CA 95110

I’m not sure when this will be useful, but it is nice to have your very own font around, and the process is kind of fun. :)

Feedback Welcome

July 29, 2013
Sundry

Daddy Voice

Link: https://dannyman.toldme.com/2013/07/29/daddy-voice/

Midnight feed. Daddy changes diaper, Mommy nurses, and everyone goes back to sleep.

Dream time.

Baby wakes up screaming as only a baby can scream.

Daddy changes diaper. Baby screams.

Mommy goes to warm a bottle. Baby screams.

Baby screams.

Baby screams.

Baby sucks on bottle.

Baby’s sucking slows.

Baby’s eyes narrow.

Daddy burps baby. Baby is wide awake.

Daddy tucks baby in.

Baby begins to fuss.

Daddy looms over baby and invokes Daddy Voice.

“No. It is time to sleep.”

Baby goes quiet.

Baby closes eyes.

Baby goes to sleep.

Dream time.

Daddy is pleased that Daddy Voice works.

Fully awakened by a screaming baby, and drunk on his new power, Daddy can’t sleep.

Feedback Welcome

July 18, 2013
JIRA

Jython: Render Wiki Text in Jira

Link: https://dannyman.toldme.com/2013/07/18/jython-render-wiki-text-in-jira/

I’m building out a simple template system for our email notifications, so of course I want to support multipart, text and email. But, hey, we have some text fields in JIRA that can take wiki markup, and JIRA will format that on display. So, how do I handle those fields in my text and HTML message attachments?

https://answers.atlassian.com/questions/191567/in-a-jira-script-how-do-i-render-wiki-text-fields
https://answers.atlassian.com/questions/135084/method-to-convert-jira-wiki-format-to-html

So, some sample code to render the custom field “Change Summary” into a pair of strings, change_summary_text and change_summary_html, suitable for inclusion into an email message:

from com.atlassian.event.api import EventPublisher
from com.atlassian.jira import ComponentManager
from com.atlassian.jira.component import ComponentAccessor
from com.atlassian.jira.issue import CustomFieldManager
from com.atlassian.jira.issue.fields import CustomField
from com.atlassian.jira.issue.fields.renderer.wiki import AtlassianWikiRenderer
from com.atlassian.jira.util.velocity import VelocityRequestContextFactory
 
# Get Custom Field
cfm = ComponentManager.getInstance().getCustomFieldManager()
change_summary = issue.getCustomFieldValue(cfm.getCustomFieldObjectByName("Change Summary"))
 
# Set up Wiki renderer
eventPublisher = ComponentAccessor.getOSGiComponentInstanceOfType(EventPublisher)
velocityRequestContextFactory = ComponentAccessor.getOSGiComponentInstanceOfType(VelocityRequestContextFactory)
wikiRenderer = AtlassianWikiRenderer(eventPublisher, velocityRequestContextFactory)
 
# Render Custom Field
change_summary_html = wikiRenderer.render(change_summary, None)
change_summary_text = wikiRenderer.renderAsText(change_summary, None)

Feedback Welcome

July 15, 2013
Technology, Testimonials

Fitbit Feedback: My Own Data Are Not a “Premium” Feature

Link: https://dannyman.toldme.com/2013/07/15/fitbit-our-data-ourselves/

Feedback to Fitbit:

Hello,

I have for a long time wanted to be able to download my data. It seems simple: I buy a device to track my data, I should have access to the data collected.

It looks like now for the low low price of $50/year I can download my own data.

Honestly, that just feels slimy. They are my data. My data are not a premium feature. This restriction puts a bad taste in my mouth and that is a strong deterrent to purchasing further products from you folks. Which is too bad, since I otherwise like the hardware and I am ready to be upsold to an NFC device. But since my data are not my data … well, I’d rather just spend my money elsewhere.

Thanks,
-danny

If anyone has an activity tracker they particularly like, I am keen to hear about it.

1 Comment

July 4, 2013
News and Reaction, Sundry, Technology

Redundant BART Employees on Strike

Link: https://dannyman.toldme.com/2013/07/04/redundant-bart-employees-on-strike/

A reaction I posted to a friend’s Facebook with regard to the present BART Strike:

Fremont BART

I’m a pro-Union Liberal who thinks it is wrong to beat up on public-sector employees. I have heard that BART staff get 40 PTO days per year and there’s a scheme where you can take PTO, then take a shift, and get overtime for that. That’s something we can fix.

The train operators literally sit on their ass and watch the train drive itself. I talked to a guy who said that he did an important job of every once in a while mashing the buttons to fix something, and if he and his comrades weren’t there, BART would have to evacuate the passengers, shut the doors, and run the train empty to its terminal. Horrors!

In NYC, they’ve been laying off station agents where possible and using video cameras to aggregate agent services remotely.

I keep hoping that one of these days a labor action will be an excuse for BART to just fire the train operators and let the system run on automatic as it was designed to do. Spend the money on more frequent service so when a train occasionally has to be taken down, its replacement appears that much more quickly. Spread some of that money to the best station agents and start installing remote presence equipment to make the most of their labor.

. . . and if those train operators are even half as as good at mashing buttons in an emergency as they think they are, they can make the same salary as an entry-level SysAdmin.

Seriously, it is sad when your job is obsoleted by technology. It is even sadder when your job was obsoleted by technology before it even existed. Saddest when your skills are in extremely high demand at higher pay, but we keep paying you to do an obsolete job of extremely marginal public benefit.

Feedback Welcome

June 3, 2013
Sundry, Technology

Flickr Provides Old Users with “Closure”

Link: https://dannyman.toldme.com/2013/06/03/flickr-users-closure/

Thea Lamkin, from Flickr’s customer support, has been busy. At long last, we are getting some clarity from Yahoo:

Landscaping
“Hit the road, Jack!”

I am hearing the following: 


– you want the option to see Flickr in a “classic” view

– textual information around your photos (and sets in particular) is too hidden in the new design

– user’s organizational choices are limited and not surfaced enough, particularly with the Collections, Set, Photo hierarchy
– you want more customizability of content and layout in your photostream and home page

[ . . . ]



To put an end to speculation, and to hopefully give some people closure, the old site is not coming back. However, we will continue to improve upon the new pages . . .

[ . . . ]

We are focusing on making Justified view better and more performant, instead of supporting multiple different views.

So, basically, the full-screen view of photos without explanatory text is here to stay, and anyone who wants to view their photos in a different format should find an alternative photo sharing service.

I guess the “closure” is nice.

Feedback Welcome

May 26, 2013
Sundry, Testimonials

Scalia Resigns as Scoutmaster

Link: https://dannyman.toldme.com/2013/05/26/scalia-resigns-as-scoutmaster/

My Red State Relative Posted this to his Facebook Wall:

Justice Scalia quit his post in a terse resignation letter that read, in part: "Some of the happiest memories of my adult life have been as a scoutmaster. Huddling under blankets around the campfire, and so forth. But now, all of that has been ruined. Ruined."

“Scalia Resigns Post as Scoutmaster”

Justice Scalia quit his post in a terse resignation letter that read, in part:
“Some of the happiest memories of my adult life have been as a scoutmaster. Huddling under blankets around the campfire, and so forth. But now, all of that has been ruined. Ruined.”

I quipped that “if enough bigots quit they’ll have to start recruiting gay adult leaders.” To which my relative responded asking how I might feel about my son on a campout with the gays, or an alcoholic, and that safety, righteousness and common sense should prevail.

Turns out, this story is satire from the New Yorker, which makes it all the more delicious. I wrote back:

I thought it sounded like The Onion.

[Relative], I hope Tommy takes an interest in scouting, and I feel better to know that if he joins, he will not be denied the friendship of a fellow scout simply because one of them is gay. I hope they go camping together, and I know from first-hand experience that when Scouts exhibit a gross failure of ethical or moral conduct, their behavior is reported and disciplinary action is taken. (Like the boys who got expelled from the Scouts for shoplifting during a camping trip.)

And, for what it is worth, our Scoutmaster was a combat Veteran and a Recovering Alcoholic. He told some good stories that I think probably helped a few of us young men make smarter decisions in our adult lives. It was always hard to get a sufficient number of adults to join our outings, which is why I will be glad to see the eventual end of the exclusion of gay adult leaders.

I never made it to Eagle, but a friend of mine who did resigned his badge and sent the pin back to HQ because of the exclusion policy. I was really really proud that he would make a sacrifice for what he knew to be correct. A lot of Eagles have resigned their rank for the same reason. There’s even a blog at http://eaglebadges.tumblr.com/. It is nice to see those sacrifices have not been in vain.

2 Comments

« Newer Stuff . . . Older Stuff »
Site Archive