web

You are currently browsing the archive for the web category.

I’ve been selling used stuff on Amazon.com off and on for well over three years now — mostly used video games, movies, accessories and such. Despite fairly hefty seller fees, it’s been a lot better than the other alternatives for me. Compared to eBay, the listing process is dramatically faster and simpler, sales prices are often higher, and items stay listed (at fixed prices) until sold. Compared to craigslist, Amazon.com gets you a much wider market (helpful for obscure games & accessories), and a simpler sales process. (coordinating a meeting time just to sell a $15 game? No thanks.)

So over the weekend I was cleaning out my office and listing some old games and controllers. Then I thought about this Lenovo ThinkPad X220 I’ve been trying to sell for months. There was a listing on Amazon.com for the X220 with a couple of other used listings, so I thought it wouldn’t hurt to give it a shot. I listed it Sunday night for $725.

That ThinkPad listing must have triggered an automated account check (due to the dollar amount, no doubt) that the last 3+ years of listings did not. Hours later, close to midnight, I got this cordial email from Amazon.com (emphasis mine):

Hello from Amazon.

We are writing to let you know that we have removed your selling privileges, canceled your listings, and placed a temporary hold on any funds in your seller account.

We took this action because our records indicate that this account is related to another selling account that was closed by Amazon. Once selling privileges have been removed, sellers are not allowed to establish new accounts.

Due to the proprietary nature of our business, we do not provide detailed information on how we determine that accounts are related.

We encourage you to take appropriate steps to resolve any pending orders. Note that any amounts paid as a result of A-to-z Guarantee claims and chargebacks may be deducted from your seller account.

After 90 days, any remaining funds will be available per your settlement schedule. Once the hold has been removed, balance and settlement information will be available in the “Payments” section of your seller account. If you have questions about these funds, please write to payments-funds@amazon.com.

While we appreciate your interest in selling on Amazon.com, the closure of this account is a permanent action.

Regards,

Seller Performance Team
Amazon.com

http://www.amazon.com

The tone of the email didn’t give me a lot of hope. It’s clear that Amazon is not willing to provide details on how they made this determination, or leave an opportunity for appeal. And to be clear, I’m certain that I’ve tripped a false positive of some sort. I have never used another seller account on Amazon.com.

I logged into the seller account to see what it looked like. There was a glimmer of hope: an Appeal button. I dutifully filled out an appeal as follows:

I have never had another seller account with Amazon.com. I’ve been using this account to sell stuff off and on for over three years now, without any issues. I can only assume that this was due to an automated false positive. Please review and reinstate my account.

Amazon replied less than twelve hours later with this:

Hello from Amazon.

Thank you for writing.  After a review of your account by an account specialist, we have decided not to reinstate your selling privileges.

We regret we are unable to provide further information on this situation. Further correspondence regarding the closure of your selling account may not be answered.

The closure of this account is a permanent action. Any subsequent accounts that are opened will be closed as well.

Regards,

Seller Performance Team
Amazon.com
http://www.amazon.com

So that’s that, it seems. It’s clear from the tone of these emails they are not especially sympathetic to the concerns of sellers whose accounts have been mistakenly flagged.

eBay & Paypal have received a lot of well-deserved flak over the years, but compared to this, they come out looking good. They have email addresses and online chat systems and phone numbers answered by actual humans who provide actual details about your case. In many of the Paypal horror stories that circulate, the worst material comes from bad customer service reps. But when you deal with Amazon.com, at least as a seller, there’s no customer service rep to talk to. Cold emails like this are all you get.

I hope this will be helpful to two groups of people:

1. Sellers — look for other alternatives. If you sell on Amazon.com, don’t put all of your eggs in that basket. For me, this just meant a harder time clearing out the closet. But for someone doing a lot of sales on Amazon.com, this could cause a serious loss of business.

2. Amazon.com staff — seriously, just look at this from the customer’s point of view, and try to tell me this is a customer friendly process. More transparency is in order. Your secret fraud detection system is fallible, and it should be treated as such.

If nothing else, this has left me seriously second-guessing my loyalty to Amazon.com. They’ve been far and away my favorite Internet retailer for years, but I’m not going to be quite as eager to shop there any more, especially in categories with strong competition.

Update

Amazon just reactivated my account at 12:15 pm today (AZ time). I did not make any further attempts to contact Amazon after the above account, so I imagine that this was only done as a result of my post hitting the front page of Hacker News. The email regarding the reactivation was as follows:

Hello from Amazon.com.

Thank you for writing regarding your Amazon.com selling account. We have reviewed this situation and have reactivated your account.

We apologize for any inconvenience this has caused. In our efforts to protect our community, we sometimes err on the side of caution.

We appreciate your interest and wish you the best of luck selling on Amazon.com.

Victory? Well, partially. I’m not totally satisfied until and unless Amazon admits to problems with their fraud detection system, and puts in place a better process for recourse. Failing that, others who don’t get this level of publicity will continue to get shafted.

Update 2

Here’s my blog’s visitor count by service provider, per Google Analytics. Looks like a few people at Amazon have taken notice.

I’ve spent the better part of the last six months doing front-end development on a Java project developed with the Spring framework. We’re currently going through the process of internationalizing the application. This necessitated spending a fair amount of time combing through all the raw English strings in templates and replacing them with Spring directives, to be filled in by the .properties file for the user’s locale.

While there is a lot more to internationalization than replacing static text strings, it’s the first (and perhaps largest) task to tackle. Here’s what that process looks like.

Let’s start with a simple template like this:

<ul>
    <li><a href="${welcomeurl}">Welcome</a></li>
    <li><a href="${registerurl}">Register</a></li>
    <li><a href="${contacturl}">Contact Us</a></li>
    <li><a href="${abouturl}">About</a></li>
</ul>

To internationalize it, you replace all of your raw text with spring:message directives as follows:

<ul>
    <li><a href="${welcomeurl}"><spring:message code="common_site_welcome"/></a></li>
    <li><a href="${registerurl}"><spring:message code="common_site_register"/></a></li>
    <li><a href="${contacturl}"><spring:message code="common_site_contact"/></a></li>
    <li><a href="${abouturl}"><spring:message code="common_site_about"/></a></li>
</ul>

Ugh, all of my readable text replaced by XML. OK then.

We’re not done yet; as mentioned, some .properties files need to be created to fill in the proper text strings. So for US English, you would create i18n/messages_en_US.properties as follows:

common_site_welcome=Welcome
common_site_register=Register
common_site_contactUs=Contact Us
common_site_about=About

and for Spanish, i18n/messages_es.properties as follows:

common_site_welcome=Bienvenido
common_site_register=Registro
common_site_contactUs=Contáctenos
common_site_about=Sobre

and if everything is configured correctly, you now have Spanish localization for those strings. Congratulations.

Enter Flask

That’s not where the story ends. This is a public-facing application, and that means there’s a marketing site to go with it. It’s currently just static html, so I thought it would be best to use a simple web framework for proper i18n support (among other things). I turned to my go-to micro-framework, Flask, and set up a small sample app to test out the i18n support.

Flask (along with Django and many other web frameworks) uses the standard GNU gettext API for i18n. Here’s how it works. We start out much the same as in the Spring example, except with Jinja2 templates and Flask’s url_for() function:

<ul>
    <li><a href="{{ url_for('welcome') }}">Welcome</a></li>
    <li><a href="{{ url_for('register') }}">Register</a></li>
    <li><a href="{{ url_for('contact') }}">Contact Us</a></li>
    <li><a href="{{ url_for('about') }}">About</a></li>
</ul>

now to internationalize that template, we just do this:

<ul>
	<li><a href="{{ url_for('welcome') }}">{{ _('Welcome') }}</a></li>
	<li><a href="{{ url_for('register') }}">{{ _('Register') }}</a></li>
	<li><a href="{{ url_for('contact') }}">{{ _('Contact Us') }}</a></li>
	<li><a href="{{ url_for('about') }}">{{ _('About') }}</a></li>
</ul>

Very cool. I just wrap all strings with a short function (_() is the common alias for gettext()) and they’re ready for localization.

Now what about messages? For that, we’ll turn to the Flask-Babel extension. After a short config file, we can do this to extract all i18n strings:

$ pybabel extract -F babel.cfg -o messages.pot .

That will give us a file with all the extracted strings from our Jinja2 template, along with some header info. What’s interesting here is the extra metadata you get with each string:

#: templates/index.html:8
msgid "Welcome"
msgstr ""

#: templates/index.html:9
msgid "Register"
msgstr ""

To generate a message file from messages.pot for a given language (Spanish again in this example), follow with this:

$ pybabel init -i messages.pot -d translations -l es

The resulting file looks much the same as messages.pot. This is the file to send off to the translator.

Taking stock of the two approaches

I see a number of benefits to the approach employed by Flask (and by extension, other frameworks that use gettext tools):

  1. Templates preserve the original English — that makes them easier to convert, more readable, and more searchable.
  2. The Flask approach adds 11 total characters to internationalize a string; Spring adds 25 (and that assumes the variable is the same length as the original English. In a larger project the tendency will be to make it longer for pseudo-namespacing as in the example.)
  3. Spring requires the programmer to define variables for every piece of static text, and manually add them to a properties file. Flask extracts strings with a single command.
  4. Flask’s messages.po files include the file & line number the string came from, as well as the original (English) string. The .properties files in Spring just have a variable name.
  5. In Flask, added and changed strings can be extracted by running a pybabel update command. This will add the new strings to all translations, and mark changed text as “fuzzy”. In Spring, you have to manage additions and changes across all files by hand.

I’m not able to come up with much in favor of the Spring approach honestly. The gettext method seems a lot easier and more maintainable, especially as the size of the project and number of supported languages increases.

Google drops H.264 support in Chrome

Plenty of tech pundits have given their two cents on Google’s turn toward WebM exclusivity, and the vibe is decidedly negative. On the other hand, the move has garnered strong support from Mozilla and Opera, and not surprisingly, the Free Software Foundation.

My take on this is somewhat conflicted. Gruber has a point that content providers will continue to use H.264, and just use Flash for clients that don’t serve it directly. At least, in the short term. On the desktop, however, WebM is now poised to take a decided market share lead. Firefox (in 4.0 beta), Chrome and Opera are all shipping with WebM (and that exclusively); while only Safari and IE remain in the H.264 camp. IE alone could tip the scales in favor of H.264, but support is only coming in version 9 (still in beta). Considering the glacial pace of user adoption for new versions of IE, I’m betting that’s at least two years out.

There will be plenty of time for WebM to gain traction, and with Adobe soon adding WebM support to Flash, the tables could turn one day — clients not supporting WebM may default to Flash on many sites. Firefox (and likely now Google) have taken a stand against ever supporting H.264, but the opposite is not true for Apple and Microsoft — if WebM gains enough momentum, it’s likely that they (especially Apple) will add WebM support .

The mobile picture is murkier. H.264 has more of a stronghold there, due to Apple’s strong position, and the importance of hardware decoder support. Even there, word is that WebM hardware support is coming on many chipsets this year. Within the next year or two, it may be commonplace for chipsets to support both formats out of the box.

On the other hand: critics have a valid point that Google’s ideological justification for this move (“hooray for open”) rings hollow, considering Google’s recent embrace of Flash. It would be one thing if Google merely tolerated Flash due to its ubiquitous use on the web, but there’s more to it than that. Does no one remember Google I/O? Google was practically gloating about Flash support on Android, and Flash support on mobile certainly isn’t the sort of obligation that it’s become on the desktop. In fact, many people (myself included) would prefer that mobile platforms remain Flash-free. Not only that, they also announced support for Adobe AIR on Android, trumpeting both with big shiny icons (Flash more than once). And for good measure, they invited Adobe CEO Shantanu Narayen (among others) on stage. This is far more than toleration–Google has embraced Flash as a competitive advantage against Apple. Open, schmopen; we’ve got it and they don’t. That was Google, circa Google I/O 2010. It’s doubtful that this move means they’ll treat Flash with any less deference.

HTML5 now just “HTML”

HTML5 is now a misnomer — the WHATWG, the standards body charged with defining this stuff, has decided to turn HTML into a rolling standard. There will be no HTML5.1, HTML6, or what have you. Just continuous revisions of HTML. Oddly this comes just a day after the W3C unveiled their shiny new HTML5 logo too.

This is a nice development, if only because HTML5 has become an extremely overloaded buzzword. When people say that, they could mean any number of things. Often it just means “dynamic, JavaScript-driven site.” It usually doesn’t mean new semantic markup elements, Web Workers, or Web Storage — all genuine constituents of the standard formerly known as HTML5. Assuming people get the message, this hopefully compel them to use more accurate terminology.

I’m not so optimistic about recruiters and their ilk, though. Expect to see job ads erroneously demanding HTML5 skills for some time — probably until another buzzword is found to take its place.